On Tue, 24 Nov 2020, Jakub Jelinek wrote: > Hi! > > As mentioned in the PR, we currently ICE on flexible array members in > structs and unions during __builtin_clear_padding processing. > > Jason said in the PR he'd prefer an error in these cases over forcefully > handling it as [0] arrays (everything is padding then) or consider the > arrays to have as many whole elements as would fit into the tail padding. > > So, this patch implements that. > > Ok for trunk if it passes bootstrap/regtest? So far has been tested just > on the dg.exp=builtin-clear-padding* dg-torture.exp=builtin-clear-padding* > check-gcc check-c++-all testsuite, but the builtin is currently not used > in anything else.
So code-gen wise this will still elide the builtin but error, right? OK then. Note it still leaves struct { int n; char c[1]; } to be handled which I think is the actual way we'll face "flexarray" members. IMHO we need to treat them as data but maybe we should emit a warning? Richard. > 2020-11-24 Jakub Jelinek <ja...@redhat.com> > > PR middle-end/97943 > * gimple-fold.c (clear_padding_union, clear_padding_type): Error on and > ignore flexible array member fields. Ignore fields with > error_mark_node type. > > * c-c++-common/builtin-clear-padding-2.c: New test. > * c-c++-common/builtin-clear-padding-3.c: New test. > * g++.dg/ext/builtin-clear-padding-1.C: New test. > * gcc.dg/builtin-clear-padding-2.c: New test. > > --- gcc/gimple-fold.c.jj 2020-11-23 17:01:48.255054823 +0100 > +++ gcc/gimple-fold.c 2020-11-24 09:53:17.724943252 +0100 > @@ -4255,6 +4255,17 @@ clear_padding_union (clear_padding_struc > for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN (field)) > if (TREE_CODE (field) == FIELD_DECL) > { > + if (DECL_SIZE_UNIT (field) == NULL_TREE) > + { > + if (TREE_TYPE (field) == error_mark_node) > + continue; > + gcc_assert (TREE_CODE (TREE_TYPE (field)) == ARRAY_TYPE > + && !COMPLETE_TYPE_P (TREE_TYPE (field))); > + error_at (buf->loc, "flexible array member %qD does not have " > + "well defined padding bits for %qs", > + field, "__builtin_clear_padding"); > + continue; > + } > HOST_WIDE_INT fldsz = tree_to_shwi (DECL_SIZE_UNIT (field)); > gcc_assert (union_buf->size == 0); > union_buf->off = start_off; > @@ -4372,11 +4383,12 @@ clear_padding_type (clear_padding_struct > for (tree field = TYPE_FIELDS (type); field; field = DECL_CHAIN > (field)) > if (TREE_CODE (field) == FIELD_DECL) > { > + tree ftype = TREE_TYPE (field); > if (DECL_BIT_FIELD (field)) > { > if (DECL_NAME (field) == NULL_TREE) > continue; > - HOST_WIDE_INT fldsz = TYPE_PRECISION (TREE_TYPE (field)); > + HOST_WIDE_INT fldsz = TYPE_PRECISION (ftype); > if (fldsz == 0) > continue; > HOST_WIDE_INT pos = int_byte_position (field); > @@ -4439,6 +4451,16 @@ clear_padding_type (clear_padding_struct > } > } > } > + else if (DECL_SIZE_UNIT (field) == NULL_TREE) > + { > + if (ftype == error_mark_node) > + continue; > + gcc_assert (TREE_CODE (ftype) == ARRAY_TYPE > + && !COMPLETE_TYPE_P (ftype)); > + error_at (buf->loc, "flexible array member %qD does not have " > + "well defined padding bits for %qs", > + field, "__builtin_clear_padding"); > + } > else > { > HOST_WIDE_INT pos = int_byte_position (field); > --- gcc/testsuite/c-c++-common/builtin-clear-padding-2.c.jj 2020-11-24 > 09:54:36.331055770 +0100 > +++ gcc/testsuite/c-c++-common/builtin-clear-padding-2.c 2020-11-24 > 10:16:30.468221320 +0100 > @@ -0,0 +1,17 @@ > +/* PR middle-end/97943 */ > +/* { dg-do compile } */ > +/* { dg-options "" } */ > + > +struct S { int a; char b[] __attribute__((aligned (2 * sizeof (int)))); }; > +struct T { int a; struct S b; }; > +union U { int a; struct S b; }; > +struct V { int a; union U b; }; > + > +void > +foo (struct S *s, struct T *t, union U *u, struct V *v) > +{ > + __builtin_clear_padding (s); /* { dg-error "flexible array member > '(S::)?b' does not have well defined padding bits for > '__builtin_clear_padding'" } */ > + __builtin_clear_padding (t); /* { dg-error "flexible array member > '(S::)?b' does not have well defined padding bits for > '__builtin_clear_padding'" } */ > + __builtin_clear_padding (u); /* { dg-error "flexible array member > '(S::)?b' does not have well defined padding bits for > '__builtin_clear_padding'" } */ > + __builtin_clear_padding (v); /* { dg-error "flexible array member > '(S::)?b' does not have well defined padding bits for > '__builtin_clear_padding'" } */ > +} > --- gcc/testsuite/c-c++-common/builtin-clear-padding-3.c.jj 2020-11-24 > 10:09:34.735913452 +0100 > +++ gcc/testsuite/c-c++-common/builtin-clear-padding-3.c 2020-11-24 > 10:16:41.732094196 +0100 > @@ -0,0 +1,15 @@ > +/* PR middle-end/97943 */ > +/* { dg-do compile } */ > +/* { dg-options "" } */ > + > +union U { int a; char b[] __attribute__((aligned (2 * sizeof (int)))); }; > /* { dg-error "flexible array member in union" } */ > +struct V { int a; union U b; }; > +struct W { int a; union U b; int c; }; > + > +void > +foo (union U *u, struct V *v, struct W *w) > +{ > + __builtin_clear_padding (u); > + __builtin_clear_padding (v); > + __builtin_clear_padding (w); > +} > --- gcc/testsuite/g++.dg/ext/builtin-clear-padding-1.C.jj 2020-11-24 > 10:10:49.315071724 +0100 > +++ gcc/testsuite/g++.dg/ext/builtin-clear-padding-1.C 2020-11-24 > 10:17:22.461634498 +0100 > @@ -0,0 +1,15 @@ > +// PR middle-end/97943 > +// { dg-do compile } > +// { dg-options "" } > + > +struct S { int a; char b[] __attribute__((aligned (2 * sizeof (int)))); }; > // { dg-error "flexible array member 'S::b' not at end of 'struct \[TV]'" } > +struct T { int a; struct S b; int c; }; // { dg-message "next member > 'int T::c' declared here|in the definition of 'struct T'" } > +union U { int a; struct S b; }; > +struct V { int a; union U b; int : 15; int c; }; // { dg-message "next > member 'int V::c' declared here|in the definition of 'struct V'" } > + > +void > +foo (struct T *t, struct V *v) > +{ > + __builtin_clear_padding (t); // { dg-error "flexible array member > 'S::b' does not have well defined padding bits for '__builtin_clear_padding'" > } > + __builtin_clear_padding (v); // { dg-error "flexible array member > 'S::b' does not have well defined padding bits for '__builtin_clear_padding'" > } > +} > --- gcc/testsuite/gcc.dg/builtin-clear-padding-2.c.jj 2020-11-24 > 10:08:47.543446090 +0100 > +++ gcc/testsuite/gcc.dg/builtin-clear-padding-2.c 2020-11-24 > 10:17:03.031853796 +0100 > @@ -0,0 +1,15 @@ > +/* PR middle-end/97943 */ > +/* { dg-do compile } */ > +/* { dg-options "" } */ > + > +struct S { int a; char b[] __attribute__((aligned (2 * sizeof (int)))); }; > +struct T { int a; struct S b; int c; }; > +union U { int a; struct S b; }; > +struct V { int a; union U b; int : 15; int c; }; > + > +void > +foo (struct T *t, struct V *v) > +{ > + __builtin_clear_padding (t); /* { dg-error "flexible array member > 'b' does not have well defined padding bits for '__builtin_clear_padding'" } > */ > + __builtin_clear_padding (v); /* { dg-error "flexible array member > 'b' does not have well defined padding bits for '__builtin_clear_padding'" } > */ > +} > > Jakub > > -- Richard Biener <rguent...@suse.de> SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg, Germany; GF: Felix Imend