From: Eli Friedman Date: Wed, 22 Apr 2009 19:23:09 +0000 (+0000) Subject: Add handling for complex->int, int->complex float, and float->complex X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1725f683432715e5afe34d476024bd6f16eac3fc;p=clang Add handling for complex->int, int->complex float, and float->complex 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 --- diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index b588eab642..1ea252fecb 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -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(); diff --git a/test/Sema/const-eval.c b/test/Sema/const-eval.c index 08daa5f8d6..ce1aacd274 100644 --- a/test/Sema/const-eval.c +++ b/test/Sema/const-eval.c @@ -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)