]> granicus.if.org Git - clang/commitdiff
Implement: <rdar://problem/7185647> [RegionStore] 'self' cannot be NULL upon entry...
authorTed Kremenek <kremenek@apple.com>
Wed, 9 Sep 2009 20:36:12 +0000 (20:36 +0000)
committerTed Kremenek <kremenek@apple.com>
Wed, 9 Sep 2009 20:36:12 +0000 (20:36 +0000)
Here we implement this as a precondition within GRExprEngine, even though it is
related to how BasicStoreManager and RegionStoreManager model 'self'
differently. Putting this as a high-level precondition is more general, which is
why it isn't in RegionStore.cpp.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@81378 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/GRExprEngine.cpp
test/Analysis/misc-ps.m

index b4b69cdcd61e8baf6494bddd59269ccf19aadb6c..ff9554c836a7b7a8966b821fc6cc76ed09f48280 100644 (file)
@@ -198,11 +198,15 @@ void GRExprEngine::AddCheck(GRSimpleAPICheck *A) {
 const GRState* GRExprEngine::getInitialState(const LocationContext *InitLoc) {
   const GRState *state = StateMgr.getInitialState(InitLoc);
 
-  // Precondition: the first argument of 'main' is an integer guaranteed
-  //  to be > 0.
+  // Preconditions.
+
   // FIXME: It would be nice if we had a more general mechanism to add
   // such preconditions.  Some day.
-  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(InitLoc->getDecl()))
+  const Decl *D = InitLoc->getDecl();
+  
+  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    // Precondition: the first argument of 'main' is an integer guaranteed
+    //  to be > 0.
     if (strcmp(FD->getIdentifier()->getName(), "main") == 0 &&
         FD->getNumParams() > 0) {
       const ParmVarDecl *PD = FD->getParamDecl(0);
@@ -218,7 +222,21 @@ const GRState* GRExprEngine::getInitialState(const LocationContext *InitLoc) {
             state = newState;
         }
     }
-
+  }
+  else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {    
+    // Precondition: 'self' is always non-null upon entry to an Objective-C
+    // method.
+    const ImplicitParamDecl *SelfD = MD->getSelfDecl();
+    const MemRegion *R = state->getRegion(SelfD, InitLoc);
+    SVal V = state->getSVal(loc::MemRegionVal(R));
+    
+    if (const Loc *LV = dyn_cast<Loc>(&V)) {
+      // Assume that the pointer value in 'self' is non-null.
+      state = state->assume(*LV, true);
+      assert(state && "'self' cannot be null");
+    }
+  }
+  
   return state;
 }
 
index cbfb5b1d46a9c21267e99c0d01ff8260c94c4255..34a09536db908445984e50be91dd33f8f20aed49 100644 (file)
@@ -554,3 +554,16 @@ void pr4781(unsigned long *raw1) {
   }
 }
 
+// <rdar://problem/7185647> - 'self' should be treated as being non-null
+// upon entry to an objective-c method.
+@interface RDar7185647
+- (id)foo;
+@end
+@implementation RDar7185647
+- (id) foo {
+  if (self)
+    return self;
+  *((int *) 0x0) = 0xDEADBEEF; // no-warning
+  return self;
+}
+@end