Fix another static analyzer crash due to a corner case in "folding" symbolic values that are constrained to be a constant.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@84320 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/SimpleSValuator.cpp b/lib/Analysis/SimpleSValuator.cpp
index 5af4c06..4487aa9 100644
--- a/lib/Analysis/SimpleSValuator.cpp
+++ b/lib/Analysis/SimpleSValuator.cpp
@@ -346,24 +346,29 @@
       nonloc::SymbolVal *slhs = cast<nonloc::SymbolVal>(&lhs);
       SymbolRef Sym = slhs->getSymbol();
       
-      // Does the symbol simplify to a constant?
+      // Does the symbol simplify to a constant?  If so, "fold" the constant
+      // by setting 'lhs' to a ConcreteInt and try again.
       if (Sym->getType(ValMgr.getContext())->isIntegerType())
         if (const llvm::APSInt *Constant = state->getSymVal(Sym)) {
-          // For shifts, there is no need to perform any conversions
-          // of the constant.
-          if (BinaryOperator::isShiftOp(op)) {
-            lhs = nonloc::ConcreteInt(*Constant);
-            continue;
-          }
+          // The symbol evaluates to a constant. If necessary, promote the
+          // folded constant (LHS) to the result type.
+          BasicValueFactory &BVF = ValMgr.getBasicValueFactory();
+          const llvm::APSInt &lhs_I = BVF.Convert(resultTy, *Constant);
+          lhs = nonloc::ConcreteInt(lhs_I);
           
-          // Other cases: do an implicit conversion.  This shouldn't be
+          // Also promote the RHS (if necessary).
+
+          // For shifts, it necessary promote the RHS to the result type.
+          if (BinaryOperator::isShiftOp(op))
+            continue;
+          
+          // Other operators: do an implicit conversion.  This shouldn't be
           // necessary once we support truncation/extension of symbolic values.
           if (nonloc::ConcreteInt *rhs_I = dyn_cast<nonloc::ConcreteInt>(&rhs)){
-            BasicValueFactory &BVF = ValMgr.getBasicValueFactory();
-            lhs = nonloc::ConcreteInt(BVF.Convert(rhs_I->getValue(),
-                                                  *Constant));
-            continue;
+            rhs = nonloc::ConcreteInt(BVF.Convert(resultTy, rhs_I->getValue()));
           }
+          
+          continue;
         }
       
       if (isa<nonloc::ConcreteInt>(rhs)) {