c: Fix up pointer types to may_alias structures [PR114493]
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. 2024-06-06 Jakub Jelinek <jakub@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. (cherry picked from commit d5a3c6d43acb8b2211d9fb59d59482d74c010f01)
This commit is contained in:
parent
35ed54f136
commit
56c73729c3
3 changed files with 60 additions and 0 deletions
|
@ -9393,6 +9393,17 @@ c_update_type_canonical (tree t)
|
|||
}
|
||||
}
|
||||
|
||||
/* 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.
|
||||
|
@ -9737,6 +9748,10 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
|
|||
|
||||
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)
|
||||
{
|
||||
|
|
19
gcc/testsuite/gcc.dg/pr114493-1.c
Normal file
19
gcc/testsuite/gcc.dg/pr114493-1.c
Normal file
|
@ -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) {};
|
||||
}
|
26
gcc/testsuite/gcc.dg/pr114493-2.c
Normal file
26
gcc/testsuite/gcc.dg/pr114493-2.c
Normal file
|
@ -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) {};
|
||||
}
|
Loading…
Add table
Reference in a new issue