unique_ptrify BugReporter::visitors

llvm-svn: 217205
This commit is contained in:
David Blaikie 2014-09-04 23:54:33 +00:00
parent 8323394017
commit 91e7902622
9 changed files with 77 additions and 97 deletions

View File

@ -63,7 +63,7 @@ public:
};
typedef const SourceRange *ranges_iterator;
typedef SmallVector<BugReporterVisitor *, 8> VisitorList;
typedef SmallVector<std::unique_ptr<BugReporterVisitor>, 8> VisitorList;
typedef VisitorList::iterator visitor_iterator;
typedef SmallVector<StringRef, 2> ExtraTextList;
@ -299,9 +299,9 @@ public:
/// \sa registerConditionVisitor(), registerTrackNullOrUndefValue(),
/// registerFindLastStore(), registerNilReceiverVisitor(), and
/// registerVarDeclsLastStore().
void addVisitor(BugReporterVisitor *visitor);
void addVisitor(std::unique_ptr<BugReporterVisitor> visitor);
/// Iterators through the custom diagnostic visitors.
/// Iterators through the custom diagnostic visitors.
visitor_iterator visitor_begin() { return Callbacks.begin(); }
visitor_iterator visitor_end() { return Callbacks.end(); }

View File

@ -48,7 +48,7 @@ public:
/// (Warning: if you have a deep subclass of BugReporterVisitorImpl, the
/// default implementation of clone() will NOT do the right thing, and you
/// will have to provide your own implementation.)
virtual BugReporterVisitor *clone() const = 0;
virtual std::unique_ptr<BugReporterVisitor> clone() const = 0;
/// \brief Return a diagnostic piece which should be associated with the
/// given node.
@ -87,8 +87,8 @@ public:
/// will have to provide your own implementation.)
template <class DERIVED>
class BugReporterVisitorImpl : public BugReporterVisitor {
BugReporterVisitor *clone() const override {
return new DERIVED(*static_cast<const DERIVED *>(this));
std::unique_ptr<BugReporterVisitor> clone() const override {
return llvm::make_unique<DERIVED>(*static_cast<const DERIVED *>(this));
}
};

View File

@ -270,7 +270,7 @@ void MacOSKeychainAPIChecker::
os << "Deallocator doesn't match the allocator: '"
<< FunctionsToTrack[PDeallocIdx].Name << "' should be used.";
BugReport *Report = new BugReport(*BT, os.str(), N);
Report->addVisitor(new SecKeychainBugVisitor(AP.first));
Report->addVisitor(llvm::make_unique<SecKeychainBugVisitor>(AP.first));
Report->addRange(ArgExpr->getSourceRange());
markInteresting(Report, AP);
C.emitReport(Report);
@ -311,7 +311,7 @@ void MacOSKeychainAPIChecker::checkPreStmt(const CallExpr *CE,
<< FunctionsToTrack[DIdx].Name
<< "'.";
BugReport *Report = new BugReport(*BT, os.str(), N);
Report->addVisitor(new SecKeychainBugVisitor(V));
Report->addVisitor(llvm::make_unique<SecKeychainBugVisitor>(V));
Report->addRange(ArgExpr->getSourceRange());
Report->markInteresting(AS->Region);
C.emitReport(Report);
@ -430,7 +430,7 @@ void MacOSKeychainAPIChecker::checkPreStmt(const CallExpr *CE,
initBugType();
BugReport *Report = new BugReport(*BT,
"Only call free if a valid (non-NULL) buffer was returned.", N);
Report->addVisitor(new SecKeychainBugVisitor(ArgSM));
Report->addVisitor(llvm::make_unique<SecKeychainBugVisitor>(ArgSM));
Report->addRange(ArgExpr->getSourceRange());
Report->markInteresting(AS->Region);
C.emitReport(Report);
@ -540,7 +540,7 @@ BugReport *MacOSKeychainAPIChecker::
BugReport *Report = new BugReport(*BT, os.str(), N, LocUsedForUniqueing,
AllocNode->getLocationContext()->getDecl());
Report->addVisitor(new SecKeychainBugVisitor(AP.first));
Report->addVisitor(llvm::make_unique<SecKeychainBugVisitor>(AP.first));
markInteresting(Report, AP);
return Report;
}

View File

@ -1467,7 +1467,7 @@ void MallocChecker::ReportMismatchedDealloc(CheckerContext &C,
BugReport *R = new BugReport(*BT_MismatchedDealloc, os.str(), N);
R->markInteresting(Sym);
R->addRange(Range);
R->addVisitor(new MallocBugVisitor(Sym));
R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym));
C.emitReport(R);
}
}
@ -1551,7 +1551,7 @@ void MallocChecker::ReportUseAfterFree(CheckerContext &C, SourceRange Range,
R->markInteresting(Sym);
R->addRange(Range);
R->addVisitor(new MallocBugVisitor(Sym));
R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym));
C.emitReport(R);
}
}
@ -1583,7 +1583,7 @@ void MallocChecker::ReportDoubleFree(CheckerContext &C, SourceRange Range,
R->markInteresting(Sym);
if (PrevSym)
R->markInteresting(PrevSym);
R->addVisitor(new MallocBugVisitor(Sym));
R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym));
C.emitReport(R);
}
}
@ -1607,7 +1607,7 @@ void MallocChecker::ReportDoubleDelete(CheckerContext &C, SymbolRef Sym) const {
"Attempt to delete released memory", N);
R->markInteresting(Sym);
R->addVisitor(new MallocBugVisitor(Sym));
R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym));
C.emitReport(R);
}
}
@ -1835,7 +1835,7 @@ void MallocChecker::reportLeak(SymbolRef Sym, ExplodedNode *N,
new BugReport(*BT_Leak[*CheckKind], os.str(), N, LocUsedForUniqueing,
AllocNode->getLocationContext()->getDecl());
R->markInteresting(Sym);
R->addVisitor(new MallocBugVisitor(Sym, true));
R->addVisitor(llvm::make_unique<MallocBugVisitor>(Sym, true));
C.emitReport(R);
}

