summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-08-08 18:23:31 +0000
committerJordan Rose <jordan_rose@apple.com>2012-08-08 18:23:31 +0000
commit356279ca2de74b0deb274a8b16396bdaebfec92b (patch)
treee55456feb9d16df82038375a4c9292091adaf575 /clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
parent3a80cec5e92da70064541f1d11222e2e5c2d4e8c (diff)
downloadbcm5719-llvm-356279ca2de74b0deb274a8b16396bdaebfec92b.tar.gz
bcm5719-llvm-356279ca2de74b0deb274a8b16396bdaebfec92b.zip
[analyzer] Track malloc'd regions stored in structs.
The main blocker on this (besides the previous commit) was that ScanReachableSymbols was not looking through LazyCompoundVals. Once that was fixed, it's easy enough to clear out malloc data on return, just like we do when we bind to a global region. <rdar://problem/10872635> llvm-svn: 161511
Diffstat (limited to 'clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp')
-rw-r--r--clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp30
1 files changed, 14 insertions, 16 deletions
diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index 4f19c2ee079..d384bc34f9a 100644
--- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -1000,10 +1000,11 @@ void MallocChecker::reportLeak(SymbolRef Sym, ExplodedNode *N,
SmallString<200> buf;
llvm::raw_svector_ostream os(buf);
os << "Memory is never released; potential leak";
- if (Region) {
+ // FIXME: Make all region pretty-printing nice enough to show.
+ if (Region && isa<VarRegion>(Region)) {
os << " of memory pointed to by '";
Region->dumpPretty(os);
- os <<'\'';
+ os << '\'';
}
BugReport *R = new BugReport(*BT_Leak, os.str(), N, LocUsedForUniqueing);
@@ -1117,7 +1118,8 @@ void MallocChecker::checkPreStmt(const ReturnStmt *S, CheckerContext &C) const {
return;
// Check if we are returning a symbol.
- SVal RetVal = C.getState()->getSVal(E, C.getLocationContext());
+ ProgramStateRef State = C.getState();
+ SVal RetVal = State->getSVal(E, C.getLocationContext());
SymbolRef Sym = RetVal.getAsSymbol();
if (!Sym)
// If we are returning a field of the allocated struct or an array element,
@@ -1128,16 +1130,18 @@ void MallocChecker::checkPreStmt(const ReturnStmt *S, CheckerContext &C) const {
if (const SymbolicRegion *BMR =
dyn_cast<SymbolicRegion>(MR->getBaseRegion()))
Sym = BMR->getSymbol();
- if (!Sym)
- return;
// Check if we are returning freed memory.
- if (checkUseAfterFree(Sym, C, E))
- return;
+ if (Sym)
+ if (checkUseAfterFree(Sym, C, E))
+ return;
- // If this function body is not inlined, check if the symbol is escaping.
- if (C.getLocationContext()->getParent() == 0)
- checkEscape(Sym, E, C);
+ // If this function body is not inlined, stop tracking any returned symbols.
+ if (C.getLocationContext()->getParent() == 0) {
+ State =
+ State->scanReachableSymbols<StopTrackingCallback>(RetVal).getState();
+ C.addTransition(State);
+ }
}
// TODO: Blocks should be either inlined or should call invalidate regions
@@ -1245,12 +1249,6 @@ void MallocChecker::checkBind(SVal loc, SVal val, const Stmt *S,
if (StoredVal != val)
escapes = (state == (state->bindLoc(*regionLoc, val)));
}
- if (!escapes) {
- // Case 4: We do not currently model what happens when a symbol is
- // assigned to a struct field, so be conservative here and let the symbol
- // go. TODO: This could definitely be improved upon.
- escapes = !isa<VarRegion>(regionLoc->getRegion());
- }
}
// If our store can represent the binding and we aren't storing to something
OpenPOWER on IntegriCloud