diff options
author | Ted Kremenek <kremenek@apple.com> | 2010-04-08 22:15:34 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2010-04-08 22:15:34 +0000 |
commit | bace4ba042d87a0ed0ec15dbe6caad946b97bd33 (patch) | |
tree | c7e5db3e59b69e31bf006299c3870d01c1cdd234 /lib/Checker/UnixAPIChecker.cpp | |
parent | 8804bdcac242741528036d7e62f26ae5b6a01261 (diff) |
For 'open' check in UnixAPIChecker, hard code value of 'O_CREAT' on Darwin.
This is still not an ideal solution, but should disable the check for other
targets where the value of O_CREAT is different.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@100818 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Checker/UnixAPIChecker.cpp')
-rw-r--r-- | lib/Checker/UnixAPIChecker.cpp | 52 |
1 files changed, 34 insertions, 18 deletions
diff --git a/lib/Checker/UnixAPIChecker.cpp b/lib/Checker/UnixAPIChecker.cpp index 213e798005..31864e7455 100644 --- a/lib/Checker/UnixAPIChecker.cpp +++ b/lib/Checker/UnixAPIChecker.cpp @@ -13,15 +13,13 @@ //===----------------------------------------------------------------------===// #include "GRExprEngineInternalChecks.h" -#include "clang/Checker/PathSensitive/CheckerVisitor.h" -#include "clang/Checker/BugReporter/BugType.h" #include "clang/Analysis/Support/Optional.h" +#include "clang/Basic/TargetInfo.h" +#include "clang/Checker/BugReporter/BugType.h" +#include "clang/Checker/PathSensitive/CheckerVisitor.h" #include "llvm/ADT/StringSwitch.h" #include <fcntl.h> -#include "clang/Basic/TargetInfo.h" - - using namespace clang; namespace { @@ -35,6 +33,9 @@ class UnixAPIChecker : public CheckerVisitor<UnixAPIChecker> { BugType *BTypes[NumChecks]; public: + Optional<uint64_t> Val_O_CREAT; + +public: UnixAPIChecker() { memset(BTypes, 0, sizeof(*BTypes) * NumChecks); } static void *getTag() { static unsigned tag = 0; return &tag; } @@ -60,10 +61,21 @@ static inline void LazyInitialize(BugType *&BT, const char *name) { // "open" (man 2 open) //===----------------------------------------------------------------------===// -static void CheckOpen(CheckerContext &C, const CallExpr *CE, BugType *&BT) { - if (C.getASTContext().Target.getTriple().getVendor() != llvm::Triple::Apple) - return; - +static void CheckOpen(CheckerContext &C, UnixAPIChecker &UC, + const CallExpr *CE, BugType *&BT) { + // The definition of O_CREAT is platform specific. We need a better way + // of querying this information from the checking environment. + if (!UC.Val_O_CREAT.hasValue()) { + if (C.getASTContext().Target.getTriple().getVendor() == llvm::Triple::Apple) + UC.Val_O_CREAT = 0x0200; + else { + // FIXME: We need a more general way of getting the O_CREAT value. + // We could possibly grovel through the preprocessor state, but + // that would require passing the Preprocessor object to the GRExprEngine. + return; + } + } + LazyInitialize(BT, "Improper use of 'open'"); // Look at the 'oflags' argument for the O_CREAT flag. @@ -85,7 +97,7 @@ static void CheckOpen(CheckerContext &C, const CallExpr *CE, BugType *&BT) { } NonLoc oflags = cast<NonLoc>(V); NonLoc ocreateFlag = - cast<NonLoc>(C.getValueManager().makeIntVal((uint64_t) O_CREAT, + cast<NonLoc>(C.getValueManager().makeIntVal(UC.Val_O_CREAT.getValue(), oflagsEx->getType())); SVal maskedFlagsUC = C.getSValuator().EvalBinOpNN(state, BinaryOperator::And, oflags, ocreateFlag, @@ -121,8 +133,8 @@ static void CheckOpen(CheckerContext &C, const CallExpr *CE, BugType *&BT) { // pthread_once //===----------------------------------------------------------------------===// -static void CheckPthreadOnce(CheckerContext &C, const CallExpr *CE, - BugType *&BT) { +static void CheckPthreadOnce(CheckerContext &C, UnixAPIChecker &, + const CallExpr *CE, BugType *&BT) { // This is similar to 'CheckDispatchOnce' in the MacOSXAPIChecker. // They can possibly be refactored. @@ -164,18 +176,21 @@ static void CheckPthreadOnce(CheckerContext &C, const CallExpr *CE, // Central dispatch function. //===----------------------------------------------------------------------===// -typedef void (*SubChecker)(CheckerContext &C, const CallExpr *CE, BugType *&BT); +typedef void (*SubChecker)(CheckerContext &C, UnixAPIChecker &UC, + const CallExpr *CE, BugType *&BT); namespace { class SubCheck { SubChecker SC; + UnixAPIChecker *UC; BugType **BT; public: - SubCheck(SubChecker sc, BugType *& bt) : SC(sc), BT(&bt) {} - SubCheck() : SC(NULL), BT(NULL) {} + SubCheck(SubChecker sc, UnixAPIChecker *uc, BugType *& bt) : SC(sc), UC(uc), + BT(&bt) {} + SubCheck() : SC(NULL), UC(NULL), BT(NULL) {} void run(CheckerContext &C, const CallExpr *CE) const { if (SC) - SC(C, CE, *BT); + SC(C, *UC, CE, *BT); } }; } // end anonymous namespace @@ -197,8 +212,9 @@ void UnixAPIChecker::PreVisitCallExpr(CheckerContext &C, const CallExpr *CE) { const SubCheck &SC = llvm::StringSwitch<SubCheck>(FI->getName()) - .Case("open", SubCheck(CheckOpen, BTypes[OpenFn])) - .Case("pthread_once", SubCheck(CheckPthreadOnce, BTypes[PthreadOnceFn])) + .Case("open", SubCheck(CheckOpen, this, BTypes[OpenFn])) + .Case("pthread_once", SubCheck(CheckPthreadOnce, this, + BTypes[PthreadOnceFn])) .Default(SubCheck()); SC.run(C, CE); |