From 5bf523b49e7b36e65b6f1ffaf9cf0a6b54cde9b3 Mon Sep 17 00:00:00 2001 From: Jordan Rose Date: Thu, 19 Feb 2015 23:57:04 +0000 Subject: [PATCH] [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 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@229934 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Checkers/RetainCountChecker.cpp | 6 ++++-- test/Analysis/properties.m | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp index fee8e766f6..366672bca1 100644 --- a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp @@ -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)) { diff --git a/test/Analysis/properties.m b/test/Analysis/properties.m index d06fa9974f..ea8d19587a 100644 --- a/test/Analysis/properties.m +++ b/test/Analysis/properties.m @@ -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 -- 2.40.0