View File

@ -1732,13 +1732,13 @@ namespace {
const ExplodedNode *N,
BugReport &BR) override;
BugReporterVisitor *clone() const override {
std::unique_ptr<BugReporterVisitor> clone() const override {
// The curiously-recurring template pattern only works for one level of
// subclassing. Rather than make a new template base for
// CFRefReportVisitor, we simply override clone() to do the right thing.
// This could be trouble someday if BugReporterVisitorImpl is ever
// used for something else besides a convenient implementation of clone().
return new CFRefLeakReportVisitor(*this);
return llvm::make_unique<CFRefLeakReportVisitor>(*this);
}
};
@ -1751,7 +1751,7 @@ namespace {
bool registerVisitor = true)
: BugReport(D, D.getDescription(), n) {
if (registerVisitor)
addVisitor(new CFRefReportVisitor(sym, GCEnabled, Log));
addVisitor(llvm::make_unique<CFRefReportVisitor>(sym, GCEnabled, Log));
addGCModeDescription(LOpts, GCEnabled);
}
@ -1759,7 +1759,7 @@ namespace {
const SummaryLogTy &Log, ExplodedNode *n, SymbolRef sym,
StringRef endText)
: BugReport(D, D.getDescription(), endText, n) {
addVisitor(new CFRefReportVisitor(sym, GCEnabled, Log));
addVisitor(llvm::make_unique<CFRefReportVisitor>(sym, GCEnabled, Log));
addGCModeDescription(LOpts, GCEnabled);
}
@ -2387,7 +2387,7 @@ CFRefLeakReport::CFRefLeakReport(CFRefBug &D, const LangOptions &LOpts,
}
}
addVisitor(new CFRefLeakReportVisitor(sym, GCEnabled, Log));
addVisitor(llvm::make_unique<CFRefLeakReportVisitor>(sym, GCEnabled, Log));
}
//===----------------------------------------------------------------------===//

View File

@ -176,7 +176,8 @@ void TestAfterDivZeroChecker::reportBug(SVal Val, CheckerContext &C) const {
"already been used for division",
N);
R->addVisitor(new DivisionBRVisitor(Val.getAsSymbol(), C.getStackFrame()));
R->addVisitor(llvm::make_unique<DivisionBRVisitor>(Val.getAsSymbol(),
C.getStackFrame()));
C.emitReport(R);
}
}

View File

