public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* aliasing between internal zero-length-arrays and other members
@ 2018-06-04 23:39 Martin Sebor
  2018-06-05 11:42 ` Richard Biener
  0 siblings, 1 reply; 3+ messages in thread
From: Martin Sebor @ 2018-06-04 23:39 UTC (permalink / raw)
  To: GCC Mailing List

GCC silently (without -Wpedantic) accepts declarations of zero
length arrays that are followed by other members in the same
struct, such as in:

   struct A { char a, b[0], c; };

Is it intended that accesses to elements of such arrays that
alias other members be well-defined?

In my tests, GCC assumes that neither read nor write accesses
to elements of internal zero-length arrays alias other members,
so assuming those aren't bugs I wonder if the documentation
should be updated to make that clear and a warning added for
such declarations (and perhaps also accesses).

For example, the test in the following function is eliminated,
implying that GCC assumes that the access to p->b does not modify
p->c, even though with i set to 0 it would:

   void f (struct A *p, int i)
   {
     int x = p->c;
     p->b[i] = 1;
     if (x != p->c)
       __builtin_abort ();
   }

Martin

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: aliasing between internal zero-length-arrays and other members
  2018-06-04 23:39 aliasing between internal zero-length-arrays and other members Martin Sebor
@ 2018-06-05 11:42 ` Richard Biener
  2018-06-05 12:54   ` Jakub Jelinek
  0 siblings, 1 reply; 3+ messages in thread
From: Richard Biener @ 2018-06-05 11:42 UTC (permalink / raw)
  To: Martin Sebor; +Cc: GCC Development

On Tue, Jun 5, 2018 at 1:39 AM Martin Sebor <msebor@gmail.com> wrote:
>
> GCC silently (without -Wpedantic) accepts declarations of zero
> length arrays that are followed by other members in the same
> struct, such as in:
>
>    struct A { char a, b[0], c; };
>
> Is it intended that accesses to elements of such arrays that
> alias other members be well-defined?

The middle-end assumes that fields in a structure do not overlap.
For overlaps you have to use a union.

In C++ I guess the rule that sizeof() of anything is at least 1 saves
you here so IMHO this is a C FE bug and we should probably simply
reject non-trailing empty arrays.

Note since b has size zero there isn't any real overlap, so ...

> In my tests, GCC assumes that neither read nor write accesses
> to elements of internal zero-length arrays alias other members,
> so assuming those aren't bugs I wonder if the documentation
> should be updated to make that clear and a warning added for
> such declarations (and perhaps also accesses).
>
> For example, the test in the following function is eliminated,
> implying that GCC assumes that the access to p->b does not modify
> p->c, even though with i set to 0 it would:
>
>    void f (struct A *p, int i)
>    {
>      int x = p->c;
>      p->b[i] = 1;
>      if (x != p->c)
>        __builtin_abort ();

... your testcase simply invokes undefined behavior by accessing
b out of bounds.

Richard.

>    }
>
> Martin

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: aliasing between internal zero-length-arrays and other members
  2018-06-05 11:42 ` Richard Biener
@ 2018-06-05 12:54   ` Jakub Jelinek
  0 siblings, 0 replies; 3+ messages in thread
From: Jakub Jelinek @ 2018-06-05 12:54 UTC (permalink / raw)
  To: Richard Biener; +Cc: Martin Sebor, GCC Development

On Tue, Jun 05, 2018 at 01:38:21PM +0200, Richard Biener wrote:
> On Tue, Jun 5, 2018 at 1:39 AM Martin Sebor <msebor@gmail.com> wrote:
> >
> > GCC silently (without -Wpedantic) accepts declarations of zero
> > length arrays that are followed by other members in the same
> > struct, such as in:
> >
> >    struct A { char a, b[0], c; };
> >
> > Is it intended that accesses to elements of such arrays that
> > alias other members be well-defined?
> 
> The middle-end assumes that fields in a structure do not overlap.
> For overlaps you have to use a union.
> 
> In C++ I guess the rule that sizeof() of anything is at least 1 saves
> you here so IMHO this is a C FE bug and we should probably simply
> reject non-trailing empty arrays.

The above is not flexible array member, but zero sized array, that is just
fine anywhere, at the toplevel as well as anywhere inside of the struct.
And yes, accessing it out of bounds is invalid, unless it is flexible-like,
i.e. at the end of the struct.

	Jakub

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2018-06-05 11:42 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-04 23:39 aliasing between internal zero-length-arrays and other members Martin Sebor
2018-06-05 11:42 ` Richard Biener
2018-06-05 12:54   ` Jakub Jelinek

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).