]> granicus.if.org Git - clang/commitdiff
Fix PR 5857. When casting from a symbolic region to an integer back to a pointer...
authorTed Kremenek <kremenek@apple.com>
Wed, 23 Dec 2009 02:52:14 +0000 (02:52 +0000)
committerTed Kremenek <kremenek@apple.com>
Wed, 23 Dec 2009 02:52:14 +0000 (02:52 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@91981 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/SValuator.cpp
test/Analysis/misc-ps-region-store.m

index ac727b0ac696ca446a00282a94cf2e7d60599754..49bc0c4c59885f218974b1017cee0c993c395f58 100644 (file)
@@ -72,10 +72,14 @@ SValuator::CastResult SValuator::EvalCast(SVal val, const GRState *state,
   // Check for casts from integers to pointers.
   if (Loc::IsLocType(castTy) && originalTy->isIntegerType()) {
     if (nonloc::LocAsInteger *LV = dyn_cast<nonloc::LocAsInteger>(&val)) {
-      // Just unpackage the lval and return it.
+      if (const MemRegion *R = LV->getLoc().getAsRegion()) {
+        StoreManager &storeMgr = ValMgr.getStateManager().getStoreManager();
+        R = storeMgr.CastRegion(R, castTy);
+        return R ? CastResult(state, loc::MemRegionVal(R))
+                 : CastResult(state, UnknownVal());
+      }
       return CastResult(state, LV->getLoc());
     }
-
     goto DispatchCast;
   }
 
@@ -136,15 +140,12 @@ SValuator::CastResult SValuator::EvalCast(SVal val, const GRState *state,
     // different type.  If the MemRegion* returned is NULL, this expression
     // evaluates to UnknownVal.
     R = storeMgr.CastRegion(R, castTy);
-
-    if (R)
-      return CastResult(state, loc::MemRegionVal(R));
-
-    return CastResult(state, UnknownVal());
+    return R ? CastResult(state, loc::MemRegionVal(R))
+             : CastResult(state, UnknownVal());
   }
 
-  // All other cases.
 DispatchCast:
+  // All other cases.
   return CastResult(state,
                     isa<Loc>(val) ? EvalCastL(cast<Loc>(val), castTy)
                                   : EvalCastNL(cast<NonLoc>(val), castTy));
index 8eae643ec7d7f45933d09ef0cefd04ade10efc89..7216608fe9f5aaad159399337beca952cad93960 100644 (file)
@@ -1,5 +1,5 @@
 // RUN: %clang_cc1 -triple i386-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -verify -fblocks -analyzer-opt-analyze-nested-blocks %s
-// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -verify -fblocks   -analyzer-opt-analyze-nested-blocks %s
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9 -DTEST_64 -analyze -analyzer-experimental-internal-checks -checker-cfref -analyzer-store=region -verify -fblocks   -analyzer-opt-analyze-nested-blocks %s
 
 typedef struct objc_selector *SEL;
 typedef signed char BOOL;
@@ -23,6 +23,13 @@ extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
 @end
 extern NSString * const NSConnectionReplyMode;
 
+#ifdef TEST_64
+typedef long long int64_t;
+typedef int64_t intptr_t;
+#else
+typedef int int32_t;
+typedef int32_t intptr_t;
+#endif
 
 //---------------------------------------------------------------------------
 // Test case 'checkaccess_union' differs for region store and basic store.
@@ -636,3 +643,22 @@ void rdar7468209() {
   }();
 }
 
+//===----------------------------------------------------------------------===//
+// PR 5857 - Test loading an integer from a byte array that has also been
+//  reinterpreted to be loaded as a field.
+//===----------------------------------------------------------------------===//
+
+typedef struct { int x; } TestFieldLoad;
+int pr5857(char *src) {
+  TestFieldLoad *tfl = (TestFieldLoad *) (intptr_t) src;
+  int y = tfl->x;
+  long long *z = (long long *) (intptr_t) src;
+  long long w = 0;
+  int n = 0;
+  for (n = 0; n < y; ++n) {
+    // Previously we crashed analyzing this statement.
+    w = *z++;
+  }
+  return 1;
+}
+