diff options
author | Ted Kremenek <kremenek@apple.com> | 2012-02-28 23:27:39 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2012-02-28 23:27:39 +0000 |
commit | 56d8fd0b8a65a7ccae3669cd650ca443cf24b73e (patch) | |
tree | e4dacce9d5a13e17d4ba3b1a478c118d35d3cf1d /lib/StaticAnalyzer/Core/PathDiagnostic.cpp | |
parent | c89f4b05721f53cfbaf32fc0c4919a4616e68440 (diff) |
[analyzer diagnostics] Refactor filtration for PathDiagnosticConsumers that don't support cross-file diagnostics
into a common place. Currently enable this filtration for Plist diagnostics as well.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151664 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/PathDiagnostic.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/PathDiagnostic.cpp | 47 |
1 files changed, 38 insertions, 9 deletions
diff --git a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp index a866b34158..2adc0f2c38 100644 --- a/lib/StaticAnalyzer/Core/PathDiagnostic.cpp +++ b/lib/StaticAnalyzer/Core/PathDiagnostic.cpp @@ -13,6 +13,7 @@ #include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h" #include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h" +#include "clang/Basic/SourceManager.h" #include "clang/AST/Expr.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclObjC.h" @@ -76,19 +77,49 @@ PathDiagnosticConsumer::~PathDiagnosticConsumer() { } void PathDiagnosticConsumer::HandlePathDiagnostic(PathDiagnostic *D) { - if (!D) - return; + llvm::OwningPtr<PathDiagnostic> OwningD(D); - if (D->path.empty()) { - delete D; + if (!D || D->path.empty()) return; - } // We need to flatten the locations (convert Stmt* to locations) because // the referenced statements may be freed by the time the diagnostics // are emitted. D->flattenLocations(); + // If the PathDiagnosticConsumer does not support diagnostics that + // cross file boundaries, prune out such diagnostics now. + if (!supportsCrossFileDiagnostics()) { + // Verify that the entire path is from the same FileID. + FileID FID; + const SourceManager &SMgr = (*D->path.begin())->getLocation().getManager(); + + for (PathPieces::const_iterator I = D->path.begin(), E = D->path.end(); + I != E; ++I) { + FullSourceLoc L = (*I)->getLocation().asLocation().getExpansionLoc(); + + if (FID.isInvalid()) { + FID = SMgr.getFileID(L); + } else if (SMgr.getFileID(L) != FID) + return; // FIXME: Emit a warning? + + // Check the source ranges. + for (PathDiagnosticPiece::range_iterator RI = (*I)->ranges_begin(), + RE = (*I)->ranges_end(); + RI != RE; ++RI) { + SourceLocation L = SMgr.getExpansionLoc(RI->getBegin()); + if (!L.isFileID() || SMgr.getFileID(L) != FID) + return; // FIXME: Emit a warning? + L = SMgr.getExpansionLoc(RI->getEnd()); + if (!L.isFileID() || SMgr.getFileID(L) != FID) + return; // FIXME: Emit a warning? + } + } + + if (FID.isInvalid()) + return; // FIXME: Emit a warning? + } + // Profile the node to see if we already have something matching it llvm::FoldingSetNodeID profile; D->Profile(profile); @@ -110,16 +141,14 @@ void PathDiagnosticConsumer::HandlePathDiagnostic(PathDiagnostic *D) { shouldKeepOriginal = false; } - if (shouldKeepOriginal) { - delete D; + if (shouldKeepOriginal) return; - } } Diags.RemoveNode(orig); delete orig; } - Diags.InsertNode(D); + Diags.InsertNode(OwningD.take()); } |