public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
From: Richard Biener <rguenther@suse.de>
To: Jakub Jelinek <jakub@redhat.com>
Cc: Jeff Law <jeffreyalaw@gmail.com>, gcc-patches@gcc.gnu.org
Subject: Re: [PATCH] tree: Fix up component_ref_sam_type handling of arrays of 0 sized elements [PR109215]
Date: Tue, 21 Mar 2023 09:40:41 +0000 (UTC)	[thread overview]
Message-ID: <nycvar.YFH.7.77.849.2303210940290.18795@jbgna.fhfr.qr> (raw)
In-Reply-To: <ZBlpWhnv6NXCrESh@tucnak>

On Tue, 21 Mar 2023, Jakub Jelinek wrote:

> Hi!
> 
> Our documentation sadly talks about elt_type arr[0]; as zero-length arrays,
> not arrays with zero elements.  Unfortunately, those aren't the only arrays
> which can have zero size, the same size can be also result of zero-length
> element, like in GNU C struct whatever {} or in GNU C/C++ if the element
> type is [0] array or combination thereof (dunno if Ada doesn't allow
> something similar too).  One can't do much with them, taking address of
> their elements, (no-op) copying of the elements in and out.  But they
> behave differently from arr[0] arrays e.g. in that using non-zero indexes
> in them (as long as they are within bounds as for normal arrays) is valid.
> 
> I think this naming inaccuracy resulted in Martin designing
> special_array_member in an inconsistent way, mixing size zero array members
> with array members of one or two or more elements and then using the
> size zero interchangeably with zero elements.
> 
> The following patch changes that (but doesn't do any
> documentation/diagnostics renaming, as this is really a corner case),
> such that int_0/trail_0 for consistency is just about [0] arrays
> plus [] for the latter, not one or more zero sized elements case.
> 
> The testcase has one xfailed case for where perhaps in later GCC versions
> we could add extra code to handle it, for some reason we don't diagnose
> out of bounds accesses for the zero sized elements cases.  It will be
> harder because e.g. FRE will canonicalize &var.fld[0] and &var.fld[10]
> to just one of them because they are provably the same address.
> But the important thing is to fix this regression (where we warn on
> completely valid code in the Linux kernel).  Anyway, for further work
> on this we don't really need any extra help from special_array_member,
> all code can just check integer_zerop (TYPE_SIZE_UNIT (TREE_TYPE (type))),
> it doesn't depend on the position of the members etc.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

Thanks,
Richard.

