In this PR the problem was that the C FE, unlike the C++ FE, didn't warn on e.g. bar (), 1;, that the RHS has no effect. This patch tries to tweak the C FE so that it follows what the C++ FE does. Note that the C++ FE uses quite imprecise locus info; the C FE's info is better. I had to slightly adjust one testcase and a header in libdecnumber.
Regtested/bootstrapped on x86_64-linux, ok for trunk? 2014-01-21 Marek Polacek <pola...@redhat.com> PR c/59871 c/ * c-typeck.c (build_compound_expr): Warn even for right-hand operand of comma expression. (emit_side_effect_warnings): Likewise. libdecnumber/ * decNumberLocal.h (UBFROMUS, UBFROMUI): Cast last argument to void. testsuite/ * gcc.dg/20020220-2.c: Adjust dg-warning message. * gcc.dg/pr59871.c: New test. --- gcc/libdecnumber/decNumberLocal.h.mp 2014-01-21 18:34:32.235540589 +0100 +++ gcc/libdecnumber/decNumberLocal.h 2014-01-21 19:04:12.173243034 +0100 @@ -155,8 +155,10 @@ see the files COPYING3 and COPYING.RUNTI /* Store a uInt, etc., into bytes starting at a char* or uByte*. */ /* Returns i, evaluated, for convenience; has to use uiwork because */ /* i may be an expression. */ - #define UBFROMUS(b, i) (uswork=(i), memcpy(b, (void *)&uswork, 2), uswork) - #define UBFROMUI(b, i) (uiwork=(i), memcpy(b, (void *)&uiwork, 4), uiwork) + #define UBFROMUS(b, i) (uswork=(i), memcpy(b, (void *)&uswork, 2), \ + (void)uswork) + #define UBFROMUI(b, i) (uiwork=(i), memcpy(b, (void *)&uiwork, 4), \ + (void)uiwork) /* X10 and X100 -- multiply integer i by 10 or 100 */ /* [shifts are usually faster than multiply; could be conditional] */ --- gcc/gcc/c/c-typeck.c.mp 2014-01-21 11:59:33.221215248 +0100 +++ gcc/gcc/c/c-typeck.c 2014-01-21 18:10:53.900279750 +0100 @@ -4757,6 +4757,18 @@ build_compound_expr (location_t loc, tre expr2 = TREE_OPERAND (expr2, 0); } + if (TREE_CODE (expr1) == COMPOUND_EXPR + && warn_unused_value) + { + tree r = expr1; + while (TREE_CODE (r) == COMPOUND_EXPR) + r = TREE_OPERAND (r, 1); + if (!TREE_SIDE_EFFECTS (r) + && !VOID_TYPE_P (TREE_TYPE (r)) + && !CONVERT_EXPR_P (r)) + warning_at (loc, OPT_Wunused_value, + "right-hand operand of comma expression has no effect"); + } if (!TREE_SIDE_EFFECTS (expr1)) { /* The left-hand operand of a comma expression is like an expression @@ -9641,6 +9653,18 @@ emit_side_effect_warnings (location_t lo if (!VOID_TYPE_P (TREE_TYPE (expr)) && !TREE_NO_WARNING (expr)) warning_at (loc, OPT_Wunused_value, "statement with no effect"); } + else if (TREE_CODE (expr) == COMPOUND_EXPR) + { + tree r = expr; + while (TREE_CODE (r) == COMPOUND_EXPR) + r = TREE_OPERAND (r, 1); + if (!TREE_SIDE_EFFECTS (r) + && !VOID_TYPE_P (TREE_TYPE (r)) + && !CONVERT_EXPR_P (r) + && !TREE_NO_WARNING (expr)) + warning_at (EXPR_LOC_OR_LOC (expr, loc), OPT_Wunused_value, + "right-hand operand of comma expression has no effect"); + } else warn_if_unused_value (expr, loc); } --- gcc/gcc/testsuite/gcc.dg/20020220-2.c.mp 2014-01-21 14:47:58.888754509 +0100 +++ gcc/gcc/testsuite/gcc.dg/20020220-2.c 2014-01-21 15:04:53.700441224 +0100 @@ -1,5 +1,5 @@ /* PR c/4697 - Test whether value computed not used warning is given for compound + Test whether operand has no effect warning is given for compound expression. */ /* { dg-do compile } */ /* { dg-options "-O2 -Wunused" } */ @@ -7,6 +7,6 @@ int b; int foo (int a) { - a = a + 1, 5 * b; /* { dg-warning "value computed is not used" } */ + a = a + 1, 5 * b; /* { dg-warning "right operand of comma operator has no effect" } */ return a; } --- gcc/gcc/testsuite/gcc.dg/pr59871.c.mp 2014-01-21 16:17:49.000000000 +0100 +++ gcc/gcc/testsuite/gcc.dg/pr59871.c 2014-01-21 16:13:39.000000000 +0100 @@ -0,0 +1,15 @@ +/* PR c/59871 */ +/* { dg-do compile } */ +/* { dg-options "-Wunused" } */ + +extern int bar (); + +void +foo (int *p) +{ + p[0] = (bar (), 1, bar ()); /* { dg-warning "right-hand operand of comma expression has no effect" } */ + p[1] = (1, bar ()); /* { dg-warning "left-hand operand of comma expression has no effect" } */ + bar (), 1, bar (); /* { dg-warning "right-hand operand of comma expression has no effect" } */ + bar (), 1; /* { dg-warning "right-hand operand of comma expression has no effect" } */ + 1, bar (); /* { dg-warning "left-hand operand of comma expression has no effect" } */ +} Marek