@@ -40,28 +40,17 @@ enum class OpenVariant {
40
40
OpenAt
41
41
};
42
42
43
- static std::optional<int > getCreateFlagValue (const ASTContext &Ctx,
44
- const Preprocessor &PP) {
45
- std::optional<int > MacroVal = tryExpandAsInteger (" O_CREAT" , PP);
46
- if (MacroVal.has_value ())
47
- return MacroVal;
48
-
49
- // If we failed, fall-back to known values.
50
- if (Ctx.getTargetInfo ().getTriple ().getVendor () == llvm::Triple::Apple)
51
- return {0x0200 };
52
- return MacroVal;
53
- }
54
-
55
43
namespace {
56
44
57
- class UnixAPIMisuseChecker : public Checker <check::PreCall> {
45
+ class UnixAPIMisuseChecker
46
+ : public Checker<check::PreCall, check::ASTDecl<TranslationUnitDecl>> {
58
47
const BugType BT_open{this , " Improper use of 'open'" , categories::UnixAPI};
59
48
const BugType BT_getline{this , " Improper use of getdelim" ,
60
49
categories::UnixAPI};
61
50
const BugType BT_pthreadOnce{this , " Improper use of 'pthread_once'" ,
62
51
categories::UnixAPI};
63
52
const BugType BT_ArgumentNull{this , " NULL pointer" , categories::UnixAPI};
64
- const std::optional<int > Val_O_CREAT;
53
+ mutable std::optional<uint64_t > Val_O_CREAT;
65
54
66
55
ProgramStateRef
67
56
EnsurePtrNotNull (SVal PtrVal, const Expr *PtrExpr, CheckerContext &C,
@@ -74,9 +63,6 @@ class UnixAPIMisuseChecker : public Checker<check::PreCall> {
74
63
const Expr *SizePtrExpr, CheckerContext &C, ProgramStateRef State) const ;
75
64
76
65
public:
77
- UnixAPIMisuseChecker (const ASTContext &Ctx, const Preprocessor &PP)
78
- : Val_O_CREAT(getCreateFlagValue(Ctx, PP)) {}
79
-
80
66
void checkASTDecl (const TranslationUnitDecl *TU, AnalysisManager &Mgr,
81
67
BugReporter &BR) const ;
82
68
@@ -148,6 +134,20 @@ ProgramStateRef UnixAPIMisuseChecker::EnsurePtrNotNull(
148
134
return PtrNotNull;
149
135
}
150
136
137
+ void UnixAPIMisuseChecker::checkASTDecl (const TranslationUnitDecl *TU,
138
+ AnalysisManager &Mgr,
139
+ BugReporter &) const {
140
+ // The definition of O_CREAT is platform specific.
141
+ // Try to get the macro value from the preprocessor.
142
+ Val_O_CREAT = tryExpandAsInteger (" O_CREAT" , Mgr.getPreprocessor ());
143
+ // If we failed, fall-back to known values.
144
+ if (!Val_O_CREAT) {
145
+ if (TU->getASTContext ().getTargetInfo ().getTriple ().getVendor () ==
146
+ llvm::Triple::Apple)
147
+ Val_O_CREAT = 0x0200 ;
148
+ }
149
+ }
150
+
151
151
// ===----------------------------------------------------------------------===//
152
152
// "open" (man 2 open)
153
153
// ===----------------------------------------------------------------------===/
@@ -262,7 +262,7 @@ void UnixAPIMisuseChecker::CheckOpenVariant(CheckerContext &C,
262
262
return ;
263
263
}
264
264
265
- if (!Val_O_CREAT. has_value () ) {
265
+ if (!Val_O_CREAT) {
266
266
return ;
267
267
}
268
268
@@ -276,7 +276,7 @@ void UnixAPIMisuseChecker::CheckOpenVariant(CheckerContext &C,
276
276
}
277
277
NonLoc oflags = V.castAs <NonLoc>();
278
278
NonLoc ocreateFlag = C.getSValBuilder ()
279
- .makeIntVal (Val_O_CREAT. value () , oflagsEx->getType ())
279
+ .makeIntVal (* Val_O_CREAT, oflagsEx->getType ())
280
280
.castAs <NonLoc>();
281
281
SVal maskedFlagsUC = C.getSValBuilder ().evalBinOpNN (state, BO_And,
282
282
oflags, ocreateFlag,
@@ -621,17 +621,14 @@ void UnixAPIPortabilityChecker::checkPreStmt(const CallExpr *CE,
621
621
// Registration.
622
622
// ===----------------------------------------------------------------------===//
623
623
624
- void ento::registerUnixAPIMisuseChecker (CheckerManager &Mgr) {
625
- Mgr.registerChecker <UnixAPIMisuseChecker>(Mgr.getASTContext (),
626
- Mgr.getPreprocessor ());
627
- }
628
- bool ento::shouldRegisterUnixAPIMisuseChecker (const CheckerManager &Mgr) {
629
- return true ;
630
- }
624
+ #define REGISTER_CHECKER (CHECKERNAME ) \
625
+ void ento::register ##CHECKERNAME(CheckerManager &mgr) { \
626
+ mgr.registerChecker <CHECKERNAME>(); \
627
+ } \
628
+ \
629
+ bool ento::shouldRegister##CHECKERNAME(const CheckerManager &mgr) { \
630
+ return true ; \
631
+ }
631
632
632
- void ento::registerUnixAPIPortabilityChecker (CheckerManager &Mgr) {
633
- Mgr.registerChecker <UnixAPIPortabilityChecker>();
634
- }
635
- bool ento::shouldRegisterUnixAPIPortabilityChecker (const CheckerManager &Mgr) {
636
- return true ;
637
- }
633
+ REGISTER_CHECKER (UnixAPIMisuseChecker)
634
+ REGISTER_CHECKER(UnixAPIPortabilityChecker)
0 commit comments