forked from OSchip/llvm-project
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:
parent
4c73d7a9b8
commit
c71d08bc22
|
@ -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<
|
||||||
|
|
|
@ -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() ||
|
||||||
|
|
|
@ -1391,25 +1391,16 @@ 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())
|
||||||
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue