]> granicus.if.org Git - clang/commitdiff
Enhance RegionStoreManager to handle 'Retrieve's from SymbolicRegions. We do this...
authorTed Kremenek <kremenek@apple.com>
Tue, 14 Jul 2009 20:48:22 +0000 (20:48 +0000)
committerTed Kremenek <kremenek@apple.com>
Tue, 14 Jul 2009 20:48:22 +0000 (20:48 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@75679 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 577ace306be98b99aa562ca18349d97f4d021452..4e83720f9fa11cc1585dd82b4a01bdd47db2a638 100644 (file)
@@ -799,9 +799,15 @@ SVal RegionStoreManager::Retrieve(const GRState *state, Loc L, QualType T) {
   // char* p = alloca();
   // read(p);
   // c = *p;
-  if (isa<SymbolicRegion>(MR) || isa<AllocaRegion>(MR))
+  if (isa<AllocaRegion>(MR))
     return UnknownVal();
-
+  
+  if (isa<SymbolicRegion>(MR)) {
+    ASTContext &Ctx = getContext();
+    SVal idx = ValMgr.makeIntVal(0, Ctx.IntTy);
+    MR = MRMgr.getElementRegion(T, idx, MR, Ctx);
+  }
+  
   // FIXME: Perhaps this method should just take a 'const MemRegion*' argument
   //  instead of 'Loc', and have the other Loc cases handled at a higher level.
   const TypedRegion *R = cast<TypedRegion>(MR);
index 7231353b6b945f9d309480dea04f7740f158e054..fc9d8e6207a2b45d3f47daeec0113755d898e4f1 100644 (file)
@@ -1,5 +1,4 @@
 // RUN: clang-cc -analyze -checker-cfref --analyzer-store=region --verify -fblocks %s
-// XFAIL
 
 typedef struct objc_selector *SEL;
 typedef signed char BOOL;
@@ -69,7 +68,6 @@ char test2() {
   return 'a';
 }
 
-// *** THIS TEST IS CURRENTLY FAILING ***
 // BasicStore handles this case incorrectly because it doesn't reason about
 // the value pointed to by 'x' and thus creates different symbolic values
 // at the declarations of 'a' and 'b' respectively.  RegionStore handles
@@ -83,3 +81,45 @@ void test_trivial_symbolic_comparison_pointer_parameter(int *x) {
   }
 }
 
+// This is a modified test from 'misc-ps.m'.  Here we have the extra
+// NULL dereferences which are pruned out by RegionStore's symbolic reasoning
+// of fields.
+typedef struct _BStruct { void *grue; } BStruct;
+void testB_aux(void *ptr);
+void testB(BStruct *b) {
+  {
+    int *__gruep__ = ((int *)&((b)->grue));
+    int __gruev__ = *__gruep__;
+    int __gruev2__ = *__gruep__;
+    if (__gruev__ != __gruev2__) {
+      int *p = 0;
+      *p = 0xDEADBEEF;
+    }
+    
+    testB_aux(__gruep__);
+  }
+  {
+    int *__gruep__ = ((int *)&((b)->grue));
+    int __gruev__ = *__gruep__;
+    int __gruev2__ = *__gruep__;
+    if (__gruev__ != __gruev2__) {
+      int *p = 0;
+      *p = 0xDEADBEEF;
+    }
+    
+    if (~0 != __gruev__) {}
+  }
+}
+
+void testB_2(BStruct *b) {
+  {
+    int **__gruep__ = ((int **)&((b)->grue));
+    int *__gruev__ = *__gruep__;
+    testB_aux(__gruep__);
+  }
+  {
+    int **__gruep__ = ((int **)&((b)->grue));
+    int *__gruev__ = *__gruep__;
+    if ((int*)~0 != __gruev__) {}
+  }
+}