From: Ted Kremenek Date: Tue, 14 Jul 2009 20:48:22 +0000 (+0000) Subject: Enhance RegionStoreManager to handle 'Retrieve's from SymbolicRegions. We do this... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=60fbe8f79838bff41fe9f5ed506ea9bc89d5d1df;p=clang Enhance RegionStoreManager to handle 'Retrieve's from SymbolicRegions. We do this by silently wrapping the region with an ElementRegion. This fixes the failures in misc-ps-region-store.m. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@75679 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/RegionStore.cpp b/lib/Analysis/RegionStore.cpp index 577ace306b..4e83720f9f 100644 --- a/lib/Analysis/RegionStore.cpp +++ b/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(MR) || isa(MR)) + if (isa(MR)) return UnknownVal(); - + + if (isa(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(MR); diff --git a/test/Analysis/misc-ps-region-store.m b/test/Analysis/misc-ps-region-store.m index 7231353b6b..fc9d8e6207 100644 --- a/test/Analysis/misc-ps-region-store.m +++ b/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__) {} + } +}