diff options
author | Ted Kremenek <kremenek@apple.com> | 2010-08-02 21:59:12 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2010-08-02 21:59:12 +0000 |
commit | 297e2e5bf603fed639d03fd7104fa1ff602c1e21 (patch) | |
tree | 62f9ada877426c72dd7cc21892a95b81f6055986 /clang/lib/Checker/CFRefCount.cpp | |
parent | 7f5f2809e80037b5e2af5b37144f65c8d4f7a61d (diff) | |
download | bcm5719-llvm-297e2e5bf603fed639d03fd7104fa1ff602c1e21.tar.gz bcm5719-llvm-297e2e5bf603fed639d03fd7104fa1ff602c1e21.zip |
Fix idempotent operations false positive caused by ivars not being invalidated in function
calls when the enclosing object had retain/release state. Fixes <rdar://problem/8261992>.
llvm-svn: 110068
Diffstat (limited to 'clang/lib/Checker/CFRefCount.cpp')
-rw-r--r-- | clang/lib/Checker/CFRefCount.cpp | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/clang/lib/Checker/CFRefCount.cpp b/clang/lib/Checker/CFRefCount.cpp index 0cc8905cb0c..e4a2a39fbe7 100644 --- a/clang/lib/Checker/CFRefCount.cpp +++ b/clang/lib/Checker/CFRefCount.cpp @@ -2623,19 +2623,25 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst, llvm::SmallVector<const MemRegion*, 10> 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<SymbolRef> 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<RefBindings>(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<RefBindings>(*I); } |