forked from OSchip/llvm-project
[analyzer] Add forwarding `addVisitor` method
The majority of all `addVisitor` callers follow the same pattern: addVisitor(std::make_unique<SomeVisitor>(arg1, arg2, ...)); This patches introduces additional overload for `addVisitor` to simplify that pattern: addVisitor<SomeVisitor>(arg1, arg2, ...); Differential Revision: https://reviews.llvm.org/D103457
This commit is contained in:
parent
8fb6c31cbb
commit
92d03c20ea
|
@ -489,11 +489,16 @@ public:
|
|||
///
|
||||
/// The visitors should be used when the default trace is not sufficient.
|
||||
/// For example, they allow constructing a more elaborate trace.
|
||||
/// \sa registerConditionVisitor(), registerTrackNullOrUndefValue(),
|
||||
/// registerFindLastStore(), registerNilReceiverVisitor(), and
|
||||
/// registerVarDeclsLastStore().
|
||||
/// @{
|
||||
void addVisitor(std::unique_ptr<BugReporterVisitor> visitor);
|
||||
|
||||
template <class VisitorType, class... Args>
|
||||
void addVisitor(Args &&... ConstructorArgs) {
|
||||
addVisitor(
|
||||
std::make_unique<VisitorType>(std::forward<Args>(ConstructorArgs)...));
|
||||
}
|
||||
/// @}
|
||||
|
||||
/// Remove all visitors attached to this bug report.
|
||||
void clearVisitors();
|
||||
|
||||
|
|
|
@ -2123,7 +2123,7 @@ void MallocChecker::HandleMismatchedDealloc(CheckerContext &C,
|
|||
os.str(), N);
|
||||
R->markInteresting(Sym);
|
||||
R->addRange(Range);
|
||||
R->addVisitor(std::make_unique<MallocBugVisitor>(Sym));
|
||||
R->addVisitor<MallocBugVisitor>(Sym);
|
||||
C.emitReport(std::move(R));
|
||||
}
|
||||
}
|
||||
|
@ -2216,7 +2216,7 @@ void MallocChecker::HandleUseAfterFree(CheckerContext &C, SourceRange Range,
|
|||
|
||||
R->markInteresting(Sym);
|
||||
R->addRange(Range);
|
||||
R->addVisitor(std::make_unique<MallocBugVisitor>(Sym));
|
||||
R->addVisitor<MallocBugVisitor>(Sym);
|
||||
|
||||
if (AF == AF_InnerBuffer)
|
||||
R->addVisitor(allocation_state::getInnerPointerBRVisitor(Sym));
|
||||
|
@ -2252,7 +2252,7 @@ void MallocChecker::HandleDoubleFree(CheckerContext &C, SourceRange Range,
|
|||
R->markInteresting(Sym);
|
||||
if (PrevSym)
|
||||
R->markInteresting(PrevSym);
|
||||
R->addVisitor(std::make_unique<MallocBugVisitor>(Sym));
|
||||
R->addVisitor<MallocBugVisitor>(Sym);
|
||||
C.emitReport(std::move(R));
|
||||
}
|
||||
}
|
||||
|
@ -2278,7 +2278,7 @@ void MallocChecker::HandleDoubleDelete(CheckerContext &C, SymbolRef Sym) const {
|
|||
*BT_DoubleDelete, "Attempt to delete released memory", N);
|
||||
|
||||
R->markInteresting(Sym);
|
||||
R->addVisitor(std::make_unique<MallocBugVisitor>(Sym));
|
||||
R->addVisitor<MallocBugVisitor>(Sym);
|
||||
C.emitReport(std::move(R));
|
||||
}
|
||||
}
|
||||
|
@ -2308,7 +2308,7 @@ void MallocChecker::HandleUseZeroAlloc(CheckerContext &C, SourceRange Range,
|
|||
R->addRange(Range);
|
||||
if (Sym) {
|
||||
R->markInteresting(Sym);
|
||||
R->addVisitor(std::make_unique<MallocBugVisitor>(Sym));
|
||||
R->addVisitor<MallocBugVisitor>(Sym);
|
||||
}
|
||||
C.emitReport(std::move(R));
|
||||
}
|
||||
|
@ -2578,7 +2578,7 @@ void MallocChecker::HandleLeak(SymbolRef Sym, ExplodedNode *N,
|
|||
*BT_Leak[*CheckKind], os.str(), N, LocUsedForUniqueing,
|
||||
AllocNode->getLocationContext()->getDecl());
|
||||
R->markInteresting(Sym);
|
||||
R->addVisitor(std::make_unique<MallocBugVisitor>(Sym, true));
|
||||
R->addVisitor<MallocBugVisitor>(Sym, true);
|
||||
C.emitReport(std::move(R));
|
||||
}
|
||||
|
||||
|
|
|
@ -170,7 +170,7 @@ private:
|
|||
auto R = std::make_unique<PathSensitiveBugReport>(*BT, Msg, N);
|
||||
if (Region) {
|
||||
R->markInteresting(Region);
|
||||
R->addVisitor(std::make_unique<NullabilityBugVisitor>(Region));
|
||||
R->addVisitor<NullabilityBugVisitor>(Region);
|
||||
}
|
||||
if (ValueExpr) {
|
||||
R->addRange(ValueExpr->getSourceRange());
|
||||
|
|
|
@ -846,7 +846,7 @@ RefCountReport::RefCountReport(const RefCountBug &D, const LangOptions &LOpts,
|
|||
: PathSensitiveBugReport(D, D.getDescription(), n), Sym(sym),
|
||||
isLeak(isLeak) {
|
||||
if (!isLeak)
|
||||
addVisitor(std::make_unique<RefCountReportVisitor>(sym));
|
||||
addVisitor<RefCountReportVisitor>(sym);
|
||||
}
|
||||
|
||||
RefCountReport::RefCountReport(const RefCountBug &D, const LangOptions &LOpts,
|
||||
|
@ -854,7 +854,7 @@ RefCountReport::RefCountReport(const RefCountBug &D, const LangOptions &LOpts,
|
|||
StringRef endText)
|
||||
: PathSensitiveBugReport(D, D.getDescription(), endText, n) {
|
||||
|
||||
addVisitor(std::make_unique<RefCountReportVisitor>(sym));
|
||||
addVisitor<RefCountReportVisitor>(sym);
|
||||
}
|
||||
|
||||
void RefLeakReport::deriveParamLocation(CheckerContext &Ctx) {
|
||||
|
@ -984,9 +984,9 @@ void RefLeakReport::findBindingToReport(CheckerContext &Ctx,
|
|||
// something like derived regions if we want to construct SVal from
|
||||
// Sym. Instead, we take the value that is definitely stored in that
|
||||
// region, thus guaranteeing that FindLastStoreBRVisitor will work.
|
||||
addVisitor(std::make_unique<FindLastStoreBRVisitor>(
|
||||
addVisitor<FindLastStoreBRVisitor>(
|
||||
AllVarBindings[0].second.castAs<KnownSVal>(), AllocBindingToReport,
|
||||
false, bugreporter::TrackingKind::Thorough));
|
||||
false, bugreporter::TrackingKind::Thorough);
|
||||
} else {
|
||||
AllocBindingToReport = AllocFirstBinding;
|
||||
}
|
||||
|
@ -1005,5 +1005,5 @@ RefLeakReport::RefLeakReport(const RefCountBug &D, const LangOptions &LOpts,
|
|||
|
||||
createDescription(Ctx);
|
||||
|
||||
addVisitor(std::make_unique<RefLeakReportVisitor>(Sym, AllocBindingToReport));
|
||||
addVisitor<RefLeakReportVisitor>(Sym, AllocBindingToReport);
|
||||
}
|
||||
|
|
|
@ -2810,12 +2810,12 @@ Optional<PathDiagnosticBuilder> PathDiagnosticBuilder::findValidReport(
|
|||
|
||||
// Register refutation visitors first, if they mark the bug invalid no
|
||||
// further analysis is required
|
||||
R->addVisitor(std::make_unique<LikelyFalsePositiveSuppressionBRVisitor>());
|
||||
R->addVisitor<LikelyFalsePositiveSuppressionBRVisitor>();
|
||||
|
||||
// Register additional node visitors.
|
||||
R->addVisitor(std::make_unique<NilReceiverBRVisitor>());
|
||||
R->addVisitor(std::make_unique<ConditionBRVisitor>());
|
||||
R->addVisitor(std::make_unique<TagVisitor>());
|
||||
R->addVisitor<NilReceiverBRVisitor>();
|
||||
R->addVisitor<ConditionBRVisitor>();
|
||||
R->addVisitor<TagVisitor>();
|
||||
|
||||
BugReporterContext BRC(Reporter);
|
||||
|
||||
|
@ -2828,7 +2828,7 @@ Optional<PathDiagnosticBuilder> PathDiagnosticBuilder::findValidReport(
|
|||
// If crosscheck is enabled, remove all visitors, add the refutation
|
||||
// visitor and check again
|
||||
R->clearVisitors();
|
||||
R->addVisitor(std::make_unique<FalsePositiveRefutationBRVisitor>());
|
||||
R->addVisitor<FalsePositiveRefutationBRVisitor>();
|
||||
|
||||
// We don't overwrite the notes inserted by other visitors because the
|
||||
// refutation manager does not add any new note to the path
|
||||
|
|
|
@ -852,10 +852,10 @@ public:
|
|||
bool EnableNullFPSuppression, PathSensitiveBugReport &BR,
|
||||
const SVal V) {
|
||||
AnalyzerOptions &Options = N->getState()->getAnalysisManager().options;
|
||||
if (EnableNullFPSuppression &&
|
||||
Options.ShouldSuppressNullReturnPaths && V.getAs<Loc>())
|
||||
BR.addVisitor(std::make_unique<MacroNullReturnSuppressionVisitor>(
|
||||
R->getAs<SubRegion>(), V));
|
||||
if (EnableNullFPSuppression && Options.ShouldSuppressNullReturnPaths &&
|
||||
V.getAs<Loc>())
|
||||
BR.addVisitor<MacroNullReturnSuppressionVisitor>(R->getAs<SubRegion>(),
|
||||
V);
|
||||
}
|
||||
|
||||
void* getTag() const {
|
||||
|
@ -1011,14 +1011,12 @@ public:
|
|||
AnalyzerOptions &Options = State->getAnalysisManager().options;
|
||||
|
||||
bool EnableNullFPSuppression = false;
|
||||
if (InEnableNullFPSuppression &&
|
||||
Options.ShouldSuppressNullReturnPaths)
|
||||
if (InEnableNullFPSuppression && Options.ShouldSuppressNullReturnPaths)
|
||||
if (Optional<Loc> RetLoc = RetVal.getAs<Loc>())
|
||||
EnableNullFPSuppression = State->isNull(*RetLoc).isConstrainedTrue();
|
||||
|
||||
BR.addVisitor(std::make_unique<ReturnVisitor>(CalleeContext,
|
||||
EnableNullFPSuppression,
|
||||
Options, TKind));
|
||||
BR.addVisitor<ReturnVisitor>(CalleeContext, EnableNullFPSuppression,
|
||||
Options, TKind);
|
||||
}
|
||||
|
||||
PathDiagnosticPieceRef visitNodeInitial(const ExplodedNode *N,
|
||||
|
@ -1589,8 +1587,8 @@ FindLastStoreBRVisitor::VisitNode(const ExplodedNode *Succ,
|
|||
dyn_cast_or_null<BlockDataRegion>(V.getAsRegion())) {
|
||||
if (const VarRegion *OriginalR = BDR->getOriginalRegion(VR)) {
|
||||
if (auto KV = State->getSVal(OriginalR).getAs<KnownSVal>())
|
||||
BR.addVisitor(std::make_unique<FindLastStoreBRVisitor>(
|
||||
*KV, OriginalR, EnableNullFPSuppression, TKind, OriginSFC));
|
||||
BR.addVisitor<FindLastStoreBRVisitor>(
|
||||
*KV, OriginalR, EnableNullFPSuppression, TKind, OriginSFC);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2070,8 +2068,7 @@ bool bugreporter::trackExpressionValue(const ExplodedNode *InputNode,
|
|||
// TODO: Shouldn't we track control dependencies of every bug location, rather
|
||||
// than only tracked expressions?
|
||||
if (LVState->getAnalysisManager().getAnalyzerOptions().ShouldTrackConditions)
|
||||
report.addVisitor(std::make_unique<TrackControlDependencyCondBRVisitor>(
|
||||
InputNode));
|
||||
report.addVisitor<TrackControlDependencyCondBRVisitor>(InputNode);
|
||||
|
||||
// The message send could be nil due to the receiver being nil.
|
||||
// At this point in the path, the receiver should be live since we are at the
|
||||
|
@ -2098,8 +2095,8 @@ bool bugreporter::trackExpressionValue(const ExplodedNode *InputNode,
|
|||
// got initialized.
|
||||
if (RR && !LVIsNull)
|
||||
if (auto KV = LVal.getAs<KnownSVal>())
|
||||
report.addVisitor(std::make_unique<FindLastStoreBRVisitor>(
|
||||
*KV, RR, EnableNullFPSuppression, TKind, SFC));
|
||||
report.addVisitor<FindLastStoreBRVisitor>(
|
||||
*KV, RR, EnableNullFPSuppression, TKind, SFC);
|
||||
|
||||
// In case of C++ references, we want to differentiate between a null
|
||||
// reference and reference to null pointer.
|
||||
|
@ -2112,20 +2109,19 @@ bool bugreporter::trackExpressionValue(const ExplodedNode *InputNode,
|
|||
|
||||
// Mark both the variable region and its contents as interesting.
|
||||
SVal V = LVState->getRawSVal(loc::MemRegionVal(R));
|
||||
report.addVisitor(
|
||||
std::make_unique<NoStoreFuncVisitor>(cast<SubRegion>(R), TKind));
|
||||
report.addVisitor<NoStoreFuncVisitor>(cast<SubRegion>(R), TKind);
|
||||
|
||||
MacroNullReturnSuppressionVisitor::addMacroVisitorIfNecessary(
|
||||
LVNode, R, EnableNullFPSuppression, report, V);
|
||||
|
||||
report.markInteresting(V, TKind);
|
||||
report.addVisitor(std::make_unique<UndefOrNullArgVisitor>(R));
|
||||
report.addVisitor<UndefOrNullArgVisitor>(R);
|
||||
|
||||
// If the contents are symbolic and null, find out when they became null.
|
||||
if (V.getAsLocSymbol(/*IncludeBaseRegions=*/true))
|
||||
if (LVState->isNull(V).isConstrainedTrue())
|
||||
report.addVisitor(std::make_unique<TrackConstraintBRVisitor>(
|
||||
V.castAs<DefinedSVal>(), false));
|
||||
report.addVisitor<TrackConstraintBRVisitor>(V.castAs<DefinedSVal>(),
|
||||
false);
|
||||
|
||||
// Add visitor, which will suppress inline defensive checks.
|
||||
if (auto DV = V.getAs<DefinedSVal>())
|
||||
|
@ -2135,14 +2131,13 @@ bool bugreporter::trackExpressionValue(const ExplodedNode *InputNode,
|
|||
// was evaluated. InputNode may as well be too early here, because
|
||||
// the symbol is already dead; this, however, is fine because we can
|
||||
// still find the node in which it collapsed to null previously.
|
||||
report.addVisitor(
|
||||
std::make_unique<SuppressInlineDefensiveChecksVisitor>(
|
||||
*DV, InputNode));
|
||||
report.addVisitor<SuppressInlineDefensiveChecksVisitor>(*DV,
|
||||
InputNode);
|
||||
}
|
||||
|
||||
if (auto KV = V.getAs<KnownSVal>())
|
||||
report.addVisitor(std::make_unique<FindLastStoreBRVisitor>(
|
||||
*KV, R, EnableNullFPSuppression, TKind, SFC));
|
||||
report.addVisitor<FindLastStoreBRVisitor>(
|
||||
*KV, R, EnableNullFPSuppression, TKind, SFC);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -2177,19 +2172,18 @@ bool bugreporter::trackExpressionValue(const ExplodedNode *InputNode,
|
|||
RVal = LVState->getSVal(L->getRegion());
|
||||
|
||||
if (CanDereference) {
|
||||
report.addVisitor(
|
||||
std::make_unique<UndefOrNullArgVisitor>(L->getRegion()));
|
||||
report.addVisitor<UndefOrNullArgVisitor>(L->getRegion());
|
||||
|
||||
if (auto KV = RVal.getAs<KnownSVal>())
|
||||
report.addVisitor(std::make_unique<FindLastStoreBRVisitor>(
|
||||
*KV, L->getRegion(), EnableNullFPSuppression, TKind, SFC));
|
||||
report.addVisitor<FindLastStoreBRVisitor>(
|
||||
*KV, L->getRegion(), EnableNullFPSuppression, TKind, SFC);
|
||||
}
|
||||
|
||||
const MemRegion *RegionRVal = RVal.getAsRegion();
|
||||
if (RegionRVal && isa<SymbolicRegion>(RegionRVal)) {
|
||||
if (isa_and_nonnull<SymbolicRegion>(RegionRVal)) {
|
||||
report.markInteresting(RegionRVal, TKind);
|
||||
report.addVisitor(std::make_unique<TrackConstraintBRVisitor>(
|
||||
loc::MemRegionVal(RegionRVal), /*assumption=*/false));
|
||||
report.addVisitor<TrackConstraintBRVisitor>(loc::MemRegionVal(RegionRVal),
|
||||
/*assumption=*/false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue