[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