isICE was evaluating ?: incorrectly with missing-gcc-LHS extension.

Add assert to isICE that, on success, result must be the same as
EvaluateAsInt()... this enforces a minimum level of sanity.

llvm-svn: 64865
This commit is contained in:
Daniel Dunbar 2009-02-18 00:47:45 +00:00
parent 62347a0c55
commit 4750e63486
3 changed files with 23 additions and 4 deletions

View File

@ -180,6 +180,9 @@ public:
bool isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx,
SourceLocation *Loc = 0,
bool isEvaluated = true) const;
bool isIntegerConstantExprInternal(llvm::APSInt &Result, ASTContext &Ctx,
SourceLocation *Loc = 0,
bool isEvaluated = true) const;
bool isIntegerConstantExpr(ASTContext &Ctx, SourceLocation *Loc = 0) const {
llvm::APSInt X;
return isIntegerConstantExpr(X, Ctx, Loc);
@ -190,7 +193,7 @@ public:
/// EvalResult is a struct with detailed info about an evaluated expression.
struct EvalResult {
/// Val - This is the scalar value the expression can be folded to.
/// Val - This is the value the expression can be folded to.
APValue Val;
/// HasSideEffects - Whether the evaluated expression has side effects.

View File

@ -871,6 +871,15 @@ bool Expr::isConstantInitializer(ASTContext &Ctx) const {
/// cast+dereference.
bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx,
SourceLocation *Loc, bool isEvaluated) const {
if (!isIntegerConstantExprInternal(Result, Ctx, Loc, isEvaluated))
return false;
assert(Result == EvaluateAsInt(Ctx) && "Inconsistent Evaluate() result!");
return true;
}
bool Expr::isIntegerConstantExprInternal(llvm::APSInt &Result, ASTContext &Ctx,
SourceLocation *Loc, bool isEvaluated) const {
// Pretest for integral type; some parts of the code crash for types that
// can't be sized.
if (!getType()->isIntegralType()) {
@ -885,6 +894,7 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx,
return cast<ParenExpr>(this)->getSubExpr()->
isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated);
case IntegerLiteralClass:
// NOTE: getValue() returns an APInt, we must set sign.
Result = cast<IntegerLiteral>(this)->getValue();
Result.setIsUnsigned(getType()->isUnsignedIntegerType());
break;
@ -1107,7 +1117,7 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx,
// The result of the constant expr is the RHS.
Result = RHS;
return true;
break;
}
assert(!Exp->isAssignmentOp() && "LHS can't be a constant expr!");
@ -1208,9 +1218,12 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx,
}
// Evaluate the false one first, discard the result.
if (FalseExp && !FalseExp->isIntegerConstantExpr(Result, Ctx, Loc, false))
llvm::APSInt Tmp;
if (FalseExp && !FalseExp->isIntegerConstantExpr(Tmp, Ctx, Loc, false))
return false;
// Evalute the true one, capture the result.
// Evalute the true one, capture the result. Note that if TrueExp
// is False then this is an instant of the gcc missing LHS
// extension, and we will just reuse Result.
if (TrueExp &&
!TrueExp->isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated))
return false;

View File

@ -29,3 +29,6 @@ void f()
// FIXME: Turn into EVAL_EXPR test once we have more folding.
_Complex float g16 = (1.0f + 1.0fi);
// ?: in constant expressions.
int g17[(3?:1) - 2];