diff options
-rw-r--r-- | lib/AST/ExprConstant.cpp | 22 | ||||
-rw-r--r-- | test/Sema/const-eval.c | 5 |
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); + |