diff options
author | Ted Kremenek <kremenek@apple.com> | 2012-02-24 07:12:52 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2012-02-24 07:12:52 +0000 |
commit | 59950d3aa54ca5066b1fb08a8c79ebfe10e0919b (patch) | |
tree | 42e09268601f206429dff425979de880528f8aca /lib/StaticAnalyzer/Core/BugReporter.cpp | |
parent | 5b03c17bc9cdc0989e59d73c8f76279600812b60 (diff) |
Make PathDiagnosticBuilder sensitive to varying LocationContexts, thus fixing a bug in the inlining diagnostics where the wrong location could be used.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151349 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/BugReporter.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/BugReporter.cpp | 44 |
1 files changed, 21 insertions, 23 deletions
diff --git a/lib/StaticAnalyzer/Core/BugReporter.cpp b/lib/StaticAnalyzer/Core/BugReporter.cpp index 0c91164045..de3c8ed81a 100644 --- a/lib/StaticAnalyzer/Core/BugReporter.cpp +++ b/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -136,11 +136,14 @@ class PathDiagnosticBuilder : public BugReporterContext { OwningPtr<ParentMap> PM; NodeMapClosure NMC; public: + const LocationContext *LC; + PathDiagnosticBuilder(GRBugReporter &br, BugReport *r, NodeBackMap *Backmap, PathDiagnosticConsumer *pdc) : BugReporterContext(br), - R(r), PDC(pdc), NMC(Backmap) {} + R(r), PDC(pdc), NMC(Backmap), LC(r->getErrorNode()->getLocationContext()) + {} PathDiagnosticLocation ExecutionContinues(const ExplodedNode *N); @@ -150,12 +153,8 @@ public: BugReport *getBugReport() { return R; } Decl const &getCodeDecl() { return R->getErrorNode()->getCodeDecl(); } - - const LocationContext* getLocationContext() { - return R->getErrorNode()->getLocationContext(); - } - - ParentMap& getParentMap() { return R->getErrorNode()->getParentMap(); } + + ParentMap& getParentMap() { return LC->getParentMap(); } const Stmt *getParent(const Stmt *S) { return getParentMap().getParent(S); @@ -178,7 +177,7 @@ public: PathDiagnosticLocation PathDiagnosticBuilder::ExecutionContinues(const ExplodedNode *N) { if (const Stmt *S = GetNextStmt(N)) - return PathDiagnosticLocation(S, getSourceManager(), getLocationContext()); + return PathDiagnosticLocation(S, getSourceManager(), LC); return PathDiagnosticLocation::createDeclEnd(N->getLocationContext(), getSourceManager()); @@ -239,7 +238,6 @@ PathDiagnosticBuilder::getEnclosingStmtLocation(const Stmt *S) { assert(S && "Null Stmt *passed to getEnclosingStmtLocation"); ParentMap &P = getParentMap(); SourceManager &SMgr = getSourceManager(); - const LocationContext *LC = getLocationContext(); while (IsNested(S, P)) { const Stmt *Parent = P.getParentIgnoreParens(S); @@ -521,11 +519,12 @@ static void GenerateMinimalPathDiagnostic(PathDiagnostic& PD, const ExplodedNode *N) { SourceManager& SMgr = PDB.getSourceManager(); - const LocationContext *LC = PDB.getLocationContext(); + const LocationContext *LC = PDB.LC; const ExplodedNode *NextNode = N->pred_empty() ? NULL : *(N->pred_begin()); while (NextNode) { N = NextNode; + PDB.LC = N->getLocationContext(); NextNode = GetPredecessorNode(N); ProgramPoint P = N->getLocation(); @@ -910,7 +909,7 @@ class EdgeBuilder { } if (S != Original) - L = PathDiagnosticLocation(S, L.getManager(), PDB.getLocationContext()); + L = PathDiagnosticLocation(S, L.getManager(), PDB.LC); } if (firstCharOnly) @@ -947,7 +946,7 @@ public: // Finally, add an initial edge from the start location of the first // statement (if it doesn't already exist). PathDiagnosticLocation L = PathDiagnosticLocation::createDeclBegin( - PDB.getLocationContext(), + PDB.LC, PDB.getSourceManager()); if (L.isValid()) rawAddEdge(L); @@ -1130,7 +1129,7 @@ void EdgeBuilder::addContext(const Stmt *S) { if (!S) return; - PathDiagnosticLocation L(S, PDB.getSourceManager(), PDB.getLocationContext()); + PathDiagnosticLocation L(S, PDB.getSourceManager(), PDB.LC); while (!CLocs.empty()) { const PathDiagnosticLocation &TopContextLoc = CLocs.back(); @@ -1178,15 +1177,13 @@ static void GenerateExtensivePathDiagnostic(PathDiagnostic& PD, PD.pushActivePath(&C->path); break; } - - // Was the predecessor in a different stack frame? - if (NextNode && - !isa<CallExit>(NextNode->getLocation()) && - NextNode->getLocationContext()->getCurrentStackFrame() != - N->getLocationContext()->getCurrentStackFrame()) { - EB.flushLocations(); - } - + + // Note that is important that we update the LocationContext + // after looking at CallExits. CallExit basically adds an + // edge in the *caller*, so we don't want to update the LocationContext + // too soon. + PDB.LC = N->getLocationContext(); + // Pop the call hierarchy if we are done walking the contents // of a function call. if (const CallEnter *CE = dyn_cast<CallEnter>(&P)) { @@ -1204,6 +1201,7 @@ static void GenerateExtensivePathDiagnostic(PathDiagnostic& PD, if (!C) C = PathDiagnosticCallPiece::construct(PD.getActivePath()); C->setCallee(*CE, SM); + EB.flushLocations(); EB.addContext(CE->getCallExpr()); break; } @@ -1215,7 +1213,7 @@ static void GenerateExtensivePathDiagnostic(PathDiagnostic& PD, // Are we jumping to the head of a loop? Add a special diagnostic. if (const Stmt *Loop = BE->getDst()->getLoopTarget()) { - PathDiagnosticLocation L(Loop, SM, PDB.getLocationContext()); + PathDiagnosticLocation L(Loop, SM, PDB.LC); const CompoundStmt *CS = NULL; if (!Term) { |