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
This commit is contained in:
Giovanni Bajo 2004-11-22 12:15:53 +00:00
parent 6cb70db4d9
commit e99f332f05
4 changed files with 55 additions and 18 deletions

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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;
}