summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Analysis/RegionStore.cpp10
-rw-r--r--clang/test/Analysis/misc-ps-region-store.m44
2 files changed, 50 insertions, 4 deletions
diff --git a/clang/lib/Analysis/RegionStore.cpp b/clang/lib/Analysis/RegionStore.cpp
index 577ace306be..4e83720f9fa 100644
--- a/clang/lib/Analysis/RegionStore.cpp
+++ b/clang/lib/Analysis/RegionStore.cpp
@@ -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);
diff --git a/clang/test/Analysis/misc-ps-region-store.m b/clang/test/Analysis/misc-ps-region-store.m
index 7231353b6b9..fc9d8e6207a 100644
--- a/clang/test/Analysis/misc-ps-region-store.m
+++ b/clang/test/Analysis/misc-ps-region-store.m
@@ -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__) {}
+ }
+}
OpenPOWER on IntegriCloud