]> granicus.if.org Git - clang/commitdiff
fix PR4073 by making designated initializer checking code use
authorChris Lattner <sabre@nondot.org>
Sat, 25 Apr 2009 21:59:05 +0000 (21:59 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 25 Apr 2009 21:59:05 +0000 (21:59 +0000)
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

include/clang/Basic/DiagnosticSemaKinds.td
lib/Sema/SemaExpr.cpp
lib/Sema/SemaInit.cpp
test/Sema/designated-initializers.c

index 6e9cde8c306eba234a0ba4fd301bf62de5204ff0..0210ceff468a599155ab0694e970f2ad1cc9c020 100644 (file)
@@ -31,8 +31,6 @@ def ext_predef_outside_function : Warning<
   "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<
index 474670dbb7ab197717354d3d3521941a93623ee5..e7d5ee18ff876f1940ee49c0d41cfdf717d34e0b 100644 (file)
@@ -4928,8 +4928,7 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
   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() ||
index 28b25565b14bf8f647f2e9bd227b17b9645be0aa..a622ef3796f9bb4991fd2ced792bc76ca5b22605 100644 (file)
@@ -1391,28 +1391,19 @@ InitListChecker::CheckDesignatedInitializer(InitListExpr *IList,
   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 @@ InitListChecker::CheckDesignatedInitializer(InitListExpr *IList,
     // 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 @@ void InitListChecker::UpdateStructuredListElement(InitListExpr *StructuredList,
 
 /// 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();
-
-  // 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 (S.VerifyIntegerConstantExpression(Index, &Value))
+    return true;
+
+  if (Value.isSigned() && Value.isNegative())
+    return S.Diag(Loc, diag::err_array_designator_negative)
       << Value.toString(10) << Index->getSourceRange();
 
   Value.setIsUnsigned(true);
index 309a53045984ea98c691d41b04e27f204b44120b..3333122202a38795285dc05bab07e603086d8409 100644 (file)
@@ -221,3 +221,14 @@ struct Enigma enigma = {
   &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
+};
+
+