18
18
#include " clang/StaticAnalyzer/Core/Checker.h"
19
19
#include " clang/StaticAnalyzer/Core/CheckerManager.h"
20
20
#include " clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
21
+ #include " clang/StaticAnalyzer/Core/PathSensitive/CheckerHelpers.h"
21
22
#include " llvm/ADT/STLExtras.h"
22
23
#include " llvm/ADT/SmallString.h"
23
24
#include " llvm/ADT/StringExtras.h"
@@ -39,13 +40,18 @@ enum class OpenVariant {
39
40
40
41
namespace {
41
42
42
- class UnixAPIMisuseChecker : public Checker < check::PreStmt<CallExpr> > {
43
+ class UnixAPIMisuseChecker
44
+ : public Checker<check::PreStmt<CallExpr>,
45
+ check::ASTDecl<TranslationUnitDecl>> {
43
46
const BugType BT_open{this , " Improper use of 'open'" , categories::UnixAPI};
44
47
const BugType BT_pthreadOnce{this , " Improper use of 'pthread_once'" ,
45
48
categories::UnixAPI};
46
49
mutable std::optional<uint64_t > Val_O_CREAT;
47
50
48
51
public:
52
+ void checkASTDecl (const TranslationUnitDecl *TU, AnalysisManager &Mgr,
53
+ BugReporter &BR) const ;
54
+
49
55
void checkPreStmt (const CallExpr *CE, CheckerContext &C) const ;
50
56
51
57
void CheckOpen (CheckerContext &C, const CallExpr *CE) const ;
@@ -55,11 +61,8 @@ class UnixAPIMisuseChecker : public Checker< check::PreStmt<CallExpr> > {
55
61
void CheckOpenVariant (CheckerContext &C,
56
62
const CallExpr *CE, OpenVariant Variant) const ;
57
63
58
- void ReportOpenBug (CheckerContext &C,
59
- ProgramStateRef State,
60
- const char *Msg,
64
+ void ReportOpenBug (CheckerContext &C, ProgramStateRef State, const char *Msg,
61
65
SourceRange SR) const ;
62
-
63
66
};
64
67
65
68
class UnixAPIPortabilityChecker : public Checker < check::PreStmt<CallExpr> > {
@@ -90,7 +93,21 @@ class UnixAPIPortabilityChecker : public Checker< check::PreStmt<CallExpr> > {
90
93
const char *fn) const ;
91
94
};
92
95
93
- } // end anonymous namespace
96
+ } // end anonymous namespace
97
+
98
+ void UnixAPIMisuseChecker::checkASTDecl (const TranslationUnitDecl *TU,
99
+ AnalysisManager &Mgr,
100
+ BugReporter &) const {
101
+ // The definition of O_CREAT is platform specific.
102
+ // Try to get the macro value from the preprocessor.
103
+ Val_O_CREAT = tryExpandAsInteger (" O_CREAT" , Mgr.getPreprocessor ());
104
+ // If we failed, fall-back to known values.
105
+ if (!Val_O_CREAT) {
106
+ if (TU->getASTContext ().getTargetInfo ().getTriple ().getVendor () ==
107
+ llvm::Triple::Apple)
108
+ Val_O_CREAT = 0x0200 ;
109
+ }
110
+ }
94
111
95
112
// ===----------------------------------------------------------------------===//
96
113
// "open" (man 2 open)
@@ -204,19 +221,8 @@ void UnixAPIMisuseChecker::CheckOpenVariant(CheckerContext &C,
204
221
return ;
205
222
}
206
223
207
- // The definition of O_CREAT is platform specific. We need a better way
208
- // of querying this information from the checking environment.
209
224
if (!Val_O_CREAT) {
210
- if (C.getASTContext ().getTargetInfo ().getTriple ().getVendor ()
211
- == llvm::Triple::Apple)
212
- Val_O_CREAT = 0x0200 ;
213
- else {
214
- // FIXME: We need a more general way of getting the O_CREAT value.
215
- // We could possibly grovel through the preprocessor state, but
216
- // that would require passing the Preprocessor object to the ExprEngine.
217
- // See also: MallocChecker.cpp / M_ZERO.
218
- return ;
219
- }
225
+ return ;
220
226
}
221
227
222
228
// Now check if oflags has O_CREAT set.
0 commit comments