]> granicus.if.org Git - clang/commitdiff
Fix: <rdar://problem/7249340> [RegionStore] model stores to symbolic parameter regions
authorTed Kremenek <kremenek@apple.com>
Thu, 24 Sep 2009 04:11:44 +0000 (04:11 +0000)
committerTed Kremenek <kremenek@apple.com>
Thu, 24 Sep 2009 04:11:44 +0000 (04:11 +0000)
The issue was a discrepancy between how RegionStoreManager::Bind() and
RegionStoreManager::Retrieve() derived the "key" for the first element
of a symbolic region.

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

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

index b54fa272a00cab1e4b27db81306d5332afffb8a0..31f52a55b3d7d872cda63d621ff71172d0ab6e17 100644 (file)
@@ -315,6 +315,9 @@ public:
                                   const GRState *state,
                                   const TypedRegion *R);
 
+  const ElementRegion *GetElementZeroRegion(const SymbolicRegion *SR,
+                                            QualType T);
+
   //===------------------------------------------------------------------===//
   // State pruning.
   //===------------------------------------------------------------------===//
@@ -857,6 +860,16 @@ static bool IsReinterpreted(QualType RTy, QualType UsedTy, ASTContext &Ctx) {
   return true;
 }
 
+const ElementRegion *
+RegionStoreManager::GetElementZeroRegion(const SymbolicRegion *SR, QualType T) {
+  ASTContext &Ctx = getContext();
+  SVal idx = ValMgr.makeZeroArrayIndex();
+  assert(!T.isNull());
+  return MRMgr.getElementRegion(T, idx, SR, Ctx);
+}
+  
+  
+
 SValuator::CastResult
 RegionStoreManager::Retrieve(const GRState *state, Loc L, QualType T) {
 
@@ -879,12 +892,8 @@ RegionStoreManager::Retrieve(const GRState *state, Loc L, QualType T) {
   if (isa<AllocaRegion>(MR))
     return SValuator::CastResult(state, UnknownVal());
 
-  if (isa<SymbolicRegion>(MR)) {
-    ASTContext &Ctx = getContext();
-    SVal idx = ValMgr.makeZeroArrayIndex();
-    assert(!T.isNull());
-    MR = MRMgr.getElementRegion(T, idx, MR, Ctx);
-  }
+  if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR))
+    MR = GetElementZeroRegion(SR, T);
 
   if (isa<CodeTextRegion>(MR))
     return SValuator::CastResult(state, UnknownVal());
@@ -1309,6 +1318,13 @@ const GRState *RegionStoreManager::Bind(const GRState *state, Loc L, SVal V) {
       }
     }
   }
+  else if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(R)) {
+    // Binding directly to a symbolic region should be treated as binding
+    // to element 0.
+    QualType T = SR->getSymbol()->getType(getContext());
+    T = cast<PointerType>(T)->getPointeeType();
+    R = GetElementZeroRegion(SR, T);
+  }
 
   // Perform the binding.
   RegionBindings B = GetRegionBindings(state->getStore());
index 4c753484bc983c11c5973c205fb63d31f69770e2..569fc790d63ef42dcfcf3b9d12437ecc8fbee37b 100644 (file)
@@ -195,3 +195,14 @@ CGFloat rdar7242006_negative(CGFloat x) {
   return y.width; // expected-warning{{garbage}}
 }
 
+// <rdar://problem/7249340> - Allow binding of values to symbolic regions.
+// This test case shows how RegionStore tracks the value bound to 'x'
+// after the assignment.
+void rdar_7249340(int *x) {
+  *x = 1;
+  if (*x)
+    return;
+  int *p = 0;   // This is unreachable.
+  *p = 0xDEADBEEF; // no-warning
+}
+