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.
This commit is contained in:
Martin Uecker
2025-05-29 19:13:46 +02:00
committed by Martin Uecker
parent 62ed7fb525
commit 0e0f963bcf
3 changed files with 22 additions and 1 deletions

View File

@@ -776,7 +776,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. */

View File

@@ -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;
}

View File

@@ -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; }