mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-03-08 11:47:28 +08:00
re PR c++/11512 (Spurious warning for comma-operator in templates)
PR c++/11512 * stmt.c (expand_expr_stmt_value): Don't warn about any void typed expression. cp: PR c++/11512 * cvt.c (convert_to_void): Indicate which side of conditional has no effects, and rhs of comma operator. Test for no sideeffect expressions here and always build a convert expr. * init.c (expand_default_init): Convert the init to void. * typeck.c (build_x_compound_expr): Do not check for side effects here. (build_compound_expr): Do not convert lhs when building a template. testsuite: PR C++/11512 * g++.dg/template/warn1.C: New. From-SVN: r70505
This commit is contained in:
parent
e767b5be43
commit
e895113a67
@ -1,3 +1,9 @@
|
||||
2003-08-16 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
PR c++/11512
|
||||
* stmt.c (expand_expr_stmt_value): Don't warn about any void
|
||||
typed expression.
|
||||
|
||||
2003-08-16 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* i386.c (ix86_fntype_regparm): Rename from ...
|
||||
|
@ -1,3 +1,15 @@
|
||||
2003-08-16 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
PR c++/11512
|
||||
* cvt.c (convert_to_void): Indicate which side of conditional has
|
||||
no effects, and rhs of comma operator. Test for no sideeffect
|
||||
expressions here and always build a convert expr.
|
||||
* init.c (expand_default_init): Convert the init to void.
|
||||
* typeck.c (build_x_compound_expr): Do not check for side effects
|
||||
here.
|
||||
(build_compound_expr): Do not convert lhs when building a
|
||||
template.
|
||||
|
||||
2003-08-15 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* cp-tree.def (NON_DEPENDENT_EXPR): Add operand.
|
||||
|
21
gcc/cp/cvt.c
21
gcc/cp/cvt.c
@ -812,8 +812,12 @@ convert_to_void (tree expr, const char *implicit)
|
||||
/* The two parts of a cond expr might be separate lvalues. */
|
||||
tree op1 = TREE_OPERAND (expr,1);
|
||||
tree op2 = TREE_OPERAND (expr,2);
|
||||
tree new_op1 = convert_to_void (op1, implicit);
|
||||
tree new_op2 = convert_to_void (op2, implicit);
|
||||
tree new_op1 = convert_to_void
|
||||
(op1, (implicit && !TREE_SIDE_EFFECTS (op2)
|
||||
? "second operand of conditional" : NULL));
|
||||
tree new_op2 = convert_to_void
|
||||
(op2, (implicit && !TREE_SIDE_EFFECTS (op1)
|
||||
? "third operand of conditional" : NULL));
|
||||
|
||||
expr = build (COND_EXPR, TREE_TYPE (new_op1),
|
||||
TREE_OPERAND (expr, 0), new_op1, new_op2);
|
||||
@ -824,7 +828,8 @@ convert_to_void (tree expr, const char *implicit)
|
||||
{
|
||||
/* The second part of a compound expr contains the value. */
|
||||
tree op1 = TREE_OPERAND (expr,1);
|
||||
tree new_op1 = convert_to_void (op1, implicit);
|
||||
tree new_op1 = convert_to_void
|
||||
(op1, implicit ? "right-hand operand of comma" : NULL);
|
||||
|
||||
if (new_op1 != op1)
|
||||
{
|
||||
@ -901,13 +906,9 @@ convert_to_void (tree expr, const char *implicit)
|
||||
|
||||
if (expr != error_mark_node && !VOID_TYPE_P (TREE_TYPE (expr)))
|
||||
{
|
||||
/* FIXME: This is where we should check for expressions with no
|
||||
effects. At the moment we do that in both build_x_component_expr
|
||||
and expand_expr_stmt -- inconsistently too. For the moment
|
||||
leave implicit void conversions unadorned so that expand_expr_stmt
|
||||
has a chance of detecting some of the cases. */
|
||||
if (!implicit)
|
||||
expr = build1 (CONVERT_EXPR, void_type_node, expr);
|
||||
if (implicit && !TREE_SIDE_EFFECTS (expr) && warn_unused_value)
|
||||
warning ("%s has no effect", implicit);
|
||||
expr = build1 (CONVERT_EXPR, void_type_node, expr);
|
||||
}
|
||||
return expr;
|
||||
}
|
||||
|
@ -1229,7 +1229,7 @@ expand_default_init (tree binfo, tree true_exp, tree exp, tree init, int flags)
|
||||
|
||||
rval = build_special_member_call (exp, ctor_name, parms, binfo, flags);
|
||||
if (TREE_SIDE_EFFECTS (rval))
|
||||
finish_expr_stmt (rval);
|
||||
finish_expr_stmt (convert_to_void (rval, NULL));
|
||||
}
|
||||
|
||||
/* This function is responsible for initializing EXP with INIT
|
||||
|
@ -4296,21 +4296,7 @@ build_x_compound_expr (tree op1, tree op2)
|
||||
|
||||
result = build_new_op (COMPOUND_EXPR, LOOKUP_NORMAL, op1, op2, NULL_TREE);
|
||||
if (!result)
|
||||
{
|
||||
if (! TREE_SIDE_EFFECTS (op1))
|
||||
{
|
||||
/* FIXME: This test should be in the implicit cast to void
|
||||
of the LHS. */
|
||||
/* the left-hand operand of a comma expression is like an expression
|
||||
statement: we should warn if it doesn't have any side-effects,
|
||||
unless it was explicitly cast to (void). */
|
||||
if (warn_unused_value
|
||||
&& !(TREE_CODE (op1) == CONVERT_EXPR
|
||||
&& VOID_TYPE_P (TREE_TYPE (op1))))
|
||||
warning("left-hand operand of comma expression has no effect");
|
||||
}
|
||||
result = build_compound_expr (op1, op2);
|
||||
}
|
||||
result = build_compound_expr (op1, op2);
|
||||
|
||||
if (processing_template_decl && result != error_mark_node)
|
||||
return build_min (COMPOUND_EXPR, TREE_TYPE (result),
|
||||
@ -4323,18 +4309,22 @@ build_x_compound_expr (tree op1, tree op2)
|
||||
tree
|
||||
build_compound_expr (tree lhs, tree rhs)
|
||||
{
|
||||
lhs = decl_constant_value (lhs);
|
||||
lhs = convert_to_void (lhs, "left-hand operand of comma");
|
||||
if (!processing_template_decl)
|
||||
{
|
||||
lhs = decl_constant_value (lhs);
|
||||
lhs = convert_to_void (lhs, "left-hand operand of comma");
|
||||
}
|
||||
|
||||
if (lhs == error_mark_node || rhs == error_mark_node)
|
||||
return error_mark_node;
|
||||
|
||||
|
||||
if (TREE_CODE (rhs) == TARGET_EXPR)
|
||||
{
|
||||
/* If the rhs is a TARGET_EXPR, then build the compound
|
||||
expression inside the target_expr's initializer. This
|
||||
helps the compiler to eliminate unncessary temporaries. */
|
||||
tree init = TREE_OPERAND (rhs, 1);
|
||||
|
||||
|
||||
init = build (COMPOUND_EXPR, TREE_TYPE (init), lhs, init);
|
||||
TREE_OPERAND (rhs, 1) = init;
|
||||
|
||||
|
14
gcc/stmt.c
14
gcc/stmt.c
@ -2152,17 +2152,13 @@ expand_expr_stmt_value (tree exp, int want_value, int maybe_last)
|
||||
except for last statement in ({...}) where they may be useful. */
|
||||
if (! want_value
|
||||
&& (expr_stmts_for_value == 0 || ! maybe_last)
|
||||
&& exp != error_mark_node)
|
||||
&& exp != error_mark_node
|
||||
&& warn_unused_value)
|
||||
{
|
||||
if (! TREE_SIDE_EFFECTS (exp))
|
||||
{
|
||||
if (warn_unused_value
|
||||
&& !(TREE_CODE (exp) == CONVERT_EXPR
|
||||
&& VOID_TYPE_P (TREE_TYPE (exp))))
|
||||
warning ("%Hstatement with no effect", &emit_locus);
|
||||
}
|
||||
else if (warn_unused_value)
|
||||
if (TREE_SIDE_EFFECTS (exp))
|
||||
warn_if_unused_value (exp);
|
||||
else if (!VOID_TYPE_P (TREE_TYPE (exp)))
|
||||
warning ("%Hstatement with no effect", &emit_locus);
|
||||
}
|
||||
|
||||
/* If EXP is of function type and we are expanding statements for
|
||||
|
@ -1,3 +1,8 @@
|
||||
2003-08-16 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
PR C++/11512
|
||||
* g++.dg/template/warn1.C: New.
|
||||
|
||||
2003-08-15 Nathan Sidwell <nathan@codesourcery.com>
|
||||
|
||||
* g++.dg/template/error2.C: New test.
|
||||
|
36
gcc/testsuite/g++.dg/template/warn1.C
Normal file
36
gcc/testsuite/g++.dg/template/warn1.C
Normal file
@ -0,0 +1,36 @@
|
||||
// { dg-do compile }
|
||||
// { dg-options "-Wall" }
|
||||
|
||||
// Copyright (C) 2003 Free Software Foundation, Inc.
|
||||
// Contributed by Nathan Sidwell 14 Aug 2003 <nathan@codesourcery.com>
|
||||
|
||||
// PR 11512. erroneous warnings
|
||||
|
||||
template <class T> void Foo(T i)
|
||||
{
|
||||
i++, i++;
|
||||
i, i++; // { dg-warning "left-hand operand" "" }
|
||||
i++, i; // { dg-warning "right-hand operand" "" }
|
||||
for (;; --i, ++i)
|
||||
;
|
||||
}
|
||||
|
||||
void Bar ()
|
||||
{
|
||||
Foo (1); // { dg-error "instantiated" "" }
|
||||
}
|
||||
|
||||
struct M {};
|
||||
|
||||
struct C
|
||||
{
|
||||
M m;
|
||||
C () :m (M ()) {}
|
||||
};
|
||||
|
||||
|
||||
void Baz (int i)
|
||||
{
|
||||
i ? i + 1 : i + 2; // { dg-error "operand of" "" }
|
||||
i ? i++ : 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user