forked from OSchip/llvm-project
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:
parent
62347a0c55
commit
4750e63486
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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];
|
||||
|
|
Loading…
Reference in New Issue