Re: [PATCH] c/c++: new warning: -Wxor-used-as-pow [PR90885]

2022-09-02 Thread David Malcolm via Gcc-patches
On Tue, 2022-08-30 at 16:40 -0400, Marek Polacek wrote:
> This looks good to me, one thing though:
> 
> On Thu, Aug 11, 2022 at 09:38:12PM -0400, David Malcolm via Gcc-
> patches wrote:
> > --- a/gcc/c-family/c.opt
> > +++ b/gcc/c-family/c.opt
> > @@ -1439,6 +1439,10 @@ Wwrite-strings
> >  C ObjC C++ ObjC++ Var(warn_write_strings) Warning
> >  In C++, nonzero means warn about deprecated conversion from string
> > literals to 'char *'.  In C, similar warning, except that the
> > conversion is of course not deprecated by the ISO C standard.
> >  
> > +Wxor-used-as-pow
> > +C C++ Common Var(warn_xor_used_as_pow) Warning Init(1)
> 
> This doesn't include ObjC/ObjC++, but...

I added ObjC/ObjC++ (and dropped Common), and retested it (and tested
it with -xobjective-c and -xobjective-c++);  I've pushed it to trunk as
r13-2386-gbedfca647a9e9c.

Thanks
Dave



Re: [PATCH] c/c++: new warning: -Wxor-used-as-pow [PR90885]

2022-08-30 Thread Marek Polacek via Gcc-patches
This looks good to me, one thing though:

On Thu, Aug 11, 2022 at 09:38:12PM -0400, David Malcolm via Gcc-patches wrote:
> --- a/gcc/c-family/c.opt
> +++ b/gcc/c-family/c.opt
> @@ -1439,6 +1439,10 @@ Wwrite-strings
>  C ObjC C++ ObjC++ Var(warn_write_strings) Warning
>  In C++, nonzero means warn about deprecated conversion from string literals 
> to 'char *'.  In C, similar warning, except that the conversion is of course 
> not deprecated by the ISO C standard.
>  
> +Wxor-used-as-pow
> +C C++ Common Var(warn_xor_used_as_pow) Warning Init(1)

This doesn't include ObjC/ObjC++, but...

> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -414,6 +414,7 @@ Objective-C and Objective-C++ Dialects}.
>  -Wvector-operation-performance @gol
>  -Wvla  -Wvla-larger-than=@var{byte-size}  -Wno-vla-larger-than @gol
>  -Wvolatile-register-var  -Wwrite-strings @gol
> +-Wxor-used-as-pow @gol
>  -Wzero-length-bounds}
>  
>  @item Static Analyzer Options
> @@ -9661,6 +9662,20 @@ modifier does not inhibit all optimizations that may 
> eliminate reads
>  and/or writes to register variables.  This warning is enabled by
>  @option{-Wall}.
>  
> +@item -Wxor-used-as-pow @r{(C, C++, Objective-C and Objective-C++ only)}

...here it includes Objective-C and Objective-C++.

Marek



Re: [PATCH] c/c++: new warning: -Wxor-used-as-pow [PR90885]

2022-08-30 Thread Jason Merrill via Gcc-patches

On 8/11/22 21:38, David Malcolm via Gcc-patches wrote:

PR c/90885 notes various places in real-world code where people have
written C/C++ code that uses ^ (exclusive or) where presumbably they
meant exponentiation.

For example
   https://codesearch.isocpp.org/cgi-bin/cgi_ppsearch?q=2%5E32=Search
currently finds 11 places using "2^32", and all of them appear to be
places where the user means 2 to the power of 32, rather than 2
exclusive-orred with 32 (which is 34).

This patch adds a new -Wxor-used-as-pow warning to the C and C++
frontends to complain about ^ when the left-hand side is the decimal
constant 2 or the decimal constant 10.

This is the same name as the corresponding clang warning:
   https://clang.llvm.org/docs/DiagnosticsReference.html#wxor-used-as-pow

As per the clang warning, the warning suggests converting the left-hand
side to a hexadecimal constant if you really mean xor, which suppresses
the warning (and this patch implements a fix-it hint for that, whereas
the clang implementation only has a fix-it hint for the initial
suggestion of exponentiation).

I initially tried implementing this without checking for decimals, but
this version had lots of false positives.  Checking for decimals
requires extending the lexer to capture whether or not a CPP_NUMBER
token was decimal.  I added a new DECIMAL_INT flag to cpplib.h for this.
Unfortunately, c_token and cp_tokens both have only an unsigned char for
their flags (as captured by c_lex_with_flags), whereas this would add
the 12th flag to cpp_tokens.  Of the first 8 flags, all but BOL are used
in the C or C++ frontends, but BOL is not, so I moved that to a higher
position, using its old value for the new DECIMAL_INT flag, so that it
is representable within an unsigned char.

