diff options
author | Jordan Rose <jordan_rose@apple.com> | 2013-10-16 17:45:35 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2013-10-16 17:45:35 +0000 |
commit | ac07c8dae7ce595b3e77d2de291fda97a1a70278 (patch) | |
tree | 5fde6dd3a80a58dda1a9b88156b91db4836f184f /clang/lib/StaticAnalyzer/Core/BugReporter.cpp | |
parent | 34cb04393a85f7a867db4a8dff25521a75aada19 (diff) | |
download | bcm5719-llvm-ac07c8dae7ce595b3e77d2de291fda97a1a70278.tar.gz bcm5719-llvm-ac07c8dae7ce595b3e77d2de291fda97a1a70278.zip |
[analyzer] Don't draw edges to C++11 in-class member initializers.
Since these aren't lexically in the constructor, drawing arrows would
be a horrible jump across the body of the class. We could still do
better here by skipping over unimportant initializers, but this at least
keeps everything within the body of the constructor.
<rdar://problem/14960554>
llvm-svn: 192818
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/BugReporter.cpp')
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/BugReporter.cpp | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp index 523b700667b..6bb9ffcea92 100644 --- a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -246,6 +246,41 @@ static void adjustCallLocations(PathPieces &Pieces, } } +/// Remove edges in and out of C++ default initializer expressions. These are +/// for fields that have in-class initializers, as opposed to being initialized +/// explicitly in a constructor or braced list. +static void removeEdgesToDefaultInitializers(PathPieces &Pieces) { + for (PathPieces::iterator I = Pieces.begin(), E = Pieces.end(); I != E;) { + if (PathDiagnosticCallPiece *C = dyn_cast<PathDiagnosticCallPiece>(*I)) + removeEdgesToDefaultInitializers(C->path); + + if (PathDiagnosticMacroPiece *M = dyn_cast<PathDiagnosticMacroPiece>(*I)) + removeEdgesToDefaultInitializers(M->subPieces); + + if (PathDiagnosticControlFlowPiece *CF = + dyn_cast<PathDiagnosticControlFlowPiece>(*I)) { + const Stmt *Start = CF->getStartLocation().asStmt(); + const Stmt *End = CF->getEndLocation().asStmt(); + if (Start && isa<CXXDefaultInitExpr>(Start)) { + I = Pieces.erase(I); + continue; + } else if (End && isa<CXXDefaultInitExpr>(End)) { + PathPieces::iterator Next = llvm::next(I); + if (Next != E) { + if (PathDiagnosticControlFlowPiece *NextCF = + dyn_cast<PathDiagnosticControlFlowPiece>(*Next)) { + NextCF->setStartLocation(CF->getStartLocation()); + } + } + I = Pieces.erase(I); + continue; + } + } + + I++; + } +} + /// Remove all pieces with invalid locations as these cannot be serialized. /// We might have pieces with invalid locations as a result of inlining Body /// Farm generated functions. @@ -3163,7 +3198,6 @@ bool GRBugReporter::generatePathDiagnostic(PathDiagnostic& PD, // Redirect all call pieces to have valid locations. adjustCallLocations(PD.getMutablePieces()); - removePiecesWithInvalidLocations(PD.getMutablePieces()); if (ActiveScheme == PathDiagnosticConsumer::AlternateExtensive) { @@ -3180,9 +3214,11 @@ bool GRBugReporter::generatePathDiagnostic(PathDiagnostic& PD, dropFunctionEntryEdge(PD.getMutablePieces(), LCM, SM); } - // Remove messages that are basically the same. + // Remove messages that are basically the same, and edges that may not + // make sense. // We have to do this after edge optimization in the Extensive mode. removeRedundantMsgs(PD.getMutablePieces()); + removeEdgesToDefaultInitializers(PD.getMutablePieces()); } // We found a report and didn't suppress it. |