From: Chris Lattner Date: Sat, 25 Apr 2009 21:59:05 +0000 (+0000) Subject: fix PR4073 by making designated initializer checking code use X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3bf6893b77c30cb774100e0fa7ae029331675ec1;p=clang 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 6e9cde8c30..0210ceff46 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -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< diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 474670dbb7..e7d5ee18ff 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -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() || diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 28b25565b1..a622ef3796 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -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); diff --git a/test/Sema/designated-initializers.c b/test/Sema/designated-initializers.c index 309a530459..3333122202 100644 --- a/test/Sema/designated-initializers.c +++ b/test/Sema/designated-initializers.c @@ -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 +}; + +