Example output:

demo.c:5:13: warning: result of '2^8' is 10; did you mean '1 << 8' (256)? 
[-Wxor-used-as-pow]
 5 | int t2_8 = 2^8;
   | ^
   |--
   |1<<
demo.c:5:12: note: you can silence this warning by using a hexadecimal constant 
(0x2 rather than 2)
 5 | int t2_8 = 2^8;
   |^
   |0x2
demo.c:21:15: warning: result of '10^6' is 12; did you mean '1e6'? 
[-Wxor-used-as-pow]
21 | int t10_6 = 10^6;
   |   ^
   | ---
   | 1e
demo.c:21:13: note: you can silence this warning by using a hexadecimal 
constant (0xa rather than 10)
21 | int t10_6 = 10^6;
   | ^~
   | 0xa

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.

OK for trunk?


Looks good to me, but a C maintainer should sign off on the C front-end 
changes.



Thanks
Dave


gcc/c-family/ChangeLog:
PR c/90885
* c-common.h (check_for_xor_used_as_pow): New decl.
* c-lex.cc (c_lex_with_flags): Add DECIMAL_INT to flags as appropriate.
* c-warn.cc (check_for_xor_used_as_pow): New.
* c.opt (Wxor-used-as-pow): New.

gcc/c/ChangeLog:
PR c/90885
* c-parser.cc (c_parser_string_literal): Clear ret.m_decimal.
(c_parser_expr_no_commas): Likewise.
(c_parser_conditional_expression): Likewise.
(c_parser_binary_expression): Clear m_decimal when popping the
stack.
(c_parser_unary_expression): Clear ret.m_decimal.
(c_parser_has_attribute_expression): Likewise for result.
(c_parser_predefined_identifier): Likewise for expr.
(c_parser_postfix_expression): Likewise for expr.
Set expr.m_decimal when handling a CPP_NUMBER that was a decimal
token.
* c-tree.h (c_expr::m_decimal): New bitfield.
* c-typeck.cc (parser_build_binary_op): Clear result.m_decimal.
(parser_build_binary_op): Call check_for_xor_used_as_pow.

gcc/cp/ChangeLog:
PR c/90885
* cp-tree.h (class cp_expr): Add bitfield m_decimal.  Clear it in
existing ctors.  Add ctor that allows specifying its value.
(cp_expr::decimal_p): New accessor.
* parser.cc (cp_parser_expression_stack_entry::flags): New field.
(cp_parser_primary_expression): Set m_decimal of cp_expr when
handling numbers.
(cp_parser_binary_expression): Extract flags from token when
populating stack.  Call check_for_xor_used_as_pow.

gcc/ChangeLog:
PR c/90885
* doc/invoke.texi (Warning Options): Add -Wxor-used-as-pow.

gcc/testsuite/ChangeLog:
PR c/90885
* c-c++-common/Wxor-used-as-pow-1.c: New test.
* c-c++-common/Wxor-used-as-pow-fixits.c: New test.
* g++.dg/parse/expr3.C: Convert 2 to 0x2 to suppress
-Wxor-used-as-pow.
* g++.dg/warn/Wparentheses-10.C: Likewise.
* g++.dg/warn/Wparentheses-18.C: Likewise.
* g++.dg/warn/Wparentheses-19.C: Likewise.
* g++.dg/warn/Wparentheses-9.C: Likewise.
* g++.dg/warn/Wxor-used-as-pow-named-op.C: New test.
* gcc.dg/Wparentheses-6.c: Convert 2 to 0x2 to suppress

[PATCH] c/c++: new warning: -Wxor-used-as-pow [PR90885]

2022-08-11 Thread David Malcolm via Gcc-patches
PR c/90885 notes various places in real-world code where people have
written C/C++ code that uses ^ (exclusive or) where presumbably they
meant exponentiation.

For example
  https://codesearch.isocpp.org/cgi-bin/cgi_ppsearch?q=2%5E32=Search
currently finds 11 places using "2^32", and all of them appear to be
places where the user means 2 to the power of 32, rather than 2
exclusive-orred with 32 (which is 34).

This patch adds a new -Wxor-used-as-pow warning to the C and C++
frontends to complain about ^ when the left-hand side is the decimal
constant 2 or the decimal constant 10.

This is the same name as the corresponding clang warning:
  https://clang.llvm.org/docs/DiagnosticsReference.html#wxor-used-as-pow

