[cfe-commits] r100818 - in /cfe/trunk: include/clang/Analysis/Support/Optional.h lib/Checker/UnixAPIChecker.cpp

Ted Kremenek kremenek at apple.com
Thu Apr 8 15:15:34 PDT 2010


Author: kremenek
Date: Thu Apr  8 17:15:34 2010
New Revision: 100818

URL: http://llvm.org/viewvc/llvm-project?rev=100818&view=rev
Log:
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.

Modified:
    cfe/trunk/include/clang/Analysis/Support/Optional.h
    cfe/trunk/lib/Checker/UnixAPIChecker.cpp

Modified: cfe/trunk/include/clang/Analysis/Support/Optional.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Support/Optional.h?rev=100818&r1=100817&r2=100818&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/Support/Optional.h (original)
+++ cfe/trunk/include/clang/Analysis/Support/Optional.h Thu Apr  8 17:15:34 2010
@@ -16,6 +16,8 @@
 #ifndef LLVM_CLANG_ANALYSIS_OPTIONAL
 #define LLVM_CLANG_ANALYSIS_OPTIONAL
 
+#include <cassert>
+
 namespace clang {
 
 template<typename T>

Modified: cfe/trunk/lib/Checker/UnixAPIChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/UnixAPIChecker.cpp?rev=100818&r1=100817&r2=100818&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/UnixAPIChecker.cpp (original)
+++ cfe/trunk/lib/Checker/UnixAPIChecker.cpp Thu Apr  8 17:15:34 2010
@@ -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 @@
   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 @@
 // "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 @@
   }
   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 @@
 // 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 @@
 // 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 @@
 
   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);





More information about the cfe-commits mailing list