[analyzer] RetainCountChecker: don't try to track ivars known to be nil.

We expect in general that any nil value has no retain count information
associated with it; violating this results in unexpected state unification
/later/ when we decide to throw the information away. Unexpectedly caching
out can lead to an assertion failure or crash.

rdar://problem/19862648

llvm-svn: 229934
This commit is contained in:
Jordan Rose 2015-02-19 23:57:04 +00:00
parent d34db1716e
commit 000bac5e17
2 changed files with 19 additions and 2 deletions

View File

@ -2852,7 +2852,7 @@ void RetainCountChecker::checkPostStmt(const ObjCIvarRefExpr *IRE,
ProgramStateRef State = C.getState();
SymbolRef Sym = State->getSVal(*IVarLoc).getAsSymbol();
if (!Sym)
if (!Sym || !wasLoadedFromIvar(Sym))
return;
// Accessing an ivar directly is unusual. If we've done that, be more
@ -2867,7 +2867,9 @@ void RetainCountChecker::checkPostStmt(const ObjCIvarRefExpr *IRE,
else
return;
if (!wasLoadedFromIvar(Sym))
// If the value is already known to be nil, don't bother tracking it.
ConstraintManager &CMgr = State->getConstraintManager();
if (CMgr.isNull(State, Sym).isConstrainedTrue())
return;
if (const RefVal *RV = getRefBinding(State, Sym)) {

View File

@ -513,6 +513,21 @@ void testOpaqueConsistency(OpaqueIntWrapper *w) {
[_ivarOnly release]; // no-warning
}
// rdar://problem/19862648
- (void)establishIvarIsNilDuringLoops {
extern id getRandomObject();
int i = 4; // Must be at least 4 to trigger the bug.
while (--i) {
id x = 0;
if (getRandomObject())
x = _ivarOnly;
if (!x)
x = getRandomObject();
[x myMethod];
}
}
@end
#endif // non-ARC