diff options
author | Ted Kremenek <kremenek@apple.com> | 2009-04-01 21:12:06 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2009-04-01 21:12:06 +0000 |
commit | afb066d1f551c0449c0fc1d53d41bee2bbfe674e (patch) | |
tree | b847e5b01a4090d890b25d55f3521f74d8a258ca | |
parent | d978cc5c63293b38778d771e001b181b9fdf1f5d (diff) | |
download | bcm5719-llvm-afb066d1f551c0449c0fc1d53d41bee2bbfe674e.tar.gz bcm5719-llvm-afb066d1f551c0449c0fc1d53d41bee2bbfe674e.zip |
BugReporter, extensive path-diagnostics: add an extra control-flow edge to the
enclosing statement when jumping to a subexpression.
llvm-svn: 68244
-rw-r--r-- | clang/lib/Analysis/BugReporter.cpp | 32 |
1 files changed, 32 insertions, 0 deletions
diff --git a/clang/lib/Analysis/BugReporter.cpp b/clang/lib/Analysis/BugReporter.cpp index 434b2d5cde7..5047e718049 100644 --- a/clang/lib/Analysis/BugReporter.cpp +++ b/clang/lib/Analysis/BugReporter.cpp @@ -793,6 +793,38 @@ static void GenExtAddEdge(PathDiagnostic& PD, return; } + // Add an extra edge when jumping between contexts. + while (1) { + if (const Stmt *PS = PrevLoc.asStmt()) + if (const Stmt *NS = NewLoc.asStmt()) { + PathDiagnosticLocation X = PDB.getEnclosingStmtLocation(PS); + // FIXME: We need a version of getParent that ignores '()' and casts. + const Stmt *parentX = PDB.getParent(X.asStmt()); + + const PathDiagnosticLocation &Y = PDB.getEnclosingStmtLocation(NS); + // FIXME: We need a version of getParent that ignores '()' and casts. + const Stmt *parentY = PDB.getParent(Y.asStmt()); + + if (IsControlFlowExpr(parentX)) { + if (IsControlFlowExpr(parentY) && parentX == parentY) { + break; + } + else { + const PathDiagnosticLocation &W = + PDB.getEnclosingStmtLocation(PDB.getParent(parentX)); + + if (W != Y) X = W; + } + } + + if (X != Y && PrevLoc.asLocation() != X.asLocation()) { + PD.push_front(new PathDiagnosticControlFlowPiece(X, PrevLoc)); + PrevLoc = X; + } + } + break; + } + PD.push_front(new PathDiagnosticControlFlowPiece(NewLoc, PrevLoc)); PrevLoc = NewLoc; } |