]> granicus.if.org Git - clang/commitdiff
Create "TypedViewRegions" that layer on top of SymbolicRegions when handling
authorTed Kremenek <kremenek@apple.com>
Wed, 4 Mar 2009 00:14:35 +0000 (00:14 +0000)
committerTed Kremenek <kremenek@apple.com>
Wed, 4 Mar 2009 00:14:35 +0000 (00:14 +0000)
pointer-to-pointer casts involving symbolic locations.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65984 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Analysis/GRExprEngine.cpp

index 916340d1750c86ba91de6e724c67ece7895225d5..0de0cea40bea7d2873735d491669e8951b3163ce 100644 (file)
@@ -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())));