aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/GRExprEngine.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2009-07-20 21:43:20 +0000
committerTed Kremenek <kremenek@apple.com>2009-07-20 21:43:20 +0000
commitbc59aa57c525dc84eb5e5dd7ac76cac63630db46 (patch)
tree8afaa3b6ca995575a21c87a070ab6a44465aa90e /lib/Analysis/GRExprEngine.cpp
parentdd6611426b96019516ed473ce25a8664065e9865 (diff)
Enhance GRExprEngine::EvalBind to handle some implicit casts from nonlocs to
locs and vis versa. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76483 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/GRExprEngine.cpp')
-rw-r--r--lib/Analysis/GRExprEngine.cpp19
1 files changed, 18 insertions, 1 deletions
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index 7459b806e2..006c3a7d9a 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -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