diff options
author | Anna Zaks <ganna@apple.com> | 2013-06-06 22:02:58 +0000 |
---|---|---|
committer | Anna Zaks <ganna@apple.com> | 2013-06-06 22:02:58 +0000 |
commit | b1b95d9409548cf8082519a1f793759e99cc3801 (patch) | |
tree | aeb0d22fc0638cc6ebdbf0ee49101276acf9e3eb /clang/lib/StaticAnalyzer/Core/BugReporter.cpp | |
parent | 496312a364ea0109520b245130be628c38aca0ff (diff) | |
download | bcm5719-llvm-b1b95d9409548cf8082519a1f793759e99cc3801.tar.gz bcm5719-llvm-b1b95d9409548cf8082519a1f793759e99cc3801.zip |
[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.
llvm-svn: 183451
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/BugReporter.cpp')
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/BugReporter.cpp | 33 |
1 files changed, 24 insertions, 9 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp index 96aa4886186..e3f43854d63 100644 --- a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -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(); |