aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Checkers/MallocChecker.cpp
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2012-03-16 23:24:20 +0000
committerAnna Zaks <ganna@apple.com>2012-03-16 23:24:20 +0000
commit56a938ff85a444eb3d30d2634d92ce5b1f6fae56 (patch)
tree9d85719ed51903e12e39c5f7d4db93f727f37763 /lib/StaticAnalyzer/Checkers/MallocChecker.cpp
parent076add680e281709cf081052be0dcb822dc8f37d (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.cpp38
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);
}