https://gcc.gnu.org/g:b25ec038dcaf7e48103911f695756a55478cd54f
commit r16-1088-gb25ec038dcaf7e48103911f695756a55478cd54f Author: Martin Uecker <uec...@tugraz.at> Date: Sun Jun 1 20:34:52 2025 +0200 c: Move checking assertions from recursion when forming composite types to avoid ICE. The checking assertion in composite_type_internal for structures and unions may fail if there are self-referential types. To avoid this, we move them out of the recursion. This should also be more efficient and covers other types. We have to ignore some cases where we form composite types with qualifiers not matching (PR120510). gcc/c/ChangeLog: * c-typeck.cc (composite_type_internal,composite_type): Move checking assertions. gcc/testsuite/ChangeLog: * gcc.dg/gnu23-tag-composite-6.c: Update. Diff: --- gcc/c/c-typeck.cc | 17 ++++++++++------- gcc/testsuite/gcc.dg/gnu23-tag-composite-6.c | 26 +++++++++++++++++++++++--- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc index 2f243cab8daa..b59b5c8a8bb1 100644 --- a/gcc/c/c-typeck.cc +++ b/gcc/c/c-typeck.cc @@ -846,12 +846,7 @@ composite_type_internal (tree t1, tree t2, struct composite_cache* cache) n = finish_struct (input_location, n, fields, attributes, NULL, &expr); - n = qualify_type (n, t1); - - gcc_checking_assert (!TYPE_NAME (n) || comptypes (n, t1)); - gcc_checking_assert (!TYPE_NAME (n) || comptypes (n, t2)); - - return n; + return qualify_type (n, t1); } /* FALLTHRU */ case ENUMERAL_TYPE: @@ -1004,7 +999,15 @@ tree composite_type (tree t1, tree t2) { struct composite_cache cache = { }; - return composite_type_internal (t1, t2, &cache); + tree n = composite_type_internal (t1, t2, &cache); + /* For function and arrays there are some cases where qualifiers do + not match. See PR120510. */ + if (FUNCTION_TYPE != TREE_CODE (n) && ARRAY_TYPE != TREE_CODE (n)) + { + gcc_checking_assert (comptypes (n, t1)); + gcc_checking_assert (comptypes (n, t2)); + } + return n; } /* Return the type of a conditional expression between pointers to diff --git a/gcc/testsuite/gcc.dg/gnu23-tag-composite-6.c b/gcc/testsuite/gcc.dg/gnu23-tag-composite-6.c index 2411b04d3884..076c066f9c82 100644 --- a/gcc/testsuite/gcc.dg/gnu23-tag-composite-6.c +++ b/gcc/testsuite/gcc.dg/gnu23-tag-composite-6.c @@ -1,11 +1,31 @@ /* { dg-do compile } */ /* { dg-options "-std=gnu23" } */ +#define NEST(...) typeof(({ (__VA_ARGS__){ }; })) + int f() { typedef struct foo bar; - struct foo { typeof(({ (struct foo { bar * x; }){ }; })) * x; } *q; - typeof(q->x) p; - 1 ? p : q; + struct foo { NEST(struct foo { bar *x; }) *x; } *q; + typeof(q->x) p0; + typeof(q->x) p1; + 1 ? p0 : q; + 1 ? p1 : q; + 1 ? p0 : p1; +} + +int g() +{ + typedef struct fo2 bar; + struct fo2 { NEST(struct fo2 { NEST(struct fo2 { bar *x; }) * x; }) *x; } *q; + typeof(q->x) p0; + typeof(q->x->x) p1; + typeof(q->x->x->x) p2; + 1 ? p0 : q; + 1 ? p1 : q; + 1 ? p2 : q; + 1 ? p0 : p1; + 1 ? p2 : p1; + 1 ? p0 : p2; }