The following code, when compiled with -Wall, gives the warning "value computed is not used". The value is in fact used, thus the warning is bogus. #include <stdio.h> #include <complex.h> int main() { double _Complex x = 2.0 + I * 2.0; ++x; printf("%f,%f\n", creal(x), cimag(x)); } Output: gcc -Wall test.c test.c: In function ‘main’: test.c:7:2: warning: value computed is not used [-Wunused-value] 7 | ++x; | ^~~
Adjusted testcase: /* PR c/97748 */ /* { dg-do compile } */ /* { dg-options "-Wunused-value" } */ double _Complex foo (double _Complex x) { ++x; /* { dg-bogus "value computed is not used" } */ return x; } double _Complex bar (double _Complex x) { --x; /* { dg-bogus "value computed is not used" } */ return x; } The tree that is not used is a COMPLEX_EXPR: (void) COMPLEX_EXPR < ++REALPART_EXPR <x>, IMAGPART_EXPR <x>> which would be used only if the result of the post increment or decrement would be actually used. So, either we should mark the COMPLEX_EXPR created for the pre-increments TREE_NO_WARNING, or the -Wunused-value would need to look through the COMPLEX_EXPR.
Untested WIP patch, though C++ FE needs some extra work: --- gcc/c-family/c-common.h.jj 2020-11-03 11:15:07.170681001 +0100 +++ gcc/c-family/c-common.h 2020-11-07 09:37:48.597233063 +0100 @@ -1362,7 +1362,7 @@ extern void warn_tautological_cmp (const tree, tree); extern void warn_logical_not_parentheses (location_t, enum tree_code, tree, tree); -extern bool warn_if_unused_value (const_tree, location_t); +extern bool warn_if_unused_value (const_tree, location_t, bool = false); extern bool strict_aliasing_warning (location_t, tree, tree); extern void sizeof_pointer_memaccess_warning (location_t *, tree, vec<tree, va_gc> *, tree *, --- gcc/c-family/c-warn.c.jj 2020-10-26 10:53:56.533885147 +0100 +++ gcc/c-family/c-warn.c 2020-11-07 09:40:51.011170825 +0100 @@ -585,7 +585,7 @@ warn_logical_not_parentheses (location_t (potential) location of the expression. */ bool -warn_if_unused_value (const_tree exp, location_t locus) +warn_if_unused_value (const_tree exp, location_t locus, bool quiet) { restart: if (TREE_USED (exp) || TREE_NO_WARNING (exp)) @@ -633,7 +633,7 @@ warn_if_unused_value (const_tree exp, lo goto restart; case COMPOUND_EXPR: - if (warn_if_unused_value (TREE_OPERAND (exp, 0), locus)) + if (warn_if_unused_value (TREE_OPERAND (exp, 0), locus, quiet)) return true; /* Let people do `(foo (), 0)' without a warning. */ if (TREE_CONSTANT (TREE_OPERAND (exp, 1))) @@ -648,6 +648,13 @@ warn_if_unused_value (const_tree exp, lo return false; goto warn; + case COMPLEX_EXPR: + /* Warn only if both operands are unused. */ + if (warn_if_unused_value (TREE_OPERAND (exp, 0), locus, true) + && warn_if_unused_value (TREE_OPERAND (exp, 1), locus, true)) + goto warn; + return false; + case INDIRECT_REF: /* Don't warn about automatic dereferencing of references, since the user cannot control it. */ @@ -671,6 +678,8 @@ warn_if_unused_value (const_tree exp, lo return false; warn: + if (quiet) + return true; return warning_at (locus, OPT_Wunused_value, "value computed is not used"); } } --- gcc/testsuite/c-c++-common/Wunused-value-1.c.jj 2020-11-07 09:51:46.407757100 +0100 +++ gcc/testsuite/c-c++-common/Wunused-value-1.c 2020-11-07 10:15:34.295574782 +0100 @@ -0,0 +1,33 @@ +/* PR c/97748 */ +/* { dg-do compile } */ +/* { dg-options "-Wunused-value" } */ + +double _Complex f (); +double _Complex *p; + +double _Complex +foo (double _Complex x) +{ + ++x; /* { dg-bogus "value computed is not used" } */ + --x; /* { dg-bogus "value computed is not used" } */ + x += 1; /* { dg-bogus "value computed is not used" } */ + x += 1.0iF; /* { dg-bogus "value computed is not used" } */ + x++; /* { dg-bogus "value computed is not used" } */ + x--; /* { dg-bogus "value computed is not used" } */ + x + 1; /* { dg-warning "value computed is not used" } */ + (void) (x + 1); /* { dg-bogus "value computed is not used" } */ + 1 + f (); /* { dg-warning "value computed is not used" } */ + f () + f (); /* { dg-warning "value computed is not used" } */ + f () + f (), f (); /* { dg-warning "value computed is not used" } */ + f (); + (void) f (); + *p++; /* { dg-warning "value computed is not used" } */ + ++*p; /* { dg-bogus "value computed is not used" } */ + (*p ? f () : 0); + ({ f (); }); + ({ f () + 1; }); + ({ f (); 0; }); + ({ f () + 1; 0; }); /* { dg-warning "value computed is not used" } */ + 1 + ({ f (); }); /* { dg-warning "value computed is not used" } */ + return x; +}
The master branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>: https://gcc.gnu.org/g:0000ea4fb4eaacbd2c954d78d7f8e9f03c7be739 commit r11-4878-g0000ea4fb4eaacbd2c954d78d7f8e9f03c7be739 Author: Jakub Jelinek <jakub@redhat.com> Date: Tue Nov 10 15:56:20 2020 +0100 c, c++: Fix up -Wunused-value on COMPLEX_EXPRs [PR97748] The -Wunused-value warning in both C and C++ FEs (implemented significantly differently between the two) sees the COMPLEX_EXPRs created e.g. for complex pre/post increment and many other expressions as useless and warns about it. For the C warning implementation, on e.g. COMPLEX_EXPR < ++REALPART_EXPR <x>, IMAGPART_EXPR <x>>; would warn even on the IMAGPART_EXPR <x> there alone etc., so what works is check if we'd warn about both operands of COMPLEX_EXPR and if yes, warn on the whole COMPLEX_EXPR, otherwise don't warn. The C++ warning implementation is significantly different and for that one the only warn if both would be warned about doesn't really work, we then miss warnings e.g. about COMPLEX_EXPR <REALPART_EXPR <SAVE_EXPR <x>> + 1.0e+0, IMAGPART_EXPR <SAVE_EXPR <x>>> >>>>> The patch replaces the warning_at call with call to the c-family warn_if_unused_value function. On the testcase which after the initial new tests contains pretty much everything from gcc.dg/Wunused-value-1.c both approaches seem to work nicely. 2020-11-10 Jakub Jelinek <jakub@redhat.com> PR c/97748 gcc/c-family/ * c-common.h (warn_if_unused_value): Add quiet argument defaulted to false. * c-warn.c (warn_if_unused_value): Likewise. Pass it down recursively and just return true instead of warning if it is true. Handle COMPLEX_EXPR. gcc/cp/ * cvt.c (convert_to_void): Check (complain & tf_warning) in the outer if rather than twice times in the inner one. Use warn_if_unused_value. Formatting fix. gcc/testsuite/ * c-c++-common/Wunused-value-1.c: New test.
The releases/gcc-10 branch has been updated by Jakub Jelinek <jakub@gcc.gnu.org>: https://gcc.gnu.org/g:9d488c191c62cb114fa40239c495ac773ff76751 commit r10-9011-g9d488c191c62cb114fa40239c495ac773ff76751 Author: Jakub Jelinek <jakub@redhat.com> Date: Tue Nov 10 15:56:20 2020 +0100 c, c++: Fix up -Wunused-value on COMPLEX_EXPRs [PR97748] The -Wunused-value warning in both C and C++ FEs (implemented significantly differently between the two) sees the COMPLEX_EXPRs created e.g. for complex pre/post increment and many other expressions as useless and warns about it. For the C warning implementation, on e.g. COMPLEX_EXPR < ++REALPART_EXPR <x>, IMAGPART_EXPR <x>>; would warn even on the IMAGPART_EXPR <x> there alone etc., so what works is check if we'd warn about both operands of COMPLEX_EXPR and if yes, warn on the whole COMPLEX_EXPR, otherwise don't warn. The C++ warning implementation is significantly different and for that one the only warn if both would be warned about doesn't really work, we then miss warnings e.g. about COMPLEX_EXPR <REALPART_EXPR <SAVE_EXPR <x>> + 1.0e+0, IMAGPART_EXPR <SAVE_EXPR <x>>> >>>>> The patch replaces the warning_at call with call to the c-family warn_if_unused_value function. On the testcase which after the initial new tests contains pretty much everything from gcc.dg/Wunused-value-1.c both approaches seem to work nicely. 2020-11-10 Jakub Jelinek <jakub@redhat.com> PR c/97748 gcc/c-family/ * c-common.h (warn_if_unused_value): Add quiet argument defaulted to false. * c-warn.c (warn_if_unused_value): Likewise. Pass it down recursively and just return true instead of warning if it is true. Handle COMPLEX_EXPR. gcc/cp/ * cvt.c (convert_to_void): Check (complain & tf_warning) in the outer if rather than twice times in the inner one. Use warn_if_unused_value. Formatting fix. gcc/testsuite/ * c-c++-common/Wunused-value-1.c: New test. (cherry picked from commit 0000ea4fb4eaacbd2c954d78d7f8e9f03c7be739)
Fixed for 10.3+.