From 0e0f963bcfbfce351dd4aad82e6dbc6fc84a0724 Mon Sep 17 00:00:00 2001 From: Martin Uecker Date: Thu, 29 May 2025 19:13:46 +0200 Subject: [PATCH] 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. --- gcc/c/c-typeck.cc | 2 +- gcc/testsuite/gcc.dg/gnu23-tag-composite-6.c | 11 +++++++++++ gcc/testsuite/gcc.dg/pr120381.c | 10 ++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/gnu23-tag-composite-6.c create mode 100644 gcc/testsuite/gcc.dg/pr120381.c diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc index 360216b9662..e5dd8d54c51 100644 --- a/gcc/c/c-typeck.cc +++ b/gcc/c/c-typeck.cc @@ -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. */ 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; } + -- 2.47.2