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.
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. */
--- /dev/null
+/* { 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;
+}
+
--- /dev/null
+/* 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; }
+