[cfe-commits] r68683 - in /cfe/trunk: lib/Analysis/GRExprEngine.cpp test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m

Ted Kremenek kremenek at apple.com
Wed Apr 8 22:45:57 PDT 2009


Author: kremenek
Date: Thu Apr  9 00:45:56 2009
New Revision: 68683

URL: http://llvm.org/viewvc/llvm-project?rev=68683&view=rev
Log:
GRExprEngine: Don't try to reason about the size of 'void' for the return type
of messages sent to nil.

Modified:
    cfe/trunk/lib/Analysis/GRExprEngine.cpp
    cfe/trunk/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m

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

==============================================================================
--- cfe/trunk/lib/Analysis/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Analysis/GRExprEngine.cpp Thu Apr  9 00:45:56 2009
@@ -1689,8 +1689,10 @@
     const GRState *StNull = Assume(state, L, false, isFeasibleNull);
     
     if (isFeasibleNull) {
+      QualType RetTy = ME->getType();
+      
       // Check if the receiver was nil and the return value a struct.
-      if(ME->getType()->isRecordType()) {
+      if(RetTy->isRecordType()) {
         if (BR.getParentMap().isConsumedExpr(ME)) {
           // The [0 ...] expressions will return garbage.  Flag either an
           // explicit or implicit error.  Because of the structure of this
@@ -1709,44 +1711,47 @@
           }
         }
       }
-      else if (BR.getParentMap().isConsumedExpr(ME)) {
+      else {
         ASTContext& Ctx = getContext();
-        // sizeof(void *)
-        const uint64_t voidPtrSize = Ctx.getTypeSize(Ctx.VoidPtrTy);
-        // sizeof(return type)
-        const uint64_t returnTypeSize = Ctx.getTypeSize(ME->getType());
-
-        if(voidPtrSize < returnTypeSize) {
-          if (NodeTy* N = Builder->generateNode(ME, StNull, Pred)) {
-            N->markAsSink();
-            if(isFeasibleNotNull)
-              NilReceiverLargerThanVoidPtrRetImplicit.insert(N);
-            else {
-              NilReceiverLargerThanVoidPtrRetExplicit.insert(N);            
+        if (RetTy != Ctx.VoidTy) {
+          if (BR.getParentMap().isConsumedExpr(ME)) {
+            // sizeof(void *)
+            const uint64_t voidPtrSize = Ctx.getTypeSize(Ctx.VoidPtrTy);
+            // sizeof(return type)
+            const uint64_t returnTypeSize = Ctx.getTypeSize(ME->getType());
+
+            if(voidPtrSize < returnTypeSize) {
+              if (NodeTy* N = Builder->generateNode(ME, StNull, Pred)) {
+                N->markAsSink();
+                if(isFeasibleNotNull)
+                  NilReceiverLargerThanVoidPtrRetImplicit.insert(N);
+                else {
+                  NilReceiverLargerThanVoidPtrRetExplicit.insert(N);            
+                  return;
+                }
+              }
+            }
+            else if (!isFeasibleNotNull) {
+              // Handle the safe cases where the return value is 0 if the
+              // receiver is nil.
+              //
+              // FIXME: For now take the conservative approach that we only
+              // return null values if we *know* that the receiver is nil.
+              // This is because we can have surprises like:
+              //
+              //   ... = [[NSScreens screens] objectAtIndex:0];
+              //
+              // What can happen is that [... screens] could return nil, but
+              // it most likely isn't nil.  We should assume the semantics
+              // of this case unless we have *a lot* more knowledge.
+              //
+              SVal V = SVal::MakeZero(getBasicVals(), ME->getType());
+              MakeNode(Dst, ME, Pred, BindExpr(StNull, ME, V));
               return;
             }
           }
         }
-        else if (!isFeasibleNotNull) {
-          // FIXME: For now take the conservative approach that we only
-          // return null values if we *know* that the receiver is nil.
-          // This is because we can have surprises like:
-          //
-          // if ([[NSScreens screens] count]) {
-          //   ... = [[NSScreens screens] objectAtIndex:0];
-          //
-          // What can happen is that [... screens] should return the same
-          // value, but we won't necessarily catch that (yet).
-          //
-          
-          // Handle the safe cases where the return value is 0 if the receiver
-          // is nil.
-          SVal V = SVal::MakeZero(getBasicVals(), ME->getType());
-          MakeNode(Dst, ME, Pred, BindExpr(StNull, ME, V));
-          return;
-        }
       }
-      
       // We have handled the cases where the receiver is nil.  The remainder
       // of this method should assume that the receiver is not nil.      
       state = StNotNull;

Modified: cfe/trunk/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m?rev=68683&r1=68682&r2=68683&view=diff

==============================================================================
--- cfe/trunk/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m (original)
+++ cfe/trunk/test/Analysis/nil-receiver-undefined-larger-than-voidptr-ret.m Thu Apr  9 00:45:56 2009
@@ -6,6 +6,7 @@
 - (long long)longlongM;
 - (double)doubleM;
 - (long double)longDoubleM;
+- (void)voidM;
 @end
 @implementation MyClass
 - (void *)voidPtrM { return (void *)0; }
@@ -13,6 +14,7 @@
 - (long long)longlongM { return 0; }
 - (double)doubleM { return 0.0; }
 - (long double)longDoubleM { return 0.0; }
+- (void)voidM {}
 @end
 
 void createFoo() {
@@ -57,3 +59,8 @@
   
   long long j = [obj longlongM]; // expected-warning{{The receiver in the message expression is 'nil' and results in the returned value}}
 }
+
+int handleVoidInComma() {
+  MyClass *obj = 0;
+  return [obj voidM], 0;
+}





More information about the cfe-commits mailing list