Commit e99f332f by Giovanni Bajo

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
parent 6cb70db4
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> 2004-11-16 Giovanni Bajo <giovannibajo@gcc.gnu.org>
* decl.c (start_preparsed_function): Call check_function_type even * decl.c (start_preparsed_function): Call check_function_type even
......
...@@ -3741,26 +3741,30 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert) ...@@ -3741,26 +3741,30 @@ build_unary_op (enum tree_code code, tree xarg, int noconvert)
switch (code) switch (code)
{ {
/* CONVERT_EXPR stands for unary plus in this context. */
case CONVERT_EXPR: 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: case NEGATE_EXPR:
if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, arg, true))) {
errstring = "wrong type argument to unary minus"; int flags = WANT_ARITH | WANT_ENUM;
else if (!noconvert && CP_INTEGRAL_TYPE_P (TREE_TYPE (arg))) /* Unary plus (but not unary minus) is allowed on pointers. */
arg = perform_integral_promotions (arg); 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; break;
case BIT_NOT_EXPR: case BIT_NOT_EXPR:
......
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> 2004-11-21 Roger Sayle <roger@eyesopen.com>
PR middle-end/18520 PR middle-end/18520
......
// { 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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment