Simplified and generalized transfer function logic for casts, allowing
the transfer function to be invoked without an Expr* for the Cast operation.

Added implicit promotions to the transfer function logic for compound
assignments.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@47444 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Analysis/GRExprEngine.cpp b/Analysis/GRExprEngine.cpp
index 1ca3761..51b0a59 100644
--- a/Analysis/GRExprEngine.cpp
+++ b/Analysis/GRExprEngine.cpp
@@ -477,7 +477,7 @@
     NodeTy* N = *I1;
     StateTy St = N->getState();
     RVal V = GetRVal(St, Ex);
-    Nodify(Dst, CastE, N, SetRVal(St, CastE, EvalCast(ValMgr, V, CastE)));
+    Nodify(Dst, CastE, N, SetRVal(St, CastE, EvalCast(V, CastE->getType())));
   }
 }
 
@@ -520,14 +520,13 @@
 void GRExprEngine::VisitSizeOfAlignOfTypeExpr(SizeOfAlignOfTypeExpr* Ex,
                                               NodeTy* Pred,
                                               NodeSet& Dst) {
-  
-  assert (Ex->isSizeOf() && "AlignOf(Expr) not yet implemented.");
+
+  assert (Ex->isSizeOf() && "FIXME: AlignOf(Expr) not yet implemented.");
   
   // 6.5.3.4 sizeof: "The result type is an integer."
   
   QualType T = Ex->getArgumentType();
-  
-  // FIXME: Implement alignof
+
 
   // FIXME: Add support for VLAs.
   if (!T.getTypePtr()->isConstantSizeType())
@@ -942,7 +941,16 @@
           else
             ((int&) Op) -= BinaryOperator::MulAssign;          
           
-          RVal Result = EvalBinOp(Op, V, RightV);
+          // Get the computation type.
+          QualType CTy = cast<CompoundAssignOperator>(B)->getComputationType();
+          
+          // Perform promotions.
+          V = EvalCast(V, CTy);
+          RightV = EvalCast(V, CTy);
+          
+          // Evaluate operands and promote to result type.
+          RVal Result = EvalCast(EvalBinOp(Op, V, RightV), B->getType());
+          
           St = SetRVal(SetRVal(St, B, Result), LeftLV, Result);
         }
       }