From abd3a857ace59100305790545d1baae5877b8945 Mon Sep 17 00:00:00 2001 From: John McCall Date: Fri, 7 May 2010 22:08:54 +0000 Subject: [PATCH] The FP constant evaluator was missing a few cases of unary operators that return floats but whose operand isn't a float: specifically, __real__ and __imag__. Instead of filtering these out, just implement them. Fixes . git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@103307 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/ExprConstant.cpp | 22 ++++++++++++++++++++-- test/CodeGen/complex.c | 4 ++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp index 30eaae14d7..e53804c86d 100644 --- a/lib/AST/ExprConstant.cpp +++ b/lib/AST/ExprConstant.cpp @@ -1703,9 +1703,11 @@ public: { return Visit(E->getChosenSubExpr(Info.Ctx)); } bool VisitUnaryExtension(const UnaryOperator *E) { return Visit(E->getSubExpr()); } + bool VisitUnaryReal(const UnaryOperator *E); + bool VisitUnaryImag(const UnaryOperator *E); - // FIXME: Missing: __real__/__imag__, array subscript of vector, - // member of vector, ImplicitValueInitExpr + // FIXME: Missing: array subscript of vector, member of vector, + // ImplicitValueInitExpr }; } // end anonymous namespace @@ -1791,6 +1793,22 @@ bool FloatExprEvaluator::VisitCallExpr(const CallExpr *E) { } } +bool FloatExprEvaluator::VisitUnaryReal(const UnaryOperator *E) { + ComplexValue CV; + if (!EvaluateComplex(E->getSubExpr(), CV, Info)) + return false; + Result = CV.FloatReal; + return true; +} + +bool FloatExprEvaluator::VisitUnaryImag(const UnaryOperator *E) { + ComplexValue CV; + if (!EvaluateComplex(E->getSubExpr(), CV, Info)) + return false; + Result = CV.FloatImag; + return true; +} + bool FloatExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) { if (E->getOpcode() == UnaryOperator::Deref) return false; diff --git a/test/CodeGen/complex.c b/test/CodeGen/complex.c index ca606109f8..055383ebbb 100644 --- a/test/CodeGen/complex.c +++ b/test/CodeGen/complex.c @@ -89,3 +89,7 @@ void t6() { --ci1; } +// +double t7(double _Complex c) { + return __builtin_fabs(__real__(c)); +}