summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-05-07 22:08:54 +0000
committerJohn McCall <rjmccall@apple.com>2010-05-07 22:08:54 +0000
commitb1fb0d3610d70b8a3a849b8652d5b46a9d1ce8fb (patch)
tree13763cd63579b21a19828572b627a1b0dd06886d /clang
parent2ae3397536d6a9b858c50a119941c815d643f7dd (diff)
downloadbcm5719-llvm-b1fb0d3610d70b8a3a849b8652d5b46a9d1ce8fb.tar.gz
bcm5719-llvm-b1fb0d3610d70b8a3a849b8652d5b46a9d1ce8fb.zip
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 <rdar://problem/7958272>. llvm-svn: 103307
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/AST/ExprConstant.cpp22
-rw-r--r--clang/test/CodeGen/complex.c4
2 files changed, 24 insertions, 2 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 30eaae14d71..e53804c86dd 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/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/clang/test/CodeGen/complex.c b/clang/test/CodeGen/complex.c
index ca606109f8b..055383ebbbe 100644
--- a/clang/test/CodeGen/complex.c
+++ b/clang/test/CodeGen/complex.c
@@ -89,3 +89,7 @@ void t6() {
--ci1;
}
+// <rdar://problem/7958272>
+double t7(double _Complex c) {
+ return __builtin_fabs(__real__(c));
+}
OpenPOWER on IntegriCloud