aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
diff options
context:
space:
mode:
authorJordy Rose <jediknil@belkadan.com>2012-03-24 03:15:09 +0000
committerJordy Rose <jediknil@belkadan.com>2012-03-24 03:15:09 +0000
commitb000fb5999265d12d54a1ef9f31848c9e334dcaa (patch)
tree77e7db92ee0e2442459413aa78377cb0030b5a73 /lib/StaticAnalyzer/Checkers/MallocChecker.cpp
parent3bc75ca0a636efdc93471c9b6bad43085a22bf3a (diff)
[analyzer] Tighten up the realloc() failure path note generation...make sure we get the right realloc()!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@153370 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Checkers/MallocChecker.cpp')
-rw-r--r--lib/StaticAnalyzer/Checkers/MallocChecker.cpp53
1 files changed, 31 insertions, 22 deletions
diff --git a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
index f5218746be..5eca9178ad 100644
--- a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
@@ -201,16 +201,22 @@ private:
protected:
enum NotificationMode {
Normal,
- Complete,
ReallocationFailed
};
// The allocated region symbol tracked by the main analysis.
SymbolRef Sym;
- NotificationMode Mode;
- public:
- MallocBugVisitor(SymbolRef S) : Sym(S), Mode(Normal) {}
+ // The mode we are in, i.e. what kind of diagnostics will be emitted.
+ NotificationMode Mode;
+
+ // A symbol from when the primary region should have been reallocated.
+ SymbolRef FailedReallocSymbol;
+
+ public:
+ MallocBugVisitor(SymbolRef S)
+ : Sym(S), Mode(Normal), FailedReallocSymbol(0) {}
+
virtual ~MallocBugVisitor() {}
void Profile(llvm::FoldingSetNodeID &ID) const {
@@ -1390,30 +1396,33 @@ MallocChecker::MallocBugVisitor::VisitNode(const ExplodedNode *N,
StackHint = new StackHintGeneratorForReallocationFailed(Sym,
"Reallocation failed");
- if (SymbolRef sym = findFailedReallocSymbol(state, statePrev))
+ if (SymbolRef sym = findFailedReallocSymbol(state, statePrev)) {
+ // Is it possible to fail two reallocs WITHOUT testing in between?
+ assert((!FailedReallocSymbol || FailedReallocSymbol == sym) &&
+ "We only support one failed realloc at a time.");
BR.markInteresting(sym);
+ FailedReallocSymbol = sym;
+ }
}
// We are in a special mode if a reallocation failed later in the path.
} else if (Mode == ReallocationFailed) {
- // Generate a special diagnostic for the first realloc we find.
- if (!isAllocated(RS, RSPrev, S) && !isReleased(RS, RSPrev, S))
- return 0;
+ assert(FailedReallocSymbol && "No symbol to look for.");
- // Check that the name of the function is realloc.
- const CallExpr *CE = dyn_cast<CallExpr>(S);
- if (!CE)
- return 0;
- const FunctionDecl *funDecl = CE->getDirectCallee();
- if (!funDecl)
- return 0;
- StringRef FunName = funDecl->getName();
- if (!(FunName.equals("realloc") || FunName.equals("reallocf")))
- return 0;
- Msg = "Attempt to reallocate memory";
- StackHint = new StackHintGeneratorForSymbol(Sym,
- "Returned reallocated memory");
- Mode = Normal;
+ // Is this is the first appearance of the reallocated symbol?
+ if (!statePrev->get<RegionState>(FailedReallocSymbol)) {
+ // If we ever hit this assert, that means BugReporter has decided to skip
+ // node pairs or visit them out of order.
+ assert(state->get<RegionState>(FailedReallocSymbol) &&
+ "Missed the reallocation point");
+
+ // We're at the reallocation point.
+ Msg = "Attempt to reallocate memory";
+ StackHint = new StackHintGeneratorForSymbol(Sym,
+ "Returned reallocated memory");
+ FailedReallocSymbol = NULL;
+ Mode = Normal;
+ }
}
if (!Msg)