diff --git a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h --- a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h +++ b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h @@ -489,11 +489,16 @@ /// /// 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 visitor); + template + void addVisitor(Args &&... ConstructorArgs) { + addVisitor( + std::make_unique(std::forward(ConstructorArgs)...)); + } + /// @} + /// Remove all visitors attached to this bug report. void clearVisitors(); diff --git a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp --- a/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -2123,7 +2123,7 @@ os.str(), N); R->markInteresting(Sym); R->addRange(Range); - R->addVisitor(std::make_unique(Sym)); + R->addVisitor(Sym); C.emitReport(std::move(R)); } } @@ -2216,7 +2216,7 @@ R->markInteresting(Sym); R->addRange(Range); - R->addVisitor(std::make_unique(Sym)); + R->addVisitor(Sym); if (AF == AF_InnerBuffer) R->addVisitor(allocation_state::getInnerPointerBRVisitor(Sym)); @@ -2252,7 +2252,7 @@ R->markInteresting(Sym); if (PrevSym) R->markInteresting(PrevSym); - R->addVisitor(std::make_unique(Sym)); + R->addVisitor(Sym); C.emitReport(std::move(R)); } } @@ -2278,7 +2278,7 @@ *BT_DoubleDelete, "Attempt to delete released memory", N); R->markInteresting(Sym); - R->addVisitor(std::make_unique(Sym)); + R->addVisitor(Sym); C.emitReport(std::move(R)); } } @@ -2308,7 +2308,7 @@ R->addRange(Range); if (Sym) { R->markInteresting(Sym); - R->addVisitor(std::make_unique(Sym)); + R->addVisitor(Sym); } C.emitReport(std::move(R)); } @@ -2578,7 +2578,7 @@ *BT_Leak[*CheckKind], os.str(), N, LocUsedForUniqueing, AllocNode->getLocationContext()->getDecl()); R->markInteresting(Sym); - R->addVisitor(std::make_unique(Sym, true)); + R->addVisitor(Sym, true); C.emitReport(std::move(R)); } diff --git a/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp --- a/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/NullabilityChecker.cpp @@ -170,7 +170,7 @@ auto R = std::make_unique(*BT, Msg, N); if (Region) { R->markInteresting(Region); - R->addVisitor(std::make_unique(Region)); + R->addVisitor(Region); } if (ValueExpr) { R->addRange(ValueExpr->getSourceRange()); diff --git a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp --- a/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.cpp @@ -846,7 +846,7 @@ : PathSensitiveBugReport(D, D.getDescription(), n), Sym(sym), isLeak(isLeak) { if (!isLeak) - addVisitor(std::make_unique(sym)); + addVisitor(sym); } RefCountReport::RefCountReport(const RefCountBug &D, const LangOptions &LOpts, @@ -854,7 +854,7 @@ StringRef endText) : PathSensitiveBugReport(D, D.getDescription(), endText, n) { - addVisitor(std::make_unique(sym)); + addVisitor(sym); } void RefLeakReport::deriveParamLocation(CheckerContext &Ctx) { @@ -984,9 +984,9 @@ // 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( + addVisitor( AllVarBindings[0].second.castAs(), AllocBindingToReport, - false, bugreporter::TrackingKind::Thorough)); + false, bugreporter::TrackingKind::Thorough); } else { AllocBindingToReport = AllocFirstBinding; } @@ -1005,5 +1005,5 @@ createDescription(Ctx); - addVisitor(std::make_unique(Sym, AllocBindingToReport)); + addVisitor(Sym, AllocBindingToReport); } diff --git a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp --- a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp @@ -2810,12 +2810,12 @@ // Register refutation visitors first, if they mark the bug invalid no // further analysis is required - R->addVisitor(std::make_unique()); + R->addVisitor(); // Register additional node visitors. - R->addVisitor(std::make_unique()); - R->addVisitor(std::make_unique()); - R->addVisitor(std::make_unique()); + R->addVisitor(); + R->addVisitor(); + R->addVisitor(); BugReporterContext BRC(Reporter); @@ -2828,7 +2828,7 @@ // If crosscheck is enabled, remove all visitors, add the refutation // visitor and check again R->clearVisitors(); - R->addVisitor(std::make_unique()); + R->addVisitor(); // We don't overwrite the notes inserted by other visitors because the // refutation manager does not add any new note to the path diff --git a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp --- a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -852,10 +852,10 @@ bool EnableNullFPSuppression, PathSensitiveBugReport &BR, const SVal V) { AnalyzerOptions &Options = N->getState()->getAnalysisManager().options; - if (EnableNullFPSuppression && - Options.ShouldSuppressNullReturnPaths && V.getAs()) - BR.addVisitor(std::make_unique( - R->getAs(), V)); + if (EnableNullFPSuppression && Options.ShouldSuppressNullReturnPaths && + V.getAs()) + BR.addVisitor(R->getAs(), + V); } void* getTag() const { @@ -1011,14 +1011,12 @@ AnalyzerOptions &Options = State->getAnalysisManager().options; bool EnableNullFPSuppression = false; - if (InEnableNullFPSuppression && - Options.ShouldSuppressNullReturnPaths) + if (InEnableNullFPSuppression && Options.ShouldSuppressNullReturnPaths) if (Optional RetLoc = RetVal.getAs()) EnableNullFPSuppression = State->isNull(*RetLoc).isConstrainedTrue(); - BR.addVisitor(std::make_unique(CalleeContext, - EnableNullFPSuppression, - Options, TKind)); + BR.addVisitor(CalleeContext, EnableNullFPSuppression, + Options, TKind); } PathDiagnosticPieceRef visitNodeInitial(const ExplodedNode *N, @@ -1589,8 +1587,8 @@ dyn_cast_or_null(V.getAsRegion())) { if (const VarRegion *OriginalR = BDR->getOriginalRegion(VR)) { if (auto KV = State->getSVal(OriginalR).getAs()) - BR.addVisitor(std::make_unique( - *KV, OriginalR, EnableNullFPSuppression, TKind, OriginSFC)); + BR.addVisitor( + *KV, OriginalR, EnableNullFPSuppression, TKind, OriginSFC); } } } @@ -2070,8 +2068,7 @@ // 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( - InputNode)); + report.addVisitor(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 @@ // got initialized. if (RR && !LVIsNull) if (auto KV = LVal.getAs()) - report.addVisitor(std::make_unique( - *KV, RR, EnableNullFPSuppression, TKind, SFC)); + report.addVisitor( + *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 @@ // Mark both the variable region and its contents as interesting. SVal V = LVState->getRawSVal(loc::MemRegionVal(R)); - report.addVisitor( - std::make_unique(cast(R), TKind)); + report.addVisitor(cast(R), TKind); MacroNullReturnSuppressionVisitor::addMacroVisitorIfNecessary( LVNode, R, EnableNullFPSuppression, report, V); report.markInteresting(V, TKind); - report.addVisitor(std::make_unique(R)); + report.addVisitor(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( - V.castAs(), false)); + report.addVisitor(V.castAs(), + false); // Add visitor, which will suppress inline defensive checks. if (auto DV = V.getAs()) @@ -2135,14 +2131,13 @@ // 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( - *DV, InputNode)); + report.addVisitor(*DV, + InputNode); } if (auto KV = V.getAs()) - report.addVisitor(std::make_unique( - *KV, R, EnableNullFPSuppression, TKind, SFC)); + report.addVisitor( + *KV, R, EnableNullFPSuppression, TKind, SFC); return true; } } @@ -2177,19 +2172,18 @@ RVal = LVState->getSVal(L->getRegion()); if (CanDereference) { - report.addVisitor( - std::make_unique(L->getRegion())); + report.addVisitor(L->getRegion()); if (auto KV = RVal.getAs()) - report.addVisitor(std::make_unique( - *KV, L->getRegion(), EnableNullFPSuppression, TKind, SFC)); + report.addVisitor( + *KV, L->getRegion(), EnableNullFPSuppression, TKind, SFC); } const MemRegion *RegionRVal = RVal.getAsRegion(); - if (RegionRVal && isa(RegionRVal)) { + if (isa_and_nonnull(RegionRVal)) { report.markInteresting(RegionRVal, TKind); - report.addVisitor(std::make_unique( - loc::MemRegionVal(RegionRVal), /*assumption=*/false)); + report.addVisitor(loc::MemRegionVal(RegionRVal), + /*assumption=*/false); } }