diff options
author | Anna Zaks <ganna@apple.com> | 2012-03-16 23:24:20 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2012-03-16 23:24:20 +0000 |
commit | 56a938ff85a444eb3d30d2634d92ce5b1f6fae56 (patch) | |
tree | 9d85719ed51903e12e39c5f7d4db93f727f37763 /lib/StaticAnalyzer/Checkers/MallocChecker.cpp | |
parent | 076add680e281709cf081052be0dcb822dc8f37d (diff) |
[analyzer] Create symbol-aware stack hints (building upon r152837).
The symbol-aware stack hint combines the checker-provided message
with the information about how the symbol was passed to the callee: as
a parameter or a return value.
For malloc, the generated messages look like this :
"Returning from 'foo'; released memory via 1st parameter"
"Returning from 'foo'; allocated memory via 1st parameter"
"Returning from 'foo'; allocated memory returned"
"Returning from 'foo'; reallocation of 1st parameter failed"
(We are yet to handle cases when the symbol is a field in a struct or
an array element.)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@152962 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Checkers/MallocChecker.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Checkers/MallocChecker.cpp | 38 |
1 files changed, 31 insertions, 7 deletions
diff --git a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index e071626eb6..2926fd5c04 100644 --- a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -243,6 +243,29 @@ private: const ExplodedNode *PrevN, BugReporterContext &BRC, BugReport &BR); + private: + class StackHintGeneratorForReallocationFailed + : public StackHintGeneratorForSymbol { + public: + StackHintGeneratorForReallocationFailed(SymbolRef S, StringRef M) + : StackHintGeneratorForSymbol(S, M) {} + + virtual std::string getMessageForArg(const Expr *ArgE, unsigned ArgIndex) { + SmallString<200> buf; + llvm::raw_svector_ostream os(buf); + + os << "; reallocation of "; + // Printed parameters start at 1, not 0. + printOrdinal(++ArgIndex, os); + os << " parameter failed"; + + return os.str(); + } + + virtual std::string getMessageForReturn(const CallExpr *CallExpr) { + return "; reallocation of returned value failed"; + } + }; }; }; } // end anonymous namespace @@ -1249,7 +1272,7 @@ MallocChecker::MallocBugVisitor::VisitNode(const ExplodedNode *N, const Stmt *S = 0; const char *Msg = 0; - const char *StackMsg = 0; + StackHintGeneratorForSymbol *StackHint = 0; // Retrieve the associated statement. ProgramPoint ProgLoc = N->getLocation(); @@ -1269,14 +1292,15 @@ MallocChecker::MallocBugVisitor::VisitNode(const ExplodedNode *N, if (Mode == Normal) { if (isAllocated(RS, RSPrev, S)) { Msg = "Memory is allocated"; - StackMsg = ", which allocated memory"; + StackHint = new StackHintGeneratorForSymbol(Sym, "; allocated memory"); } else if (isReleased(RS, RSPrev, S)) { Msg = "Memory is released"; - StackMsg = ", which released memory"; + StackHint = new StackHintGeneratorForSymbol(Sym, "; released memory"); } else if (isReallocFailedCheck(RS, RSPrev, S)) { Mode = ReallocationFailed; Msg = "Reallocation failed"; - StackMsg = ", where reallocation failed"; + StackHint = new StackHintGeneratorForReallocationFailed(Sym, + "; reallocation failed"); } // We are in a special mode if a reallocation failed later in the path. @@ -1296,18 +1320,18 @@ MallocChecker::MallocBugVisitor::VisitNode(const ExplodedNode *N, if (!(FunName.equals("realloc") || FunName.equals("reallocf"))) return 0; Msg = "Attempt to reallocate memory"; - StackMsg = ", which attempted to reallocate memory"; + StackHint = new StackHintGeneratorForSymbol(Sym, "; reallocated memory"); Mode = Normal; } if (!Msg) return 0; - assert(StackMsg); + assert(StackHint); // Generate the extra diagnostic. PathDiagnosticLocation Pos(S, BRC.getSourceManager(), N->getLocationContext()); - return new PathDiagnosticEventPiece(Pos, Msg, true, StackMsg); + return new PathDiagnosticEventPiece(Pos, Msg, true, StackHint); } |