[llvm-branch-commits] [cfe-tag] r93102 - in /cfe/tags/Apple/clang/clang/tools/clang: lib/Analysis/GRExprEngine.cpp test/Analysis/misc-ps-ranges.m test/Analysis/misc-ps-region-store.m

Ted Kremenek kremenek at apple.com
Sat Jan 9 19:28:02 PST 2010


Author: kremenek
Date: Sat Jan  9 21:28:02 2010
New Revision: 93102

URL: http://llvm.org/viewvc/llvm-project?rev=93102&view=rev
Log:
Merge in r93017 and r93081.

Modified:
    cfe/tags/Apple/clang/clang/tools/clang/lib/Analysis/GRExprEngine.cpp
    cfe/tags/Apple/clang/clang/tools/clang/test/Analysis/misc-ps-ranges.m
    cfe/tags/Apple/clang/clang/tools/clang/test/Analysis/misc-ps-region-store.m

Modified: cfe/tags/Apple/clang/clang/tools/clang/lib/Analysis/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/tags/Apple/clang/clang/tools/clang/lib/Analysis/GRExprEngine.cpp?rev=93102&r1=93101&r2=93102&view=diff

==============================================================================
--- cfe/tags/Apple/clang/clang/tools/clang/lib/Analysis/GRExprEngine.cpp (original)
+++ cfe/tags/Apple/clang/clang/tools/clang/lib/Analysis/GRExprEngine.cpp Sat Jan  9 21:28:02 2010
@@ -47,10 +47,9 @@
 }
 
 
