public inbox for gcc-cvs@sourceware.org help / color / mirror / Atom feed
From: Jakub Jelinek <jakub@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org Subject: [gcc r14-10045] c: Fix ICE with -g and -std=c23 related to incomplete types [PR114361] Date: Fri, 19 Apr 2024 22:11:32 +0000 (GMT) [thread overview] Message-ID: <20240419221132.D49B2384AB43@sourceware.org> (raw) https://gcc.gnu.org/g:a39983bf58d3097c472252f6989d19b60909dd9a commit r14-10045-ga39983bf58d3097c472252f6989d19b60909dd9a Author: Jakub Jelinek <jakub@redhat.com> Date: Sat Apr 20 00:05:21 2024 +0200 c: 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 for flag_isoc23 TYPE_STRUCTURAL_EQUALITY_P for incomplete structure and union types and then update TYPE_CANONICAL later, though update it only for the variants and derived pointer types which can be easily discovered. Other derived types created while the type was still incomplete will remain TYPE_STRUCTURAL_EQUALITY_P. See PR114574 for discussion. 2024-04-20 Martin Uecker <uecker@tugraz.at> Jakub Jelinek <jakub@redhat.com> PR lto/114574 PR c/114361 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. Diff: --- gcc/c/c-decl.cc | 49 ++++++++++++++++++++++++++++- gcc/c/c-typeck.cc | 4 ++- gcc/testsuite/gcc.dg/c23-tag-incomplete-1.c | 11 +++++++ gcc/testsuite/gcc.dg/c23-tag-incomplete-2.c | 11 +++++++ gcc/testsuite/gcc.dg/pr114361.c | 10 ++++++ gcc/testsuite/gcc.dg/pr114574-1.c | 7 +++++ gcc/testsuite/gcc.dg/pr114574-2.c | 7 +++++ 7 files changed, 97 insertions(+), 2 deletions(-) diff --git a/gcc/c/c-decl.cc b/gcc/c/c-decl.cc index 345090dae38..52af8f32998 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,45 @@ is_flexible_array_member_p (bool is_last_field, return false; } +/* Recompute TYPE_CANONICAL for variants of the type including 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)) + { + if (TYPE_QUALS (x) == TYPE_QUALS (t)) + TYPE_CANONICAL (x) = TYPE_CANONICAL (t); + else if (TYPE_CANONICAL (t) != t + || check_qualified_type (x, t, TYPE_QUALS (x))) + 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 +9740,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 +9754,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/testsuite/gcc.dg/c23-tag-incomplete-1.c b/gcc/testsuite/gcc.dg/c23-tag-incomplete-1.c new file mode 100644 index 00000000000..837de05948c --- /dev/null +++ b/gcc/testsuite/gcc.dg/c23-tag-incomplete-1.c @@ -0,0 +1,11 @@ +/* { 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..ba36789e59b --- /dev/null +++ b/gcc/testsuite/gcc.dg/c23-tag-incomplete-2.c @@ -0,0 +1,11 @@ +/* { 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..1d5babaa966 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr114361.c @@ -0,0 +1,10 @@ +/* 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..e125b68a646 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr114574-1.c @@ -0,0 +1,7 @@ +/* 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..0e709975e61 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr114574-2.c @@ -0,0 +1,7 @@ +/* PR lto/114574 + * { dg-do compile } + * { dg-options "-flto -std=c23" } */ + +const struct S * x; +struct S {}; +void f(const struct S **);
reply other threads:[~2024-04-19 22:11 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=20240419221132.D49B2384AB43@sourceware.org \ --to=jakub@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ /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: linkBe 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).