forked from OSchip/llvm-project
[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. llvm-svn: 151664
This commit is contained in:
parent
2429c6ffe7
commit
0f70a6f51e
|
|
@ -68,6 +68,10 @@ public:
|
|||
virtual bool supportsLogicalOpControlFlow() const { return false; }
|
||||
virtual bool supportsAllBlockEdges() const { return false; }
|
||||
virtual bool useVerboseDescription() const { return true; }
|
||||
|
||||
/// Return true if the PathDiagnosticConsumer supports individual
|
||||
/// PathDiagnostics that span multiple files.
|
||||
virtual bool supportsCrossFileDiagnostics() const { return false; }
|
||||
|
||||
protected:
|
||||
bool flushed;
|
||||
|
|
|
|||
|
|
@ -145,35 +145,14 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D,
|
|||
// First flatten out the entire path to make it easier to use.
|
||||
PathPieces path;
|
||||
flattenPath(path, D.path);
|
||||
|
||||
|
||||
// The path as already been prechecked that all parts of the path are
|
||||
// from the same file and that it is non-empty.
|
||||
const SourceManager &SMgr = (*path.begin())->getLocation().getManager();
|
||||
FileID FID;
|
||||
|
||||
// Verify that the entire path is from the same FileID.
|
||||
for (PathPieces::const_iterator I = path.begin(), E = 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?
|
||||
assert(!path.empty());
|
||||
FileID FID =
|
||||
(*path.begin())->getLocation().asLocation().getExpansionLoc().getFileID();
|
||||
assert(!FID.isInvalid());
|
||||
|
||||
// Create a new rewriter to generate HTML.
|
||||
Rewriter R(const_cast<SourceManager&>(SMgr), PP.getLangOptions());
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue