https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77423
Bug ID: 77423 Summary: -Wlogical-not-parentheses false positive for bitwise expression with _Bool operands Product: gcc Version: 7.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: msebor at gcc dot gnu.org Target Milestone: --- -Wlogical-not-parentheses option is documented as follows: Warn about logical not used on the left hand side operand of a comparison. This option does not warn if the RHS operand is of a boolean type. Thanks to integer promotions there's a bit of a mismatch between the specification and the implementation in GCC when operands of type _Bool are involved. In C, _Bool operands are promoted to int so the RHS operand's type is never _Bool, but it may be Boolean in nature. The mismatch is due to the documentation failing to spell out what GCC considers a "boolean type" in this context. This came up during the review of the fix for bug 77292 where it was observed that the warning is issued for bitwise expressions and not for logical expressions involving _Bool operands. The following test case shows the inconsistency. The type of both of the RHS operands of the equality expressions is int and not _Bool, yet only the one involving the bitwise OR is diagnosed even though with _Bool operands they are equivalent and often used interchangeably. I think the warning should not be issued for this case or any case where the operand can be considered to be Boolean (i.e., it's the result of either logical or bitwise expression on all Boolean operands). As a separate issue, the documentation should avoid referring to the type of the RHS operand (since its type need not be _Bool). Instead, it could say something like "this option does not warn if the right operand is considered to be a Boolean expression." $ cat t.c && /build/gcc-trunk/gcc/xgcc -B /build/gcc-trunk/gcc -S -Wlogical-not-parentheses t.c _Bool f (int a, _Bool b, _Bool c) { _Bool r; r = !a == (b || c); // no warning (okay) r = !a == (b | c); // warning (unexpected) return r; } t.c: In function âfâ: t.c:6:10: warning: logical not is only applied to the left hand side of comparison [-Wlogical-not-parentheses] r = !a == (b | c); // warning (unexpected) ^~ t.c:6:7: note: add parentheses around left hand side expression to silence this warning r = !a == (b | c); // warning (unexpected) ^~ ( )