> 2023-03-21  Jakub Jelinek  <jakub@redhat.com>
> 
> 	PR tree-optimization/109215
> 	* tree.h (enum special_array_member): Adjust comments for int_0
> 	and trail_0.
> 	* tree.cc (component_ref_sam_type): Clear zero_elts if memtype
> 	has zero sized element type and the array has variable number of
> 	elements or constant one or more elements.
> 	(component_ref_size): Adjust comments, formatting fix.
> 
> 	* gcc.dg/Wzero-length-array-bounds-3.c: New test.
> 
> --- gcc/tree.h.jj	2023-03-14 19:11:52.296936422 +0100
> +++ gcc/tree.h	2023-03-20 18:48:23.068788830 +0100
> @@ -5579,8 +5579,8 @@ extern tree component_ref_field_offset (
>  enum struct special_array_member
>    {
>      none,	/* Not a special array member.  */
> -    int_0,	/* Interior array member with size zero.  */
> -    trail_0,	/* Trailing array member with size zero.  */
> +    int_0,	/* Interior array member with zero elements.  */
> +    trail_0,	/* Trailing array member with zero elements.  */
>      trail_1,	/* Trailing array member with one element.  */
>      trail_n,	/* Trailing array member with two or more elements.  */
>      int_n	/* Interior array member with one or more elements.  */
> --- gcc/tree.cc.jj	2023-03-10 10:38:46.551473829 +0100
> +++ gcc/tree.cc	2023-03-20 19:41:35.605580732 +0100
> @@ -13032,14 +13032,27 @@ component_ref_sam_type (tree ref)
>  	return sam_type;
>  
>        bool trailing = false;
> -      (void)array_ref_flexible_size_p (ref, &trailing);
> -      bool zero_length = integer_zerop (memsize);
> -      if (!trailing && !zero_length)
> -	/* MEMBER is an interior array with
> -	  more than one element.  */
> +      (void) array_ref_flexible_size_p (ref, &trailing);
> +      bool zero_elts = integer_zerop (memsize);
> +      if (zero_elts && integer_zerop (TYPE_SIZE_UNIT (TREE_TYPE (memtype))))
> +	{
> +	  /* If array element has zero size, verify if it is a flexible
> +	     array member or zero length array.  Clear zero_elts if
> +	     it has one or more members or is a VLA member.  */
> +	  if (tree dom = TYPE_DOMAIN (memtype))
> +	    if (tree min = TYPE_MIN_VALUE (dom))
> +	      if (tree max = TYPE_MAX_VALUE (dom))
> +		if (TREE_CODE (min) != INTEGER_CST
> +		    || TREE_CODE (max) != INTEGER_CST
> +		    || !((integer_zerop (min) && integer_all_onesp (max))
> +			 || tree_int_cst_lt (max, min)))
> +		  zero_elts = false;
> +	}
> +      if (!trailing && !zero_elts)
> +	/* MEMBER is an interior array with more than one element.  */
>  	return special_array_member::int_n;
>  
> -      if (zero_length)
> +      if (zero_elts)
>  	{
>  	  if (trailing)
>  	    return special_array_member::trail_0;
> @@ -13047,7 +13060,7 @@ component_ref_sam_type (tree ref)
>  	    return special_array_member::int_0;
>  	}
>  
> -      if (!zero_length)
> +      if (!zero_elts)
>  	if (tree dom = TYPE_DOMAIN (memtype))
>  	  if (tree min = TYPE_MIN_VALUE (dom))
>  	    if (tree max = TYPE_MAX_VALUE (dom))
> @@ -13114,14 +13127,14 @@ component_ref_size (tree ref, special_ar
>  
>        tree afield_decl = TREE_OPERAND (ref, 1);
>        gcc_assert (TREE_CODE (afield_decl) == FIELD_DECL);
> -      /* if the trailing array is a not a flexible array member, treat it as
> +      /* If the trailing array is a not a flexible array member, treat it as
>  	 a normal array.  */
>        if (DECL_NOT_FLEXARRAY (afield_decl)
>  	  && *sam != special_array_member::int_0)
>  	return memsize;
>  
>        if (*sam == special_array_member::int_0)
> -	  memsize = NULL_TREE;
> +	memsize = NULL_TREE;
>  
>        /* For a reference to a flexible array member of a union
>  	 use the size of the union instead of the size of the member.  */
> @@ -13129,7 +13142,7 @@ component_ref_size (tree ref, special_ar
>  	memsize = TYPE_SIZE_UNIT (argtype);
>      }
>  
> -  /* MEMBER is either a bona fide flexible array member, or a zero-length
> +  /* MEMBER is either a bona fide flexible array member, or a zero-elements
>       array member, or an array of length one treated as such.  */
>  
>    /* If the reference is to a declared object and the member a true
> --- gcc/testsuite/gcc.dg/Wzero-length-array-bounds-3.c.jj	2023-03-20 19:17:21.290648885 +0100
> +++ gcc/testsuite/gcc.dg/Wzero-length-array-bounds-3.c	2023-03-20 19:16:48.494123583 +0100
> @@ -0,0 +1,19 @@
> +/* PR tree-optimization/109215 */
> +/* { dg-do compile } */
> +/* { dg-options "-O2 -Wall" } */
> +
> +struct S {};
> +struct T { struct S s[3]; struct S t; };
> +void foo (struct S *);
> +
> +void
> +bar (struct T *t)
> +{
> +  foo (&t->s[2]);	/* { dg-bogus "array subscript 2 is outside the bounds of an interior zero-length array" } */
> +}
> +
> +void
> +baz (struct T *t)
> +{
> +  foo (&t->s[3]);	/* { dg-error "" "" { xfail *-*-* } } */
> +}
> 
> 	Jakub
> 
> 

-- 
Richard Biener <rguenther@suse.de>
SUSE Software Solutions Germany GmbH, Frankenstrasse 146, 90461 Nuernberg,
Germany; GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman;
HRB 36809 (AG Nuernberg)

      reply	other threads:[~2023-03-21  9:40 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-03-21  8:22 Jakub Jelinek
2023-03-21  9:40 ` Richard Biener [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=nycvar.YFH.7.77.849.2303210940290.18795@jbgna.fhfr.qr \
    --to=rguenther@suse.de \
    --cc=gcc-patches@gcc.gnu.org \
    --cc=jakub@redhat.com \
    --cc=jeffreyalaw@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).