Enhance GRExprEngine::EvalBind to handle some implicit casts from nonlocs to
authorTed Kremenek <kremenek@apple.com>
Mon, 20 Jul 2009 21:43:20 +0000 (21:43 +0000)
committerTed Kremenek <kremenek@apple.com>
Mon, 20 Jul 2009 21:43:20 +0000 (21:43 +0000)
locs and vis versa.

llvm-svn: 76483

clang/lib/Analysis/GRExprEngine.cpp

index 7459b806e250bfe2101b88b419acec0f40a15a1e..006c3a7d9affa5f4cedf01ab5a7a1d7e556240db 100644 (file)
@@ -1049,7 +1049,24 @@ void GRExprEngine::EvalBind(NodeSet& Dst, Expr* Ex, NodeTy* Pred,
   else {
     // We are binding to a value other than 'unknown'.  Perform the binding
     // using the StoreManager.
-    newState = state->bindLoc(cast<Loc>(location), Val);
+    Loc L = cast<Loc>(location);
+
+    // Handle implicit casts not reflected in the AST.  This can be due to
+    // custom checker logic such as what handles OSAtomicCompareAndSwap.
+    if (!Val.isUnknownOrUndef())
+      if (const TypedRegion *R =
+            dyn_cast_or_null<TypedRegion>(L.getAsRegion())) {
+        assert(R->isBoundable());
+        QualType ValTy = R->getValueType(getContext());
+        if (Loc::IsLocType(ValTy)) {
+          if (!isa<Loc>(Val))
+            Val = SVator.EvalCastNL(cast<NonLoc>(Val), ValTy);
+        }
+        else if (!isa<NonLoc>(Val))
+          Val = SVator.EvalCastL(cast<Loc>(Val), ValTy);
+      }
+    
+    newState = state->bindLoc(L, Val);
   }
 
   // The next thing to do is check if the GRTransferFuncs object wants to