diff options
author | George Karpenkov <ekarpenkov@apple.com> | 2018-02-23 23:26:54 +0000 |
---|---|---|
committer | George Karpenkov <ekarpenkov@apple.com> | 2018-02-23 23:26:54 +0000 |
commit | 80e4ba24b9baa6d7312df70b681e613cc85a77f3 (patch) | |
tree | a19c02f827b9bdbdeb7da544b5629d2002e3d03c /clang/lib/StaticAnalyzer/Core/BugReporter.cpp | |
parent | c79333413a5b9738ac43417173f44794efb3a7c8 (diff) | |
download | bcm5719-llvm-80e4ba24b9baa6d7312df70b681e613cc85a77f3.tar.gz bcm5719-llvm-80e4ba24b9baa6d7312df70b681e613cc85a77f3.zip |
[analyzer] Consider switch- and goto- labels when constructing the set of executed lines
When viewing the report in the collapsed mode the label signifying where
did the execution go is often necessary for properly understanding the
context.
Differential Revision: https://reviews.llvm.org/D43145
llvm-svn: 325975
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/BugReporter.cpp')
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/BugReporter.cpp | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp index 6e8b05b820a..5d32ef36327 100644 --- a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -3547,6 +3547,16 @@ static void populateExecutedLinesWithFunctionSignature( ExecutedLines->operator[](FID.getHashValue()).insert(Line); } +static void populateExecutedLinesWithStmt( + const Stmt *S, SourceManager &SM, + std::unique_ptr<FilesToLineNumsMap> &ExecutedLines) { + SourceLocation Loc = S->getSourceRange().getBegin(); + SourceLocation ExpansionLoc = SM.getExpansionLoc(Loc); + FileID FID = SM.getFileID(ExpansionLoc); + unsigned LineNo = SM.getExpansionLineNumber(ExpansionLoc); + ExecutedLines->operator[](FID.getHashValue()).insert(LineNo); +} + /// \return all executed lines including function signatures on the path /// starting from \p N. static std::unique_ptr<FilesToLineNumsMap> @@ -3567,13 +3577,21 @@ findExecutedLines(SourceManager &SM, const ExplodedNode *N) { populateExecutedLinesWithFunctionSignature(D, SM, ExecutedLines); } else if (const Stmt *S = PathDiagnosticLocation::getStmt(N)) { + populateExecutedLinesWithStmt(S, SM, ExecutedLines); + + // Show extra context for some parent kinds. + const Stmt *P = N->getParentMap().getParent(S); + + // The path exploration can die before the node with the associated + // return statement is generated, but we do want to show the whole + // return. + if (auto *RS = dyn_cast_or_null<ReturnStmt>(P)) { + populateExecutedLinesWithStmt(RS, SM, ExecutedLines); + P = N->getParentMap().getParent(RS); + } - // Otherwise: show lines associated with the processed statement. - SourceLocation Loc = S->getSourceRange().getBegin(); - SourceLocation ExpansionLoc = SM.getExpansionLoc(Loc); - FileID FID = SM.getFileID(ExpansionLoc); - unsigned LineNo = SM.getExpansionLineNumber(ExpansionLoc); - ExecutedLines->operator[](FID.getHashValue()).insert(LineNo); + if (P && (isa<SwitchCase>(P) || isa<LabelStmt>(P))) + populateExecutedLinesWithStmt(P, SM, ExecutedLines); } N = N->getFirstPred(); |