Re: [PATCH v3] c, c++: Implement -Wsizeof-array-div [PR91741]

2020-10-22 Thread Joseph Myers
The C parts are OK.

-- 
Joseph S. Myers
jos...@codesourcery.com


Re: [PATCH v3] c, c++: Implement -Wsizeof-array-div [PR91741]

2020-10-19 Thread Marek Polacek via Gcc-patches
Ping.

On Thu, Oct 08, 2020 at 11:04:40AM -0400, Marek Polacek via Gcc-patches wrote:
> Ping for the C parts.
> 
> On Mon, Sep 28, 2020 at 02:15:41PM -0400, Marek Polacek via Gcc-patches wrote:
> > On Tue, Sep 22, 2020 at 04:07:41PM -0400, Jason Merrill wrote:
> > > On 9/22/20 1:29 PM, Marek Polacek wrote:
> > > > Ping.
> > > 
> > > The C++ change is OK.
> > 
> > Ping for the C parts.
> > 
> > > > On Tue, Sep 15, 2020 at 04:33:05PM -0400, Marek Polacek via Gcc-patches 
> > > > wrote:
> > > > > On Tue, Sep 15, 2020 at 09:04:41AM +0200, Jakub Jelinek via 
> > > > > Gcc-patches wrote:
> > > > > > On Mon, Sep 14, 2020 at 09:30:44PM -0400, Marek Polacek via 
> > > > > > Gcc-patches wrote:
> > > > > > > --- a/gcc/c/c-tree.h
> > > > > > > +++ b/gcc/c/c-tree.h
> > > > > > > @@ -147,6 +147,11 @@ struct c_expr
> > > > > > >etc), so we stash a copy here.  */
> > > > > > > source_range src_range;
> > > > > > > +  /* True iff the sizeof expression was enclosed in parentheses.
> > > > > > > + NB: This member is currently only initialized when 
> > > > > > > .original_code
> > > > > > > + is a SIZEOF_EXPR.  ??? Add a default constructor to this 
> > > > > > > class.  */
> > > > > > > +  bool parenthesized_p;
> > > > > > > +
> > > > > > > /* Access to the first and last locations within the source 
> > > > > > > spelling
> > > > > > >of this expression.  */
> > > > > > > location_t get_start () const { return src_range.m_start; }
> > > > > > 
> > > > > > I think a magic tree code would be better, c_expr is used in too 
> > > > > > many places
> > > > > > and returned by many functions, so it is copied over and over.
> > > > > > Even if you must add it, it would be better to change the struct 
> > > > > > layout,
> > > > > > because right now there are fields: tree, location_t, tree, 
> > > > > > 2xlocation_t,
> > > > > > which means 32-bit gap on 64-bit hosts before the second tree, so 
> > > > > > the new
> > > > > > field would fit in there.  But, if it is mostly uninitialized, it 
> > > > > > is kind of
> > > > > > unclean.
> > > > > 
> > > > > Ok, here's a version with PAREN_SIZEOF_EXPR.  It doesn't require 
> > > > > changes to
> > > > > c_expr, but adding a new tree code is always a pain...
> > > > > 
> > > > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> > > > > 
> > > > > -- >8 --
> > > > > This patch implements a new warning, -Wsizeof-array-div.  It warns 
> > > > > about
> > > > > code like
> > > > > 
> > > > >int arr[10];
> > > > >sizeof (arr) / sizeof (short);
> > > > > 
> > > > > where we have a division of two sizeof expressions, where the first
> > > > > argument is an array, and the second sizeof does not equal the size
> > > > > of the array element.  See e.g. 
> > > > > .
> > > > > 
> > > > > Clang makes it possible to suppress the warning by parenthesizing the
> > > > > second sizeof like this:
> > > > > 
> > > > >sizeof (arr) / (sizeof (short));
> > > > > 
> > > > > so I followed suit.  In the C++ FE this was rather easy, because
> > > > > finish_parenthesized_expr already set TREE_NO_WARNING.  In the C FE
> > > > > I've added a new tree code, PAREN_SIZEOF_EXPR, to discern between the
> > > > > non-() and () versions.
> > > > > 
> > > > > This warning is enabled by -Wall.  An example of the output:
> > > > > 
> > > > > x.c:5:23: warning: expression does not compute the number of elements 
> > > > > in this array; element type is ‘int’, not ‘short int’ 
> > > > > [-Wsizeof-array-div]
> > > > >  5 |   return sizeof (arr) / sizeof (short);
> > > > >|  ~^~~~
> > > > > x.c:5:25: note: add parentheses around ‘sizeof (short int)’ to 
> > > > > silence this warning
> > > > >  5 |   return sizeof (arr) / sizeof (short);
> > > > >| ^~
> > > > >| ( )
> > > > > x.c:4:7: note: array ‘arr’ declared here
> > > > >  4 |   int arr[10];
> > > > >|   ^~~
> > > > > 
> > > > > gcc/c-family/ChangeLog:
> > > > > 
> > > > >   PR c++/91741
> > > > >   * c-common.c (verify_tree): Handle PAREN_SIZEOF_EXPR.
> > > > >   (c_common_init_ts): Likewise.
> > > > >   * c-common.def (PAREN_SIZEOF_EXPR): New tree code.
> > > > >   * c-common.h (maybe_warn_sizeof_array_div): Declare.
> > > > >   * c-warn.c (sizeof_pointer_memaccess_warning): Unwrap NOP_EXPRs.
> > > > >   (maybe_warn_sizeof_array_div): New function.
> > > > >   * c.opt (Wsizeof-array-div): New option.
> > > > > 
> > > > > gcc/c/ChangeLog:
> > > > > 
> > > > >   PR c++/91741
> > > > >   * c-parser.c (c_parser_binary_expression): Implement 
> > > > > -Wsizeof-array-div.
> > > > >   (c_parser_postfix_expression): Set PAREN_SIZEOF_EXPR.
> > > > >   (c_parser_expr_list): Handle PAREN_SIZEOF_EXPR like SIZEOF_EXPR.
> > > > >   * c-tree.h (char_type_p): Declare.
> > > > >

