From patchwork Sun Apr 14 12:30:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Uecker X-Patchwork-Id: 1923465 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=tugraz.at header.i=@tugraz.at header.a=rsa-sha256 header.s=mailrelay header.b=rgcS6D7h; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4VHV5l1z4lz1yYP for ; Sun, 14 Apr 2024 22:31:05 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id C7A2D3858C60 for ; Sun, 14 Apr 2024 12:31:02 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mailrelay.tugraz.at (mailrelay.tugraz.at [129.27.2.202]) by sourceware.org (Postfix) with ESMTPS id 46AFC3858D34 for ; Sun, 14 Apr 2024 12:30:38 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 46AFC3858D34 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=tugraz.at Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=tugraz.at ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 46AFC3858D34 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=129.27.2.202 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1713097841; cv=none; b=kmV30yjthfmGHwPaZoesf/qky+mtLqruGZxxasm8gM0wyz5YjQ7SdGqglxo6b0ZiKnADyO4oMcip577tHslccDuJ9YVfTt/lWLJz6fT+wOrRYN4RyobBrFh9J3hcOAQCVKmm7yYL5szAmKWKv2q6k5NbUVxmaj/3PqtVYS1ctLc= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1713097841; c=relaxed/simple; bh=2kTeiX6R0A3wL2mBgg1j5Jhkj3d01hHVLZx16H1DGek=; h=DKIM-Signature:Message-ID:Subject:From:To:Date:MIME-Version; b=d2fAvTyyR92xNzUImbxCDchoLjm/B1hDTkzuVI+ytpRi3mpDNMCG+bJPL+jmmrTqVw54cof9t4uHp/fnrXU1qlSeUuHQW7K+dsHN7qaJqEGEA21Xi9/fBaCxauRJ85pSouS25bHWywgK1j9+OJxwj8uBf2Y6lFVcILyJOShS3Tk= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from vra-171-135.tugraz.at (vra-171-135.tugraz.at [129.27.171.135]) by mailrelay.tugraz.at (Postfix) with ESMTPSA id 4VHV4z74P3z3wgF; Sun, 14 Apr 2024 14:30:27 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tugraz.at; s=mailrelay; t=1713097828; bh=ucVwitmF+Llij8Usym84MGKBvw9ovRMJiNVOULym0KE=; h=Subject:From:To:Cc:Date:In-Reply-To:References; b=rgcS6D7hl9Ogx3Vm6Daq6S/tLYM6Rg97Rpl5uRrKo5R2q3199qEO9hyc2vM8t56Be IoeYkGV3IpsOd3A9NfW2dGTk2zmFmMyq0IszABo8mCizxxJUCcU0clgR9MTg22BB0r Rbr+Ne80mFdVFc0G6WKwemiqlaax2/yvmb9NC5CI= Message-ID: <448b0744f89d5c6ba5d6a5bacda154fcb74b7bca.camel@tugraz.at> Subject: [C PATCH, v2] Fix ICE with -g and -std=c23 related to incomplete types [PR114361] From: Martin Uecker To: gcc-patches@gcc.gnu.org Cc: Joseph Myers , Richard Biener , jakub@redhat.com Date: Sun, 14 Apr 2024 14:30:27 +0200 In-Reply-To: <02a9b94e4d653b6f1b9f89a1b62187f46e871738.camel@tugraz.at> References: <02a9b94e4d653b6f1b9f89a1b62187f46e871738.camel@tugraz.at> User-Agent: Evolution 3.46.4-2 MIME-Version: 1.0 X-TUG-Backscatter-control: G/VXY7/6zeyuAY/PU2/0qw X-Spam-Scanner: SpamAssassin 3.003001 X-Spam-Score-relay: -1.9 X-Scanned-By: MIMEDefang 2.74 on 129.27.10.117 X-Spam-Status: No, score=-11.5 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org 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 Jakub Jelinek 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::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 **); + + +