diff options
author | Giovanni Bajo <giovannibajo@gcc.gnu.org> | 2004-11-22 12:15:53 +0000 |
---|---|---|
committer | Giovanni Bajo <giovannibajo@gcc.gnu.org> | 2004-11-22 12:15:53 +0000 |
commit | e99f332f05fbe3e18d628a91cb363dc67047e19f (patch) | |
tree | 09703038def87536054944b70def832562af54cd | |
parent | 6cb70db4d9333ea241e1076147ec8f3516ea7982 (diff) | |
download | gcc-e99f332f05fbe3e18d628a91cb363dc67047e19f.zip gcc-e99f332f05fbe3e18d628a91cb363dc67047e19f.tar.gz gcc-e99f332f05fbe3e18d628a91cb363dc67047e19f.tar.bz2 |
re PR c++/18354 (expression "+1" not considered constant (as template parameter).)
PR c++/18354
* typeck.c (build_unary_op) <CONVERT_EXPR, NEGATE_EXPR>: Unify code.
Make sure the result is always a rvalue.
PR c++/18354
* g++.dg/template/nontype11.C: New test.
From-SVN: r91008
-rw-r--r-- | gcc/cp/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cp/typeck.c | 40 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/template/nontype11.C | 22 |
4 files changed, 55 insertions, 18 deletions
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 <giovannibajo@gcc.gnu.org> + + PR c++/18354 + * typeck.c (build_unary_op) <CONVERT_EXPR, NEGATE_EXPR>: Unify code. + Make sure the result is always a rvalue. + 2004-11-16 Giovanni Bajo <giovannibajo@gcc.gnu.org> * 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 <giovannibajo@gcc.gnu.org> + + PR c++/18354 + * g++.dg/template/nontype11.C: New test. + 2004-11-21 Roger Sayle <roger@eyesopen.com> 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: <fsm at robots dot ox dot ac dot uk> +// PR c++/18354: Unary plus should not be wrapped in NON_LVALUE_EXPR + +template <int N> +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; +} |