On Sun, Jun 22, 2014 at 10:33:57PM +0200, Gerald Pfeifer wrote: > On Mon, 2 Jun 2014, Marek Polacek wrote: > > * c-typeck.c (parser_build_binary_op): Warn when logical not is used > > on the left hand side operand of a comparison. > > This... > > > +/* Warn about logical not used on the left hand side operand of a > > comparison. > > ...and this... > > > + warning_at (location, OPT_Wlogical_not_parentheses, > > + "logical not is only applied to the left hand side of " > > + "comparison"); > > ...does not appear consistent with the actual warning. > > Why does that warning say "is _ONLY_ applied to the left hand side"? > > Based on the message, I naively assumed that the code should not warn > about > > int same(int a, int b) { > return !a == !b; > } > > alas this is not the case. (Code like this occurs in Wine where > bool types are emulated and !!a or a comparison like above ensure > that those emulated bools are normalized to either 0 or 1.) > > > I understand there is ambiguity in cases like > > return !a == b; > > where the warning would be approriately worded and the programmer > might have intended !(a == b). > > > I do recommend to either omit "only" from the text of the warning > or not warn for cases where ! occurs on both sides of the comparison > (and keep the text as is).
I think the latter is better, incidentally, g++ doesn't warn either. The following one liner makes cc1 behave as cc1plus. Thanks for the report. Regtested/bootstrapped on x86_64. Joseph, is this ok? 2014-06-23 Marek Polacek <pola...@redhat.com> * c-typeck.c (parser_build_binary_op): Don't call warn_logical_not_parentheses if the RHS is TRUTH_NOT_EXPR. * c-c++-common/pr49706-2.c: New test. diff --git gcc/c/c-typeck.c gcc/c/c-typeck.c index 63bd65e..0764630 100644 --- gcc/c/c-typeck.c +++ gcc/c/c-typeck.c @@ -3402,7 +3402,8 @@ parser_build_binary_op (location_t location, enum tree_code code, code1, arg1.value, code2, arg2.value); if (warn_logical_not_paren - && code1 == TRUTH_NOT_EXPR) + && code1 == TRUTH_NOT_EXPR + && code2 != TRUTH_NOT_EXPR) warn_logical_not_parentheses (location, code, arg1.value, arg2.value); /* Warn about comparisons against string literals, with the exception diff --git gcc/testsuite/c-c++-common/pr49706-2.c gcc/testsuite/c-c++-common/pr49706-2.c index e69de29..09cc9eb 100644 --- gcc/testsuite/c-c++-common/pr49706-2.c +++ gcc/testsuite/c-c++-common/pr49706-2.c @@ -0,0 +1,20 @@ +/* { dg-do compile } */ +/* { dg-options "-Wlogical-not-parentheses" } */ + +/* Test that we don't warn if both operands of the comparison + are negated. */ + +#ifndef __cplusplus +#define bool _Bool +#endif + +bool r; + +int +same (int a, int b) +{ + r = !a == !b; + r = !!a == !!b; + r = !!a == !b; + r = !a == !!b; +} Marek