diff options
author | Jakub Jelinek <jakub@redhat.com> | 2024-06-06 22:12:11 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2024-06-06 22:12:11 +0200 |
commit | d5a3c6d43acb8b2211d9fb59d59482d74c010f01 (patch) | |
tree | 0ed21629018bc186f921e0fea7fd9308eda19100 /gcc/c | |
parent | 230d62a2cdd16c1ec8fe87998ec01081503f010d (diff) | |
download | gcc-d5a3c6d43acb8b2211d9fb59d59482d74c010f01.zip gcc-d5a3c6d43acb8b2211d9fb59d59482d74c010f01.tar.gz gcc-d5a3c6d43acb8b2211d9fb59d59482d74c010f01.tar.bz2 |
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.
Diffstat (limited to 'gcc/c')
-rw-r--r-- | gcc/c/c-decl.cc | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index 64924b8..6c09eb7 100644 --- a/gcc/c/c-decl.cc +++ b/gcc/c/c-decl.cc @@ -9446,6 +9446,17 @@ verify_counted_by_attribute (tree struct_type, tree field_decl) 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, 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 && !C_TYPE_VARIABLE_SIZE (t)) { |