[analyzer] Move report false positive suppression to report visitors.

llvm-svn: 173956
This commit is contained in:
Anna Zaks 2013-01-30 19:12:34 +00:00
parent 70aa53180d
commit be60830378
4 changed files with 65 additions and 39 deletions

View File

@ -457,11 +457,6 @@ public:
void Register(BugType *BT);
/// \brief Suppress reports that might lead to known false positives.
///
/// Currently this suppresses reports based on locations of bugs.
bool suppressReport(BugReport *R);
/// \brief Add the given report to the set of reports tracked by BugReporter.
///
/// The reports are usually generated by the checkers. Further, they are

View File

@ -230,6 +230,33 @@ public:
llvm::Optional<bool> &prunable);
};
/// \brief Suppress reports that might lead to known false positives.
///
/// Currently this suppresses reports based on locations of bugs.
class LikelyFalsePositiveSuppressionBRVisitor
: public BugReporterVisitorImpl<LikelyFalsePositiveSuppressionBRVisitor> {
public:
static void *getTag() {
static int Tag = 0;
return static_cast<void *>(&Tag);
}
void Profile(llvm::FoldingSetNodeID &ID) const {
ID.AddPointer(getTag());
}
virtual PathDiagnosticPiece *VisitNode(const ExplodedNode *N,
const ExplodedNode *Prev,
BugReporterContext &BRC,
BugReport &BR) {
return 0;
}
virtual PathDiagnosticPiece *getEndPath(BugReporterContext &BRC,
const ExplodedNode *N,
BugReport &BR);
};
/// \brief When a region containing undefined value or '0' value is passed
/// as an argument in a call, marks the call as interesting.
///

View File

@ -2047,6 +2047,7 @@ bool GRBugReporter::generatePathDiagnostic(PathDiagnostic& PD,
// Register additional node visitors.
R->addVisitor(new NilReceiverBRVisitor());
R->addVisitor(new ConditionBRVisitor());
R->addVisitor(new LikelyFalsePositiveSuppressionBRVisitor());
BugReport::VisitorList visitors;
unsigned originalReportConfigToken, finalReportConfigToken;
@ -2067,16 +2068,17 @@ bool GRBugReporter::generatePathDiagnostic(PathDiagnostic& PD,
// Generate the very last diagnostic piece - the piece is visible before
// the trace is expanded.
if (PDB.getGenerationScheme() != PathDiagnosticConsumer::None) {
PathDiagnosticPiece *LastPiece = 0;
for (BugReport::visitor_iterator I = visitors.begin(), E = visitors.end();
I != E; ++I) {
if (PathDiagnosticPiece *Piece = (*I)->getEndPath(PDB, N, *R)) {
assert (!LastPiece &&
"There can only be one final piece in a diagnostic.");
LastPiece = Piece;
}
PathDiagnosticPiece *LastPiece = 0;
for (BugReport::visitor_iterator I = visitors.begin(), E = visitors.end();
I != E; ++I) {
if (PathDiagnosticPiece *Piece = (*I)->getEndPath(PDB, N, *R)) {
assert (!LastPiece &&
"There can only be one final piece in a diagnostic.");
LastPiece = Piece;
}
}
if (PDB.getGenerationScheme() != PathDiagnosticConsumer::None) {
if (!LastPiece)
LastPiece = BugReporterVisitor::getDefaultEndPath(PDB, N, *R);
if (LastPiece)
@ -2141,32 +2143,7 @@ void BugReporter::Register(BugType *BT) {
BugTypes = F.add(BugTypes, BT);
}
bool BugReporter::suppressReport(BugReport *R) {
const Stmt *S = R->getStmt();
if (!S)
return false;
// Here we suppress false positives coming from system macros. This list is
// based on known issues.
// Skip reports within the sys/queue.h macros as we do not have the ability to
// reason about data structure shapes.
SourceManager &SM = getSourceManager();
SourceLocation Loc = S->getLocStart();
while (Loc.isMacroID()) {
if (SM.isInSystemMacro(Loc) &&
(SM.getFilename(SM.getSpellingLoc(Loc)).endswith("sys/queue.h")))
return true;
Loc = SM.getSpellingLoc(Loc);
}
return false;
}
void BugReporter::emitReport(BugReport* R) {
if (suppressReport(R))
return;
// Compute the bug report's hash to determine its equivalence class.
llvm::FoldingSetNodeID ID;
R->Profile(ID);

View File

@ -1156,6 +1156,33 @@ ConditionBRVisitor::VisitTrueTest(const Expr *Cond,
return event;
}
PathDiagnosticPiece *
LikelyFalsePositiveSuppressionBRVisitor::getEndPath(BugReporterContext &BRC,
const ExplodedNode *N,
BugReport &BR) {
const Stmt *S = BR.getStmt();
if (!S)
return 0;
// Here we suppress false positives coming from system macros. This list is
// based on known issues.
// Skip reports within the sys/queue.h macros as we do not have the ability to
// reason about data structure shapes.
SourceManager &SM = BRC.getSourceManager();
SourceLocation Loc = S->getLocStart();
while (Loc.isMacroID()) {
if (SM.isInSystemMacro(Loc) &&
(SM.getFilename(SM.getSpellingLoc(Loc)).endswith("sys/queue.h"))) {
BR.markInvalid(getTag(), 0);
return 0;
}
Loc = SM.getSpellingLoc(Loc);
}
return 0;
}
PathDiagnosticPiece *
UndefOrNullArgVisitor::VisitNode(const ExplodedNode *N,
const ExplodedNode *PrevN,