Re: [PATCH v3] c, c++: Implement -Wsizeof-array-div [PR91741]

2020-10-08 Thread Marek Polacek via Gcc-patches
Ping for the C parts.

On Mon, Sep 28, 2020 at 02:15:41PM -0400, Marek Polacek via Gcc-patches wrote:
> On Tue, Sep 22, 2020 at 04:07:41PM -0400, Jason Merrill wrote:
> > On 9/22/20 1:29 PM, Marek Polacek wrote:
> > > Ping.
> > 
> > The C++ change is OK.
> 
> Ping for the C parts.
> 
> > > On Tue, Sep 15, 2020 at 04:33:05PM -0400, Marek Polacek via Gcc-patches 
> > > wrote:
> > > > On Tue, Sep 15, 2020 at 09:04:41AM +0200, Jakub Jelinek via Gcc-patches 
> > > > wrote:
> > > > > On Mon, Sep 14, 2020 at 09:30:44PM -0400, Marek Polacek via 
> > > > > Gcc-patches wrote:
> > > > > > --- a/gcc/c/c-tree.h
> > > > > > +++ b/gcc/c/c-tree.h
> > > > > > @@ -147,6 +147,11 @@ struct c_expr
> > > > > >etc), so we stash a copy here.  */
> > > > > > source_range src_range;
> > > > > > +  /* True iff the sizeof expression was enclosed in parentheses.
> > > > > > + NB: This member is currently only initialized when 
> > > > > > .original_code
> > > > > > + is a SIZEOF_EXPR.  ??? Add a default constructor to this 
> > > > > > class.  */
> > > > > > +  bool parenthesized_p;
> > > > > > +
> > > > > > /* Access to the first and last locations within the source 
> > > > > > spelling
> > > > > >of this expression.  */
> > > > > > location_t get_start () const { return src_range.m_start; }
> > > > > 
> > > > > I think a magic tree code would be better, c_expr is used in too many 
> > > > > places
> > > > > and returned by many functions, so it is copied over and over.
> > > > > Even if you must add it, it would be better to change the struct 
> > > > > layout,
> > > > > because right now there are fields: tree, location_t, tree, 
> > > > > 2xlocation_t,
> > > > > which means 32-bit gap on 64-bit hosts before the second tree, so the 
> > > > > new
> > > > > field would fit in there.  But, if it is mostly uninitialized, it is 
> > > > > kind of
> > > > > unclean.
> > > > 
> > > > Ok, here's a version with PAREN_SIZEOF_EXPR.  It doesn't require 
> > > > changes to
> > > > c_expr, but adding a new tree code is always a pain...
> > > > 
> > > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> > > > 
> > > > -- >8 --
> > > > This patch implements a new warning, -Wsizeof-array-div.  It warns about
> > > > code like
> > > > 
> > > >int arr[10];
> > > >sizeof (arr) / sizeof (short);
> > > > 
> > > > where we have a division of two sizeof expressions, where the first
> > > > argument is an array, and the second sizeof does not equal the size
> > > > of the array element.  See e.g. 
> > > > .
> > > > 
> > > > Clang makes it possible to suppress the warning by parenthesizing the
> > > > second sizeof like this:
> > > > 
> > > >sizeof (arr) / (sizeof (short));
> > > > 
> > > > so I followed suit.  In the C++ FE this was rather easy, because
> > > > finish_parenthesized_expr already set TREE_NO_WARNING.  In the C FE
> > > > I've added a new tree code, PAREN_SIZEOF_EXPR, to discern between the
> > > > non-() and () versions.
> > > > 
> > > > This warning is enabled by -Wall.  An example of the output:
> > > > 
> > > > x.c:5:23: warning: expression does not compute the number of elements 
> > > > in this array; element type is ‘int’, not ‘short int’ 
> > > > [-Wsizeof-array-div]
> > > >  5 |   return sizeof (arr) / sizeof (short);
> > > >|  ~^~~~
> > > > x.c:5:25: note: add parentheses around ‘sizeof (short int)’ to silence 
> > > > this warning
> > > >  5 |   return sizeof (arr) / sizeof (short);
> > > >| ^~
> > > >| ( )
> > > > x.c:4:7: note: array ‘arr’ declared here
> > > >  4 |   int arr[10];
> > > >|   ^~~
> > > > 
> > > > gcc/c-family/ChangeLog:
> > > > 
> > > > PR c++/91741
> > > > * c-common.c (verify_tree): Handle PAREN_SIZEOF_EXPR.
> > > > (c_common_init_ts): Likewise.
> > > > * c-common.def (PAREN_SIZEOF_EXPR): New tree code.
> > > > * c-common.h (maybe_warn_sizeof_array_div): Declare.
> > > > * c-warn.c (sizeof_pointer_memaccess_warning): Unwrap NOP_EXPRs.
> > > > (maybe_warn_sizeof_array_div): New function.
> > > > * c.opt (Wsizeof-array-div): New option.
> > > > 
> > > > gcc/c/ChangeLog:
> > > > 
> > > > PR c++/91741
> > > > * c-parser.c (c_parser_binary_expression): Implement 
> > > > -Wsizeof-array-div.
> > > > (c_parser_postfix_expression): Set PAREN_SIZEOF_EXPR.
> > > > (c_parser_expr_list): Handle PAREN_SIZEOF_EXPR like SIZEOF_EXPR.
> > > > * c-tree.h (char_type_p): Declare.
> > > > * c-typeck.c (char_type_p): No longer static.
> > > > 
> > > > gcc/cp/ChangeLog:
> > > > 
> > > > PR c++/91741
> > > > * typeck.c (cp_build_binary_op): Implement -Wsizeof-array-div.
> > > > 
> > > > gcc/ChangeLog:
> > > > 
> > > > PR c++/91741
> > > > * 

