From e99f332f05fbe3e18d628a91cb363dc67047e19f Mon Sep 17 00:00:00 2001 From: Giovanni Bajo Date: Mon, 22 Nov 2004 12:15:53 +0000 Subject: [PATCH] re PR c++/18354 (expression "+1" not considered constant (as template parameter).) PR c++/18354 * typeck.c (build_unary_op) : Unify code. Make sure the result is always a rvalue. PR c++/18354 * g++.dg/template/nontype11.C: New test. From-SVN: r91008 --- gcc/cp/ChangeLog | 6 +++++ gcc/cp/typeck.c | 40 +++++++++++++++++-------------- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/g++.dg/template/nontype11.C | 22 +++++++++++++++++ 4 files changed, 55 insertions(+), 18 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/nontype11.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ddb1e99..bcb9d21 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2004-11-22 Giovanni Bajo + + PR c++/18354 + * typeck.c (build_unary_op) : Unify code. + Make sure the result is always a rvalue. + 2004-11-16 Giovanni Bajo * decl.c (start_preparsed_function): Call check_function_type even diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index b1a85d5..4caf051 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -3741,26 +3741,30 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert) switch (code) { + /* CONVERT_EXPR stands for unary plus in this context. */ case CONVERT_EXPR: - /* This is used for unary plus, because a CONVERT_EXPR - is enough to prevent anybody from looking inside for - associativity, but won't generate any code. */ - if (!(arg = build_expr_type_conversion - (WANT_ARITH | WANT_ENUM | WANT_POINTER, arg, true))) - errstring = "wrong type argument to unary plus"; - else - { - if (!noconvert) - arg = default_conversion (arg); - arg = build1 (NON_LVALUE_EXPR, TREE_TYPE (arg), arg); - } - break; - case NEGATE_EXPR: - if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, arg, true))) - errstring = "wrong type argument to unary minus"; - else if (!noconvert && CP_INTEGRAL_TYPE_P (TREE_TYPE (arg))) - arg = perform_integral_promotions (arg); + { + int flags = WANT_ARITH | WANT_ENUM; + /* Unary plus (but not unary minus) is allowed on pointers. */ + if (code == CONVERT_EXPR) + flags |= WANT_POINTER; + arg = build_expr_type_conversion (flags, arg, true); + if (!arg) + errstring = (code == NEGATE_EXPR + ? "wrong type argument to unary minus" + : "wrong type argument to unary plus"); + else + { + if (!noconvert && CP_INTEGRAL_TYPE_P (TREE_TYPE (arg))) + arg = perform_integral_promotions (arg); + + /* Make sure the result is not a lvalue: a unary plus or minus + expression is always a rvalue. */ + if (real_lvalue_p (arg)) + arg = build1 (NON_LVALUE_EXPR, TREE_TYPE (arg), arg); + } + } break; case BIT_NOT_EXPR: diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index b9ec394..3601740 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2004-11-22 Giovanni Bajo + + PR c++/18354 + * g++.dg/template/nontype11.C: New test. + 2004-11-21 Roger Sayle PR middle-end/18520 diff --git a/gcc/testsuite/g++.dg/template/nontype11.C b/gcc/testsuite/g++.dg/template/nontype11.C new file mode 100644 index 0000000..d52eb9a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/nontype11.C @@ -0,0 +1,22 @@ +// { dg-do compile } +// Origin: +// PR c++/18354: Unary plus should not be wrapped in NON_LVALUE_EXPR + +template +struct X { }; + +const int n = 1; + +void f() +{ + X< 1> a; + X<-1> b; + X<+1> c; +} + +void g() +{ + X< n> a; + X<-n> b; + X<+n> c; +} -- 2.7.4