From 6838710779a23ea5dfdb5764ad7b7a7451b00bf8 Mon Sep 17 00:00:00 2001 From: Anna Zaks Date: Thu, 6 Jun 2013 22:02:58 +0000 Subject: [PATCH] [analyzer] Ensure that pieces with invalid locations always get removed from the BugReport 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 | 33 ++++++++++++++++++------- test/Analysis/unix-fns.c | 2 +- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/lib/StaticAnalyzer/Core/BugReporter.cpp b/lib/StaticAnalyzer/Core/BugReporter.cpp index 96aa488618..e3f43854d6 100644 --- a/lib/StaticAnalyzer/Core/BugReporter.cpp +++ b/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -162,13 +162,6 @@ static bool removeUnneededCalls(PathPieces &pieces, BugReport *R, IntrusiveRefCntPtr 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(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(*I)) + removePiecesWithInvalidLocations(C->path); + + if (PathDiagnosticMacroPiece *M = dyn_cast(*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(); diff --git a/test/Analysis/unix-fns.c b/test/Analysis/unix-fns.c index 2258a8e5f0..ecd2421d5d 100644 --- a/test/Analysis/unix-fns.c +++ b/test/Analysis/unix-fns.c @@ -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]; -- 2.40.0