[clang] Bb/reland expose astcontext to checker ctors (PR #128369)
Balazs Benics via cfe-commits
cfe-commits at lists.llvm.org
Sat Feb 22 12:02:00 PST 2025
https://github.com/steakhal created https://github.com/llvm/llvm-project/pull/128369
Reapply "[analyzer] Delay the checker constructions after parsing" (#128350)
This reverts commit db836edf47f36ed04cab919a7a2c4414f4d0d7e6, as-is.
Depends on #128368
>From 6fd30233a570ace5ccf3f04f649ddd37bd4149b2 Mon Sep 17 00:00:00 2001
From: Balazs Benics <benicsbalazs at gmail.com>
Date: Sat, 22 Feb 2025 20:50:31 +0100
Subject: [PATCH 1/2] [analyzer] Clean up slightly the messed up ownership
model of the analyzer
Well, yes. It's not pretty.
At least after this we would have a bit more unique pointers than before.
This is for fixing the memory leak diagnosed by:
https://lab.llvm.org/buildbot/#/builders/24/builds/5580
And that caused the revert of #127409.
After these uptrs that patch can re-land finally.
---
.../clang/Analysis/AnalysisDeclContext.h | 2 +-
.../Core/BugReporter/BugReporter.h | 24 +++++++++++--------
.../Core/PathDiagnosticConsumers.h | 3 ++-
.../Core/PathSensitive/AnalysisManager.h | 7 +++---
.../Frontend/AnalysisConsumer.h | 3 ++-
clang/lib/Analysis/AnalysisDeclContext.cpp | 4 ++--
.../StaticAnalyzer/Core/AnalysisManager.cpp | 23 +++++++-----------
clang/lib/StaticAnalyzer/Core/BugReporter.cpp | 22 ++++++++---------
.../StaticAnalyzer/Core/HTMLDiagnostics.cpp | 6 +++--
.../StaticAnalyzer/Core/PlistDiagnostics.cpp | 12 +++++-----
.../StaticAnalyzer/Core/SarifDiagnostics.cpp | 5 ++--
.../Frontend/AnalysisConsumer.cpp | 21 ++++++++--------
.../BugReportInterestingnessTest.cpp | 6 +++--
.../StaticAnalyzer/CheckerRegistration.h | 4 ++--
clang/unittests/StaticAnalyzer/Reusables.h | 7 +++---
15 files changed, 77 insertions(+), 72 deletions(-)
diff --git a/clang/include/clang/Analysis/AnalysisDeclContext.h b/clang/include/clang/Analysis/AnalysisDeclContext.h
index a517a4e757c9f..ced4bb8595bea 100644
--- a/clang/include/clang/Analysis/AnalysisDeclContext.h
+++ b/clang/include/clang/Analysis/AnalysisDeclContext.h
@@ -451,7 +451,7 @@ class AnalysisDeclContextManager {
bool synthesizeBodies = false, bool addStaticInitBranches = false,
bool addCXXNewAllocator = true, bool addRichCXXConstructors = true,
bool markElidedCXXConstructors = true, bool addVirtualBaseBranches = true,
- CodeInjector *injector = nullptr);
+ std::unique_ptr<CodeInjector> injector = nullptr);
AnalysisDeclContext *getContext(const Decl *D);
diff --git a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
index 7563d8bbd1d27..8e1d25b3eefa1 100644
--- a/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
+++ b/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h
@@ -570,7 +570,8 @@ class BugReporterData {
public:
virtual ~BugReporterData() = default;
- virtual ArrayRef<PathDiagnosticConsumer*> getPathDiagnosticConsumers() = 0;
+ virtual ArrayRef<std::unique_ptr<PathDiagnosticConsumer>>
+ getPathDiagnosticConsumers() = 0;
virtual ASTContext &getASTContext() = 0;
virtual SourceManager &getSourceManager() = 0;
virtual AnalyzerOptions &getAnalyzerOptions() = 0;
@@ -608,7 +609,8 @@ class BugReporter {
/// Generate and flush diagnostics for all bug reports.
void FlushReports();
- ArrayRef<PathDiagnosticConsumer*> getPathDiagnosticConsumers() {
+ ArrayRef<std::unique_ptr<PathDiagnosticConsumer>>
+ getPathDiagnosticConsumers() {
return D.getPathDiagnosticConsumers();
}
@@ -670,9 +672,10 @@ class BugReporter {
protected:
/// Generate the diagnostics for the given bug report.
virtual std::unique_ptr<DiagnosticForConsumerMapTy>
- generateDiagnosticForConsumerMap(BugReport *exampleReport,
- ArrayRef<PathDiagnosticConsumer *> consumers,
- ArrayRef<BugReport *> bugReports);
+ generateDiagnosticForConsumerMap(
+ BugReport *exampleReport,
+ ArrayRef<std::unique_ptr<PathDiagnosticConsumer>> consumers,
+ ArrayRef<BugReport *> bugReports);
};
/// GRBugReporter is used for generating path-sensitive reports.
@@ -684,10 +687,11 @@ class PathSensitiveBugReporter final : public BugReporter {
SmallVectorImpl<BugReport *> &bugReports) override;
/// Generate the diagnostics for the given bug report.
- std::unique_ptr<DiagnosticForConsumerMapTy>
- generateDiagnosticForConsumerMap(BugReport *exampleReport,
- ArrayRef<PathDiagnosticConsumer *> consumers,
- ArrayRef<BugReport *> bugReports) override;
+ std::unique_ptr<DiagnosticForConsumerMapTy> generateDiagnosticForConsumerMap(
+ BugReport *exampleReport,
+ ArrayRef<std::unique_ptr<PathDiagnosticConsumer>> consumers,
+ ArrayRef<BugReport *> bugReports) override;
+
public:
PathSensitiveBugReporter(BugReporterData& d, ExprEngine& eng)
: BugReporter(d), Eng(eng) {}
@@ -706,7 +710,7 @@ class PathSensitiveBugReporter final : public BugReporter {
/// Iterates through the bug reports within a single equivalence class,
/// stops at a first non-invalidated report.
std::unique_ptr<DiagnosticForConsumerMapTy> generatePathDiagnostics(
- ArrayRef<PathDiagnosticConsumer *> consumers,
+ ArrayRef<std::unique_ptr<PathDiagnosticConsumer>> consumers,
ArrayRef<PathSensitiveBugReport *> &bugReports);
void emitReport(std::unique_ptr<BugReport> R) override;
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h b/clang/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h
index 88a9d76f24887..9fafd6acaa2ac 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathDiagnosticConsumers.h
@@ -30,7 +30,8 @@ class CrossTranslationUnitContext;
namespace ento {
class PathDiagnosticConsumer;
-typedef std::vector<PathDiagnosticConsumer*> PathDiagnosticConsumers;
+using PathDiagnosticConsumers =
+ std::vector<std::unique_ptr<PathDiagnosticConsumer>>;
#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN) \
void CREATEFN(PathDiagnosticConsumerOptions Diagopts, \
diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
index c76e9c0326afe..e3cf1bac83ad0 100644
--- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
+++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h
@@ -47,11 +47,11 @@ class AnalysisManager : public BugReporterData {
AnalyzerOptions &options;
AnalysisManager(ASTContext &ctx, Preprocessor &PP,
- const PathDiagnosticConsumers &Consumers,
+ PathDiagnosticConsumers Consumers,
StoreManagerCreator storemgr,
ConstraintManagerCreator constraintmgr,
CheckerManager *checkerMgr, AnalyzerOptions &Options,
- CodeInjector *injector = nullptr);
+ std::unique_ptr<CodeInjector> injector = nullptr);
~AnalysisManager() override;
@@ -91,7 +91,8 @@ class AnalysisManager : public BugReporterData {
return LangOpts;
}
- ArrayRef<PathDiagnosticConsumer*> getPathDiagnosticConsumers() override {
+ ArrayRef<std::unique_ptr<PathDiagnosticConsumer>>
+ getPathDiagnosticConsumers() override {
return PathConsumers;
}
diff --git a/clang/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h b/clang/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h
index f3b1c1f206459..2163d66466c1c 100644
--- a/clang/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h
+++ b/clang/include/clang/StaticAnalyzer/Frontend/AnalysisConsumer.h
@@ -29,7 +29,8 @@ class CheckerRegistry;
class AnalysisASTConsumer : public ASTConsumer {
public:
- virtual void AddDiagnosticConsumer(PathDiagnosticConsumer *Consumer) = 0;
+ virtual void
+ AddDiagnosticConsumer(std::unique_ptr<PathDiagnosticConsumer> Consumer) = 0;
/// This method allows registering statically linked custom checkers that are
/// not a part of the Clang tree. It employs the same mechanism that is used
diff --git a/clang/lib/Analysis/AnalysisDeclContext.cpp b/clang/lib/Analysis/AnalysisDeclContext.cpp
index d3a1a993711fb..d0b663bd94580 100644
--- a/clang/lib/Analysis/AnalysisDeclContext.cpp
+++ b/clang/lib/Analysis/AnalysisDeclContext.cpp
@@ -71,8 +71,8 @@ AnalysisDeclContextManager::AnalysisDeclContextManager(
bool addLoopExit, bool addScopes, bool synthesizeBodies,
bool addStaticInitBranch, bool addCXXNewAllocator,
bool addRichCXXConstructors, bool markElidedCXXConstructors,
- bool addVirtualBaseBranches, CodeInjector *injector)
- : Injector(injector), FunctionBodyFarm(ASTCtx, injector),
+ bool addVirtualBaseBranches, std::unique_ptr<CodeInjector> injector)
+ : Injector(std::move(injector)), FunctionBodyFarm(ASTCtx, Injector.get()),
SynthesizeBodies(synthesizeBodies) {
cfgBuildOptions.PruneTriviallyFalseEdges = !useUnoptimizedCFG;
cfgBuildOptions.AddImplicitDtors = addImplicitDtors;
diff --git a/clang/lib/StaticAnalyzer/Core/AnalysisManager.cpp b/clang/lib/StaticAnalyzer/Core/AnalysisManager.cpp
index f9750db7b5017..8a16716f951b8 100644
--- a/clang/lib/StaticAnalyzer/Core/AnalysisManager.cpp
+++ b/clang/lib/StaticAnalyzer/Core/AnalysisManager.cpp
@@ -14,32 +14,28 @@ using namespace ento;
void AnalysisManager::anchor() { }
AnalysisManager::AnalysisManager(ASTContext &ASTCtx, Preprocessor &PP,
- const PathDiagnosticConsumers &PDC,
+ PathDiagnosticConsumers PDC,
StoreManagerCreator storemgr,
ConstraintManagerCreator constraintmgr,
CheckerManager *checkerMgr,
AnalyzerOptions &Options,
- CodeInjector *injector)
+ std::unique_ptr<CodeInjector> injector)
: AnaCtxMgr(
ASTCtx, Options.UnoptimizedCFG,
Options.ShouldIncludeImplicitDtorsInCFG,
- /*addInitializers=*/true,
- Options.ShouldIncludeTemporaryDtorsInCFG,
+ /*addInitializers=*/true, Options.ShouldIncludeTemporaryDtorsInCFG,
Options.ShouldIncludeLifetimeInCFG,
// Adding LoopExit elements to the CFG is a requirement for loop
// unrolling.
- Options.ShouldIncludeLoopExitInCFG ||
- Options.ShouldUnrollLoops,
- Options.ShouldIncludeScopesInCFG,
- Options.ShouldSynthesizeBodies,
+ Options.ShouldIncludeLoopExitInCFG || Options.ShouldUnrollLoops,
+ Options.ShouldIncludeScopesInCFG, Options.ShouldSynthesizeBodies,
Options.ShouldConditionalizeStaticInitializers,
/*addCXXNewAllocator=*/true,
Options.ShouldIncludeRichConstructorsInCFG,
Options.ShouldElideConstructors,
- /*addVirtualBaseBranches=*/true,
- injector),
+ /*addVirtualBaseBranches=*/true, std::move(injector)),
Ctx(ASTCtx), PP(PP), LangOpts(ASTCtx.getLangOpts()),
- PathConsumers(PDC), CreateStoreMgr(storemgr),
+ PathConsumers(std::move(PDC)), CreateStoreMgr(storemgr),
CreateConstraintMgr(constraintmgr), CheckerMgr(checkerMgr),
options(Options) {
AnaCtxMgr.getCFGBuildOptions().setAllAlwaysAdd();
@@ -50,14 +46,11 @@ AnalysisManager::AnalysisManager(ASTContext &ASTCtx, Preprocessor &PP,
AnalysisManager::~AnalysisManager() {
FlushDiagnostics();
- for (PathDiagnosticConsumer *Consumer : PathConsumers) {
- delete Consumer;
- }
}
void AnalysisManager::FlushDiagnostics() {
PathDiagnosticConsumer::FilesMade filesMade;
- for (PathDiagnosticConsumer *Consumer : PathConsumers) {
+ for (const auto &Consumer : PathConsumers) {
Consumer->FlushDiagnostics(&filesMade);
}
}
diff --git a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp
index 13677ed341d0c..7101b1eb2c7f5 100644
--- a/clang/lib/StaticAnalyzer/Core/BugReporter.cpp
+++ b/clang/lib/StaticAnalyzer/Core/BugReporter.cpp
@@ -2958,7 +2958,7 @@ std::optional<PathDiagnosticBuilder> PathDiagnosticBuilder::findValidReport(
std::unique_ptr<DiagnosticForConsumerMapTy>
PathSensitiveBugReporter::generatePathDiagnostics(
- ArrayRef<PathDiagnosticConsumer *> consumers,
+ ArrayRef<std::unique_ptr<PathDiagnosticConsumer>> consumers,
ArrayRef<PathSensitiveBugReport *> &bugReports) {
assert(!bugReports.empty());
@@ -2968,9 +2968,9 @@ PathSensitiveBugReporter::generatePathDiagnostics(
PathDiagnosticBuilder::findValidReport(bugReports, *this);
if (PDB) {
- for (PathDiagnosticConsumer *PC : consumers) {
- if (std::unique_ptr<PathDiagnostic> PD = PDB->generate(PC)) {
- (*Out)[PC] = std::move(PD);
+ for (const auto &PC : consumers) {
+ if (std::unique_ptr<PathDiagnostic> PD = PDB->generate(PC.get())) {
+ (*Out)[PC.get()] = std::move(PD);
}
}
}
@@ -3164,7 +3164,7 @@ void BugReporter::FlushReport(BugReportEquivClass &EQ) {
return;
}
- ArrayRef<PathDiagnosticConsumer*> Consumers = getPathDiagnosticConsumers();
+ ArrayRef Consumers = getPathDiagnosticConsumers();
std::unique_ptr<DiagnosticForConsumerMapTy> Diagnostics =
generateDiagnosticForConsumerMap(report, Consumers, bugReports);
@@ -3298,12 +3298,13 @@ findExecutedLines(const SourceManager &SM, const ExplodedNode *N) {
std::unique_ptr<DiagnosticForConsumerMapTy>
BugReporter::generateDiagnosticForConsumerMap(
- BugReport *exampleReport, ArrayRef<PathDiagnosticConsumer *> consumers,
+ BugReport *exampleReport,
+ ArrayRef<std::unique_ptr<PathDiagnosticConsumer>> consumers,
ArrayRef<BugReport *> bugReports) {
auto *basicReport = cast<BasicBugReport>(exampleReport);
auto Out = std::make_unique<DiagnosticForConsumerMapTy>();
- for (auto *Consumer : consumers)
- (*Out)[Consumer] =
+ for (const auto &Consumer : consumers)
+ (*Out)[Consumer.get()] =
generateDiagnosticForBasicReport(basicReport, AnalysisEntryPoint);
return Out;
}
@@ -3371,11 +3372,10 @@ static void resetDiagnosticLocationToMainFile(PathDiagnostic &PD) {
}
}
-
-
std::unique_ptr<DiagnosticForConsumerMapTy>
PathSensitiveBugReporter::generateDiagnosticForConsumerMap(
- BugReport *exampleReport, ArrayRef<PathDiagnosticConsumer *> consumers,
+ BugReport *exampleReport,
+ ArrayRef<std::unique_ptr<PathDiagnosticConsumer>> consumers,
ArrayRef<BugReport *> bugReports) {
std::vector<BasicBugReport *> BasicBugReports;
std::vector<PathSensitiveBugReport *> PathSensitiveBugReports;
diff --git a/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp b/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
index 5c0df8808c272..21d99a359ca80 100644
--- a/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
+++ b/clang/lib/StaticAnalyzer/Core/HTMLDiagnostics.cpp
@@ -193,7 +193,8 @@ void ento::createHTMLDiagnosticConsumer(
if (OutputDir.empty())
return;
- C.push_back(new HTMLDiagnostics(std::move(DiagOpts), OutputDir, PP, true));
+ C.emplace_back(std::make_unique<HTMLDiagnostics>(std::move(DiagOpts),
+ OutputDir, PP, true));
}
void ento::createHTMLSingleFileDiagnosticConsumer(
@@ -208,7 +209,8 @@ void ento::createHTMLSingleFileDiagnosticConsumer(
if (OutputDir.empty())
return;
- C.push_back(new HTMLDiagnostics(std::move(DiagOpts), OutputDir, PP, false));
+ C.emplace_back(std::make_unique<HTMLDiagnostics>(std::move(DiagOpts),
+ OutputDir, PP, false));
}
void ento::createPlistHTMLDiagnosticConsumer(
diff --git a/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp b/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
index d806d970acf8d..2ab248f9aa6d9 100644
--- a/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
+++ b/clang/lib/StaticAnalyzer/Core/PlistDiagnostics.cpp
@@ -541,9 +541,9 @@ void ento::createPlistDiagnosticConsumer(
if (OutputFile.empty())
return;
- C.push_back(new PlistDiagnostics(DiagOpts, OutputFile, PP, CTU,
- MacroExpansions,
- /*supportsMultipleFiles=*/false));
+ C.push_back(std::make_unique<PlistDiagnostics>(
+ DiagOpts, OutputFile, PP, CTU, MacroExpansions,
+ /*supportsMultipleFiles=*/false));
createTextMinimalPathDiagnosticConsumer(std::move(DiagOpts), C, OutputFile,
PP, CTU, MacroExpansions);
}
@@ -558,9 +558,9 @@ void ento::createPlistMultiFileDiagnosticConsumer(
if (OutputFile.empty())
return;
- C.push_back(new PlistDiagnostics(DiagOpts, OutputFile, PP, CTU,
- MacroExpansions,
- /*supportsMultipleFiles=*/true));
+ C.push_back(std::make_unique<PlistDiagnostics>(
+ DiagOpts, OutputFile, PP, CTU, MacroExpansions,
+ /*supportsMultipleFiles=*/true));
createTextMinimalPathDiagnosticConsumer(std::move(DiagOpts), C, OutputFile,
PP, CTU, MacroExpansions);
}
diff --git a/clang/lib/StaticAnalyzer/Core/SarifDiagnostics.cpp b/clang/lib/StaticAnalyzer/Core/SarifDiagnostics.cpp
index fab520098f13e..cae6e872a7df5 100644
--- a/clang/lib/StaticAnalyzer/Core/SarifDiagnostics.cpp
+++ b/clang/lib/StaticAnalyzer/Core/SarifDiagnostics.cpp
@@ -23,6 +23,7 @@
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/JSON.h"
#include "llvm/Support/Path.h"
+#include <memory>
using namespace llvm;
using namespace clang;
@@ -60,8 +61,8 @@ void ento::createSarifDiagnosticConsumer(
if (Output.empty())
return;
- C.push_back(
- new SarifDiagnostics(Output, PP.getLangOpts(), PP.getSourceManager()));
+ C.push_back(std::make_unique<SarifDiagnostics>(Output, PP.getLangOpts(),
+ PP.getSourceManager()));
createTextMinimalPathDiagnosticConsumer(std::move(DiagOpts), C, Output, PP,
CTU, MacroExpansions);
}
diff --git a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
index 189d7d6bede8e..8a4bb35925e2c 100644
--- a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -90,7 +90,7 @@ class AnalysisConsumer : public AnalysisASTConsumer,
const std::string OutDir;
AnalyzerOptions &Opts;
ArrayRef<std::string> Plugins;
- CodeInjector *Injector;
+ std::unique_ptr<CodeInjector> Injector;
cross_tu::CrossTranslationUnitContext CTU;
/// Stores the declarations from the local translation unit.
@@ -123,10 +123,10 @@ class AnalysisConsumer : public AnalysisASTConsumer,
AnalysisConsumer(CompilerInstance &CI, const std::string &outdir,
AnalyzerOptions &opts, ArrayRef<std::string> plugins,
- CodeInjector *injector)
+ std::unique_ptr<CodeInjector> injector)
: RecVisitorMode(0), RecVisitorBR(nullptr), Ctx(nullptr),
- PP(CI.getPreprocessor()), OutDir(outdir), Opts(opts),
- Plugins(plugins), Injector(injector), CTU(CI),
+ PP(CI.getPreprocessor()), OutDir(outdir), Opts(opts), Plugins(plugins),
+ Injector(std::move(injector)), CTU(CI),
MacroExpansions(CI.getLangOpts()) {
DigestAnalyzerOptions();
if (Opts.AnalyzerDisplayProgress || Opts.PrintStats ||
@@ -229,9 +229,9 @@ class AnalysisConsumer : public AnalysisASTConsumer,
checkerMgr = std::make_unique<CheckerManager>(*Ctx, Opts, PP, Plugins,
CheckerRegistrationFns);
- Mgr = std::make_unique<AnalysisManager>(*Ctx, PP, PathConsumers,
- CreateStoreMgr, CreateConstraintMgr,
- checkerMgr.get(), Opts, Injector);
+ Mgr = std::make_unique<AnalysisManager>(
+ *Ctx, PP, std::move(PathConsumers), CreateStoreMgr, CreateConstraintMgr,
+ checkerMgr.get(), Opts, std::move(Injector));
}
/// Store the top level decls in the set to be processed later on.
@@ -342,8 +342,9 @@ class AnalysisConsumer : public AnalysisASTConsumer,
return true;
}
- void AddDiagnosticConsumer(PathDiagnosticConsumer *Consumer) override {
- PathConsumers.push_back(Consumer);
+ void AddDiagnosticConsumer(
+ std::unique_ptr<PathDiagnosticConsumer> Consumer) override {
+ PathConsumers.push_back(std::move(Consumer));
}
void AddCheckerRegistrationFn(std::function<void(CheckerRegistry&)> Fn) override {
@@ -794,5 +795,5 @@ ento::CreateAnalysisConsumer(CompilerInstance &CI) {
return std::make_unique<AnalysisConsumer>(
CI, CI.getFrontendOpts().OutputFile, analyzerOpts,
CI.getFrontendOpts().Plugins,
- hasModelPath ? new ModelInjector(CI) : nullptr);
+ hasModelPath ? std::make_unique<ModelInjector>(CI) : nullptr);
}
diff --git a/clang/unittests/StaticAnalyzer/BugReportInterestingnessTest.cpp b/clang/unittests/StaticAnalyzer/BugReportInterestingnessTest.cpp
index 70a58026da95f..0ef63b049621e 100644
--- a/clang/unittests/StaticAnalyzer/BugReportInterestingnessTest.cpp
+++ b/clang/unittests/StaticAnalyzer/BugReportInterestingnessTest.cpp
@@ -19,6 +19,7 @@
#include "clang/StaticAnalyzer/Frontend/CheckerRegistry.h"
#include "clang/Tooling/Tooling.h"
#include "gtest/gtest.h"
+#include <memory>
using namespace clang;
using namespace ento;
@@ -114,8 +115,9 @@ class TestAction : public ASTFrontendAction {
StringRef File) override {
std::unique_ptr<AnalysisASTConsumer> AnalysisConsumer =
CreateAnalysisConsumer(Compiler);
- AnalysisConsumer->AddDiagnosticConsumer(new VerifyPathDiagnosticConsumer(
- std::move(ExpectedDiags), Compiler.getSourceManager()));
+ AnalysisConsumer->AddDiagnosticConsumer(
+ std::make_unique<VerifyPathDiagnosticConsumer>(
+ std::move(ExpectedDiags), Compiler.getSourceManager()));
AnalysisConsumer->AddCheckerRegistrationFn([](CheckerRegistry &Registry) {
Registry.addChecker<InterestingnessTestChecker>("test.Interestingness",
"Description", "");
diff --git a/clang/unittests/StaticAnalyzer/CheckerRegistration.h b/clang/unittests/StaticAnalyzer/CheckerRegistration.h
index 82646167ba545..c4c6e7a9a896d 100644
--- a/clang/unittests/StaticAnalyzer/CheckerRegistration.h
+++ b/clang/unittests/StaticAnalyzer/CheckerRegistration.h
@@ -95,10 +95,10 @@ template <AddCheckerFn... Fns> class TestAction : public ASTFrontendAction {
CreateAnalysisConsumer(Compiler);
if (OnlyEmitWarnings)
AnalysisConsumer->AddDiagnosticConsumer(
- new OnlyWarningsDiagConsumer(DiagsOutput));
+ std::make_unique<OnlyWarningsDiagConsumer>(DiagsOutput));
else
AnalysisConsumer->AddDiagnosticConsumer(
- new PathDiagConsumer(DiagsOutput));
+ std::make_unique<PathDiagConsumer>(DiagsOutput));
addChecker<Fns...>(*AnalysisConsumer, Compiler.getAnalyzerOpts());
return std::move(AnalysisConsumer);
}
diff --git a/clang/unittests/StaticAnalyzer/Reusables.h b/clang/unittests/StaticAnalyzer/Reusables.h
index 5bd62a3e68047..367ef52414370 100644
--- a/clang/unittests/StaticAnalyzer/Reusables.h
+++ b/clang/unittests/StaticAnalyzer/Reusables.h
@@ -59,10 +59,9 @@ class ExprEngineConsumer : public ASTConsumer {
ExprEngineConsumer(CompilerInstance &C)
: C(C),
ChkMgr(C.getASTContext(), C.getAnalyzerOpts(), C.getPreprocessor()),
- CTU(C), Consumers(),
- AMgr(C.getASTContext(), C.getPreprocessor(), Consumers,
- CreateRegionStoreManager, CreateRangeConstraintManager, &ChkMgr,
- C.getAnalyzerOpts()),
+ CTU(C), AMgr(C.getASTContext(), C.getPreprocessor(), {},
+ CreateRegionStoreManager, CreateRangeConstraintManager,
+ &ChkMgr, C.getAnalyzerOpts()),
VisitedCallees(), FS(),
Eng(CTU, AMgr, &VisitedCallees, &FS, ExprEngine::Inline_Regular) {}
};
>From ea932d93a47e6747f50768fc232d2c9e9375b6da Mon Sep 17 00:00:00 2001
From: Balazs Benics <benicsbalazs at gmail.com>
Date: Sat, 22 Feb 2025 12:07:23 +0100
Subject: [PATCH 2/2] Reapply "[analyzer] Delay the checker constructions after
parsing" (#128350)
This reverts commit db836edf47f36ed04cab919a7a2c4414f4d0d7e6.
---
.../Checkers/UnixAPIChecker.cpp | 61 ++++++++++---------
.../Frontend/AnalysisConsumer.cpp | 18 +++---
2 files changed, 40 insertions(+), 39 deletions(-)
diff --git a/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
index da2d16ca9b5dd..10dfa73cc522d 100644
--- a/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
@@ -40,17 +40,28 @@ enum class OpenVariant {
OpenAt
};
+static std::optional<int> getCreateFlagValue(const ASTContext &Ctx,
+ const Preprocessor &PP) {
+ std::optional<int> MacroVal = tryExpandAsInteger("O_CREAT", PP);
+ if (MacroVal.has_value())
+ return MacroVal;
+
+ // If we failed, fall-back to known values.
+ if (Ctx.getTargetInfo().getTriple().getVendor() == llvm::Triple::Apple)
+ return {0x0200};
+ return MacroVal;
+}
+
namespace {
-class UnixAPIMisuseChecker
- : public Checker<check::PreCall, check::ASTDecl<TranslationUnitDecl>> {
+class UnixAPIMisuseChecker : public Checker<check::PreCall> {
const BugType BT_open{this, "Improper use of 'open'", categories::UnixAPI};
const BugType BT_getline{this, "Improper use of getdelim",
categories::UnixAPI};
const BugType BT_pthreadOnce{this, "Improper use of 'pthread_once'",
categories::UnixAPI};
const BugType BT_ArgumentNull{this, "NULL pointer", categories::UnixAPI};
- mutable std::optional<uint64_t> Val_O_CREAT;
+ const std::optional<int> Val_O_CREAT;
ProgramStateRef
EnsurePtrNotNull(SVal PtrVal, const Expr *PtrExpr, CheckerContext &C,
@@ -63,6 +74,9 @@ class UnixAPIMisuseChecker
const Expr *SizePtrExpr, CheckerContext &C, ProgramStateRef State) const;
public:
+ UnixAPIMisuseChecker(const ASTContext &Ctx, const Preprocessor &PP)
+ : Val_O_CREAT(getCreateFlagValue(Ctx, PP)) {}
+
void checkASTDecl(const TranslationUnitDecl *TU, AnalysisManager &Mgr,
BugReporter &BR) const;
@@ -134,20 +148,6 @@ ProgramStateRef UnixAPIMisuseChecker::EnsurePtrNotNull(
return PtrNotNull;
}
-void UnixAPIMisuseChecker::checkASTDecl(const TranslationUnitDecl *TU,
- AnalysisManager &Mgr,
- BugReporter &) const {
- // The definition of O_CREAT is platform specific.
- // Try to get the macro value from the preprocessor.
- Val_O_CREAT = tryExpandAsInteger("O_CREAT", Mgr.getPreprocessor());
- // If we failed, fall-back to known values.
- if (!Val_O_CREAT) {
- if (TU->getASTContext().getTargetInfo().getTriple().getVendor() ==
- llvm::Triple::Apple)
- Val_O_CREAT = 0x0200;
- }
-}
-
//===----------------------------------------------------------------------===//
// "open" (man 2 open)
//===----------------------------------------------------------------------===/
@@ -262,7 +262,7 @@ void UnixAPIMisuseChecker::CheckOpenVariant(CheckerContext &C,
return;
}
- if (!Val_O_CREAT) {
+ if (!Val_O_CREAT.has_value()) {
return;
}
@@ -276,7 +276,7 @@ void UnixAPIMisuseChecker::CheckOpenVariant(CheckerContext &C,
}
NonLoc oflags = V.castAs<NonLoc>();
NonLoc ocreateFlag = C.getSValBuilder()
- .makeIntVal(*Val_O_CREAT, oflagsEx->getType())
+ .makeIntVal(Val_O_CREAT.value(), oflagsEx->getType())
.castAs<NonLoc>();
SVal maskedFlagsUC = C.getSValBuilder().evalBinOpNN(state, BO_And,
oflags, ocreateFlag,
@@ -621,14 +621,17 @@ void UnixAPIPortabilityChecker::checkPreStmt(const CallExpr *CE,
// Registration.
//===----------------------------------------------------------------------===//
-#define REGISTER_CHECKER(CHECKERNAME) \
- void ento::register##CHECKERNAME(CheckerManager &mgr) { \
- mgr.registerChecker<CHECKERNAME>(); \
- } \
- \
- bool ento::shouldRegister##CHECKERNAME(const CheckerManager &mgr) { \
- return true; \
- }
+void ento::registerUnixAPIMisuseChecker(CheckerManager &Mgr) {
+ Mgr.registerChecker<UnixAPIMisuseChecker>(Mgr.getASTContext(),
+ Mgr.getPreprocessor());
+}
+bool ento::shouldRegisterUnixAPIMisuseChecker(const CheckerManager &Mgr) {
+ return true;
+}
-REGISTER_CHECKER(UnixAPIMisuseChecker)
-REGISTER_CHECKER(UnixAPIPortabilityChecker)
+void ento::registerUnixAPIPortabilityChecker(CheckerManager &Mgr) {
+ Mgr.registerChecker<UnixAPIPortabilityChecker>();
+}
+bool ento::shouldRegisterUnixAPIPortabilityChecker(const CheckerManager &Mgr) {
+ return true;
+}
diff --git a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
index 8a4bb35925e2c..6f49860a41d10 100644
--- a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -224,16 +224,6 @@ class AnalysisConsumer : public AnalysisASTConsumer,
}
}
- void Initialize(ASTContext &Context) override {
- Ctx = &Context;
- checkerMgr = std::make_unique<CheckerManager>(*Ctx, Opts, PP, Plugins,
- CheckerRegistrationFns);
-
- Mgr = std::make_unique<AnalysisManager>(
- *Ctx, PP, std::move(PathConsumers), CreateStoreMgr, CreateConstraintMgr,
- checkerMgr.get(), Opts, std::move(Injector));
- }
-
/// Store the top level decls in the set to be processed later on.
/// (Doing this pre-processing avoids deserialization of data from PCH.)
bool HandleTopLevelDecl(DeclGroupRef D) override;
@@ -616,6 +606,14 @@ void AnalysisConsumer::HandleTranslationUnit(ASTContext &C) {
if (Diags.hasErrorOccurred() || Diags.hasFatalErrorOccurred())
return;
+ Ctx = &C;
+ checkerMgr = std::make_unique<CheckerManager>(*Ctx, Opts, PP, Plugins,
+ CheckerRegistrationFns);
+
+ Mgr = std::make_unique<AnalysisManager>(
+ *Ctx, PP, std::move(PathConsumers), CreateStoreMgr, CreateConstraintMgr,
+ checkerMgr.get(), Opts, std::move(Injector));
+
// Explicitly destroy the PathDiagnosticConsumer. This will flush its output.
// FIXME: This should be replaced with something that doesn't rely on
// side-effects in PathDiagnosticConsumer's destructor. This is required when
More information about the cfe-commits
mailing list