public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-10045] c: Fix ICE with -g and -std=c23 related to incomplete types [PR114361]
@ 2024-04-19 22:11 Jakub Jelinek
  0 siblings, 0 replies; only message in thread
From: Jakub Jelinek @ 2024-04-19 22:11 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:a39983bf58d3097c472252f6989d19b60909dd9a

commit r14-10045-ga39983bf58d3097c472252f6989d19b60909dd9a
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Sat Apr 20 00:05:21 2024 +0200

    c: Fix ICE with -g and -std=c23 related to incomplete types [PR114361]
    
    We did not update TYPE_CANONICAL for incomplete variants when
    completing a structure.  We now set for flag_isoc23 TYPE_STRUCTURAL_EQUALITY_P
    for incomplete structure and union types and then update TYPE_CANONICAL
    later, though update it only for the variants and derived pointer types
    which can be easily discovered.  Other derived types created while
    the type was still incomplete will remain TYPE_STRUCTURAL_EQUALITY_P.
    See PR114574 for discussion.
    
    2024-04-20  Martin Uecker  <uecker@tugraz.at>
                Jakub Jelinek  <jakub@redhat.com>
    
            PR lto/114574
            PR c/114361
    gcc/c/
            * c-decl.cc (shadow_tag_warned): For flag_isoc23 and code not
            ENUMERAL_TYPE use SET_TYPE_STRUCTURAL_EQUALITY.
            (parser_xref_tag): Likewise.
            (start_struct): For flag_isoc23 use SET_TYPE_STRUCTURAL_EQUALITY.
            (c_update_type_canonical): New function.
            (finish_struct): Put NULL as second == operand rather than first.
            Assert TYPE_STRUCTURAL_EQUALITY_P.  Call c_update_type_canonical.
            * c-typeck.cc (composite_type_internal): Use
            SET_TYPE_STRUCTURAL_EQUALITY.  Formatting fix.
    gcc/testsuite/
            * gcc.dg/pr114574-1.c: New test.
            * gcc.dg/pr114574-2.c: New test.
            * gcc.dg/pr114361.c: New test.
            * gcc.dg/c23-tag-incomplete-1.c: New test.
            * gcc.dg/c23-tag-incomplete-2.c: New test.

Diff:
---
 gcc/c/c-decl.cc                             | 49 ++++++++++++++++++++++++++++-
 gcc/c/c-typeck.cc                           |  4 ++-
 gcc/testsuite/gcc.dg/c23-tag-incomplete-1.c | 11 +++++++
 gcc/testsuite/gcc.dg/c23-tag-incomplete-2.c | 11 +++++++
 gcc/testsuite/gcc.dg/pr114361.c             | 10 ++++++
 gcc/testsuite/gcc.dg/pr114574-1.c           |  7 +++++
 gcc/testsuite/gcc.dg/pr114574-2.c           |  7 +++++
 7 files changed, 97 insertions(+), 2 deletions(-)

diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 345090dae38..52af8f32998 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -5051,6 +5051,8 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
 	      if (t == NULL_TREE)
 		{
 		  t = make_node (code);
+		  if (flag_isoc23 && code != ENUMERAL_TYPE)
+		    SET_TYPE_STRUCTURAL_EQUALITY (t);
 		  pushtag (input_location, name, t);
 		}
 	    }
