From: Ted Kremenek Date: Mon, 2 Aug 2010 21:59:12 +0000 (+0000) Subject: Fix idempotent operations false positive caused by ivars not being invalidated in... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=074ae35bb156bd379cb9bc0b1b85d76e164a1776;p=clang Fix idempotent operations false positive caused by ivars not being invalidated in function calls when the enclosing object had retain/release state. Fixes . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110068 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Checker/CFRefCount.cpp b/lib/Checker/CFRefCount.cpp index 0cc8905cb0..e4a2a39fbe 100644 --- a/lib/Checker/CFRefCount.cpp +++ b/lib/Checker/CFRefCount.cpp @@ -2623,19 +2623,25 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst, llvm::SmallVector RegionsToInvalidate; + // HACK: Symbols that have ref-count state that are referenced directly + // (not as structure or array elements, or via bindings) by an argument + // should not have their ref-count state stripped after we have + // done an invalidation pass. + llvm::DenseSet WhitelistedSymbols; + for (ConstExprIterator I = arg_beg; I != arg_end; ++I, ++idx) { SVal V = state->getSValAsScalarOrLoc(*I); SymbolRef Sym = V.getAsLocSymbol(); if (Sym) if (RefBindings::data_type* T = state->get(Sym)) { + WhitelistedSymbols.insert(Sym); state = Update(state, Sym, *T, Summ.getArg(idx), hasErr); if (hasErr) { ErrorRange = (*I)->getSourceRange(); ErrorSym = Sym; break; } - continue; } tryAgain: @@ -2721,7 +2727,10 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst, state = state->makeWithStore(store); for (StoreManager::InvalidatedSymbols::iterator I = IS.begin(), E = IS.end(); I!=E; ++I) { - // Remove any existing reference-count binding. + SymbolRef sym = *I; + if (WhitelistedSymbols.count(sym)) + continue; + // Remove any existing reference-count binding. state = state->remove(*I); } diff --git a/test/Analysis/retain-release-region-store.m b/test/Analysis/retain-release-region-store.m index db49b91c27..7b9855473d 100644 --- a/test/Analysis/retain-release-region-store.m +++ b/test/Analysis/retain-release-region-store.m @@ -50,6 +50,7 @@ typedef struct _NSZone NSZone; @end @protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end @interface NSObject {} +- (id)init; + (id)allocWithZone:(NSZone *)zone; + (id)alloc; - (void)dealloc; @@ -223,3 +224,29 @@ void pr6699(int x) { } } +// Idempotent operation checker false positive with ObjC ivars +@interface R8261992 : NSObject { + @package int myIvar; +} +@end + +static void R8261992_ChangeMyIvar(R8261992 *tc) { + tc->myIvar = 5; +} + +void R8261992_test(R8261992 *tc) { + int temp = tc->myIvar; + // The ivar binding for tc->myIvar gets invalidated. + R8261992_ChangeMyIvar(tc); + tc->myIvar = temp; // no-warning + tc = [[R8261992 alloc] init]; + temp = tc->myIvar; // no-warning + // The ivar binding for tc->myIvar gets invalidated. + R8261992_ChangeMyIvar(tc); + tc->myIvar = temp; + [tc release]; // no-warning + // did we analyze this? + int *p = 0x0; + *p = 0xDEADBEEF; // expected-warning{{null}} +} +