Re: [PATCH v3] c, c++: Implement -Wsizeof-array-div [PR91741]

2020-09-28 Thread Marek Polacek via Gcc-patches
On Tue, Sep 22, 2020 at 04:07:41PM -0400, Jason Merrill wrote:
> On 9/22/20 1:29 PM, Marek Polacek wrote:
> > Ping.
> 
> The C++ change is OK.

Ping for the C parts.

> > On Tue, Sep 15, 2020 at 04:33:05PM -0400, Marek Polacek via Gcc-patches 
> > wrote:
> > > On Tue, Sep 15, 2020 at 09:04:41AM +0200, Jakub Jelinek via Gcc-patches 
> > > wrote:
> > > > On Mon, Sep 14, 2020 at 09:30:44PM -0400, Marek Polacek via Gcc-patches 
> > > > wrote:
> > > > > --- a/gcc/c/c-tree.h
> > > > > +++ b/gcc/c/c-tree.h
> > > > > @@ -147,6 +147,11 @@ struct c_expr
> > > > >etc), so we stash a copy here.  */
> > > > > source_range src_range;
> > > > > +  /* True iff the sizeof expression was enclosed in parentheses.
> > > > > + NB: This member is currently only initialized when 
> > > > > .original_code
> > > > > + is a SIZEOF_EXPR.  ??? Add a default constructor to this class. 
> > > > >  */
> > > > > +  bool parenthesized_p;
> > > > > +
> > > > > /* Access to the first and last locations within the source 
> > > > > spelling
> > > > >of this expression.  */
> > > > > location_t get_start () const { return src_range.m_start; }
> > > > 
> > > > I think a magic tree code would be better, c_expr is used in too many 
> > > > places
> > > > and returned by many functions, so it is copied over and over.
> > > > Even if you must add it, it would be better to change the struct layout,
> > > > because right now there are fields: tree, location_t, tree, 
> > > > 2xlocation_t,
> > > > which means 32-bit gap on 64-bit hosts before the second tree, so the 
> > > > new
> > > > field would fit in there.  But, if it is mostly uninitialized, it is 
> > > > kind of
> > > > unclean.
> > > 
> > > Ok, here's a version with PAREN_SIZEOF_EXPR.  It doesn't require changes 
> > > to
> > > c_expr, but adding a new tree code is always a pain...
> > > 
> > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> > > 
> > > -- >8 --
> > > This patch implements a new warning, -Wsizeof-array-div.  It warns about
> > > code like
> > > 
> > >int arr[10];
> > >sizeof (arr) / sizeof (short);
> > > 
> > > where we have a division of two sizeof expressions, where the first
> > > argument is an array, and the second sizeof does not equal the size
> > > of the array element.  See e.g. 
> > > .
> > > 
> > > Clang makes it possible to suppress the warning by parenthesizing the
> > > second sizeof like this:
> > > 
> > >sizeof (arr) / (sizeof (short));
> > > 
> > > so I followed suit.  In the C++ FE this was rather easy, because
> > > finish_parenthesized_expr already set TREE_NO_WARNING.  In the C FE
> > > I've added a new tree code, PAREN_SIZEOF_EXPR, to discern between the
> > > non-() and () versions.
> > > 
> > > This warning is enabled by -Wall.  An example of the output:
> > > 
> > > x.c:5:23: warning: expression does not compute the number of elements in 
> > > this array; element type is ‘int’, not ‘short int’ [-Wsizeof-array-div]
> > >  5 |   return sizeof (arr) / sizeof (short);
> > >|  ~^~~~
> > > x.c:5:25: note: add parentheses around ‘sizeof (short int)’ to silence 
> > > this warning
> > >  5 |   return sizeof (arr) / sizeof (short);
> > >| ^~
> > >| ( )
> > > x.c:4:7: note: array ‘arr’ declared here
> > >  4 |   int arr[10];
> > >|   ^~~
> > > 
> > > gcc/c-family/ChangeLog:
> > > 
> > >   PR c++/91741
> > >   * c-common.c (verify_tree): Handle PAREN_SIZEOF_EXPR.
> > >   (c_common_init_ts): Likewise.
> > >   * c-common.def (PAREN_SIZEOF_EXPR): New tree code.
> > >   * c-common.h (maybe_warn_sizeof_array_div): Declare.
> > >   * c-warn.c (sizeof_pointer_memaccess_warning): Unwrap NOP_EXPRs.
> > >   (maybe_warn_sizeof_array_div): New function.
> > >   * c.opt (Wsizeof-array-div): New option.
> > > 
> > > gcc/c/ChangeLog:
> > > 
> > >   PR c++/91741
> > >   * c-parser.c (c_parser_binary_expression): Implement -Wsizeof-array-div.
> > >   (c_parser_postfix_expression): Set PAREN_SIZEOF_EXPR.
> > >   (c_parser_expr_list): Handle PAREN_SIZEOF_EXPR like SIZEOF_EXPR.
> > >   * c-tree.h (char_type_p): Declare.
> > >   * c-typeck.c (char_type_p): No longer static.
> > > 
> > > gcc/cp/ChangeLog:
> > > 
> > >   PR c++/91741
> > >   * typeck.c (cp_build_binary_op): Implement -Wsizeof-array-div.
> > > 
> > > gcc/ChangeLog:
> > > 
> > >   PR c++/91741
> > >   * doc/invoke.texi: Document -Wsizeof-array-div.
> > > 
> > > gcc/testsuite/ChangeLog:
> > > 
> > >   PR c++/91741
> > >   * c-c++-common/Wsizeof-pointer-div.c: Add dg-warning.
> > >   * c-c++-common/Wsizeof-array-div1.c: New test.
> > >   * g++.dg/warn/Wsizeof-array-div1.C: New test.
> > >   * g++.dg/warn/Wsizeof-array-div2.C: New test.
> > > ---
> > >   gcc/c-family/c-common.c   |  2 +
> > >   gcc/c-family/c-common.def |  3 +
> 