-static bool CalleeReturnsReference(const CallExpr *CE) { 
+static QualType GetCalleeReturnType(const CallExpr *CE) { 
   const Expr *Callee = CE->getCallee();
   QualType T = Callee->getType();
-  
   if (const PointerType *PT = T->getAs<PointerType>()) {
     const FunctionType *FT = PT->getPointeeType()->getAs<FunctionType>();
     T = FT->getResultType();
@@ -58,17 +57,36 @@
   else {
     const BlockPointerType *BT = T->getAs<BlockPointerType>();
     T = BT->getPointeeType()->getAs<FunctionType>()->getResultType();
-  }  
-  return T->isReferenceType();
+  }
+  return T;
+}
+
+static bool CalleeReturnsReference(const CallExpr *CE) { 
+  return (bool) GetCalleeReturnType(CE)->getAs<ReferenceType>();
 }
 
 static bool ReceiverReturnsReference(const ObjCMessageExpr *ME) {
   const ObjCMethodDecl *MD = ME->getMethodDecl();
   if (!MD)
     return false;
-  return MD->getResultType()->isReferenceType();
+  return MD->getResultType()->getAs<ReferenceType>();
+}
+
+#ifndef NDEBUG
+static bool ReceiverReturnsReferenceOrRecord(const ObjCMessageExpr *ME) {
+  const ObjCMethodDecl *MD = ME->getMethodDecl();
+  if (!MD)
+    return false;
+  QualType T = MD->getResultType();
+  return T->getAs<RecordType>() || T->getAs<ReferenceType>();
 }
 
+static bool CalleeReturnsReferenceOrRecord(const CallExpr *CE) {
+  QualType T = GetCalleeReturnType(CE);
+  return T->getAs<ReferenceType>() || T->getAs<RecordType>();
+}
+#endif
+
 //===----------------------------------------------------------------------===//
 // Batch auditor.  DEPRECATED.
 //===----------------------------------------------------------------------===//
@@ -825,7 +843,7 @@
     case Stmt::CallExprClass:
     case Stmt::CXXOperatorCallExprClass: {
       CallExpr *C = cast<CallExpr>(Ex);
-      assert(CalleeReturnsReference(C));
+      assert(CalleeReturnsReferenceOrRecord(C));
       VisitCall(C, Pred, C->arg_begin(), C->arg_end(), Dst, true);      
       break;
     }
@@ -856,7 +874,7 @@
       
     case Stmt::ObjCMessageExprClass: {
       ObjCMessageExpr *ME = cast<ObjCMessageExpr>(Ex);
-      assert(ReceiverReturnsReference(ME));
+      assert(ReceiverReturnsReferenceOrRecord(ME));
       VisitObjCMessageExpr(ME, Pred, Dst, true); 
       return;
     }
@@ -1221,7 +1239,8 @@
 
     do {
       nonloc::ConcreteInt CaseVal(getBasicVals().getValue(V1.Val.getInt()));
-      DefinedOrUnknownSVal Res = SVator.EvalEQ(DefaultSt, CondV, CaseVal);
+      DefinedOrUnknownSVal Res = SVator.EvalEQ(DefaultSt ? DefaultSt : state,
+                                               CondV, CaseVal);
             
       // Now "assume" that the case matches.
       if (const GRState* stateNew = state->Assume(Res, true)) {
@@ -1236,11 +1255,17 @@
 
       // Now "assume" that the case doesn't match.  Add this state
       // to the default state (if it is feasible).
-      if (const GRState *stateNew = DefaultSt->Assume(Res, false)) {
-        defaultIsFeasible = true;
-        DefaultSt = stateNew;
+      if (DefaultSt) {
+        if (const GRState *stateNew = DefaultSt->Assume(Res, false)) {
+          defaultIsFeasible = true;
+          DefaultSt = stateNew;
+        }
+        else {
+          defaultIsFeasible = false;
+          DefaultSt = NULL;
+        }
       }
-
+        
       // Concretize the next value in the range.
       if (V1.Val.getInt() == V2.Val.getInt())
         break;

Modified: cfe/tags/Apple/clang/clang/tools/clang/test/Analysis/misc-ps-ranges.m
URL: http://llvm.org/viewvc/llvm-project/cfe/tags/Apple/clang/clang/tools/clang/test/Analysis/misc-ps-ranges.m?rev=93102&r1=93101&r2=93102&view=diff

==============================================================================
--- cfe/tags/Apple/clang/clang/tools/clang/test/Analysis/misc-ps-ranges.m (original)
+++ cfe/tags/Apple/clang/clang/tools/clang/test/Analysis/misc-ps-ranges.m Sat Jan  9 21:28:02 2010
@@ -21,3 +21,40 @@
 
   return *p; // no-warning
 }
+
+// PR 5969: the comparison of argc < 3 || argc > 4 should constraint the switch
+//  statement from having the 'default' branch taken.  This previously reported a false
+//  positive with the use of 'v'.
+
+int pr5969(int argc, char *argv[]) {
+
+  int v;
+
+  if ((argc < 3) || (argc > 4)) return 0;
+
+  switch(argc) {
+    case 3:
+      v = 33;
+      break;
+    case 4:
+      v = 44;
+      break;
+  }
+
+  return v; // no-warning
+}
+
+int pr5969_positive(int argc, char *argv[]) {
+
+  int v;
+
+  if ((argc < 3) || (argc > 4)) return 0;
+
+  switch(argc) {
+    case 3:
+      v = 33;
+      break;
+  }
+
+  return v; // expected-warning{{Undefined or garbage value returned to caller}}
+}

Modified: cfe/tags/Apple/clang/clang/tools/clang/test/Analysis/misc-ps-region-store.m
URL: http://llvm.org/viewvc/llvm-project/cfe/tags/Apple/clang/clang/tools/clang/test/Analysis/misc-ps-region-store.m?rev=93102&r1=93101&r2=93102&view=diff

==============================================================================
--- cfe/tags/Apple/clang/clang/tools/clang/test/Analysis/misc-ps-region-store.m (original)
+++ cfe/tags/Apple/clang/clang/tools/clang/test/Analysis/misc-ps-region-store.m Sat Jan  9 21:28:02 2010
@@ -55,7 +55,7 @@
 
 // Check our handling of fields being invalidated by function calls.
 struct test2_struct { int x; int y; char* s; };
-void test2_helper(struct test2_struct* p);
+void test2_help(struct test2_struct* p);
 
 char test2() {
   struct test2_struct s;
@@ -387,7 +387,7 @@
     char value[1];
     if ( *(value) != 1 ) {} // expected-warning{{The left operand of '!=' is a garbage value}}
 }
-void rdar_rdar_7332673_test2_aux(char *x);
+int rdar_7332673_test2_aux(char *x);
 void rdar_7332673_test2() {
     char *value;
     if ( rdar_7332673_test2_aux(value) != 1 ) {} // expected-warning{{Pass-by-value argument in function call is undefined}}
@@ -631,7 +631,7 @@
 //===----------------------------------------------------------------------===//
 
 int rdar7468209_aux();
-void rdar7468209_aux2();
+void rdar7468209_aux_2();
 
 void rdar7468209() {
   __block int x = 0;
@@ -684,3 +684,29 @@
   }
   pr4358_aux(uninit); // no-warning
 }
+
+//===----------------------------------------------------------------------===//
+// <rdar://problem/7526777>
+// Test handling fields of values returned from function calls or
+// message expressions.
+//===----------------------------------------------------------------------===//
+
+typedef struct testReturn_rdar_7526777 {
+  int x;
+  int y;
+} testReturn_rdar_7526777;
+
+ at interface TestReturnStruct_rdar_7526777
+- (testReturn_rdar_7526777) foo;
+ at end
+
+int test_return_struct(TestReturnStruct_rdar_7526777 *x) {
+  return [x foo].x;
+}
+
+testReturn_rdar_7526777 test_return_struct_2_aux_rdar_7526777();
+
+int test_return_struct_2_rdar_7526777() {
+  return test_return_struct_2_aux_rdar_7526777().x;
+}
+





More information about the llvm-branch-commits mailing list