]> granicus.if.org Git - clang/commitdiff
Add handling for complex->int, int->complex float, and float->complex
authorEli Friedman <eli.friedman@gmail.com>
Wed, 22 Apr 2009 19:23:09 +0000 (19:23 +0000)
committerEli Friedman <eli.friedman@gmail.com>
Wed, 22 Apr 2009 19:23:09 +0000 (19:23 +0000)
int.  Note that constant int->complex float and float->complex int casts
were being miscompiled.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69821 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/ExprConstant.cpp
test/Sema/const-eval.c

index b588eab642abf82e68992a7faa8cd817e7c9f130..1ea252fecb76297d1255c6db54444d29f00333b6 100644 (file)
@@ -1205,7 +1205,18 @@ bool IntExprEvaluator::VisitCastExpr(CastExpr *E) {
     return true;
   }
 
-  // FIXME: Handle complex types
+  if (SrcType->isAnyComplexType()) {
+    APValue C;
+    if (!EvaluateComplex(SubExpr, C, Info))
+      return false;
+    if (C.isComplexFloat())
+      return Success(HandleFloatToIntCast(DestType, SrcType,
+                                          C.getComplexFloatReal(), Info.Ctx),
+                     E);
+    else
+      return Success(HandleIntToIntCast(DestType, SrcType,
+                                        C.getComplexIntReal(), Info.Ctx), E);
+  }
   // FIXME: Handle vectors
 
   if (!SrcType->isRealFloatingType())
@@ -1467,28 +1478,41 @@ public:
 
     if (SubType->isRealFloatingType()) {
       APFloat Result(0.0);
-                     
+
       if (!EvaluateFloat(SubExpr, Result, Info))
         return APValue();
-      
-      // Apply float conversion if necessary.
-      Result = HandleFloatToFloatCast(EltType, SubType, Result, Info.Ctx);
-      return APValue(Result, 
-                     APFloat(Result.getSemantics(), APFloat::fcZero, false));
+
+      if (EltType->isRealFloatingType()) {
+        Result = HandleFloatToFloatCast(EltType, SubType, Result, Info.Ctx);
+        return APValue(Result, 
+                       APFloat(Result.getSemantics(), APFloat::fcZero, false));
+      } else {
+        llvm::APSInt IResult;
+        IResult = HandleFloatToIntCast(EltType, SubType, Result, Info.Ctx);
+        llvm::APSInt Zero(IResult.getBitWidth(), !IResult.isSigned());
+        Zero = 0;
+        return APValue(IResult, Zero);
+      }
     } else if (SubType->isIntegerType()) {
       APSInt Result;
-                     
+
       if (!EvaluateInteger(SubExpr, Result, Info))
         return APValue();
 
-      // Apply integer conversion if necessary.
-      Result = HandleIntToIntCast(EltType, SubType, Result, Info.Ctx);
-      llvm::APSInt Zero(Result.getBitWidth(), !Result.isSigned());
-      Zero = 0;
-      return APValue(Result, Zero);
+      if (EltType->isRealFloatingType()) {
+        APFloat FResult =
+            HandleIntToFloatCast(EltType, SubType, Result, Info.Ctx);
+        return APValue(FResult, 
+                       APFloat(FResult.getSemantics(), APFloat::fcZero, false));
+      } else {
+        Result = HandleIntToIntCast(EltType, SubType, Result, Info.Ctx);
+        llvm::APSInt Zero(Result.getBitWidth(), !Result.isSigned());
+        Zero = 0;
+        return APValue(Result, Zero);
+      }
     } else if (const ComplexType *CT = SubType->getAsComplexType()) {
       APValue Src;
-                     
+
       if (!EvaluateComplex(SubExpr, Src, Info))
         return APValue();
 
index 08daa5f8d6ee0f3cbfa915c6d4615b32532555ec..ce1aacd2745af934c6d5b138ccf1fe4ba42e7493 100644 (file)
@@ -61,3 +61,5 @@ EVAL_EXPR(29, (_Complex int)1 ? 1 : -1)
 struct a { int x, y };
 static struct a V2 = (struct a)(struct a){ 1, 2};
 static const struct a V1 = (struct a){ 1, 2};
+
+EVAL_EXPR(30, (int)(_Complex float)((1<<30)-1) == (1<<30) ? 1 : -1)