Re: [PATCH v3] c, c++: Implement -Wsizeof-array-div [PR91741]

2020-09-22 Thread Jason Merrill via Gcc-patches

On 9/22/20 1:29 PM, Marek Polacek wrote:

Ping.


The C++ change is OK.


On Tue, Sep 15, 2020 at 04:33:05PM -0400, Marek Polacek via Gcc-patches wrote:

On Tue, Sep 15, 2020 at 09:04:41AM +0200, Jakub Jelinek via Gcc-patches wrote:

On Mon, Sep 14, 2020 at 09:30:44PM -0400, Marek Polacek via Gcc-patches wrote:

--- a/gcc/c/c-tree.h
+++ b/gcc/c/c-tree.h
@@ -147,6 +147,11 @@ struct c_expr
   etc), so we stash a copy here.  */
source_range src_range;
  
+  /* True iff the sizeof expression was enclosed in parentheses.

+ NB: This member is currently only initialized when .original_code
+ is a SIZEOF_EXPR.  ??? Add a default constructor to this class.  */
+  bool parenthesized_p;
+
/* Access to the first and last locations within the source spelling
   of this expression.  */
location_t get_start () const { return src_range.m_start; }


I think a magic tree code would be better, c_expr is used in too many places
and returned by many functions, so it is copied over and over.
Even if you must add it, it would be better to change the struct layout,
because right now there are fields: tree, location_t, tree, 2xlocation_t,
which means 32-bit gap on 64-bit hosts before the second tree, so the new
field would fit in there.  But, if it is mostly uninitialized, it is kind of
unclean.


