Re: [C/C++ PATCH] -Wlogical-not-parentheses tweaks (PR c/65120)

2015-02-20 Thread Marek Polacek
On Fri, Feb 20, 2015 at 01:03:26AM +0100, Jakub Jelinek wrote:
> Hi!
> 
> As reported, !!x == y is quite common in the Linux kernel
> and unlike the !x == y case it usually doesn't mean mistyped
> !(x == y) or x != y.  clang++ apparently doesn't warn about that
> either, and it doesn't warn even about the case where ! is applied
> to a bool.

Note that first version of -Wlogical-not-parentheses didn't warn
when LHS had a boolean type, this has been changed later on.  I have
no strong preference either way.

> As the argument is already folded, it isn't easy to determine
> those cases always, but I hope the following is sufficient until we switch
> to late folding.
 
Yes, this means that we warn for

  return !(a != 0) == b;

but not for

  return !(a == 0) == b;

I think we can live with that for now.

> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
> 
> 2015-02-19  Jakub Jelinek  
> 
>   PR c/65120
>   * c-typeck.c (parser_build_binary_op): Don't warn for
>   !!x == y or !b == y where b is _Bool.
> 
>   * parser.c (cp_parser_binary_expression): Don't warn for
>   !!x == y or !b == y where b is bool.
> 
>   * c-c++-common/pr49706.c: Adjust tests for not warning
>   about !!x == y or !b == y where b is boolean, and add
>   some further tests.
>   * c-c++-common/pr62199-2.c: Likewise.

The C part is ok.  Maybe we should also update the docs to reflect that
-Wlogical-not-parentheses does not warn if the RHS *or LHS* operand is of
a boolean type.  Thanks,

Marek


Re: [C/C++ PATCH] -Wlogical-not-parentheses tweaks (PR c/65120)

2015-02-20 Thread Jakub Jelinek
On Fri, Feb 20, 2015 at 04:35:05PM +0100, Marek Polacek wrote:
> Note that first version of -Wlogical-not-parentheses didn't warn
> when LHS had a boolean type, this has been changed later on.  I have
> no strong preference either way.
> 
> > As the argument is already folded, it isn't easy to determine
> > those cases always, but I hope the following is sufficient until we switch
> > to late folding.
>  
> Yes, this means that we warn for
> 
>   return !(a != 0) == b;
> 
> but not for
> 
>   return !(a == 0) == b;
> 
> I think we can live with that for now.

Well, for the !! case another option is, as we at least in the C++ FE
peek at the first token if it is !, peek another token if it is ! too.
Then we would warn for !(!a) == b and would not warn for !!a == b.
Guess that would be fine too.
For the ! of bool, if we want to detect that case (have done that primarily
because clang++ does that (clang doesn't support
-Wlogical-not-parentheses)), for C because of the conversion to int it is
still more likely we catch it, but for C++ we'd need to parse the expression
twice or do similar uglities.
For everything the answer is of course less folding early, but it will take
some time.

> The C part is ok.  Maybe we should also update the docs to reflect that
> -Wlogical-not-parentheses does not warn if the RHS *or LHS* operand is of
> a boolean type.  Thanks,

RHS operand or operand of ! on the LHS to be precise, though that is not
what is implemented for C++ right now, e.g. !(a > 20) == 0 shouldn't warn
in C++ because a > 20 is bool, but it is really hard after the folding to
find out what was the original ! operand.
Though of course, it would be weird if we don't warn for !(a > 20) == 0
for C (where a > 20 is not _Bool) but do warn for C++ (where it is bool).

If preferred, I can do just the !! case that in theory should be reliably
detected, and warn for everything else.

Jakub


Re: [C/C++ PATCH] -Wlogical-not-parentheses tweaks (PR c/65120)

2015-02-27 Thread Jason Merrill

On 02/19/2015 07:03 PM, Jakub Jelinek wrote:

+ /* Avoid warning for !!b == y where b is boolean.  */
+ && (!DECL_P (current.lhs)
+ || TREE_TYPE (current.lhs) == NULL_TREE
+ || TREE_CODE (TREE_TYPE (current.lhs)) != BOOLEAN_TYPE))


There's something wrong here.  If the type is null, trying to check its 
TREE_CODE will SEGV.


Jason



Re: [C/C++ PATCH] -Wlogical-not-parentheses tweaks (PR c/65120)

2015-03-09 Thread Jakub Jelinek
On Fri, Feb 27, 2015 at 05:29:47PM -0500, Jason Merrill wrote:
> On 02/19/2015 07:03 PM, Jakub Jelinek wrote:
> >+  /* Avoid warning for !!b == y where b is boolean.  */
> >+  && (!DECL_P (current.lhs)
> >+  || TREE_TYPE (current.lhs) == NULL_TREE
> >+  || TREE_CODE (TREE_TYPE (current.lhs)) != BOOLEAN_TYPE))
> 
> There's something wrong here.  If the type is null, trying to check its
> TREE_CODE will SEGV.

If the type is NULL, then it will just call warn_logical_not_parentheses
and won't check TREE_CODE.  Only when it is non-NULL, it will check
TREE_CODE and if it is not BOOLEAN_TYPE, will call
warn_logical_not_parentheses.

Jakub


Re: [C/C++ PATCH] -Wlogical-not-parentheses tweaks (PR c/65120)

2015-03-09 Thread Jason Merrill

On 03/09/2015 10:34 AM, Jakub Jelinek wrote:

On Fri, Feb 27, 2015 at 05:29:47PM -0500, Jason Merrill wrote:

On 02/19/2015 07:03 PM, Jakub Jelinek wrote:

+ /* Avoid warning for !!b == y where b is boolean.  */
+ && (!DECL_P (current.lhs)
+ || TREE_TYPE (current.lhs) == NULL_TREE
+ || TREE_CODE (TREE_TYPE (current.lhs)) != BOOLEAN_TYPE))


There's something wrong here.  If the type is null, trying to check its
TREE_CODE will SEGV.


If the type is NULL, then it will just call warn_logical_not_parentheses
and won't check TREE_CODE.  Only when it is non-NULL, it will check
TREE_CODE and if it is not BOOLEAN_TYPE, will call
warn_logical_not_parentheses.


You're right, of course.  I guess I was reading the || as an &&.  The 
patch is OK.


Jason