aboutsummaryrefslogtreecommitdiff
path: root/lib/Analysis/GRExprEngine.cpp
diff options
context:
space:
mode:
authorTed Kremenek <kremenek@apple.com>2009-03-04 00:14:35 +0000
committerTed Kremenek <kremenek@apple.com>2009-03-04 00:14:35 +0000
commitdc402902277b8dd30fca50402b9e020ea7b5d353 (patch)
treef8d92db2e782b50de293f6aa4f07b5c495ce4452 /lib/Analysis/GRExprEngine.cpp
parent3f4d5abe9062069a6fd07a098ef448d3077b8cf5 (diff)
Create "TypedViewRegions" that layer on top of SymbolicRegions when handling
pointer-to-pointer casts involving symbolic locations. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65984 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Analysis/GRExprEngine.cpp')
-rw-r--r--lib/Analysis/GRExprEngine.cpp28
1 files changed, 23 insertions, 5 deletions
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index 916340d175..0de0cea40b 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -162,7 +162,6 @@ void GRExprEngine::ProcessStmt(Stmt* S, StmtNodeBuilder& builder) {
// Set up our simple checks.
if (BatchAuditor)
Builder->setAuditor(BatchAuditor.get());
-
// Create the cleaned state.
SymbolReaper SymReaper(Liveness, SymMgr);
@@ -1743,8 +1742,7 @@ void GRExprEngine::VisitCast(Expr* CastE, Expr* Ex, NodeTy* Pred, NodeSet& Dst){
Visit(Ex, Pred, S1);
// Check for casting to "void".
- if (T->isVoidType()) {
-
+ if (T->isVoidType()) {
for (NodeSet::iterator I1 = S1.begin(), E1 = S1.end(); I1 != E1; ++I1)
Dst.Add(*I1);
@@ -1761,14 +1759,12 @@ void GRExprEngine::VisitCast(Expr* CastE, Expr* Ex, NodeTy* Pred, NodeSet& Dst){
SVal V = GetSVal(state, Ex);
// Unknown?
-
if (V.isUnknown()) {
Dst.Add(N);
continue;
}
// Undefined?
-
if (V.isUndef()) {
MakeNode(Dst, CastE, N, BindExpr(state, CastE, V));
continue;
@@ -1841,6 +1837,28 @@ void GRExprEngine::VisitCast(Expr* CastE, Expr* Ex, NodeTy* Pred, NodeSet& Dst){
continue;
}
+ // If we are casting a symbolic value, make a symbolic region and a
+ // TypedViewRegion subregion.
+ if (loc::SymbolVal* SV = dyn_cast<loc::SymbolVal>(&V)) {
+ SymbolRef Sym = SV->getSymbol();
+ StoreManager& StoreMgr = getStoreManager();
+ const MemRegion* R =
+ StoreMgr.getRegionManager().getSymbolicRegion(Sym, getSymbolManager());
+
+ // Delegate to store manager to get the result of casting a region
+ // to a different type.
+ const StoreManager::CastResult& Res = StoreMgr.CastRegion(state, R, T);
+
+ // Inspect the result. If the MemRegion* returned is NULL, this
+ // expression evaluates to UnknownVal.
+ R = Res.getRegion();
+ if (R) { V = loc::MemRegionVal(R); } else { V = UnknownVal(); }
+
+ // Generate the new node in the ExplodedGraph.
+ MakeNode(Dst, CastE, N, BindExpr(Res.getState(), CastE, V));
+ continue;
+ }
+
// All other cases.
MakeNode(Dst, CastE, N, BindExpr(state, CastE,
EvalCast(V, CastE->getType())));