aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/PathDiagnostic.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2012-02-28 23:27:39 +0000
committerTed Kremenek <kremenek@apple.com>2012-02-28 23:27:39 +0000
commit56d8fd0b8a65a7ccae3669cd650ca443cf24b73e (patch)
treee4dacce9d5a13e17d4ba3b1a478c118d35d3cf1d /lib/StaticAnalyzer/Core/PathDiagnostic.cpp
parentc89f4b05721f53cfbaf32fc0c4919a4616e68440 (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.cpp47
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());
}