]> granicus.if.org Git - clang/commitdiff
For 'open' check in UnixAPIChecker, hard code value of 'O_CREAT' on Darwin.
authorTed Kremenek <kremenek@apple.com>
Thu, 8 Apr 2010 22:15:34 +0000 (22:15 +0000)
committerTed Kremenek <kremenek@apple.com>
Thu, 8 Apr 2010 22:15:34 +0000 (22:15 +0000)
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

include/clang/Analysis/Support/Optional.h
lib/Checker/UnixAPIChecker.cpp

index a4e6d519a04f8fe1f8599d8d3a8caeb0b06c100a..77c4825b4e536b7bd51459256380dd4f230036cd 100644 (file)
@@ -16,6 +16,8 @@
 #ifndef LLVM_CLANG_ANALYSIS_OPTIONAL
 #define LLVM_CLANG_ANALYSIS_OPTIONAL
 
+#include <cassert>
+
 namespace clang {
 
 template<typename T>
index 213e7980053774425329f19407e0a0c34e44d9e1..31864e74550dec660558146988248bf2108dbdbd 100644 (file)
 //===----------------------------------------------------------------------===//
 
 #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 {
@@ -34,6 +32,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);