Ok, here's a version with PAREN_SIZEOF_EXPR.  It doesn't require changes to
c_expr, but adding a new tree code is always a pain...

Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

-- >8 --
This patch implements a new warning, -Wsizeof-array-div.  It warns about
code like

   int arr[10];
   sizeof (arr) / sizeof (short);

where we have a division of two sizeof expressions, where the first
argument is an array, and the second sizeof does not equal the size
of the array element.  See e.g. .

Clang makes it possible to suppress the warning by parenthesizing the
second sizeof like this:

   sizeof (arr) / (sizeof (short));

so I followed suit.  In the C++ FE this was rather easy, because
finish_parenthesized_expr already set TREE_NO_WARNING.  In the C FE
I've added a new tree code, PAREN_SIZEOF_EXPR, to discern between the
non-() and () versions.

This warning is enabled by -Wall.  An example of the output:

x.c:5:23: warning: expression does not compute the number of elements in this 
array; element type is ‘int’, not ‘short int’ [-Wsizeof-array-div]
 5 |   return sizeof (arr) / sizeof (short);
   |  ~^~~~
x.c:5:25: note: add parentheses around ‘sizeof (short int)’ to silence this 
warning
 5 |   return sizeof (arr) / sizeof (short);
   | ^~
   | ( )
x.c:4:7: note: array ‘arr’ declared here
 4 |   int arr[10];
   |   ^~~

gcc/c-family/ChangeLog:

PR c++/91741
* c-common.c (verify_tree): Handle PAREN_SIZEOF_EXPR.
(c_common_init_ts): Likewise.
* c-common.def (PAREN_SIZEOF_EXPR): New tree code.
* c-common.h (maybe_warn_sizeof_array_div): Declare.
* c-warn.c (sizeof_pointer_memaccess_warning): Unwrap NOP_EXPRs.
(maybe_warn_sizeof_array_div): New function.
* c.opt (Wsizeof-array-div): New option.

gcc/c/ChangeLog:

