aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/AST/ExprConstant.cpp22
-rw-r--r--test/Sema/const-eval.c5
2 files changed, 24 insertions, 3 deletions
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 68818dbf7b..86a7e8217f 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -645,9 +645,7 @@ public:
}
bool VisitChooseExpr(const ChooseExpr *E);
- bool VisitUnaryReal(const UnaryOperator *E) {
- return Visit(E->getSubExpr());
- }
+ bool VisitUnaryReal(const UnaryOperator *E);
bool VisitUnaryImag(const UnaryOperator *E);
private:
@@ -1192,7 +1190,25 @@ bool IntExprEvaluator::VisitChooseExpr(const ChooseExpr *E) {
return Visit(EvalExpr);
}
+bool IntExprEvaluator::VisitUnaryReal(const UnaryOperator *E) {
+ if (E->getSubExpr()->getType()->isAnyComplexType()) {
+ APValue LV;
+ if (!EvaluateComplex(E->getSubExpr(), LV, Info) || !LV.isComplexInt())
+ return Error(E->getExprLoc(), diag::note_invalid_subexpr_in_ice, E);
+ return Success(LV.getComplexIntReal(), E);
+ }
+
+ return Visit(E->getSubExpr());
+}
+
bool IntExprEvaluator::VisitUnaryImag(const UnaryOperator *E) {
+ if (E->getSubExpr()->getType()->isComplexIntegerType()) {
+ APValue LV;
+ if (!EvaluateComplex(E->getSubExpr(), LV, Info) || !LV.isComplexInt())
+ return Error(E->getExprLoc(), diag::note_invalid_subexpr_in_ice, E);
+ return Success(LV.getComplexIntImag(), E);
+ }
+
if (!E->getSubExpr()->isEvaluatable(Info.Ctx))
Info.EvalResult.HasSideEffects = true;
return Success(0, E);
diff --git a/test/Sema/const-eval.c b/test/Sema/const-eval.c
index aebcb6a3fd..fd7b40ea1b 100644
--- a/test/Sema/const-eval.c
+++ b/test/Sema/const-eval.c
@@ -42,3 +42,8 @@ struct s {
EVAL_EXPR(19, ((int)&*(char*)10 == 10 ? 1 : -1));
EVAL_EXPR(20, __builtin_constant_p(*((int*) 10), -1, 1));
+
+EVAL_EXPR(21, (__imag__ 2i) == 2 ? 1 : -1);
+
+EVAL_EXPR(22, (__real__ (2i+3)) == 3 ? 1 : -1);
+