]> granicus.if.org Git - clang/commitdiff
[analyzer] Ensure that pieces with invalid locations always get removed from the...
authorAnna Zaks <ganna@apple.com>
Thu, 6 Jun 2013 22:02:58 +0000 (22:02 +0000)
committerAnna Zaks <ganna@apple.com>
Thu, 6 Jun 2013 22:02:58 +0000 (22:02 +0000)
The function in which we were doing it used to be conditionalized. Add a new unconditional
cleanup step.

This fixes PR16227 (radar://14073870) - a crash when generating html output for one of the test files.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@183451 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/Core/BugReporter.cpp
test/Analysis/unix-fns.c

index 96aa48861868751b2c19441369da3c6f99c4cae4..e3f43854d635d53cf3162784d2b9141d37337ce4 100644 (file)
@@ -162,13 +162,6 @@ static bool removeUnneededCalls(PathPieces &pieces, BugReport *R,
     IntrusiveRefCntPtr<PathDiagnosticPiece> piece(pieces.front());
     pieces.pop_front();
     
-    // Throw away pieces with invalid locations. Note that we can't throw away
-    // calls just yet because they might have something interesting inside them.
-    // If so, their locations will be adjusted as necessary later.
-    if (piece->getKind() != PathDiagnosticPiece::Call &&
-        piece->getLocation().asLocation().isInvalid())
-      continue;
-
     switch (piece->getKind()) {
       case PathDiagnosticPiece::Call: {
         PathDiagnosticCallPiece *call = cast<PathDiagnosticCallPiece>(piece);
@@ -218,8 +211,7 @@ static bool hasImplicitBody(const Decl *D) {
 }
 
 /// Recursively scan through a path and make sure that all call pieces have
-/// valid locations. Note that all other pieces with invalid locations should
-/// have already been pruned out.
+/// valid locations. 
 static void adjustCallLocations(PathPieces &Pieces,
                                 PathDiagnosticLocation *LastCallLocation = 0) {
   for (PathPieces::iterator I = Pieces.begin(), E = Pieces.end(); I != E; ++I) {
@@ -252,6 +244,26 @@ static void adjustCallLocations(PathPieces &Pieces,
   }
 }
 
+/// 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.
+static void removePiecesWithInvalidLocations(PathPieces &Pieces) {
+  for (PathPieces::iterator I = Pieces.begin(), E = Pieces.end(); I != E; ++I) {
+    if (PathDiagnosticCallPiece *C = dyn_cast<PathDiagnosticCallPiece>(*I))
+      removePiecesWithInvalidLocations(C->path);
+
+    if (PathDiagnosticMacroPiece *M = dyn_cast<PathDiagnosticMacroPiece>(*I))
+      removePiecesWithInvalidLocations(M->subPieces);
+
+    if (!(*I)->getLocation().isValid() ||
+        !(*I)->getLocation().asLocation().isValid()) {
+      Pieces.erase(I);
+      continue;
+    }
+    
+  }
+}
+
 //===----------------------------------------------------------------------===//
 // PathDiagnosticBuilder and its associated routines and helper objects.
 //===----------------------------------------------------------------------===//
@@ -3151,8 +3163,11 @@ bool GRBugReporter::generatePathDiagnostic(PathDiagnostic& PD,
         (void)stillHasNotes;
       }
 
+      // Redirect all call pieces to have valid locations.
       adjustCallLocations(PD.getMutablePieces());
 
+      removePiecesWithInvalidLocations(PD.getMutablePieces());
+
       if (ActiveScheme == PathDiagnosticConsumer::AlternateExtensive) {
         SourceManager &SM = getSourceManager();
 
index 2258a8e5f046bf5482b951ee928c5bdc4f8dbb91..ecd2421d5da4020df639245f50d0528476032b0e 100644 (file)
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -analyze -analyzer-checker=core,unix.API,osx.API %s -analyzer-store=region -analyzer-output=plist -analyzer-eagerly-assume -analyzer-config faux-bodies=true -analyzer-config path-diagnostics-alternate=false -fblocks -verify -o %t.plist
 // RUN: FileCheck --input-file=%t.plist %s
-
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.API,osx.API -analyzer-output=html -analyzer-config faux-bodies=true -fblocks -o %T/dir %s
 struct _opaque_pthread_once_t {
   long __sig;
   char __opaque[8];