forked from OSchip/llvm-project
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
This commit is contained in:
parent
7f5f2809e8
commit
297e2e5bf6
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -50,6 +50,7 @@ typedef struct _NSZone NSZone;
|
|||
@end @protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder;
|
||||
@end
|
||||
@interface NSObject <NSObject> {}
|
||||
- (id)init;
|
||||
+ (id)allocWithZone:(NSZone *)zone;
|
||||
+ (id)alloc;
|
||||
- (void)dealloc;
|
||||
|
@ -223,3 +224,29 @@ void pr6699(int x) {
|
|||
}
|
||||
}
|
||||
|
||||
// <rdar://problem/8261992> 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}}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue