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.

Reply via email to