]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c: Move checking assertions from recursion when forming composite types to avoid...
authorMartin Uecker <uecker@tugraz.at>
Sun, 1 Jun 2025 18:34:52 +0000 (20:34 +0200)
committerMartin Uecker <uecker@gcc.gnu.org>
Tue, 3 Jun 2025 16:41:46 +0000 (18:41 +0200)
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.

gcc/c/c-typeck.cc
gcc/testsuite/gcc.dg/gnu23-tag-composite-6.c

index 2f243cab8daa1f3f609c4ec0a57a1fb32f1e7d95..b59b5c8a8bb198cca7a2ea4336a481ebdf1af839 100644 (file)
@@ -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
index 2411b04d3884275b2772a7a330ffa5027bb9d2b3..076c066f9c820efa52b75688953279f84b04c28c 100644 (file)
@@ -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;
 }