[analyzer] RetainCountChecker: don't try to track ivars known to be nil.
authorJordan Rose <jordan_rose@apple.com>
Thu, 19 Feb 2015 23:57:04 +0000 (23:57 +0000)
committerJordan Rose <jordan_rose@apple.com>
Thu, 19 Feb 2015 23:57:04 +0000 (23:57 +0000)
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

clang/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
clang/test/Analysis/properties.m

index fee8e76..366672b 100644 (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)) {
index d06fa99..ea8d195 100644 (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