diff mbox series

c: Fix up pointer types to may_alias structures [PR114493]

Message ID Zl61SWqTwyrk9jm4@tucnak
State New
Headers show
Series c: Fix up pointer types to may_alias structures [PR114493] | expand

Commit Message

Jakub Jelinek June 4, 2024, 6:33 a.m. UTC
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?

2024-06-04  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.


	Jakub

Comments

Martin Uecker June 5, 2024, 6:47 a.m. UTC | #1
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  <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.
> 
> --- 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
>
Joseph Myers June 6, 2024, 7:57 p.m. UTC | #2
On Tue, 4 Jun 2024, Jakub Jelinek wrote:

> 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?
> 
> 2024-06-04  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.

OK.
diff mbox series

Patch

--- 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) {};
+}