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 supportsLogicalOpControlFlow() const { return false; }
|
||||||
virtual bool supportsAllBlockEdges() const { return false; }
|
virtual bool supportsAllBlockEdges() const { return false; }
|
||||||
virtual bool useVerboseDescription() const { return true; }
|
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:
|
protected:
|
||||||
bool flushed;
|
bool flushed;
|
||||||
|
|
|
||||||
|
|
@ -145,35 +145,14 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D,
|
||||||
// First flatten out the entire path to make it easier to use.
|
// First flatten out the entire path to make it easier to use.
|
||||||
PathPieces path;
|
PathPieces path;
|
||||||
flattenPath(path, D.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();
|
const SourceManager &SMgr = (*path.begin())->getLocation().getManager();
|
||||||
FileID FID;
|
assert(!path.empty());
|
||||||
|
FileID FID =
|
||||||
// Verify that the entire path is from the same FileID.
|
(*path.begin())->getLocation().asLocation().getExpansionLoc().getFileID();
|
||||||
for (PathPieces::const_iterator I = path.begin(), E = path.end();
|
assert(!FID.isInvalid());
|
||||||
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?
|
|
||||||
|
|
||||||
// Create a new rewriter to generate HTML.
|
// Create a new rewriter to generate HTML.
|
||||||
Rewriter R(const_cast<SourceManager&>(SMgr), PP.getLangOptions());
|
Rewriter R(const_cast<SourceManager&>(SMgr), PP.getLangOptions());
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
|
#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"
|
||||||
#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
|
#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
|
||||||
|
#include "clang/Basic/SourceManager.h"
|
||||||
#include "clang/AST/Expr.h"
|
#include "clang/AST/Expr.h"
|
||||||
#include "clang/AST/Decl.h"
|
#include "clang/AST/Decl.h"
|
||||||
#include "clang/AST/DeclObjC.h"
|
#include "clang/AST/DeclObjC.h"
|
||||||
|
|
@ -76,19 +77,49 @@ PathDiagnosticConsumer::~PathDiagnosticConsumer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PathDiagnosticConsumer::HandlePathDiagnostic(PathDiagnostic *D) {
|
void PathDiagnosticConsumer::HandlePathDiagnostic(PathDiagnostic *D) {
|
||||||
if (!D)
|
llvm::OwningPtr<PathDiagnostic> OwningD(D);
|
||||||
return;
|
|
||||||
|
|
||||||
if (D->path.empty()) {
|
if (!D || D->path.empty())
|
||||||
delete D;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
// We need to flatten the locations (convert Stmt* to locations) because
|
// We need to flatten the locations (convert Stmt* to locations) because
|
||||||
// the referenced statements may be freed by the time the diagnostics
|
// the referenced statements may be freed by the time the diagnostics
|
||||||
// are emitted.
|
// are emitted.
|
||||||
D->flattenLocations();
|
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
|
// Profile the node to see if we already have something matching it
|
||||||
llvm::FoldingSetNodeID profile;
|
llvm::FoldingSetNodeID profile;
|
||||||
D->Profile(profile);
|
D->Profile(profile);
|
||||||
|
|
@ -110,16 +141,14 @@ void PathDiagnosticConsumer::HandlePathDiagnostic(PathDiagnostic *D) {
|
||||||
shouldKeepOriginal = false;
|
shouldKeepOriginal = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shouldKeepOriginal) {
|
if (shouldKeepOriginal)
|
||||||
delete D;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Diags.RemoveNode(orig);
|
Diags.RemoveNode(orig);
|
||||||
delete orig;
|
delete orig;
|
||||||
}
|
}
|
||||||
|
|
||||||
Diags.InsertNode(D);
|
Diags.InsertNode(OwningD.take());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue