On 09/05/16 14:03, Marek Polacek wrote: > On Fri, Sep 02, 2016 at 03:51:49PM +0000, Bernd Edlinger wrote: >> Hi, >> >> > + r += !a == ~b; >> > + r += !a == ~(int) b; >> >> I don't understand why ~b should not be warned at -Wall. > > Yeah, there was an RFE for this but I'm not finding it. >
I certainly agree that the warning is compeletely misleading here: test.c: In function 'f': test.c:10:11: warning: logical not is only applied to the left hand side of comparison [-Wlogical-not-parentheses] r += !a == ~b; ^~ test.c:10:8: note: add parentheses around left hand side expression to silence this warning r += !a == ~b; ^~ ( ) this will not fix it, but make it worse. I think a better warning would be warning: ~ on boolean value, did you mean ! ? >> Frankly I don't even understand why the above statements are >> completely optimized away. >> >> r += !a == ~b; >> is optimized away, but >> >> b = ~b; >> r += !a == b; >> >> Is not. Why? > > Something in ccp I suppose. But I didn't investigate closely because > it's not really relevant to this patch, sorry. > Yes, I think the problem is that ~ on bool maps [0:1] to [-1:-2] and thus the result is no longer boolean. But probaby the assignment normalizes the result again: b = ~b; has the effect of setting b = 1. A warning for "~ on boolean" would not be too difficult, but making a fix-it will probably need more work: Index: gcc/c/c-typeck.c =================================================================== --- gcc/c/c-typeck.c (revision 239971) +++ gcc/c/c-typeck.c (working copy) @@ -4192,6 +4192,17 @@ build_unary_op (location_t location, break; case BIT_NOT_EXPR: + { + tree e = arg; + + /* Warn if the condition has boolean value. */ + while (TREE_CODE (e) == COMPOUND_EXPR) + e = TREE_OPERAND (e, 1); + + if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE + || truth_value_p (TREE_CODE (e))) + warning(0, "~ on boolean value, did you mean ! ?"); + } /* ~ works on integer types and non float vectors. */ if (typecode == INTEGER_TYPE || (typecode == VECTOR_TYPE Index: gcc/cp/typeck.c =================================================================== --- gcc/cp/typeck.c (revision 239971) +++ gcc/cp/typeck.c (working copy) @@ -5839,6 +5839,8 @@ cp_build_unary_op (enum tree_code code, tree xarg, break; case BIT_NOT_EXPR: + if (TREE_CODE (TREE_TYPE (arg)) == BOOLEAN_TYPE) + warning (0, "~ on boolean value, did you mean ! ?"); if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE) { code = CONJ_EXPR; Bernd.