From: Ted Kremenek Date: Wed, 17 Dec 2008 19:42:34 +0000 (+0000) Subject: Fix : X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=90b3236cbea10044c38ea40585dce8150236f1ca;p=clang Fix : - 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 --- 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& Dst, } const TypedRegion* R = dyn_cast(MR->getRegion()); + + // Blast through AnonTypedRegions to get the original region type. + while (R) { + const AnonTypedRegion* ATR = dyn_cast(R); + if (!ATR) break; + R = dyn_cast(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& Dst, SymbolRef NewSym = Eng.getSymbolManager().getConjuredSymbol(*I, T, Count); - state = state.BindLoc(*MR, + state = state.BindLoc(Loc::MakeVal(R), Loc::IsLocType(T) ? cast(loc::SymbolVal(NewSym)) : cast(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.}} } +// +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 +}