From: Martin Uecker <uecker@tugraz.at>
To: gcc-patches@gcc.gnu.org
Cc: Joseph Myers <joseph@codesourcery.com>,
Richard Biener <rguenther@suse.de>,
jakub@redhat.com
Subject: [C PATCH, v2] Fix ICE with -g and -std=c23 related to incomplete types [PR114361]
Date: Sun, 14 Apr 2024 14:30:27 +0200 [thread overview]
Message-ID: <448b0744f89d5c6ba5d6a5bacda154fcb74b7bca.camel@tugraz.at> (raw)
In-Reply-To: <02a9b94e4d653b6f1b9f89a1b62187f46e871738.camel@tugraz.at>
I had to revert the old patch because it broke LTO which lead
to PR114574. We now set TYPE_STRUCTURAL_EQUALITY and properly
update TYPE_CANONICAL for such types and also for pointers
to such types via a new function c_update_type_canonical
(thanks to Jakob).
Bootstrapped and regession tested on x86_64.
Fix ICE with -g and -std=c23 related to incomplete types [PR114361]
We did not update TYPE_CANONICAL for incomplete variants when
completing a structure. We now set TYPE_STRUCTURAL_EQUALITY for
incomplete structure and union types and then update TYPE_CANONICAL
later. See PR114574 for discussion.
2024-04-12 Martin Uecker <uecker@tugraz.at>
Jakub Jelinek <jakub@redhat.com>
PR lto/114574
PR c/114361
gcc/
* ipa-free-lang-data.cc (fld_incomplete_type_of): Allow
either of the types in the assert to have TYPE_STRUCTURAL_EQUALITY_P.
gcc/c/
* c-decl.cc (shadow_tag_warned): For flag_isoc23 and code not
ENUMERAL_TYPE use SET_TYPE_STRUCTURAL_EQUALITY.
(parser_xref_tag): Likewise.
(start_struct): For flag_isoc23 use SET_TYPE_STRUCTURAL_EQUALITY.
(c_update_type_canonical): New function.
(finish_struct): Put NULL as second == operand rather than first.
Assert TYPE_STRUCTURAL_EQUALITY_P. Call c_update_type_canonical.
* c-typeck.cc (composite_type_internal): Use
SET_TYPE_STRUCTURAL_EQUALITY. Formatting fix.
gcc/testsuite/
* gcc.dg/pr114574-1.c: New test.
* gcc.dg/pr114574-2.c: New test.
* gcc.dg/pr114361.c: New test.
* gcc.dg/c23-tag-incomplete-1.c: New test.
* gcc.dg/c23-tag-incomplete-2.c: New test.
---
gcc/c/c-decl.cc | 47 ++++++++++++++++++++-
gcc/c/c-typeck.cc | 4 +-
gcc/ipa-free-lang-data.cc | 4 +-
gcc/testsuite/gcc.dg/c23-tag-incomplete-1.c | 14 ++++++
gcc/testsuite/gcc.dg/c23-tag-incomplete-2.c | 13 ++++++
gcc/testsuite/gcc.dg/pr114361.c | 11 +++++
gcc/testsuite/gcc.dg/pr114574-1.c | 10 +++++
gcc/testsuite/gcc.dg/pr114574-2.c | 10 +++++
8 files changed, 110 insertions(+), 3 deletions(-)
create mode 100644 gcc/testsuite/gcc.dg/c23-tag-incomplete-1.c
create mode 100644 gcc/testsuite/gcc.dg/c23-tag-incomplete-2.c
create mode 100644 gcc/testsuite/gcc.dg/pr114361.c
create mode 100644 gcc/testsuite/gcc.dg/pr114574-1.c
create mode 100644 gcc/testsuite/gcc.dg/pr114574-2.c
diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc
index 345090dae38..54917297b6a 100644
--- a/gcc/c/c-decl.cc
+++ b/gcc/c/c-decl.cc
@@ -5051,6 +5051,8 @@ shadow_tag_warned (const struct c_declspecs *declspecs, int warned)
if (t == NULL_TREE)
{
t = make_node (code);
+ if (flag_isoc23 && code != ENUMERAL_TYPE)
+ SET_TYPE_STRUCTURAL_EQUALITY (t);
pushtag (input_location, name, t);
}
}
@@ -8809,6 +8811,8 @@ parser_xref_tag (location_t loc, enum tree_code code, tree name,
the forward-reference will be altered into a real type. */
ref = make_node (code);
+ if (flag_isoc23 && code != ENUMERAL_TYPE)
+ SET_TYPE_STRUCTURAL_EQUALITY (ref);
if (code == ENUMERAL_TYPE)
{
/* Give the type a default layout like unsigned int
@@ -8910,6 +8914,8 @@ start_struct (location_t loc, enum tree_code code, tree name,
if (ref == NULL_TREE || TREE_CODE (ref) != code)
{
ref = make_node (code);
+ if (flag_isoc23)
+ SET_TYPE_STRUCTURAL_EQUALITY (ref);
pushtag (loc, name, ref);
}
@@ -9347,6 +9353,43 @@ is_flexible_array_member_p (bool is_last_field,
return false;
}
+/* Recompute TYPE_CANONICAL for qualified versions of the type and
+ related pointer types after an aggregate type has been finalized.
+ Will not update array types, pointers to array types, function
+ types and other derived types created while the type was still
+ incomplete, those will remain TYPE_STRUCTURAL_EQUALITY_P. */
+
+static void
+c_update_type_canonical (tree t)
+{
+ for (tree x = TYPE_MAIN_VARIANT (t); x; x = TYPE_NEXT_VARIANT (x))
+ {
+ if (x != t
+ && TYPE_STRUCTURAL_EQUALITY_P (x)
+ && check_qualified_type (x, t, TYPE_QUALS (x)))
+ {
+ if (TYPE_CANONICAL (t) != t)
+ TYPE_CANONICAL (x)
+ = build_qualified_type (TYPE_CANONICAL (t), TYPE_QUALS (x));
+ else
+ TYPE_CANONICAL (x) = x;
+ }
+ else if (x != t)
+ continue;
+ for (tree p = TYPE_POINTER_TO (x); p; p = TYPE_NEXT_PTR_TO (p))
+ {
+ if (!TYPE_STRUCTURAL_EQUALITY_P (p))
+ continue;
+ if (TYPE_CANONICAL (x) != x || TYPE_REF_CAN_ALIAS_ALL (p))
+ TYPE_CANONICAL (p)
+ = build_pointer_type_for_mode (TYPE_CANONICAL (x), TYPE_MODE (p),
+ false);
+ else
+ TYPE_CANONICAL (p) = p;
+ c_update_type_canonical (p);
+ }
+ }
+}
/* Fill in the fields of a RECORD_TYPE or UNION_TYPE node, T.
LOC is the location of the RECORD_TYPE or UNION_TYPE's definition.
@@ -9695,11 +9738,12 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
/* Set type canonical based on equivalence class. */
if (flag_isoc23)
{
- if (NULL == c_struct_htab)
+ if (c_struct_htab == NULL)
c_struct_htab = hash_table<c_struct_hasher>::create_ggc (61);
hashval_t hash = c_struct_hasher::hash (t);
+ gcc_checking_assert (TYPE_STRUCTURAL_EQUALITY_P (t));
tree *e = c_struct_htab->find_slot_with_hash (t, hash, INSERT);
if (*e)
TYPE_CANONICAL (t) = *e;
@@ -9708,6 +9752,7 @@ finish_struct (location_t loc, tree t, tree fieldlist, tree attributes,
TYPE_CANONICAL (t) = t;
*e = t;
}
+ c_update_type_canonical (t);
}
tree incomplete_vars = C_TYPE_INCOMPLETE_VARS (TYPE_MAIN_VARIANT (t));
diff --git a/gcc/c/c-typeck.cc b/gcc/c/c-typeck.cc
index ddeab1e2a8a..4567b114734 100644
--- a/gcc/c/c-typeck.cc
+++ b/gcc/c/c-typeck.cc
@@ -532,6 +532,7 @@ composite_type_internal (tree t1, tree t2, struct composite_cache* cache)
/* Otherwise, create a new type node and link it into the cache. */
tree n = make_node (code1);
+ SET_TYPE_STRUCTURAL_EQUALITY (n);
TYPE_NAME (n) = TYPE_NAME (t1);
struct composite_cache cache2 = { t1, t2, n, cache };
@@ -590,7 +591,8 @@ composite_type_internal (tree t1, tree t2, struct composite_cache* cache)
TYPE_STUB_DECL (n) = pushdecl (build_decl (input_location, TYPE_DECL,
NULL_TREE, n));
- n = finish_struct(input_location, n, fields, attributes, NULL, &expr);
+ n = finish_struct (input_location, n, fields, attributes, NULL,
+ &expr);
n = qualify_type (n, t1);
diff --git a/gcc/ipa-free-lang-data.cc b/gcc/ipa-free-lang-data.cc
index 16ed55e2e5a..6f75444e513 100644
--- a/gcc/ipa-free-lang-data.cc
+++ b/gcc/ipa-free-lang-data.cc
@@ -255,7 +255,9 @@ fld_incomplete_type_of (tree t, class free_lang_data_d *fld)
first = build_reference_type_for_mode (t2, TYPE_MODE (t),
TYPE_REF_CAN_ALIAS_ALL (t));
gcc_assert (TYPE_CANONICAL (t2) != t2
- && TYPE_CANONICAL (t2) == TYPE_CANONICAL (TREE_TYPE (t)));
+ && (TYPE_CANONICAL (t2) == TYPE_CANONICAL (TREE_TYPE (t))
+ || TYPE_STRUCTURAL_EQUALITY_P (t2)
+ || TYPE_STRUCTURAL_EQUALITY_P (TREE_TYPE (t))));
if (!fld->pset.add (first))
add_tree_to_fld_list (first, fld);
return fld_type_variant (first, t, fld);
diff --git a/gcc/testsuite/gcc.dg/c23-tag-incomplete-1.c b/gcc/testsuite/gcc.dg/c23-tag-incomplete-1.c
new file mode 100644
index 00000000000..82d652569e9
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c23-tag-incomplete-1.c
@@ -0,0 +1,14 @@
+/* { dg-do compile }
+ * { dg-options "-std=c23 -g" } */
+
+struct a;
+typedef struct a b;
+
+void g() {
+ struct a { b* x; };
+}
+
+struct a { b* x; };
+
+
+
diff --git a/gcc/testsuite/gcc.dg/c23-tag-incomplete-2.c b/gcc/testsuite/gcc.dg/c23-tag-incomplete-2.c
new file mode 100644
index 00000000000..bc47a04ece5
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c23-tag-incomplete-2.c
@@ -0,0 +1,13 @@
+/* { dg-do compile }
+ * { dg-options "-std=c23 -g" } */
+
+struct a;
+typedef struct a b;
+
+void f() {
+ extern struct a { b* x; } t;
+}
+
+extern struct a { b* x; } t;
+
+
diff --git a/gcc/testsuite/gcc.dg/pr114361.c b/gcc/testsuite/gcc.dg/pr114361.c
new file mode 100644
index 00000000000..0f3feb53566
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr114361.c
@@ -0,0 +1,11 @@
+/* PR c/114361 */
+/* { dg-do compile } */
+/* { dg-options "-std=gnu23 -g" } */
+
+void f()
+{
+ typedef struct foo bar;
+ typedef __typeof( ({ (struct foo { bar *x; }){ }; }) ) wuz;
+ struct foo { wuz *x; };
+}
+
diff --git a/gcc/testsuite/gcc.dg/pr114574-1.c b/gcc/testsuite/gcc.dg/pr114574-1.c
new file mode 100644
index 00000000000..060dcdbe73e
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr114574-1.c
@@ -0,0 +1,10 @@
+/* PR lto/114574
+ * { dg-do compile }
+ * { dg-options "-flto" } */
+
+const struct S * x;
+struct S {};
+void f(const struct S **);
+
+
+
diff --git a/gcc/testsuite/gcc.dg/pr114574-2.c b/gcc/testsuite/gcc.dg/pr114574-2.c
new file mode 100644
index 00000000000..723291e2211
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr114574-2.c
@@ -0,0 +1,10 @@
+/* PR lto/114574
+ * { dg-do compile }
+ * { dg-options "-flto -std=c23" } */
+
+const struct S * x;
+struct S {};
+void f(const struct S **);
+
+
+
--
2.39.2
next prev parent reply other threads:[~2024-04-14 12:30 UTC|newest]
Thread overview: 67+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-11-16 21:36 c23 type compatibility rules, v3 Martin Uecker
2023-11-16 21:38 ` [PATCH 1/4] c23: tag compatibility rules for struct and unions Martin Uecker
2023-11-23 23:17 ` Joseph Myers
2023-11-16 21:38 ` [PATCH 2/4] c23: tag compatibility rules for enums Martin Uecker
2023-11-23 23:26 ` Joseph Myers
2023-11-16 21:39 ` [PATCH 3/4] c23: aliasing of compatible tagged types Martin Uecker
2023-11-23 23:47 ` Joseph Myers
2023-11-26 22:48 ` Martin Uecker
2023-11-27 7:46 ` Richard Biener
2023-11-28 1:00 ` Joseph Myers
2023-11-28 6:49 ` Martin Uecker
2023-11-28 10:47 ` Richard Biener
2023-11-28 11:51 ` Martin Uecker
2023-11-16 21:40 ` [PATCH 4/4] c23: construct composite type for " Martin Uecker
2023-11-27 13:16 ` [V4] [C PATCH 1/4] c23: tag compatibility rules for struct and unions Martin Uecker
2023-12-14 20:53 ` Joseph Myers
2023-11-27 13:16 ` [V4] [PATCH 2/4] c23: tag compatibility rules for enums Martin Uecker
2023-12-14 20:58 ` Joseph Myers
2023-11-27 13:16 ` [V4] [PATCH 3/4] c23: aliasing of compatible tagged types Martin Uecker
2023-12-14 21:10 ` Joseph Myers
2023-11-27 13:16 ` [V4] [PATCH 4/4] c23: construct composite type for " Martin Uecker
2023-12-17 17:41 ` [V5] [C PATCH 1/4] c23: tag compatibility rules for struct and unions Martin Uecker
2023-12-19 21:48 ` Joseph Myers
2023-12-17 17:42 ` [V5] [C PATCH 2/4] c23: tag compatibility rules for enums Martin Uecker
2023-12-19 21:50 ` Joseph Myers
2023-12-17 17:42 ` [V5] [C PATCH 3/4] c23: aliasing of compatible tagged types Martin Uecker
2023-12-19 22:02 ` Joseph Myers
2023-12-17 17:42 ` [V5] [C PATCH 4/4] c23: construct composite type for " Martin Uecker
2023-12-19 22:25 ` Joseph Myers
2023-12-21 21:47 ` [V6] " Martin Uecker
2023-12-22 16:27 ` Joseph Myers
2023-12-27 19:23 ` [C PATCH] C: Fix type compatibility for structs with variable sized fields Martin Uecker
2023-12-29 15:57 ` Joseph Myers
2024-01-27 16:10 ` Fix ICE with -g and -std=c23 when forming composite types [PR113438] Martin Uecker
2024-01-29 20:27 ` Joseph Myers
2024-04-02 18:54 ` [C PATCH] Fix ICE with -g and -std=c23 related to incomplete types [PR114361] Martin Uecker
2024-04-02 20:31 ` Joseph Myers
2024-04-02 19:02 ` [C PATCH] fix aliasing for structures/unions with incomplete types Martin Uecker
2024-04-02 20:42 ` Joseph Myers
2024-04-02 21:22 ` Martin Uecker
2024-04-03 15:33 ` Joseph Myers
2024-04-14 12:30 ` Martin Uecker [this message]
2024-04-14 12:38 ` [C PATCH, v2] Fix ICE with -g and -std=c23 related to incomplete types [PR114361] Martin Uecker
2024-04-15 6:55 ` Richard Biener
2024-04-15 7:38 ` Jakub Jelinek
2024-04-15 7:59 ` Jakub Jelinek
2024-04-15 8:02 ` Richard Biener
2024-04-15 8:05 ` Jakub Jelinek
2024-04-15 10:48 ` [PATCH] c, v3: " Jakub Jelinek
2024-04-15 11:33 ` Richard Biener
2024-04-16 7:20 ` Jakub Jelinek
2024-04-19 20:39 ` Joseph Myers
2024-04-15 7:03 ` [C PATCH, v2] " Jakub Jelinek
2024-05-18 13:27 ` [C PATCH] Fix for some variably modified types not being recognized [PR114831] Martin Uecker
2024-05-18 13:29 ` Martin Uecker
2024-05-20 21:18 ` Joseph Myers
2024-05-18 20:18 ` [C PATCH] Fix for redeclared enumerator initialized with different type [PR115109] Martin Uecker
2024-05-19 10:24 ` [C PATCH, v2] " Martin Uecker
2024-05-20 21:30 ` Joseph Myers
2024-05-21 5:40 ` Martin Uecker
2024-05-23 20:51 ` Joseph Myers
2024-05-21 12:18 ` [C PATCH]: allow aliasing of compatible types derived from enumeral types [PR115157] Martin Uecker
2024-05-23 20:59 ` Joseph Myers
2024-05-23 21:30 ` Ian Lance Taylor
2024-05-23 21:47 ` Martin Uecker
2024-05-23 21:53 ` Ian Lance Taylor
2024-05-24 5:56 ` Richard Biener
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=448b0744f89d5c6ba5d6a5bacda154fcb74b7bca.camel@tugraz.at \
--to=uecker@tugraz.at \
--cc=gcc-patches@gcc.gnu.org \
--cc=jakub@redhat.com \
--cc=joseph@codesourcery.com \
--cc=rguenther@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).