@@ -8809,6 +8811,8 @@ parser_xref_tag (location_t loc, enum tree_code code, tree name,
      the forward-reference will be altered into a real type.  */
 
   ref = make_node (code);
+  if (flag_isoc23 && code != ENUMERAL_TYPE)
+    SET_TYPE_STRUCTURAL_EQUALITY (ref);
   if (code == ENUMERAL_TYPE)
     {
       /* Give the type a default layout like unsigned int
@@ -8910,6 +8914,8 @@ start_struct (location_t loc, enum tree_code code, tree name,
   if (ref == NULL_TREE || TREE_CODE (ref) != code)
     {
       ref = make_node (code);
+      if (flag_isoc23)
+	SET_TYPE_STRUCTURAL_EQUALITY (ref);
       pushtag (loc, name, ref);
     }
 
@@ -9347,6 +9353,45 @@ is_flexible_array_member_p (bool is_last_field,
   return false;
 }
 
+/* Recompute TYPE_CANONICAL for variants of the type including qualified
+   versions of the type and related pointer types after an aggregate type
+   has been finalized.
+   Will not update array types, pointers to array types, function
+   types and other derived types created while the type was still
+   incomplete, those will remain TYPE_STRUCTURAL_EQUALITY_P.  */
+
+static void
+c_update_type_canonical (tree t)
+{
+  for (tree x = TYPE_MAIN_VARIANT (t); x; x = TYPE_NEXT_VARIANT (x))
+    {
+      if (x != t && TYPE_STRUCTURAL_EQUALITY_P (x))
+	{
+	  if (TYPE_QUALS (x) == TYPE_QUALS (t))
+	    TYPE_CANONICAL (x) = TYPE_CANONICAL (t);
+	  else if (TYPE_CANONICAL (t) != t
+		   || check_qualified_type (x, t, TYPE_QUALS (x)))
+	    TYPE_CANONICAL (x)
+	      = build_qualified_type (TYPE_CANONICAL (t), TYPE_QUALS (x));
+	  else
+	    TYPE_CANONICAL (x) = x;
+	}
+      else if (x != t)
+	continue;
+      for (tree p = TYPE_POINTER_TO (x); p; p = TYPE_NEXT_PTR_TO (p))
+	{
+	  if (!TYPE_STRUCTURAL_EQUALITY_P (p))
+	    continue;
+	  if (TYPE_CANONICAL (x) != x || TYPE_REF_CAN_ALIAS_ALL (p))
+	    TYPE_CANONICAL (p)
+	      = build_pointer_type_for_mode (TYPE_CANONICAL (x), TYPE_MODE (p),
+					     false);
+	  else
+	    TYPE_CANONICAL (p) = p;
+	  c_update_type_canonical (p);
+	}
+    }
+}
 
 /* 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.
@@ -9695,11 +9740,12 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
   /* Set type canonical based on equivalence class.  */
   if (flag_isoc23)
     {
-      if (NULL == c_struct_htab)
+      if (c_struct_htab == NULL)
 	c_struct_htab = hash_table<c_struct_hasher>::create_ggc (61);
 
       hashval_t hash = c_struct_hasher::hash (t);
 
+      gcc_checking_assert (TYPE_STRUCTURAL_EQUALITY_P (t));
       tree *e = c_struct_htab->find_slot_with_hash (t, hash, INSERT);
       if (*e)
 	TYPE_CANONICAL (t) = *e;
@@ -9708,6 +9754,7 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
 	  TYPE_CANONICAL (t) = t;
 	  *e = t;
 	}
+      c_update_type_canonical (t);
     }
 
   tree incomplete_vars = C_TYPE_INCOMPLETE_VARS (TYPE_MAIN_VARIANT (t));
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index ddeab1e2a8a..4567b114734 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -532,6 +532,7 @@ composite_type_internal (tree t1, tree t2, struct composite_cache* cache)
 	  /* Otherwise, create a new type node and link it into the cache.  */
 
 	  tree n = make_node (code1);
+	  SET_TYPE_STRUCTURAL_EQUALITY (n);
 	  TYPE_NAME (n) = TYPE_NAME (t1);
 
 	  struct composite_cache cache2 = { t1, t2, n, cache };
@@ -590,7 +591,8 @@ composite_type_internal (tree t1, tree t2, struct composite_cache* cache)
 	  TYPE_STUB_DECL (n) = pushdecl (build_decl (input_location, TYPE_DECL,
 						     NULL_TREE, n));
 
-	  n = finish_struct(input_location, n, fields, attributes, NULL, &expr);
+	  n = finish_struct (input_location, n, fields, attributes, NULL,
+			     &expr);
 
 	  n = qualify_type (n, t1);
 
diff --git a/gcc/testsuite/gcc.dg/c23-tag-incomplete-1.c b/gcc/testsuite/gcc.dg/c23-tag-incomplete-1.c
new file mode 100644
index 00000000000..837de05948c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c23-tag-incomplete-1.c
@@ -0,0 +1,11 @@
+/* { dg-do compile }
+ * { dg-options "-std=c23 -g" } */
+
+struct a;
+typedef struct a b;
+
+void g() {
+    struct a { b* x; };
+}
+
+struct a { b* x; };
diff --git a/gcc/testsuite/gcc.dg/c23-tag-incomplete-2.c b/gcc/testsuite/gcc.dg/c23-tag-incomplete-2.c
new file mode 100644
index 00000000000..ba36789e59b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c23-tag-incomplete-2.c
@@ -0,0 +1,11 @@
+/* { dg-do compile }
+ * { dg-options "-std=c23 -g" } */
+
+struct a;
+typedef struct a b;
+
+void f() {
+	extern struct a { b* x; } t;
+}
+
+extern struct a { b* x; } t;
diff --git a/gcc/testsuite/gcc.dg/pr114361.c b/gcc/testsuite/gcc.dg/pr114361.c
new file mode 100644
index 00000000000..1d5babaa966
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr114361.c
@@ -0,0 +1,10 @@
+/* PR c/114361 */
+/* { dg-do compile } */
+/* { dg-options "-std=gnu23 -g" } */
+
+void f()
+{
+    typedef struct foo bar;
+    typedef __typeof( ({ (struct foo { bar *x; }){ }; }) ) wuz;
+    struct foo { wuz *x; };
+}
diff --git a/gcc/testsuite/gcc.dg/pr114574-1.c b/gcc/testsuite/gcc.dg/pr114574-1.c
new file mode 100644
index 00000000000..e125b68a646
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr114574-1.c
@@ -0,0 +1,7 @@
+/* PR lto/114574
+ * { dg-do compile }
+ * { dg-options "-flto" } */
+
+const struct S * x;
+struct S {};
+void f(const struct S **);
diff --git a/gcc/testsuite/gcc.dg/pr114574-2.c b/gcc/testsuite/gcc.dg/pr114574-2.c
new file mode 100644
index 00000000000..0e709975e61
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr114574-2.c
@@ -0,0 +1,7 @@
+/* PR lto/114574
+ * { dg-do compile }
+ * { dg-options "-flto -std=c23" } */
+
+const struct S * x;
+struct S {};
+void f(const struct S **);

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2024-04-19 22:11 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-19 22:11 [gcc r14-10045] c: Fix ICE with -g and -std=c23 related to incomplete types [PR114361] Jakub Jelinek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).