зеркало из https://github.com/microsoft/clang-1.git
Use the APFloat routines to evaluate FP immediates as
integer constant expressions. The only questionable thing is that we now reject: void foo() { switch (1) { case (int)1.0e10000: ; } } with: t.c:5:13: error: case label does not reduce to an integer constant case (int)1.0e10000: ~~~~~^~~~~~~~~ GCC accepts this, emitting the pedwarn: t.c:5: warning: floating constant exceeds range of 'double' git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42238 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
3d2313ef5d
Коммит
987b15db39
37
AST/Expr.cpp
37
AST/Expr.cpp
|
@ -715,16 +715,16 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx,
|
|||
if (Loc) *Loc = SubExpr->getLocStart();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
uint32_t DestWidth =
|
||||
static_cast<uint32_t>(Ctx.getTypeSize(getType(), CastLoc));
|
||||
|
||||
// Handle simple integer->integer casts.
|
||||
if (SubExpr->getType()->isIntegerType()) {
|
||||
if (!SubExpr->isIntegerConstantExpr(Result, Ctx, Loc, isEvaluated))
|
||||
return false;
|
||||
|
||||
// Figure out if this is a truncate, extend or noop cast.
|
||||
unsigned DestWidth =
|
||||
static_cast<uint32_t>(Ctx.getTypeSize(getType(), CastLoc));
|
||||
|
||||
// If the input is signed, do a sign extend, noop, or truncate.
|
||||
if (SubExpr->getType()->isSignedIntegerType())
|
||||
Result.sextOrTrunc(DestWidth);
|
||||
|
@ -738,14 +738,29 @@ bool Expr::isIntegerConstantExpr(llvm::APSInt &Result, ASTContext &Ctx,
|
|||
const Expr *Operand = SubExpr;
|
||||
while (const ParenExpr *PE = dyn_cast<ParenExpr>(Operand))
|
||||
Operand = PE->getSubExpr();
|
||||
|
||||
if (const FloatingLiteral *FL = dyn_cast<FloatingLiteral>(Operand)) {
|
||||
// FIXME: Evaluate this correctly!
|
||||
Result = (int)FL->getValueAsDouble();
|
||||
break;
|
||||
|
||||
// If this isn't a floating literal, we can't handle it.
|
||||
const FloatingLiteral *FL = dyn_cast<FloatingLiteral>(Operand);
|
||||
if (!FL) {
|
||||
if (Loc) *Loc = Operand->getLocStart();
|
||||
return false;
|
||||
}
|
||||
if (Loc) *Loc = Operand->getLocStart();
|
||||
return false;
|
||||
|
||||
// Determine whether we are converting to unsigned or signed.
|
||||
bool DestSigned = getType()->isSignedIntegerType();
|
||||
|
||||
uint64_t Space[4];
|
||||
|
||||
llvm::APFloat::opStatus Status =
|
||||
FL->getValue().convertToInteger(Space, DestWidth, DestSigned,
|
||||
llvm::APFloat::rmNearestTiesToEven);
|
||||
if (Status != llvm::APFloat::opOK && Status != llvm::APFloat::opInexact) {
|
||||
if (Loc) *Loc = Operand->getLocStart();
|
||||
return false; // FIXME: need to accept this as an extension.
|
||||
}
|
||||
|
||||
Result = llvm::APInt(DestWidth, 4, Space);
|
||||
break;
|
||||
}
|
||||
case ConditionalOperatorClass: {
|
||||
const ConditionalOperator *Exp = cast<ConditionalOperator>(this);
|
||||
|
|
Загрузка…
Ссылка в новой задаче