PR c++/91741
* c-parser.c (c_parser_binary_expression): Implement -Wsizeof-array-div.
(c_parser_postfix_expression): Set PAREN_SIZEOF_EXPR.
(c_parser_expr_list): Handle PAREN_SIZEOF_EXPR like SIZEOF_EXPR.
* c-tree.h (char_type_p): Declare.
* c-typeck.c (char_type_p): No longer static.

gcc/cp/ChangeLog:

PR c++/91741
* typeck.c (cp_build_binary_op): Implement -Wsizeof-array-div.

gcc/ChangeLog:

PR c++/91741
* doc/invoke.texi: Document -Wsizeof-array-div.

gcc/testsuite/ChangeLog:

PR c++/91741
* c-c++-common/Wsizeof-pointer-div.c: Add dg-warning.
* c-c++-common/Wsizeof-array-div1.c: New test.
* g++.dg/warn/Wsizeof-array-div1.C: New test.
* g++.dg/warn/Wsizeof-array-div2.C: New test.
---
  gcc/c-family/c-common.c   |  2 +
  gcc/c-family/c-common.def |  3 +
  gcc/c-family/c-common.h   |  1 +
  gcc/c-family/c-warn.c | 47 
  gcc/c-family/c.opt|  5 ++
  gcc/c/c-parser.c  | 48 ++--
  gcc/c/c-tree.h|  1 +
  gcc/c/c-typeck.c  |  2 +-
  gcc/cp/typeck.c   | 10 +++-
  gcc/doc/invoke.texi   | 19 +++
  .../c-c++-common/Wsizeof-array-div1.c | 56 +++
  .../c-c++-common/Wsizeof-pointer-div.c|  2 +-
  .../g++.dg/warn/Wsizeof-array-div1.C  | 37 
  .../g++.dg/warn/Wsizeof-array-div2.C  | 15 +
  14 files changed, 

Re: [PATCH v3] c, c++: Implement -Wsizeof-array-div [PR91741]

2020-09-22 Thread Marek Polacek via Gcc-patches
Ping.

