When conjuring symbols to recover path-sensitivity, don't conjure symbols that represent an entire struct.  We need to implement struct temporaries as an actual "region", and then bind symbols to the FieldRegion of those temporaries.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57739 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp
index e720096..23613d1 100644
--- a/lib/Analysis/CFRefCount.cpp
+++ b/lib/Analysis/CFRefCount.cpp
@@ -1518,13 +1518,20 @@
           // Set the value of the variable to be a conjured symbol.
           unsigned Count = Builder.getCurrentBlockCount();
           QualType T = R->getType();
-          SymbolID NewSym =
-            Eng.getSymbolManager().getConjuredSymbol(*I, T, Count);
           
-          state = state.SetSVal(*MR,
-                                Loc::IsLocType(T)
-                                ? cast<SVal>(loc::SymbolVal(NewSym))
-                                : cast<SVal>(nonloc::SymbolVal(NewSym)));
+          // FIXME: handle structs.
+          if (T->isIntegerType() || Loc::IsLocType(T)) {
+            SymbolID NewSym =
+              Eng.getSymbolManager().getConjuredSymbol(*I, T, Count);
+            
+            state = state.SetSVal(*MR,
+                                  Loc::IsLocType(T)
+                                  ? cast<SVal>(loc::SymbolVal(NewSym))
+                                  : cast<SVal>(nonloc::SymbolVal(NewSym)));
+          }
+          else {
+            state = state.SetSVal(*MR, UnknownVal());
+          }
         }
         else
           state = state.SetSVal(*MR, UnknownVal());
@@ -1566,13 +1573,18 @@
     default:
       assert (false && "Unhandled RetEffect."); break;
       
-    case RetEffect::NoRet:
+    case RetEffect::NoRet: {
       
       // Make up a symbol for the return value (not reference counted).
       // FIXME: This is basically copy-and-paste from GRSimpleVals.  We 
       //  should compose behavior, not copy it.
       
-      if (Ex->getType() != Eng.getContext().VoidTy) {    
+      // FIXME: We eventually should handle structs and other compound types
+      // that are returned by value.
+      
+      QualType T = Ex->getType();
+      
+      if (T->isIntegerType() || Loc::IsLocType(T)) {
         unsigned Count = Builder.getCurrentBlockCount();
         SymbolID Sym = Eng.getSymbolManager().getConjuredSymbol(Ex, Count);
         
@@ -1584,6 +1596,7 @@
       }      
       
       break;
+    }
       
     case RetEffect::Alias: {
       unsigned idx = RE.getIndex();
diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp
index bdf42e9..98e8427 100644
--- a/lib/Analysis/GRExprEngine.cpp
+++ b/lib/Analysis/GRExprEngine.cpp
@@ -2038,8 +2038,10 @@
         case BinaryOperator::Assign: {
           
           // EXPERIMENTAL: "Conjured" symbols.
+          // FIXME: Handle structs.
+          QualType T = RHS->getType();
           
-          if (RightV.isUnknown()) {            
+          if (RightV.isUnknown() && (T->isIntegerType() || Loc::IsLocType(T))) {            
             unsigned Count = Builder->getCurrentBlockCount();
             SymbolID Sym = SymMgr.getConjuredSymbol(B->getRHS(), Count);
             
diff --git a/lib/Analysis/GRSimpleVals.cpp b/lib/Analysis/GRSimpleVals.cpp
index 2b1d9b5..d0055e5 100644
--- a/lib/Analysis/GRSimpleVals.cpp
+++ b/lib/Analysis/GRSimpleVals.cpp
@@ -379,9 +379,11 @@
     
   }
   
-  // Make up a symbol for the return value of this function.
-  
-  if (CE->getType() != Eng.getContext().VoidTy) {    
+  // Make up a symbol for the return value of this function.  
+  // FIXME: We eventually should handle structs and other compound types
+  // that are returned by value.
+  QualType T = CE->getType();  
+  if (T->isIntegerType() || Loc::IsLocType(T)) {    
     unsigned Count = Builder.getCurrentBlockCount();
     SymbolID Sym = Eng.getSymbolManager().getConjuredSymbol(CE, Count);