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

Reply via email to