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.

llvm-svn: 70081
This commit is contained in:
Chris Lattner 2009-04-25 21:59:05 +00:00
parent 4c73d7a9b8
commit c71d08bc22
4 changed files with 26 additions and 30 deletions

View File

@ -31,8 +31,6 @@ def ext_predef_outside_function : Warning<
"predefined identifier is only valid inside function">; "predefined identifier is only valid inside function">;
// C99 Designated Initializers // C99 Designated Initializers
def err_array_designator_nonconstant : Error<
"array designator value must be a constant expression">;
def err_array_designator_negative : Error< def err_array_designator_negative : Error<
"array designator value '%0' is negative">; "array designator value '%0' is negative">;
def err_array_designator_empty_range : Error< def err_array_designator_empty_range : Error<

View File

@ -4928,8 +4928,7 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy,
return isInvalid; return isInvalid;
} }
bool Sema::VerifyIntegerConstantExpression(const Expr* E, llvm::APSInt *Result) bool Sema::VerifyIntegerConstantExpression(const Expr *E, llvm::APSInt *Result){
{
Expr::EvalResult EvalResult; Expr::EvalResult EvalResult;
if (!E->Evaluate(EvalResult, Context) || !EvalResult.Val.isInt() || if (!E->Evaluate(EvalResult, Context) || !EvalResult.Val.isInt() ||

View File

@ -1391,28 +1391,19 @@ InitListChecker::CheckDesignatedInitializer(InitListExpr *IList,
llvm::APSInt DesignatedStartIndex, DesignatedEndIndex; llvm::APSInt DesignatedStartIndex, DesignatedEndIndex;
if (D->isArrayDesignator()) { if (D->isArrayDesignator()) {
IndexExpr = DIE->getArrayIndex(*D); IndexExpr = DIE->getArrayIndex(*D);
DesignatedStartIndex = IndexExpr->EvaluateAsInt(SemaRef.Context);
bool ConstExpr
= IndexExpr->isIntegerConstantExpr(DesignatedStartIndex, SemaRef.Context);
assert(ConstExpr && "Expression must be constant"); (void)ConstExpr;
DesignatedEndIndex = DesignatedStartIndex; DesignatedEndIndex = DesignatedStartIndex;
} else { } else {
assert(D->isArrayRangeDesignator() && "Need array-range designator"); 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); IndexExpr = DIE->getArrayRangeEnd(*D);
if (DesignatedStartIndex.getZExtValue() != DesignatedEndIndex.getZExtValue()) if (DesignatedStartIndex.getZExtValue() !=DesignatedEndIndex.getZExtValue())
FullyStructuredList->sawArrayRangeDesignator(); FullyStructuredList->sawArrayRangeDesignator();
} }
@ -1434,7 +1425,8 @@ InitListChecker::CheckDesignatedInitializer(InitListExpr *IList,
// Make sure the bit-widths and signedness match. // Make sure the bit-widths and signedness match.
if (DesignatedStartIndex.getBitWidth() > DesignatedEndIndex.getBitWidth()) if (DesignatedStartIndex.getBitWidth() > DesignatedEndIndex.getBitWidth())
DesignatedEndIndex.extend(DesignatedStartIndex.getBitWidth()); DesignatedEndIndex.extend(DesignatedStartIndex.getBitWidth());
else if (DesignatedStartIndex.getBitWidth() < DesignatedEndIndex.getBitWidth()) else if (DesignatedStartIndex.getBitWidth() <
DesignatedEndIndex.getBitWidth())
DesignatedStartIndex.extend(DesignatedEndIndex.getBitWidth()); DesignatedStartIndex.extend(DesignatedEndIndex.getBitWidth());
DesignatedStartIndex.setIsUnsigned(true); DesignatedStartIndex.setIsUnsigned(true);
DesignatedEndIndex.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 /// Check that the given Index expression is a valid array designator
/// value. This is essentailly just a wrapper around /// 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 /// and produces a reasonable diagnostic if there is a
/// failure. Returns true if there was an error, false otherwise. If /// failure. Returns true if there was an error, false otherwise. If
/// everything went okay, Value will receive the value of the constant /// everything went okay, Value will receive the value of the constant
/// expression. /// expression.
static bool static bool
CheckArrayDesignatorExpr(Sema &Self, Expr *Index, llvm::APSInt &Value) { CheckArrayDesignatorExpr(Sema &S, Expr *Index, llvm::APSInt &Value) {
SourceLocation Loc = Index->getSourceRange().getBegin(); SourceLocation Loc = Index->getSourceRange().getBegin();
// Make sure this is an integer constant expression. // Make sure this is an integer constant expression.
if (!Index->isIntegerConstantExpr(Value, Self.Context, &Loc)) if (S.VerifyIntegerConstantExpression(Index, &Value))
return Self.Diag(Loc, diag::err_array_designator_nonconstant) return true;
<< Index->getSourceRange();
// Make sure this constant expression is non-negative. if (Value.isSigned() && Value.isNegative())
llvm::APSInt Zero(llvm::APSInt::getNullValue(Value.getBitWidth()), return S.Diag(Loc, diag::err_array_designator_negative)
Value.isUnsigned());
if (Value < Zero)
return Self.Diag(Loc, diag::err_array_designator_negative)
<< Value.toString(10) << Index->getSourceRange(); << Value.toString(10) << Index->getSourceRange();
Value.setIsUnsigned(true); Value.setIsUnsigned(true);

View File

@ -221,3 +221,14 @@ struct Enigma enigma = {
&c0, &c0,
.float_ptr = &f0 // expected-warning{{overrides}} .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
};