fix PR4073 by making designated initializer checking code use
VerifyIntegerConstantExpression instead of isIntegerConstantExpr.
This makes it ext-warn but tolerate things that fold to a constant
but that are not valid i-c-e's.

There must be a bug in the i-c-e computation though, because it
doesn't catch this case even with pedantic.

This also switches the later code to use EvaluateAsInt which is
simpler and handles everything that evaluate does.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70081 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 6e9cde8..0210cef 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -31,8 +31,6 @@
   "predefined identifier is only valid inside function">;
 
 // C99 Designated Initializers
-def err_array_designator_nonconstant : Error<
-  "array designator value must be a constant expression">;
 def err_array_designator_negative : Error<
   "array designator value '%0' is negative">;
 def err_array_designator_empty_range : Error<
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 474670d..e7d5ee1 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -4928,8 +4928,7 @@
   return isInvalid;
 }
 
-bool Sema::VerifyIntegerConstantExpression(const Expr* E, llvm::APSInt *Result)
-{
+bool Sema::VerifyIntegerConstantExpression(const Expr *E, llvm::APSInt *Result){
   Expr::EvalResult EvalResult;
 
   if (!E->Evaluate(EvalResult, Context) || !EvalResult.Val.isInt() ||
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index 28b2556..a622ef3 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -1391,28 +1391,19 @@
   llvm::APSInt DesignatedStartIndex, DesignatedEndIndex;
   if (D->isArrayDesignator()) {
     IndexExpr = DIE->getArrayIndex(*D);
-    
-    bool ConstExpr 
-      = IndexExpr->isIntegerConstantExpr(DesignatedStartIndex, SemaRef.Context);
-    assert(ConstExpr && "Expression must be constant"); (void)ConstExpr;
-    
+    DesignatedStartIndex = IndexExpr->EvaluateAsInt(SemaRef.Context);
     DesignatedEndIndex = DesignatedStartIndex;
   } else {
     assert(D->isArrayRangeDesignator() && "Need array-range designator");
-    
-    bool StartConstExpr
-      = DIE->getArrayRangeStart(*D)->isIntegerConstantExpr(DesignatedStartIndex,
-                                                           SemaRef.Context);
-    assert(StartConstExpr && "Expression must be constant"); (void)StartConstExpr;
 
-    bool EndConstExpr
-      = DIE->getArrayRangeEnd(*D)->isIntegerConstantExpr(DesignatedEndIndex,
-                                                         SemaRef.Context);
-    assert(EndConstExpr && "Expression must be constant"); (void)EndConstExpr;
     
+    DesignatedStartIndex = 
+      DIE->getArrayRangeStart(*D)->EvaluateAsInt(SemaRef.Context);
+    DesignatedEndIndex = 
+      DIE->getArrayRangeEnd(*D)->EvaluateAsInt(SemaRef.Context);
     IndexExpr = DIE->getArrayRangeEnd(*D);
 
-    if (DesignatedStartIndex.getZExtValue() != DesignatedEndIndex.getZExtValue())
+    if (DesignatedStartIndex.getZExtValue() !=DesignatedEndIndex.getZExtValue())
       FullyStructuredList->sawArrayRangeDesignator();
   }
 
@@ -1434,7 +1425,8 @@
     // Make sure the bit-widths and signedness match.
     if (DesignatedStartIndex.getBitWidth() > DesignatedEndIndex.getBitWidth())
       DesignatedEndIndex.extend(DesignatedStartIndex.getBitWidth());
-    else if (DesignatedStartIndex.getBitWidth() < DesignatedEndIndex.getBitWidth())
+    else if (DesignatedStartIndex.getBitWidth() <
+             DesignatedEndIndex.getBitWidth())
       DesignatedStartIndex.extend(DesignatedEndIndex.getBitWidth());
     DesignatedStartIndex.setIsUnsigned(true);
     DesignatedEndIndex.setIsUnsigned(true);
@@ -1602,25 +1594,21 @@
 
 /// Check that the given Index expression is a valid array designator
 /// value. This is essentailly just a wrapper around
-/// Expr::isIntegerConstantExpr that also checks for negative values
+/// VerifyIntegerConstantExpression that also checks for negative values
 /// and produces a reasonable diagnostic if there is a
 /// failure. Returns true if there was an error, false otherwise.  If
 /// everything went okay, Value will receive the value of the constant
 /// expression.
 static bool 
-CheckArrayDesignatorExpr(Sema &Self, Expr *Index, llvm::APSInt &Value) {
+CheckArrayDesignatorExpr(Sema &S, Expr *Index, llvm::APSInt &Value) {
   SourceLocation Loc = Index->getSourceRange().getBegin();
 
   // Make sure this is an integer constant expression.
-  if (!Index->isIntegerConstantExpr(Value, Self.Context, &Loc))
-    return Self.Diag(Loc, diag::err_array_designator_nonconstant)
-      << Index->getSourceRange();
+  if (S.VerifyIntegerConstantExpression(Index, &Value))
+    return true;
 
-  // Make sure this constant expression is non-negative.
-  llvm::APSInt Zero(llvm::APSInt::getNullValue(Value.getBitWidth()), 
-                    Value.isUnsigned());
-  if (Value < Zero)
-    return Self.Diag(Loc, diag::err_array_designator_negative)
+  if (Value.isSigned() && Value.isNegative())
+    return S.Diag(Loc, diag::err_array_designator_negative)
       << Value.toString(10) << Index->getSourceRange();
 
   Value.setIsUnsigned(true);
diff --git a/test/Sema/designated-initializers.c b/test/Sema/designated-initializers.c
index 309a530..3333122 100644
--- a/test/Sema/designated-initializers.c
+++ b/test/Sema/designated-initializers.c
@@ -221,3 +221,14 @@
   &c0,
   .float_ptr = &f0 // expected-warning{{overrides}}
 };
+
+
+/// PR4073
+/// Should use evaluate to fold aggressively and emit a warning if not an ice.
+extern int crazy_x;
+
+int crazy_Y[] = {
+  [ 0 ? crazy_x : 4] = 1
+};
+
+