cp/ 2004-11-14 Giovanni Bajo PR c++/18354 * typeck.c (build_unary_op) : Unify code. Make sure the result is always a rvalue. testsuite/ 2004-11-14 Giovanni Bajo PR c++/18354 * g++.dg/template/nontype11.C: New test. Index: typeck.c =================================================================== RCS file: /cvs/gcc/gcc/gcc/cp/typeck.c,v retrieving revision 1.596 diff -c -3 -p -r1.596 typeck.c *** typeck.c 11 Nov 2004 03:13:03 -0000 1.596 --- typeck.c 16 Nov 2004 01:27:38 -0000 *************** build_unary_op (enum tree_code code, tre *** 3741,3766 **** switch (code) { 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); break; case BIT_NOT_EXPR: --- 3741,3769 ---- switch (code) { + /* CONVERT_EXPR stands for unary plus in this context. */ case CONVERT_EXPR: case NEGATE_EXPR: ! { ! int flags = WANT_ARITH | WANT_ENUM; ! /* Unary plus (but not unary minus) is allowed on pointers. */ ! if (code == CONVERT_EXPR) ! flags |= WANT_POINTER; ! if (!(arg = build_expr_type_conversion (flags, arg, true))) ! 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: an 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: // { dg-do compile } // Origin: // PR c++/18354: Unary plus should not be wrapped in NON_LVALUE_EXPR template struct X { }; void f() { X< 1> a; X<-1> b; X<+1> c; }