[cfe-commits] r42238 - /cfe/trunk/AST/Expr.cpp
Chris Lattner
sabre at nondot.org
Sat Sep 22 12:04:13 PDT 2007
Author: lattner
Date: Sat Sep 22 14:04:13 2007
New Revision: 42238
URL: http://llvm.org/viewvc/llvm-project?rev=42238&view=rev
Log:
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'
Modified:
cfe/trunk/AST/Expr.cpp
Modified: cfe/trunk/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/Expr.cpp?rev=42238&r1=42237&r2=42238&view=diff
==============================================================================
--- cfe/trunk/AST/Expr.cpp (original)
+++ cfe/trunk/AST/Expr.cpp Sat Sep 22 14:04:13 2007
@@ -715,16 +715,16 @@
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 @@
const Expr *Operand = SubExpr;
while (const ParenExpr *PE = dyn_cast<ParenExpr>(Operand))
Operand = PE->getSubExpr();
+
+ // 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 (const FloatingLiteral *FL = dyn_cast<FloatingLiteral>(Operand)) {
- // FIXME: Evaluate this correctly!
- Result = (int)FL->getValueAsDouble();
- break;
+ // 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.
}
- if (Loc) *Loc = Operand->getLocStart();
- return false;
+
+ Result = llvm::APInt(DestWidth, 4, Space);
+ break;
}
case ConditionalOperatorClass: {
const ConditionalOperator *Exp = cast<ConditionalOperator>(this);
More information about the cfe-commits
mailing list