On Tue, Sep 15, 2020 at 04:33:05PM -0400, Marek Polacek via Gcc-patches wrote:
> On Tue, Sep 15, 2020 at 09:04:41AM +0200, Jakub Jelinek via Gcc-patches wrote:
> > On Mon, Sep 14, 2020 at 09:30:44PM -0400, Marek Polacek via Gcc-patches 
> > wrote:
> > > --- a/gcc/c/c-tree.h
> > > +++ b/gcc/c/c-tree.h
> > > @@ -147,6 +147,11 @@ struct c_expr
> > >   etc), so we stash a copy here.  */
> > >source_range src_range;
> > >  
> > > +  /* True iff the sizeof expression was enclosed in parentheses.
> > > + NB: This member is currently only initialized when .original_code
> > > + is a SIZEOF_EXPR.  ??? Add a default constructor to this class.  */
> > > +  bool parenthesized_p;
> > > +
> > >/* Access to the first and last locations within the source spelling
> > >   of this expression.  */
> > >location_t get_start () const { return src_range.m_start; }
> > 
> > I think a magic tree code would be better, c_expr is used in too many places
> > and returned by many functions, so it is copied over and over.
> > Even if you must add it, it would be better to change the struct layout,
> > because right now there are fields: tree, location_t, tree, 2xlocation_t,
> > which means 32-bit gap on 64-bit hosts before the second tree, so the new
> > field would fit in there.  But, if it is mostly uninitialized, it is kind of
> > unclean.
> 
> Ok, here's a version with PAREN_SIZEOF_EXPR.  It doesn't require changes to
> c_expr, but adding a new tree code is always a pain...
> 
> Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?
> 
> -- >8 --
> This patch implements a new warning, -Wsizeof-array-div.  It warns about
> code like
> 
>   int arr[10];
>   sizeof (arr) / sizeof (short);
> 
> where we have a division of two sizeof expressions, where the first
> argument is an array, and the second sizeof does not equal the size
> of the array element.  See e.g. .
> 
> Clang makes it possible to suppress the warning by parenthesizing the
> second sizeof like this:
> 
>   sizeof (arr) / (sizeof (short));
> 
> so I followed suit.  In the C++ FE this was rather easy, because
> finish_parenthesized_expr already set TREE_NO_WARNING.  In the C FE
> I've added a new tree code, PAREN_SIZEOF_EXPR, to discern between the
> non-() and () versions.
> 
> This warning is enabled by -Wall.  An example of the output:
> 
> x.c:5:23: warning: expression does not compute the number of elements in this 
> array; element type is ‘int’, not ‘short int’ [-Wsizeof-array-div]
> 5 |   return sizeof (arr) / sizeof (short);
>   |  ~^~~~
> x.c:5:25: note: add parentheses around ‘sizeof (short int)’ to silence this 
> warning
> 5 |   return sizeof (arr) / sizeof (short);
>   | ^~
>   | ( )
> x.c:4:7: note: array ‘arr’ declared here
> 4 |   int arr[10];
>   |   ^~~
> 
> gcc/c-family/ChangeLog:
> 
>   PR c++/91741
>   * c-common.c (verify_tree): Handle PAREN_SIZEOF_EXPR.
>   (c_common_init_ts): Likewise.
>   * c-common.def (PAREN_SIZEOF_EXPR): New tree code.
>   * c-common.h (maybe_warn_sizeof_array_div): Declare.
>   * c-warn.c (sizeof_pointer_memaccess_warning): Unwrap NOP_EXPRs.
>   (maybe_warn_sizeof_array_div): New function.
>   * c.opt (Wsizeof-array-div): New option.
> 
> gcc/c/ChangeLog:
> 
>   PR c++/91741
>   * c-parser.c (c_parser_binary_expression): Implement -Wsizeof-array-div.
>   (c_parser_postfix_expression): Set PAREN_SIZEOF_EXPR.
>   (c_parser_expr_list): Handle PAREN_SIZEOF_EXPR like SIZEOF_EXPR.
>   * c-tree.h (char_type_p): Declare.
>   * c-typeck.c (char_type_p): No longer static.
> 
> gcc/cp/ChangeLog:
> 
>   PR c++/91741
>   * typeck.c (cp_build_binary_op): Implement -Wsizeof-array-div.
> 
> gcc/ChangeLog:
> 
>   PR c++/91741
>   * doc/invoke.texi: Document -Wsizeof-array-div.
> 
> gcc/testsuite/ChangeLog:
> 
>   PR c++/91741
>   * c-c++-common/Wsizeof-pointer-div.c: Add dg-warning.
>   * c-c++-common/Wsizeof-array-div1.c: New test.
>   * g++.dg/warn/Wsizeof-array-div1.C: New test.
>   * g++.dg/warn/Wsizeof-array-div2.C: New test.
> ---
>  gcc/c-family/c-common.c   |  2 +
>  gcc/c-family/c-common.def |  3 +
>  gcc/c-family/c-common.h   |  1 +
>  gcc/c-family/c-warn.c | 47 
>  gcc/c-family/c.opt|  5 ++
>  gcc/c/c-parser.c  | 48 ++--
>  gcc/c/c-tree.h|  1 +
>  gcc/c/c-typeck.c  |  2 +-
>  gcc/cp/typeck.c   | 10 +++-
>  gcc/doc/invoke.texi   | 19 +++
>  .../c-c++-common/Wsizeof-array-div1.c | 56 +++
>  

Re: [PATCH v3] c, c++: Implement -Wsizeof-array-div [PR91741]

2020-09-15 Thread Marek Polacek via Gcc-patches
On Tue, Sep 15, 2020 at 09:04:41AM +0200, Jakub Jelinek via Gcc-patches wrote:
> On Mon, Sep 14, 2020 at 09:30:44PM -0400, Marek Polacek via Gcc-patches wrote:
> > --- a/gcc/c/c-tree.h
> > +++ b/gcc/c/c-tree.h
> > @@ -147,6 +147,11 @@ struct c_expr
> >   etc), so we stash a copy here.  */
> >source_range src_range;
> >  
> > +  /* True iff the sizeof expression was enclosed in parentheses.
> > + NB: This member is currently only initialized when .original_code
> > + is a SIZEOF_EXPR.  ??? Add a default constructor to this class.  */
> > +  bool parenthesized_p;
> > +
> >/* Access to the first and last locations within the source spelling
> >   of this expression.  */
> >location_t get_start () const { return src_range.m_start; }
> 
> I think a magic tree code would be better, c_expr is used in too many places
> and returned by many functions, so it is copied over and over.
> Even if you must add it, it would be better to change the struct layout,
> because right now there are fields: tree, location_t, tree, 2xlocation_t,
> which means 32-bit gap on 64-bit hosts before the second tree, so the new
> field would fit in there.  But, if it is mostly uninitialized, it is kind of
> unclean.

