This is a fun one. 

Bootstrapped and regression tested for x86_64.

Martin


    c: fix ICE for mutually recursive structures [PR120381]
    
    For invalid nesting of a structure definition in a definition
    of itself or when using a rather obscure construction using statement
    expressions, we can create mutually recursive pairs of non-identical
    but compatible structure types.  This can lead to invalid composite
    types and an ICE.  If we detect recursion even for swapped pairs
    when forming composite types, this is avoided.
    
            PR c/120381
    
    gcc/c/ChangeLog:
            * c-typeck.cc (composite_type_internal): Stop recursion for
            swapped pairs.
    
    gcc/testsuite/ChangeLog:
            * gcc.dg/pr120381.c: New test.
            * gcc.dg/gnu23-tag-composite-6.c: New test.

diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index 0e1f842e22d..c8c1b86aa21 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -773,7 +773,7 @@ composite_type_internal (tree t1, tree t2, struct 
composite_cache* cache)
             construction, return it.  */
 
          for (struct composite_cache *c = cache; c != NULL; c = c->next)
-           if (c->t1 == t1 && c->t2 == t2)
+           if ((c->t1 == t1 && c->t2 == t2) || (c->t1 == t2 && c->t2 == t1))
               return c->composite;
 
          /* Otherwise, create a new type node and link it into the cache.  */
diff --git a/gcc/testsuite/gcc.dg/gnu23-tag-composite-6.c 
b/gcc/testsuite/gcc.dg/gnu23-tag-composite-6.c
new file mode 100644
index 00000000000..2411b04d388
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/gnu23-tag-composite-6.c
@@ -0,0 +1,11 @@
+/* { dg-do compile } */
+/* { dg-options "-std=gnu23" } */
+
+int f()
+{
+    typedef struct foo bar;
+    struct foo { typeof(({ (struct foo { bar * x; }){ }; })) * x; } *q;
+    typeof(q->x) p;
+    1 ? p : q;
+}
+
diff --git a/gcc/testsuite/gcc.dg/pr120381.c b/gcc/testsuite/gcc.dg/pr120381.c
new file mode 100644
index 00000000000..5c017e60c6b
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr120381.c
@@ -0,0 +1,10 @@
+/* PR120381 */
+/* { dg-do compile } */
+
+struct A {
+  struct A {           /* { dg-error "nested redefinition" } */
+    struct A *p;
+  } *p;
+};
+int foo(const struct A *q) { return q->p == q; }
+

Reply via email to