Am Dienstag, dem 04.06.2024 um 08:33 +0200 schrieb Jakub Jelinek: > Hi! > > The following testcase ICEs in ipa-free-lang, because the > fld_incomplete_type_of > gcc_assert (TYPE_CANONICAL (t2) != t2 > && TYPE_CANONICAL (t2) == TYPE_CANONICAL (TREE_TYPE > (t))); > assertion doesn't hold. > This is because t is a struct S * type which was created while struct S > was still incomplete and without the may_alias attribute (and TYPE_CANONICAL > of a pointer type is a type created with can_alias_all = false argument), > while later on on the struct definition may_alias attribute was used. > fld_incomplete_type_of then creates an incomplete distinct copy of the > structure (but with the original attributes) but pointers created for it > are because of the "may_alias" attribute TYPE_REF_CAN_ALIAS_ALL, including > their TYPE_CANONICAL, because while that is created with !can_alias_all > argument, we later set it because of the "may_alias" attribute on the > to_type. > > This doesn't ICE with C++ since PR70512 fix because the C++ FE sets > TYPE_REF_CAN_ALIAS_ALL on all pointer types to the class type (and its > variants) when the may_alias is added. > > The following patch does that in the C FE as well. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk and > release branches?
>From my (irrelevant) side this patch looks good. Martin > > 2024-06-04 Jakub Jelinek <ja...@redhat.com> > > PR c/114493 > * c-decl.cc (c_fixup_may_alias): New function. > (finish_struct): Call it if "may_alias" attribute is > specified. > > * gcc.dg/pr114493-1.c: New test. > * gcc.dg/pr114493-2.c: New test. > > --- gcc/c/c-decl.cc.jj 2024-05-07 08:47:35.974836903 +0200 > +++ gcc/c/c-decl.cc 2024-06-03 19:55:53.819586291 +0200 > @@ -9446,6 +9446,17 @@ verify_counted_by_attribute (tree struct > return; > } > > +/* TYPE is a struct or union that we're applying may_alias to after the body > is > + parsed. Fixup any POINTER_TO types. */ > + > +static void > +c_fixup_may_alias (tree type) > +{ > + for (tree t = TYPE_POINTER_TO (type); t; t = TYPE_NEXT_PTR_TO (t)) > + for (tree v = TYPE_MAIN_VARIANT (t); v; v = TYPE_NEXT_VARIANT (v)) > + TYPE_REF_CAN_ALIAS_ALL (v) = true; > +} > + > /* Fill in the fields of a RECORD_TYPE or UNION_TYPE node, T. > LOC is the location of the RECORD_TYPE or UNION_TYPE's definition. > FIELDLIST is a chain of FIELD_DECL nodes for the fields. > @@ -9791,6 +9802,10 @@ finish_struct (location_t loc, tree t, t > > C_TYPE_BEING_DEFINED (t) = 0; > > + if (lookup_attribute ("may_alias", TYPE_ATTRIBUTES (t))) > + for (x = TYPE_MAIN_VARIANT (t); x; x = TYPE_NEXT_VARIANT (x)) > + c_fixup_may_alias (x); > + > /* Set type canonical based on equivalence class. */ > if (flag_isoc23 && !C_TYPE_VARIABLE_SIZE (t)) > { > --- gcc/testsuite/gcc.dg/pr114493-1.c.jj 2024-06-03 19:59:58.774336785 > +0200 > +++ gcc/testsuite/gcc.dg/pr114493-1.c 2024-06-03 19:59:12.931944923 +0200 > @@ -0,0 +1,19 @@ > +/* PR c/114493 */ > +/* { dg-do compile { target lto } } */ > +/* { dg-options "-O2 -flto" } */ > + > +void foo (void); > +struct S; > +struct S bar (struct S **); > +struct S qux (const struct S **); > + > +struct __attribute__((__may_alias__)) S { > + int s; > +}; > + > +struct S > +baz (void) > +{ > + foo (); > + return (struct S) {}; > +} > --- gcc/testsuite/gcc.dg/pr114493-2.c.jj 2024-06-03 19:59:58.774336785 > +0200 > +++ gcc/testsuite/gcc.dg/pr114493-2.c 2024-06-03 20:01:00.886512830 +0200 > @@ -0,0 +1,26 @@ > +/* PR c/114493 */ > +/* { dg-do compile { target lto } } */ > +/* { dg-options "-O2 -flto -std=c23" } */ > + > +void foo (void); > +struct S; > +struct S bar (struct S **); > +struct S qux (const struct S **); > + > +void > +corge (void) > +{ > + struct S { int s; } s; > + s.s = 0; > +} > + > +struct __attribute__((__may_alias__)) S { > + int s; > +}; > + > +struct S > +baz (void) > +{ > + foo (); > + return (struct S) {}; > +} > > Jakub >