Ok, here's a version with PAREN_SIZEOF_EXPR.  It doesn't require changes to
c_expr, but adding a new tree code is always a pain...

Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk?

-- >8 --
This patch implements a new warning, -Wsizeof-array-div.  It warns about
code like

  int arr[10];
  sizeof (arr) / sizeof (short);

where we have a division of two sizeof expressions, where the first
argument is an array, and the second sizeof does not equal the size
of the array element.  See e.g. .

Clang makes it possible to suppress the warning by parenthesizing the
second sizeof like this:

  sizeof (arr) / (sizeof (short));

so I followed suit.  In the C++ FE this was rather easy, because
finish_parenthesized_expr already set TREE_NO_WARNING.  In the C FE
I've added a new tree code, PAREN_SIZEOF_EXPR, to discern between the
non-() and () versions.

This warning is enabled by -Wall.  An example of the output:

x.c:5:23: warning: expression does not compute the number of elements in this 
array; element type is ‘int’, not ‘short int’ [-Wsizeof-array-div]
5 |   return sizeof (arr) / sizeof (short);
  |  ~^~~~
x.c:5:25: note: add parentheses around ‘sizeof (short int)’ to silence this 
warning
5 |   return sizeof (arr) / sizeof (short);
  | ^~
  | ( )
x.c:4:7: note: array ‘arr’ declared here
4 |   int arr[10];
  |   ^~~

gcc/c-family/ChangeLog:

PR c++/91741
* c-common.c (verify_tree): Handle PAREN_SIZEOF_EXPR.
(c_common_init_ts): Likewise.
* c-common.def (PAREN_SIZEOF_EXPR): New tree code.
* c-common.h (maybe_warn_sizeof_array_div): Declare.
* c-warn.c (sizeof_pointer_memaccess_warning): Unwrap NOP_EXPRs.
(maybe_warn_sizeof_array_div): New function.
* c.opt (Wsizeof-array-div): New option.

gcc/c/ChangeLog:

PR c++/91741
* c-parser.c (c_parser_binary_expression): Implement -Wsizeof-array-div.
(c_parser_postfix_expression): Set PAREN_SIZEOF_EXPR.
(c_parser_expr_list): Handle PAREN_SIZEOF_EXPR like SIZEOF_EXPR.
* c-tree.h (char_type_p): Declare.
* c-typeck.c (char_type_p): No longer static.

gcc/cp/ChangeLog:

PR c++/91741
* typeck.c (cp_build_binary_op): Implement -Wsizeof-array-div.

gcc/ChangeLog:

PR c++/91741
* doc/invoke.texi: Document -Wsizeof-array-div.

gcc/testsuite/ChangeLog:

PR c++/91741
* c-c++-common/Wsizeof-pointer-div.c: Add dg-warning.
* c-c++-common/Wsizeof-array-div1.c: New test.
* g++.dg/warn/Wsizeof-array-div1.C: New test.
* g++.dg/warn/Wsizeof-array-div2.C: New test.
---
 gcc/c-family/c-common.c   |  2 +
 gcc/c-family/c-common.def |  3 +
 gcc/c-family/c-common.h   |  1 +
 gcc/c-family/c-warn.c | 47 
 gcc/c-family/c.opt|  5 ++
 gcc/c/c-parser.c  | 48 ++--
 gcc/c/c-tree.h|  1 +
 gcc/c/c-typeck.c  |  2 +-
 gcc/cp/typeck.c   | 10 +++-
 gcc/doc/invoke.texi   | 19 +++
 .../c-c++-common/Wsizeof-array-div1.c | 56 +++
 .../c-c++-common/Wsizeof-pointer-div.c|  2 +-
 .../g++.dg/warn/Wsizeof-array-div1.C  | 37 
 .../g++.dg/warn/Wsizeof-array-div2.C  | 15 +
 14 files changed, 226 insertions(+), 22 deletions(-)
 create mode 100644 gcc/testsuite/c-c++-common/Wsizeof-array-div1.c
 create mode