summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer/Core/BugReporter.cpp
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2013-10-16 17:45:35 +0000
committerJordan Rose <jordan_rose@apple.com>2013-10-16 17:45:35 +0000
commitac07c8dae7ce595b3e77d2de291fda97a1a70278 (patch)
tree5fde6dd3a80a58dda1a9b88156b91db4836f184f /clang/lib/StaticAnalyzer/Core/BugReporter.cpp
parent34cb04393a85f7a867db4a8dff25521a75aada19 (diff)
downloadbcm5719-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.cpp40
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.
OpenPOWER on IntegriCloud