aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/BugReporter.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/Core/BugReporter.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/Core/BugReporter.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/BugReporter.cpp33
1 files changed, 20 insertions, 13 deletions
diff --git a/lib/StaticAnalyzer/Core/BugReporter.cpp b/lib/StaticAnalyzer/Core/BugReporter.cpp
index b59405bcd2..363a6dffee 100644
--- a/lib/StaticAnalyzer/Core/BugReporter.cpp
+++ b/lib/StaticAnalyzer/Core/BugReporter.cpp
@@ -380,22 +380,29 @@ PathDiagnosticBuilder::getEnclosingStmtLocation(const Stmt *S) {
//===----------------------------------------------------------------------===//
// "Minimal" path diagnostic generation algorithm.
//===----------------------------------------------------------------------===//
+typedef std::pair<PathDiagnosticCallPiece*, const ExplodedNode*> StackDiagPair;
+typedef SmallVector<StackDiagPair, 6> StackDiagVector;
+
static void updateStackPiecesWithMessage(PathDiagnosticPiece *P,
- llvm::SmallVector<PathDiagnosticCallPiece*, 6> &CallStack) {
+ StackDiagVector &CallStack) {
// If the piece contains a special message, add it to all the call
// pieces on the active stack.
if (PathDiagnosticEventPiece *ep =
dyn_cast<PathDiagnosticEventPiece>(P)) {
- StringRef stackMsg = ep->getCallStackMessage();
- if (!stackMsg.empty())
- for (llvm::SmallVector<PathDiagnosticCallPiece*, 6>::iterator
- I = CallStack.begin(), E = CallStack.end(); I != E; ++I)
+ if (ep->hasCallStackHint())
+ for (StackDiagVector::iterator I = CallStack.begin(),
+ E = CallStack.end(); I != E; ++I) {
+ PathDiagnosticCallPiece *CP = I->first;
+ const ExplodedNode *N = I->second;
+ StringRef stackMsg = ep->getCallStackMessage(N);
+
// The last message on the path to final bug is the most important
// one. Since we traverse the path backwards, do not add the message
// if one has been previously added.
- if (!(*I)->hasCallStackMessage())
- (*I)->setCallStackMessage(stackMsg);
+ if (!CP->hasCallStackMessage())
+ CP->setCallStackMessage(stackMsg);
+ }
}
}
@@ -410,7 +417,7 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
const ExplodedNode *NextNode = N->pred_empty()
? NULL : *(N->pred_begin());
- llvm::SmallVector<PathDiagnosticCallPiece*, 6> CallStack;
+ StackDiagVector CallStack;
while (NextNode) {
N = NextNode;
@@ -424,7 +431,7 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
PathDiagnosticCallPiece::construct(N, *CE, SMgr);
PD.getActivePath().push_front(C);
PD.pushActivePath(&C->path);
- CallStack.push_back(C);
+ CallStack.push_back(StackDiagPair(C, N));
continue;
}
@@ -446,7 +453,7 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
}
C->setCallee(*CE, SMgr);
if (!CallStack.empty()) {
- assert(CallStack.back() == C);
+ assert(CallStack.back().first == C);
CallStack.pop_back();
}
continue;
@@ -1047,7 +1054,7 @@ static void GenerateExtensivePathDiagnostic(PathDiagnostic& PD,
const ExplodedNode *N) {
EdgeBuilder EB(PD, PDB);
const SourceManager& SM = PDB.getSourceManager();
- llvm::SmallVector<PathDiagnosticCallPiece*, 6> CallStack;
+ StackDiagVector CallStack;
const ExplodedNode *NextNode = N->pred_empty() ? NULL : *(N->pred_begin());
while (NextNode) {
@@ -1068,7 +1075,7 @@ static void GenerateExtensivePathDiagnostic(PathDiagnostic& PD,
PathDiagnosticCallPiece::construct(N, *CE, SM);
PD.getActivePath().push_front(C);
PD.pushActivePath(&C->path);
- CallStack.push_back(C);
+ CallStack.push_back(StackDiagPair(C, N));
break;
}
@@ -1104,7 +1111,7 @@ static void GenerateExtensivePathDiagnostic(PathDiagnostic& PD,
EB.addContext(CE->getCallExpr());
if (!CallStack.empty()) {
- assert(CallStack.back() == C);
+ assert(CallStack.back().first == C);
CallStack.pop_back();
}
break;