@ -92,8 +92,8 @@ UndefCapturedBlockVarChecker::checkPostStmt(const BlockExpr *BE,
BugReport *R = new BugReport(*BT, os.str(), N);
if (const Expr *Ex = FindBlockDeclRefExpr(BE->getBody(), VD))
R->addRange(Ex->getSourceRange());
R->addVisitor(new FindLastStoreBRVisitor(*V, VR,
/*EnableNullFPSuppression*/false));
R->addVisitor(llvm::make_unique<FindLastStoreBRVisitor>(
*V, VR, /*EnableNullFPSuppression*/ false));
R->disablePathPruning();
// need location of block
C.emitReport(R);

View File

@ -499,10 +499,9 @@ PathDiagnosticBuilder::getEnclosingStmtLocation(const Stmt *S) {
//===----------------------------------------------------------------------===//
// "Visitors only" path diagnostic generation algorithm.
//===----------------------------------------------------------------------===//
static bool GenerateVisitorsOnlyPathDiagnostic(PathDiagnostic &PD,
PathDiagnosticBuilder &PDB,
const ExplodedNode *N,
ArrayRef<BugReporterVisitor *> visitors) {
static bool GenerateVisitorsOnlyPathDiagnostic(
PathDiagnostic &PD, PathDiagnosticBuilder &PDB, const ExplodedNode *N,
ArrayRef<std::unique_ptr<BugReporterVisitor>> visitors) {
// All path generation skips the very first node (the error node).
// This is because there is special handling for the end-of-path note.
N = N->getFirstPred();
@ -511,11 +510,9 @@ static bool GenerateVisitorsOnlyPathDiagnostic(PathDiagnostic &PD,
BugReport *R = PDB.getBugReport();
while (const ExplodedNode *Pred = N->getFirstPred()) {
for (ArrayRef<BugReporterVisitor *>::iterator I = visitors.begin(),
E = visitors.end();
I != E; ++I) {
for (auto &V : visitors) {
// Visit all the node pairs, but throw the path pieces away.
PathDiagnosticPiece *Piece = (*I)->VisitNode(N, Pred, PDB, *R);
PathDiagnosticPiece *Piece = V->VisitNode(N, Pred, PDB, *R);
delete Piece;
}
@ -556,11 +553,10 @@ static void updateStackPiecesWithMessage(PathDiagnosticPiece *P,
static void CompactPathDiagnostic(PathPieces &path, const SourceManager& SM);
static bool GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
PathDiagnosticBuilder &PDB,
const ExplodedNode *N,
LocationContextMap &LCM,
ArrayRef<BugReporterVisitor *> visitors) {
static bool GenerateMinimalPathDiagnostic(
PathDiagnostic &PD, PathDiagnosticBuilder &PDB, const ExplodedNode *N,
LocationContextMap &LCM,
ArrayRef<std::unique_ptr<BugReporterVisitor>> visitors) {
SourceManager& SMgr = PDB.getSourceManager();
const LocationContext *LC = PDB.LC;
@ -870,10 +866,8 @@ static bool GenerateMinimalPathDiagnostic(PathDiagnostic& PD,
if (NextNode) {
// Add diagnostic pieces from custom visitors.
BugReport *R = PDB.getBugReport();
for (ArrayRef<BugReporterVisitor *>::iterator I = visitors.begin(),
E = visitors.end();
I != E; ++I) {
if (PathDiagnosticPiece *p = (*I)->VisitNode(N, NextNode, PDB, *R)) {
for (auto &V : visitors) {
if (PathDiagnosticPiece *p = V->VisitNode(N, NextNode, PDB, *R)) {
PD.getActivePath().push_front(p);
updateStackPiecesWithMessage(p, CallStack);
}
@ -1392,11 +1386,10 @@ static bool isInLoopBody(ParentMap &PM, const Stmt *S, const Stmt *Term) {
// Top-level logic for generating extensive path diagnostics.
//===----------------------------------------------------------------------===//
static bool GenerateExtensivePathDiagnostic(PathDiagnostic& PD,
PathDiagnosticBuilder &PDB,
const ExplodedNode *N,
LocationContextMap &LCM,
ArrayRef<BugReporterVisitor *> visitors) {
static bool GenerateExtensivePathDiagnostic(
PathDiagnostic &PD, PathDiagnosticBuilder &PDB, const ExplodedNode *N,
LocationContextMap &LCM,
ArrayRef<std::unique_ptr<BugReporterVisitor>> visitors) {
EdgeBuilder EB(PD, PDB);
const SourceManager& SM = PDB.getSourceManager();
StackDiagVector CallStack;
@ -1573,10 +1566,8 @@ static bool GenerateExtensivePathDiagnostic(PathDiagnostic& PD,
// Add pieces from custom visitors.
BugReport *R = PDB.getBugReport();
for (ArrayRef<BugReporterVisitor *>::iterator I = visitors.begin(),
E = visitors.end();
I != E; ++I) {
if (PathDiagnosticPiece *p = (*I)->VisitNode(N, NextNode, PDB, *R)) {
for (auto &V : visitors) {
if (PathDiagnosticPiece *p = V->VisitNode(N, NextNode, PDB, *R)) {
const PathDiagnosticLocation &Loc = p->getLocation();
EB.addEdge(Loc, true);
PD.getActivePath().push_front(p);
@ -1635,12 +1626,10 @@ static const char StrLoopRangeEmpty[] =
static const char StrLoopCollectionEmpty[] =
"Loop body skipped when collection is empty";
static bool
GenerateAlternateExtensivePathDiagnostic(PathDiagnostic& PD,
PathDiagnosticBuilder &PDB,
const ExplodedNode *N,
LocationContextMap &LCM,
ArrayRef<BugReporterVisitor *> visitors) {
static bool GenerateAlternateExtensivePathDiagnostic(
PathDiagnostic &PD, PathDiagnosticBuilder &PDB, const ExplodedNode *N,
LocationContextMap &LCM,
ArrayRef<std::unique_ptr<BugReporterVisitor>> visitors) {
BugReport *report = PDB.getBugReport();
const SourceManager& SM = PDB.getSourceManager();
@ -1867,10 +1856,8 @@ GenerateAlternateExtensivePathDiagnostic(PathDiagnostic& PD,
continue;
// Add pieces from custom visitors.
for (ArrayRef<BugReporterVisitor *>::iterator I = visitors.begin(),
E = visitors.end();
I != E; ++I) {
if (PathDiagnosticPiece *p = (*I)->VisitNode(N, NextNode, PDB, *report)) {
for (auto &V : visitors) {
if (PathDiagnosticPiece *p = V->VisitNode(N, NextNode, PDB, *report)) {
addEdgeToPath(PD.getActivePath(), PrevLoc, p->getLocation(), PDB.LC);
PD.getActivePath().push_front(p);
updateStackPiecesWithMessage(p, CallStack);
@ -2547,7 +2534,7 @@ void BuiltinBug::anchor() {}
void BugReport::NodeResolver::anchor() {}
void BugReport::addVisitor(BugReporterVisitor* visitor) {
void BugReport::addVisitor(std::unique_ptr<BugReporterVisitor> visitor) {
if (!visitor)
return;
@ -2555,20 +2542,15 @@ void BugReport::addVisitor(BugReporterVisitor* visitor) {
visitor->Profile(ID);
void *InsertPos;
if (CallbacksSet.FindNodeOrInsertPos(ID, InsertPos)) {
delete visitor;
if (CallbacksSet.FindNodeOrInsertPos(ID, InsertPos))
return;
}
CallbacksSet.InsertNode(visitor, InsertPos);
Callbacks.push_back(visitor);
CallbacksSet.InsertNode(visitor.get(), InsertPos);
Callbacks.push_back(std::move(visitor));
++ConfigurationChangeToken;
}
BugReport::~BugReport() {
for (visitor_iterator I = visitor_begin(), E = visitor_end(); I != E; ++I) {
delete *I;
}
while (!interestingSymbols.empty()) {
popInterestingSymbolsAndRegions();
}
@ -3126,9 +3108,9 @@ bool GRBugReporter::generatePathDiagnostic(PathDiagnostic& PD,
const ExplodedNode *N = ErrorGraph.ErrorNode;
// Register additional node visitors.
R->addVisitor(new NilReceiverBRVisitor());
R->addVisitor(new ConditionBRVisitor());
R->addVisitor(new LikelyFalsePositiveSuppressionBRVisitor());
R->addVisitor(llvm::make_unique<NilReceiverBRVisitor>());
R->addVisitor(llvm::make_unique<ConditionBRVisitor>());
R->addVisitor(llvm::make_unique<LikelyFalsePositiveSuppressionBRVisitor>());
BugReport::VisitorList visitors;
unsigned origReportConfigToken, finalReportConfigToken;
@ -3188,7 +3170,7 @@ bool GRBugReporter::generatePathDiagnostic(PathDiagnostic& PD,
}
// Clean up the visitors we used.
llvm::DeleteContainerPointers(visitors);
visitors.clear();
// Did anything change while generating this path?
finalReportConfigToken = R->getConfigurationChangeToken();

View File

@ -218,7 +218,8 @@ public:
EnableNullFPSuppression = State->isNull(*RetLoc).isConstrainedTrue();
BR.markInteresting(CalleeContext);
BR.addVisitor(new ReturnVisitor(CalleeContext, EnableNullFPSuppression));
BR.addVisitor(llvm::make_unique<ReturnVisitor>(CalleeContext,
EnableNullFPSuppression));
}
/// Returns true if any counter-suppression heuristics are enabled for
@ -565,8 +566,8 @@ PathDiagnosticPiece *FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
if (const VarRegion *OriginalR = BDR->getOriginalRegion(VR)) {
if (Optional<KnownSVal> KV =
State->getSVal(OriginalR).getAs<KnownSVal>())
BR.addVisitor(new FindLastStoreBRVisitor(*KV, OriginalR,
EnableNullFPSuppression));
BR.addVisitor(llvm::make_unique<FindLastStoreBRVisitor>(
*KV, OriginalR, EnableNullFPSuppression));
}
}
}
@ -975,8 +976,8 @@ bool bugreporter::trackNullOrUndefValue(const ExplodedNode *N,
// got initialized.
if (const MemRegion *RR = getLocationRegionIfReference(Inner, N)) {
if (Optional<KnownSVal> KV = LVal.getAs<KnownSVal>())
report.addVisitor(new FindLastStoreBRVisitor(*KV, RR,
EnableNullFPSuppression));
report.addVisitor(llvm::make_unique<FindLastStoreBRVisitor>(
*KV, RR, EnableNullFPSuppression));
}
}
@ -986,30 +987,26 @@ bool bugreporter::trackNullOrUndefValue(const ExplodedNode *N,
report.markInteresting(R);
report.markInteresting(V);
report.addVisitor(new UndefOrNullArgVisitor(R));
report.addVisitor(llvm::make_unique<UndefOrNullArgVisitor>(R));
// If the contents are symbolic, find out when they became null.
if (V.getAsLocSymbol(/*IncludeBaseRegions*/ true)) {
BugReporterVisitor *ConstraintTracker =
new TrackConstraintBRVisitor(V.castAs<DefinedSVal>(), false);
report.addVisitor(ConstraintTracker);
}
if (V.getAsLocSymbol(/*IncludeBaseRegions*/ true))
report.addVisitor(llvm::make_unique<TrackConstraintBRVisitor>(
V.castAs<DefinedSVal>(), false));
// Add visitor, which will suppress inline defensive checks.
if (Optional<DefinedSVal> DV = V.getAs<DefinedSVal>()) {
if (!DV->isZeroConstant() &&
LVState->isNull(*DV).isConstrainedTrue() &&
EnableNullFPSuppression) {
BugReporterVisitor *IDCSuppressor =
new SuppressInlineDefensiveChecksVisitor(*DV,
LVNode);
report.addVisitor(IDCSuppressor);
if (!DV->isZeroConstant() && LVState->isNull(*DV).isConstrainedTrue() &&
EnableNullFPSuppression) {
report.addVisitor(
llvm::make_unique<SuppressInlineDefensiveChecksVisitor>(*DV,
LVNode));
}
}
if (Optional<KnownSVal> KV = V.getAs<KnownSVal>())
report.addVisitor(new FindLastStoreBRVisitor(*KV, R,
EnableNullFPSuppression));
report.addVisitor(llvm::make_unique<FindLastStoreBRVisitor>(
*KV, R, EnableNullFPSuppression));
return true;
}
}
@ -1040,12 +1037,12 @@ bool bugreporter::trackNullOrUndefValue(const ExplodedNode *N,
RVal = state->getSVal(L->getRegion());
const MemRegion *RegionRVal = RVal.getAsRegion();
report.addVisitor(new UndefOrNullArgVisitor(L->getRegion()));
report.addVisitor(llvm::make_unique<UndefOrNullArgVisitor>(L->getRegion()));
if (RegionRVal && isa<SymbolicRegion>(RegionRVal)) {
report.markInteresting(RegionRVal);
report.addVisitor(new TrackConstraintBRVisitor(
loc::MemRegionVal(RegionRVal), false));
report.addVisitor(llvm::make_unique<TrackConstraintBRVisitor>(
loc::MemRegionVal(RegionRVal), false));
}
}
@ -1128,8 +1125,8 @@ void FindLastStoreBRVisitor::registerStatementVarDecls(BugReport &BR,
if (V.getAs<loc::ConcreteInt>() || V.getAs<nonloc::ConcreteInt>()) {
// Register a new visitor with the BugReport.
BR.addVisitor(new FindLastStoreBRVisitor(V.castAs<KnownSVal>(), R,
EnableNullFPSuppression));
BR.addVisitor(llvm::make_unique<FindLastStoreBRVisitor>(
V.castAs<KnownSVal>(), R, EnableNullFPSuppression));
}
}
}