isICE was evaluating ?: incorrectly with missing-gcc-LHS extension.

Add assert to isICE that, on success, result must be the same as
EvaluateAsInt()... this enforces a minimum level of sanity.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64865 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index c1117e8..0cd68ce 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -871,6 +871,15 @@
 /// cast+dereference.
 bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx,
                                  SourceLocation *Loc, bool isEvaluated) const {
+  if (!isIntegerConstantExprInternal(Result, Ctx, Loc, isEvaluated))
+    return false;
+  assert(Result == EvaluateAsInt(Ctx) && "Inconsistent Evaluate() result!");
+  return true;
+}
+
+bool Expr::isIntegerConstantExprInternal(llvm::APSInt &Result, ASTContext &Ctx,
+                                 SourceLocation *Loc, bool isEvaluated) const {
+  
   // Pretest for integral type; some parts of the code crash for types that
   // can't be sized.
   if (!getType()->isIntegralType()) {
@@ -885,6 +894,7 @@
     return cast<ParenExpr>(this)->getSubExpr()->
                      isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated);
   case IntegerLiteralClass:
+    // NOTE: getValue() returns an APInt, we must set sign.
     Result = cast<IntegerLiteral>(this)->getValue();
     Result.setIsUnsigned(getType()->isUnsignedIntegerType());    
     break;
@@ -1107,7 +1117,7 @@
       
       // The result of the constant expr is the RHS.
       Result = RHS;
-      return true;
+      break;
     }
 
     assert(!Exp->isAssignmentOp() && "LHS can't be a constant expr!");
@@ -1208,9 +1218,12 @@
       }
     
     // Evaluate the false one first, discard the result.
-    if (FalseExp && !FalseExp->isIntegerConstantExpr(Result, Ctx, Loc, false))
+    llvm::APSInt Tmp;
+    if (FalseExp && !FalseExp->isIntegerConstantExpr(Tmp, Ctx, Loc, false))
       return false;
-    // Evalute the true one, capture the result.
+    // Evalute the true one, capture the result. Note that if TrueExp
+    // is False then this is an instant of the gcc missing LHS
+    // extension, and we will just reuse Result.
     if (TrueExp && 
         !TrueExp->isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated))
       return false;