Skip to content

Revert "[analyzer] Delay the checker constructions after parsing" #128350

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 29 additions & 32 deletions clang/lib/StaticAnalyzer/Checkers/UnixAPIChecker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,28 +40,17 @@ 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> {
class UnixAPIMisuseChecker
: public Checker<check::PreCall, check::ASTDecl<TranslationUnitDecl>> {
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};
const std::optional<int> Val_O_CREAT;
mutable std::optional<uint64_t> Val_O_CREAT;

ProgramStateRef
EnsurePtrNotNull(SVal PtrVal, const Expr *PtrExpr, CheckerContext &C,
Expand All @@ -74,9 +63,6 @@ class UnixAPIMisuseChecker : public Checker<check::PreCall> {
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;

Expand Down Expand Up @@ -148,6 +134,20 @@ 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)
//===----------------------------------------------------------------------===/
Expand Down Expand Up @@ -262,7 +262,7 @@ void UnixAPIMisuseChecker::CheckOpenVariant(CheckerContext &C,
return;
}

if (!Val_O_CREAT.has_value()) {
if (!Val_O_CREAT) {
return;
}

Expand All @@ -276,7 +276,7 @@ void UnixAPIMisuseChecker::CheckOpenVariant(CheckerContext &C,
}
NonLoc oflags = V.castAs<NonLoc>();
NonLoc ocreateFlag = C.getSValBuilder()
.makeIntVal(Val_O_CREAT.value(), oflagsEx->getType())
.makeIntVal(*Val_O_CREAT, oflagsEx->getType())
.castAs<NonLoc>();
SVal maskedFlagsUC = C.getSValBuilder().evalBinOpNN(state, BO_And,
oflags, ocreateFlag,
Expand Down Expand Up @@ -621,17 +621,14 @@ void UnixAPIPortabilityChecker::checkPreStmt(const CallExpr *CE,
// Registration.
//===----------------------------------------------------------------------===//

void ento::registerUnixAPIMisuseChecker(CheckerManager &Mgr) {
Mgr.registerChecker<UnixAPIMisuseChecker>(Mgr.getASTContext(),
Mgr.getPreprocessor());
}
bool ento::shouldRegisterUnixAPIMisuseChecker(const CheckerManager &Mgr) {
return true;
}
#define REGISTER_CHECKER(CHECKERNAME) \
void ento::register##CHECKERNAME(CheckerManager &mgr) { \
mgr.registerChecker<CHECKERNAME>(); \
} \
\
bool ento::shouldRegister##CHECKERNAME(const CheckerManager &mgr) { \
return true; \
}

void ento::registerUnixAPIPortabilityChecker(CheckerManager &Mgr) {
Mgr.registerChecker<UnixAPIPortabilityChecker>();
}
bool ento::shouldRegisterUnixAPIPortabilityChecker(const CheckerManager &Mgr) {
return true;
}
REGISTER_CHECKER(UnixAPIMisuseChecker)
REGISTER_CHECKER(UnixAPIPortabilityChecker)
18 changes: 10 additions & 8 deletions clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,16 @@ 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, PathConsumers,
CreateStoreMgr, CreateConstraintMgr,
checkerMgr.get(), Opts, 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;
Expand Down Expand Up @@ -605,14 +615,6 @@ 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, PathConsumers,
CreateStoreMgr, CreateConstraintMgr,
checkerMgr.get(), Opts, 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
Expand Down
Loading