aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2008-12-17 19:42:34 +0000
committerTed Kremenek <kremenek@apple.com>2008-12-17 19:42:34 +0000
commit90b3236cbea10044c38ea40585dce8150236f1ca (patch)
treeb8d945b5fec794545f9450e750674ac423251340
parent500d2ee83d407106d80920fb4325fa2e06fa61a5 (diff)
Fix <rdar://problem/6451816>:
- Because of the introduction of AnonTypedRegions when reasoning about casts, we had a regression in the "symbolication" of variable values passed-by-reference to a function. This is now fixed in CFRefCount.cpp (-checker-cfref) by blasting through the layer of AnonTypedRegions when symbolicating the value of the variable. This logic may get moved elsewhere. Note that this change affects only -checker-cfref and not -checker-simple; eventually this logic should get pulled out of CFRefCount.cpp into a more common place. All users use -checker-cfref by default, and -checker-simple should probably just be removed. - Updated test 'Analysis/uninit-vals-ps.c' to only use -checker-cfref and added a test case for this regression. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@61147 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Analysis/CFRefCount.cpp10
-rw-r--r--test/Analysis/uninit-vals-ps.c22
2 files changed, 29 insertions, 3 deletions
diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp
index e044d1d789..c85d934ebb 100644
--- a/lib/Analysis/CFRefCount.cpp
+++ b/lib/Analysis/CFRefCount.cpp
@@ -1599,6 +1599,14 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
}
const TypedRegion* R = dyn_cast<TypedRegion>(MR->getRegion());
+
+ // Blast through AnonTypedRegions to get the original region type.
+ while (R) {
+ const AnonTypedRegion* ATR = dyn_cast<AnonTypedRegion>(R);
+ if (!ATR) break;
+ R = dyn_cast<TypedRegion>(ATR->getSuperRegion());
+ }
+
if (R) {
// Set the value of the variable to be a conjured symbol.
unsigned Count = Builder.getCurrentBlockCount();
@@ -1609,7 +1617,7 @@ void CFRefCount::EvalSummary(ExplodedNodeSet<GRState>& Dst,
SymbolRef NewSym =
Eng.getSymbolManager().getConjuredSymbol(*I, T, Count);
- state = state.BindLoc(*MR,
+ state = state.BindLoc(Loc::MakeVal(R),
Loc::IsLocType(T)
? cast<SVal>(loc::SymbolVal(NewSym))
: cast<SVal>(nonloc::SymbolVal(NewSym)));
diff --git a/test/Analysis/uninit-vals-ps.c b/test/Analysis/uninit-vals-ps.c
index 58f64311f2..b860000929 100644
--- a/test/Analysis/uninit-vals-ps.c
+++ b/test/Analysis/uninit-vals-ps.c
@@ -1,5 +1,5 @@
-// RUN: clang -checker-simple -verify %s &&
-// RUN: clang -checker-simple -analyzer-store-region -verify %s
+// RUN: clang -checker-cfref -verify %s &&
+// RUN: clang -checker-cfref -analyzer-store-region -verify %s
struct FPRec {
void (*my_func)(int * x);
@@ -49,4 +49,22 @@ int ret_uninit() {
return *p; // expected-warning{{Uninitialized or undefined return value returned to caller.}}
}
+// <rdar://problem/6451816>
+typedef unsigned char Boolean;
+typedef const struct __CFNumber * CFNumberRef;
+typedef signed long CFIndex;
+typedef CFIndex CFNumberType;
+typedef unsigned long UInt32;
+typedef UInt32 CFStringEncoding;
+typedef const struct __CFString * CFStringRef;
+extern Boolean CFNumberGetValue(CFNumberRef number, CFNumberType theType, void *valuePtr);
+extern CFStringRef CFStringConvertEncodingToIANACharSetName(CFStringEncoding encoding);
+
+CFStringRef rdar_6451816(CFNumberRef nr) {
+ CFStringEncoding encoding;
+ // &encoding is casted to void*. This test case tests whether or not
+ // we properly invalidate the value of 'encoding'.
+ CFNumberGetValue(nr, 9, &encoding);
+ return CFStringConvertEncodingToIANACharSetName(encoding); // no-warning
+}