]> granicus.if.org Git - clang/commitdiff
Correctly invalidate reference count state when passing objects by reference in messa...
authorTed Kremenek <kremenek@apple.com>
Thu, 1 May 2008 21:31:50 +0000 (21:31 +0000)
committerTed Kremenek <kremenek@apple.com>
Thu, 1 May 2008 21:31:50 +0000 (21:31 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@50541 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/CFRefCount.cpp
lib/Analysis/ValueState.cpp

index 540090401329350ceb533bfe2f85bbb1d21baf61..98287921d3b3196480c7cc4bb744ea02e4605657 100644 (file)
@@ -294,7 +294,7 @@ CFRefSummary* CFRefSummaryManager::getCFSummary(FunctionDecl* FD,
   
   if (strcmp(FName, "Release") == 0)
     return getUnaryCFSummary(FT, cfrelease);
-  
+
   if (strcmp(FName, "MakeCollectable") == 0)
     return getUnaryCFSummary(FT, cfmakecollectable);
   
@@ -962,8 +962,43 @@ void CFRefCount::EvalObjCMessageExpr(ExplodedNodeSet<ValueState>& Dst,
                                      ObjCMessageExpr* ME,
                                      ExplodedNode<ValueState>* Pred) {
   
-  if (EvalObjCMessageExprAux(Dst, Eng, Builder, ME, Pred))
-    GRSimpleVals::EvalObjCMessageExpr(Dst, Eng, Builder, ME, Pred);
+  if (!EvalObjCMessageExprAux(Dst, Eng, Builder, ME, Pred))
+    return;
+  
+  // The basic transfer function logic for message expressions does nothing.
+  // We just invalidate all arguments passed in by references.
+  
+  ValueStateManager& StateMgr = Eng.getStateManager();
+  ValueState* St = Builder.GetState(Pred);
+  RefBindings B = GetRefBindings(*St);
+  
+  for (ObjCMessageExpr::arg_iterator I = ME->arg_begin(), E = ME->arg_end();
+       I != E; ++I) {
+    
+    RVal V = StateMgr.GetRVal(St, *I);
+    
+    if (isa<LVal>(V)) {
+
+      LVal lv = cast<LVal>(V);
+      
+      // Did the lval bind to a symbol?
+      RVal X = StateMgr.GetRVal(St, lv);
+      
+      if (isa<lval::SymbolVal>(X)) {
+        SymbolID Sym = cast<lval::SymbolVal>(V).getSymbol();
+        B = Remove(B, Sym);
+        
+        // Create a new state with the updated bindings.  
+        ValueState StVals = *St;
+        SetRefBindings(StVals, B);
+        St = StateMgr.getPersistentState(StVals);
+      }
+        
+      St = StateMgr.SetRVal(St, cast<LVal>(V), UnknownVal());
+    }
+  }
+  
+  Builder.MakeNode(Dst, ME, Pred, St);
 }
 
 bool CFRefCount::EvalObjCMessageExprAux(ExplodedNodeSet<ValueState>& Dst,
index 19ff06f0044ab163a87a36a751ee4274e18eda5f..96b94ea8cfaf2af33175d326eb56235ae826e197 100644 (file)
@@ -203,6 +203,12 @@ RVal ValueStateManager::GetRVal(ValueState* St, LVal LV, QualType T) {
       
       return UnknownVal();
     }
+    
+    case lval::ConcreteIntKind:
+      // Some clients may call GetRVal with such an option simply because
+      // they are doing a quick scan through their LVals (potentially to
+      // invalidate their bindings).  Just return Undefined.
+      return UndefinedVal();
       
     case lval::ArrayOffsetKind:
     case lval::FieldOffsetKind: