[cfe-commits] r50535 - in /cfe/trunk: include/clang/Analysis/PathSensitive/GRExprEngine.h lib/Analysis/GRExprEngine.cpp

Ted Kremenek kremenek at apple.com
Thu May 1 11:33:28 PDT 2008


Author: kremenek
Date: Thu May  1 13:33:28 2008
New Revision: 50535

URL: http://llvm.org/viewvc/llvm-project?rev=50535&view=rev
Log:
Added temporary fix for Obj-C exception handling in the static analyzer: treat these as panic functions.

Modified:
    cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
    cfe/trunk/lib/Analysis/GRExprEngine.cpp

Modified: cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h?rev=50535&r1=50534&r2=50535&view=diff

==============================================================================
--- cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h (original)
+++ cfe/trunk/include/clang/Analysis/PathSensitive/GRExprEngine.h Thu May  1 13:33:28 2008
@@ -89,6 +89,13 @@
   /// CurrentStmt - The current block-level statement.
   Stmt* CurrentStmt;
   
+  // Obj-C Class Identifiers.
+  IdentifierInfo* NSExceptionII;
+  
+  // Obj-C Selectors.
+  Selector* NSExceptionInstanceRaiseSelectors;
+  Selector RaiseSel;
+  
   typedef llvm::SmallVector<GRSimpleAPICheck*,2> SimpleChecksTy;
   
   SimpleChecksTy CallChecks;

Modified: cfe/trunk/lib/Analysis/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/GRExprEngine.cpp?rev=50535&r1=50534&r2=50535&view=diff

==============================================================================
--- cfe/trunk/lib/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Analysis/GRExprEngine.cpp Thu May  1 13:33:28 2008
@@ -32,6 +32,11 @@
 // Engine construction and deletion.
 //===----------------------------------------------------------------------===//
 
+static inline Selector GetNullarySelector(const char* name, ASTContext& Ctx) {
+  IdentifierInfo* II = &Ctx.Idents.get(name);
+  return Ctx.Selectors.getSelector(0, &II);
+}
+
 
 GRExprEngine::GRExprEngine(CFG& cfg, Decl& CD, ASTContext& Ctx)
   : CoreEngine(cfg, CD, Ctx, *this), 
@@ -42,7 +47,9 @@
     BasicVals(StateMgr.getBasicValueFactory()),
     TF(NULL), // FIXME
     SymMgr(StateMgr.getSymbolManager()),
-    CurrentStmt(NULL) {
+    CurrentStmt(NULL),
+  NSExceptionII(NULL), NSExceptionInstanceRaiseSelectors(NULL),
+  RaiseSel(GetNullarySelector("raise", G.getContext())) {
   
   // Compute liveness information.
   Liveness.runOnCFG(G.getCFG());
@@ -60,6 +67,8 @@
   for (SimpleChecksTy::iterator I=MsgExprChecks.begin(), E=MsgExprChecks.end();
        I != E; ++I)
     delete *I;  
+  
+  delete [] NSExceptionInstanceRaiseSelectors;
 }
 
 //===----------------------------------------------------------------------===//
@@ -1218,6 +1227,8 @@
   // FIXME: More logic for the processing the method call. 
   
   ValueState* St = GetState(Pred);
+  bool RaisesException = false;
+  
   
   if (Expr* Receiver = ME->getReceiver()) {
     
@@ -1235,6 +1246,56 @@
       
       return;
     }
+    
+    // Check if the "raise" message was sent.
+    if (ME->getSelector() == RaiseSel)
+      RaisesException = true;
+  }
+  else {
+    
+    IdentifierInfo* ClsName = ME->getClassName();
+    Selector S = ME->getSelector();
+    
+    // Check for special instance methods.
+        
+    if (!NSExceptionII) {      
+      ASTContext& Ctx = getContext();
+      
+      NSExceptionII = &Ctx.Idents.get("NSException");
+    }
+    
+    if (ClsName == NSExceptionII) {
+        
+      enum { NUM_RAISE_SELECTORS = 2 };
+      
+      // Lazily create a cache of the selectors.
+
+      if (!NSExceptionInstanceRaiseSelectors) {
+        
+        ASTContext& Ctx = getContext();
+        
+        NSExceptionInstanceRaiseSelectors = new Selector[NUM_RAISE_SELECTORS];
+      
+        llvm::SmallVector<IdentifierInfo*, NUM_RAISE_SELECTORS> II;
+        unsigned idx = 0;
+        
+        // raise:format:      
+        II.push_back(&Ctx.Idents.get("raise:"));
+        II.push_back(&Ctx.Idents.get("format:"));      
+        NSExceptionInstanceRaiseSelectors[idx++] =
+          Ctx.Selectors.getSelector(II.size(), &II[0]);      
+        
+        // raise:format::arguments:      
+        II.push_back(&Ctx.Idents.get("arguments:"));
+        NSExceptionInstanceRaiseSelectors[idx++] =
+          Ctx.Selectors.getSelector(II.size(), &II[0]);
+      }
+      
+      for (unsigned i = 0; i < NUM_RAISE_SELECTORS; ++i)
+        if (S == NSExceptionInstanceRaiseSelectors[i]) {
+          RaisesException = true; break;
+        }
+    }
   }
   
   // Check for any arguments that are uninitialized/undefined.
@@ -1255,12 +1316,19 @@
       
       return;
     }    
-  }    
+  }
+  
+  // Check if we raise an exception.  For now treat these as sinks.  Eventually
+  // we will want to handle exceptions properly.
+  
+  SaveAndRestore<bool> OldSink(Builder->BuildSinks);
+
+  if (RaisesException)
+    Builder->BuildSinks = true;
+  
   // Dispatch to plug-in transfer function.
   
   unsigned size = Dst.size();
-
-  SaveAndRestore<bool> OldSink(Builder->BuildSinks);
   SaveOr OldHasGen(Builder->HasGeneratedNode);
  
   EvalObjCMessageExpr(Dst, ME, Pred);





More information about the cfe-commits mailing list