aboutsummaryrefslogtreecommitdiff
path: root/lib/Checker/UnixAPIChecker.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2010-04-08 22:15:34 +0000
committerTed Kremenek <kremenek@apple.com>2010-04-08 22:15:34 +0000
commitbace4ba042d87a0ed0ec15dbe6caad946b97bd33 (patch)
treec7e5db3e59b69e31bf006299c3870d01c1cdd234 /lib/Checker/UnixAPIChecker.cpp
parent8804bdcac242741528036d7e62f26ae5b6a01261 (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.cpp52
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);