As per the clang warning, the warning suggests converting the left-hand
side to a hexadecimal constant if you really mean xor, which suppresses
the warning (and this patch implements a fix-it hint for that, whereas
the clang implementation only has a fix-it hint for the initial
suggestion of exponentiation).

I initially tried implementing this without checking for decimals, but
this version had lots of false positives.  Checking for decimals
requires extending the lexer to capture whether or not a CPP_NUMBER
token was decimal.  I added a new DECIMAL_INT flag to cpplib.h for this.
Unfortunately, c_token and cp_tokens both have only an unsigned char for
their flags (as captured by c_lex_with_flags), whereas this would add
the 12th flag to cpp_tokens.  Of the first 8 flags, all but BOL are used
in the C or C++ frontends, but BOL is not, so I moved that to a higher
position, using its old value for the new DECIMAL_INT flag, so that it
is representable within an unsigned char.

Example output:

demo.c:5:13: warning: result of '2^8' is 10; did you mean '1 << 8' (256)? 
[-Wxor-used-as-pow]
5 | int t2_8 = 2^8;
  | ^
  |--
  |1<<
demo.c:5:12: note: you can silence this warning by using a hexadecimal constant 
(0x2 rather than 2)
5 | int t2_8 = 2^8;
  |^
  |0x2
demo.c:21:15: warning: result of '10^6' is 12; did you mean '1e6'? 
[-Wxor-used-as-pow]
   21 | int t10_6 = 10^6;
  |   ^
  | ---
  | 1e
demo.c:21:13: note: you can silence this warning by using a hexadecimal 
constant (0xa rather than 10)
   21 | int t10_6 = 10^6;
  | ^~
  | 0xa

Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu.

OK for trunk?

Thanks
Dave


gcc/c-family/ChangeLog:
PR c/90885
* c-common.h (check_for_xor_used_as_pow): New decl.
* c-lex.cc (c_lex_with_flags): Add DECIMAL_INT to flags as appropriate.
* c-warn.cc (check_for_xor_used_as_pow): New.
* c.opt (Wxor-used-as-pow): New.

gcc/c/ChangeLog:
PR c/90885
* c-parser.cc (c_parser_string_literal): Clear ret.m_decimal.
(c_parser_expr_no_commas): Likewise.
(c_parser_conditional_expression): Likewise.
(c_parser_binary_expression): Clear m_decimal when popping the
stack.
(c_parser_unary_expression): Clear ret.m_decimal.
(c_parser_has_attribute_expression): Likewise for result.
(c_parser_predefined_identifier): Likewise for expr.
(c_parser_postfix_expression): Likewise for expr.
Set expr.m_decimal when handling a CPP_NUMBER that was a decimal
token.
* c-tree.h (c_expr::m_decimal): New bitfield.
* c-typeck.cc (parser_build_binary_op): Clear result.m_decimal.
(parser_build_binary_op): Call check_for_xor_used_as_pow.

gcc/cp/ChangeLog:
PR c/90885
* cp-tree.h (class cp_expr): Add bitfield m_decimal.  Clear it in
existing ctors.  Add ctor that allows specifying its value.
(cp_expr::decimal_p): New accessor.
* parser.cc (cp_parser_expression_stack_entry::flags): New field.
(cp_parser_primary_expression): Set m_decimal of cp_expr when
handling numbers.
(cp_parser_binary_expression): Extract flags from token when
populating stack.  Call check_for_xor_used_as_pow.

gcc/ChangeLog:
PR c/90885
* doc/invoke.texi (Warning Options): Add -Wxor-used-as-pow.

gcc/testsuite/ChangeLog:
PR c/90885
* c-c++-common/Wxor-used-as-pow-1.c: New test.
* c-c++-common/Wxor-used-as-pow-fixits.c: New test.
* g++.dg/parse/expr3.C: Convert 2 to 0x2 to suppress
-Wxor-used-as-pow.
* g++.dg/warn/Wparentheses-10.C: Likewise.
* g++.dg/warn/Wparentheses-18.C: Likewise.
* g++.dg/warn/Wparentheses-19.C: Likewise.
* g++.dg/warn/Wparentheses-9.C: Likewise.
* g++.dg/warn/Wxor-used-as-pow-named-op.C: New test.
* gcc.dg/Wparentheses-6.c: Convert 2 to 0x2 to suppress
-Wxor-used-as-pow.
* gcc.dg/Wparentheses-7.c: Likewise.
* gcc.dg/precedence-1.c: Likewise.

libcpp/ChangeLog:
PR c/90885
*