[clang] 5865807 - Reapply "[analyzer] Delay the checker constructions after parsing" (#128369)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Mar 18 03:40:42 PDT 2025
Author: Balazs Benics
Date: 2025-03-18T11:40:39+01:00
New Revision: 586580742123a8e3c1032369e8a2750c2c49685f
URL: https://github.com/llvm/llvm-project/commit/586580742123a8e3c1032369e8a2750c2c49685f
DIFF: https://github.com/llvm/llvm-project/commit/586580742123a8e3c1032369e8a2750c2c49685f.diff
LOG: Reapply "[analyzer] Delay the checker constructions after parsing" (#128369)
Reapply "[analyzer] Delay the checker constructions after parsing"
(#128350)
This reverts commit db836edf47f36ed04cab919a7a2c4414f4d0d7e6, as-is.
Depends on #128368
Added:
Modified:
clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
Removed:
################################################################################
diff --git a/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
index a05361f89ed89..897e654f3bbc2 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 b4222eddc09f9..491aa93c96e49 100644
--- a/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
+++ b/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
@@ -227,16 +227,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;
@@ -619,6 +609,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