From patchwork Mon Aug 28 13:58:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 137037 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:a7d1:0:b0:3f2:4152:657d with SMTP id p17csp3346864vqm; Mon, 28 Aug 2023 06:59:26 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFKq8g9RrB2BTepDgFxAIyJ8aYEjdl3jeckXJOXX2wGQ3f7nU44RBEIacs5zPh1+hFduMcW X-Received: by 2002:a17:906:8d86:b0:9a5:c4e9:34b5 with SMTP id ry6-20020a1709068d8600b009a5c4e934b5mr257486ejc.35.1693231165876; Mon, 28 Aug 2023 06:59:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1693231165; cv=none; d=google.com; s=arc-20160816; b=T5mORw0j4Hc9DWmwmKIfzaHEBytphjdbZ/XwoDlR+IAWWZlqSe2QOwYCV57xm3L5W8 1QpJRQOExmZz1ZvMJCsh7LnqqXoaEKmT+diElp5mOruh3czJY76tBhso7jwaAuZzIswm IgVC4lcnso1PBzzcH/SVVhwBMs6Cm8e6XvXHt4ai8aG1rNhHhXsSu4954SGL0/Xyjmsq lRJa6Rkkf1ChgKclWzEOsDGU/tupi32ou19kNrrc5yGDd1MbvETqEoINH/av2RwYOZtM bsZ/x0vW9oNawYmpbg/y//0aKebu/dTX1zlOfSraxxEu9n/e95fPNxd4LwflaKSZSN8D kScA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:reply-to:from:list-subscribe:list-help:list-post :list-archive:list-unsubscribe:list-id:precedence :content-disposition:in-reply-to:mime-version:references:message-id :subject:cc:to:date:dmarc-filter:delivered-to:dkim-signature :dkim-filter; bh=8O6q0mCLoA6cDd+bvA49uRpkcSE/JOk+a6A4b3C+qx0=; fh=0xZT+NBKSeH8qOu04/61f1ZGePpF4jF/gxp331YE14k=; b=xX+ECcw0oQRL8BTsjSw/oWAxpvyfb2uoFACwtofDZQ3SwGOaRQigGOsKVTcY5Ugsou AfHLjbelu8VmR+Uz4E1pE6JTzC6raSoPCsv7VN1Z7AtZB6M8W0A5XWtf9XSu9fZALnki IrSPSmaUeCKxEwPhOuiWEkpc/WvdITZza9A97HyxsqutH5H5ZgZe2adASGjt+Nx9AueC EMwbndgpheksU4kHBqhEGxv/R/T4M0iJlkO13+JHp9GE72ebnhYsQUys1Yh0UiUC+hyl 9XAwK+nBcOOk6FdAN1Vb21KWv6r2MVmvkLdZPC7+cpiZMO4gzAbSgMb3qnktEn9Be24f lC3w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=UKqgflwG; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (ip-8-43-85-97.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id g6-20020a1709061c8600b00984f07f9bc1si2574433ejh.395.2023.08.28.06.59.25 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 28 Aug 2023 06:59:25 -0700 (PDT) Received-SPF: pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@gcc.gnu.org header.s=default header.b=UKqgflwG; spf=pass (google.com: domain of gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=gnu.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id B2AC3385841F for ; Mon, 28 Aug 2023 13:59:24 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B2AC3385841F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1693231164; bh=8O6q0mCLoA6cDd+bvA49uRpkcSE/JOk+a6A4b3C+qx0=; h=Date:To:Cc:Subject:References:In-Reply-To:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:List-Subscribe: From:Reply-To:From; b=UKqgflwGoUYtXml25Lf2phf/Sj2tZILXRI9dIltJv5VFsOsMWXCEc02N3LyN07l0U B8MK66ukrrP8ts9WkKqFu7UNZqXd/o9eFS1tsW6PWJpIuwb9KaGVU87C6uMMHgtwpG EM05/6tL+xHo5yHfld8oi/0wnPXTrnodT3P7lMfw= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by sourceware.org (Postfix) with ESMTPS id 5829E3858D33 for ; Mon, 28 Aug 2023 13:58:28 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 5829E3858D33 Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-112---aPcwrQNzmvW-GUbqMGFw-1; Mon, 28 Aug 2023 09:58:22 -0400 X-MC-Unique: --aPcwrQNzmvW-GUbqMGFw-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id E840418A65C3 for ; Mon, 28 Aug 2023 13:58:21 +0000 (UTC) Received: from tucnak.zalov.cz (unknown [10.45.224.16]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 776592166B26; Mon, 28 Aug 2023 13:58:21 +0000 (UTC) Received: from tucnak.zalov.cz (localhost [127.0.0.1]) by tucnak.zalov.cz (8.17.1/8.17.1) with ESMTPS id 37SDwJlh1504087 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Mon, 28 Aug 2023 15:58:19 +0200 Received: (from jakub@localhost) by tucnak.zalov.cz (8.17.1/8.17.1/Submit) id 37SDwJMm1504086; Mon, 28 Aug 2023 15:58:19 +0200 Date: Mon, 28 Aug 2023 15:58:19 +0200 To: Jason Merrill Cc: gcc-patches@gcc.gnu.org Subject: [PATCH] c++, v2: Fix up mangling of function/block scope static structured bindings and emit abi tags [PR111069] Message-ID: References: <88ab126d-1f07-3b00-d489-b7cdd4698828@redhat.com> MIME-Version: 1.0 In-Reply-To: X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Disposition: inline X-Spam-Status: No, score=-3.4 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H4, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, 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: , X-Patchwork-Original-From: Jakub Jelinek via Gcc-patches From: Jakub Jelinek Reply-To: Jakub Jelinek Errors-To: gcc-patches-bounces+ouuuleilei=gmail.com@gcc.gnu.org Sender: "Gcc-patches" X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1775481562871554036 X-GMAIL-MSGID: 1775481562871554036 Hi! On Thu, Aug 24, 2023 at 06:39:10PM +0200, Jakub Jelinek via Gcc-patches wrote: > > Maybe do this in mangle_decomp, based on the actual mangling in process > > instead of this pseudo-mangling? > > Not sure that is possible, for 2 reasons: > 1) determine_local_discriminator otherwise works on DECL_NAME, not mangled > names, so if one uses (albeit implementation reserved) > _ZZN1N3fooI1TB3bazEEivEDC1h1iEB6foobar and similar identifiers, they > could clash with the counting of the structured bindings > 2) seems the local discriminator counting shouldn't take into account > details like abi tags, e.g. if I have: The following updated patch handles everything except it leaves for the above 2 reasons the determination of local discriminator where it was. I had to add a new (defaulted) argument to cp_finish_decl and do cp_maybe_mangle_decomp from there, so that it is after e.g. auto type deduction and maybe_commonize_var (which had to be changed as well) and spots in cp_finish_decl where we need or might need mangled names already. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? There is one difference between g++ with this patch and clang++, g++ uses _ZZ3barI1TB3quxEivEDC1o1pEB3qux while clang++ uses _ZZ3barI1TB3quxEivEDC1o1pE but from what I can see, such a difference is there also when just using normal local decls: struct [[gnu::abi_tag ("foobar")]] S { int i; }; struct [[gnu::abi_tag ("qux")]] T { int i; S j; int k; }; inline int foo () { static S c; static T d; return ++c.i + ++d.i; } template inline int bar () { static S c; static T d; return ++c.i + ++d.i; } int (*p) () = &foo; int (*q) () = &bar; where both compilers mangle c in foo as: _ZZ3foovE1cB6foobar and d in there as _ZZ3foovE1dB3qux and similarly both compilers mangle c in bar as _ZZ3barI1TB3quxEivE1cB6foobar but g++ mangles d in bar as _ZZ3barI1TB3quxEivE1dB3qux while clang++ mangles it as just _ZZ3barI1TB3quxEivE1d No idea what is right or wrong according to Itanium mangling. 2023-08-28 Jakub Jelinek PR c++/111069 gcc/ * common.opt (fabi-version=): Document version 19. * doc/invoke.texi (-fabi-version=): Likewise. gcc/c-family/ * c-opts.cc (c_common_post_options): Change latest_abi_version to 19. gcc/cp/ * cp-tree.h (determine_local_discriminator): Add NAME argument with NULL_TREE default. (struct cp_decomp): New type. (cp_finish_decl): Add DECOMP argument defaulted to nullptr. (cp_maybe_mangle_decomp): Remove declaration. * decl.cc (determine_local_discriminator): Add NAME argument, use it if non-NULL, otherwise compute it the old way. (maybe_commonize_var): Don't return early for structured bindings. (cp_finish_decl): Add DECOMP argument, if non-NULL, call cp_maybe_mangle_decomp. (cp_maybe_mangle_decomp): Make it static with a forward declaration. Call determine_local_discriminator. * mangle.cc (find_decomp_unqualified_name): Remove. (write_unqualified_name): Don't call find_decomp_unqualified_name. (mangle_decomp): Handle mangling of static function/block scope structured bindings. Don't call decl_mangling_context twice. Call check_abi_tags, call write_abi_tags for abi version >= 19 and emit -Wabi warnings if needed. (write_guarded_var_name): Handle structured bindings. (mangle_ref_init_variable): Use write_guarded_var_name. * parser.cc (cp_convert_range_for, cp_parser_decomposition_declaration, cp_finish_omp_range_for): Don't call cp_maybe_mangle_decomp, adjust cp_finish_decl callers. * pt.cc (tsubst_expr): Likewise. gcc/testsuite/ * g++.dg/cpp2a/decomp8.C: New test. * g++.dg/cpp2a/decomp9.C: New test. * g++.dg/abi/macro0.C: Expect __GXX_ABI_VERSION 1019 rather than 1018. Jakub --- gcc/common.opt.jj 2023-08-28 10:32:41.519579280 +0200 +++ gcc/common.opt 2023-08-28 10:35:30.337342832 +0200 @@ -1010,6 +1010,9 @@ Driver Undocumented ; 18: Corrects errors in mangling of lambdas with additional context. ; Default in G++ 13. ; +; 19: Emits ABI tags if needed in structured binding mangled names. +; Default in G++ 14. +; ; Additional positive integers will be assigned as new versions of ; the ABI become the default version of the ABI. fabi-version= --- gcc/doc/invoke.texi.jj 2023-08-28 10:32:42.322568643 +0200 +++ gcc/doc/invoke.texi 2023-08-28 10:35:30.342342766 +0200 @@ -3016,6 +3016,9 @@ in C++14 and up. Version 18, which first appeard in G++ 13, fixes manglings of lambdas that have additional context. +Version 19, which first appeard in G++ 14, fixes manglings of structured +bindings to include ABI tags. + See also @option{-Wabi}. @opindex fabi-compat-version --- gcc/c-family/c-opts.cc.jj 2023-08-28 10:32:41.462580035 +0200 +++ gcc/c-family/c-opts.cc 2023-08-28 10:35:30.338342819 +0200 @@ -974,7 +974,7 @@ c_common_post_options (const char **pfil /* Change flag_abi_version to be the actual current ABI level, for the benefit of c_cpp_builtins, and to make comparison simpler. */ - const int latest_abi_version = 18; + const int latest_abi_version = 19; /* Generate compatibility aliases for ABI v13 (8.2) by default. */ const int abi_compat_default = 13; --- gcc/cp/cp-tree.h.jj 2023-08-28 10:33:10.972189104 +0200 +++ gcc/cp/cp-tree.h 2023-08-28 10:41:19.782716871 +0200 @@ -6858,7 +6858,7 @@ extern void pop_switch (void); extern void note_break_stmt (void); extern bool note_iteration_stmt_body_start (void); extern void note_iteration_stmt_body_end (bool); -extern void determine_local_discriminator (tree); +extern void determine_local_discriminator (tree, tree = NULL_TREE); extern bool member_like_constrained_friend_p (tree); extern bool fns_correspond (tree, tree); extern int decls_match (tree, tree, bool = true); @@ -6891,9 +6891,9 @@ extern tree start_decl (const cp_decl extern void start_decl_1 (tree, bool); extern bool check_array_initializer (tree, tree, tree); extern void omp_declare_variant_finalize (tree, tree); -extern void cp_finish_decl (tree, tree, bool, tree, int); +struct cp_decomp { tree decl; unsigned int count; }; +extern void cp_finish_decl (tree, tree, bool, tree, int, cp_decomp * = nullptr); extern tree lookup_decomp_type (tree); -extern void cp_maybe_mangle_decomp (tree, tree, unsigned int); extern void cp_finish_decomp (tree, tree, unsigned int); extern int cp_complete_array_type (tree *, tree, bool); extern int cp_complete_array_type_or_error (tree *, tree, bool, tsubst_flags_t); --- gcc/cp/decl.cc.jj 2023-08-28 10:32:42.170570656 +0200 +++ gcc/cp/decl.cc 2023-08-28 12:10:38.973074234 +0200 @@ -911,15 +911,16 @@ static GTY((deletable)) vec generally very few of these in any particular function. */ void -determine_local_discriminator (tree decl) +determine_local_discriminator (tree decl, tree name) { auto_cond_timevar tv (TV_NAME_LOOKUP); retrofit_lang_decl (decl); tree ctx = DECL_CONTEXT (decl); - tree name = (TREE_CODE (decl) == TYPE_DECL - && TYPE_UNNAMED_P (TREE_TYPE (decl)) - ? NULL_TREE : DECL_NAME (decl)); size_t nelts = vec_safe_length (local_entities); + if (name == NULL_TREE) + name = (TREE_CODE (decl) == TYPE_DECL + && TYPE_UNNAMED_P (TREE_TYPE (decl)) + ? NULL_TREE : DECL_NAME (decl)); for (size_t i = 0; i < nelts; i += 2) { tree *pair = &(*local_entities)[i]; @@ -6417,8 +6418,9 @@ layout_var_decl (tree decl) void maybe_commonize_var (tree decl) { - /* Don't mess with __FUNCTION__ and similar. */ - if (DECL_ARTIFICIAL (decl)) + /* Don't mess with __FUNCTION__ and similar. But do handle structured + bindings. */ + if (DECL_ARTIFICIAL (decl) && !DECL_DECOMPOSITION_P (decl)) return; /* Static data in a function with comdat linkage also has comdat @@ -8212,6 +8214,8 @@ omp_declare_variant_finalize (tree decl, } } +static void cp_maybe_mangle_decomp (tree, tree, unsigned int); + /* Finish processing of a declaration; install its line number and initial value. If the length of an array type is not known before, @@ -8221,11 +8225,14 @@ omp_declare_variant_finalize (tree decl, true, then INIT is an integral constant expression. FLAGS is LOOKUP_ONLYCONVERTING if the = init syntax was used, else 0 - if the (init) syntax was used. */ + if the (init) syntax was used. + + DECOMP is first identifier's DECL and identifier count in a structured + bindings, nullptr if not a structured binding. */ void cp_finish_decl (tree decl, tree init, bool init_const_expr_p, - tree asmspec_tree, int flags) + tree asmspec_tree, int flags, cp_decomp *decomp) { vec *cleanups = NULL; const char *asmspec = NULL; @@ -8600,6 +8607,9 @@ cp_finish_decl (tree decl, tree init, bo return; } + if (decomp) + cp_maybe_mangle_decomp (decl, decomp->decl, decomp->count); + /* If this is a local variable that will need a mangled name, register it now. We must do this before processing the initializer for the variable, since the initialization might @@ -9070,7 +9080,7 @@ lookup_decomp_type (tree v) /* Mangle a decomposition declaration if needed. Arguments like in cp_finish_decomp. */ -void +static void cp_maybe_mangle_decomp (tree decl, tree first, unsigned int count) { if (!processing_template_decl @@ -9082,6 +9092,25 @@ cp_maybe_mangle_decomp (tree decl, tree tree d = first; for (unsigned int i = 0; i < count; i++, d = DECL_CHAIN (d)) v[count - i - 1] = d; + if (DECL_FUNCTION_SCOPE_P (decl)) + { + size_t sz = 3; + for (unsigned int i = 0; i < count; ++i) + sz += IDENTIFIER_LENGTH (DECL_NAME (v[i])) + 1; + char *name = XALLOCAVEC (char, sz); + name[0] = 'D'; + name[1] = 'C'; + char *p = name + 2; + for (unsigned int i = 0; i < count; ++i) + { + size_t len = IDENTIFIER_LENGTH (DECL_NAME (v[i])); + *p++ = ' '; + memcpy (p, IDENTIFIER_POINTER (DECL_NAME (v[i])), len); + p += len; + } + *p = '\0'; + determine_local_discriminator (decl, get_identifier (name)); + } SET_DECL_ASSEMBLER_NAME (decl, mangle_decomp (decl, v)); maybe_apply_pragma_weak (decl); } --- gcc/cp/mangle.cc.jj 2023-08-28 10:32:42.172570630 +0200 +++ gcc/cp/mangle.cc 2023-08-28 10:35:30.333342885 +0200 @@ -1347,51 +1347,6 @@ write_template_prefix (const tree node) add_substitution (substitution); } -/* As the list of identifiers for the structured binding declaration - DECL is likely gone, try to recover the DC + E portion - from its mangled name. Return pointer to the DC and set len to - the length up to and including the terminating E. On failure - return NULL. */ - -static const char * -find_decomp_unqualified_name (tree decl, size_t *len) -{ - const char *p = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); - const char *end = p + IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (decl)); - bool nested = false; - if (!startswith (p, "_Z")) - return NULL; - p += 2; - if (startswith (p, "St")) - p += 2; - else if (*p == 'N') - { - nested = true; - ++p; - while (ISDIGIT (p[0])) - { - char *e; - long num = strtol (p, &e, 10); - if (num >= 1 && num < end - e) - p = e + num; - else - break; - } - } - if (!startswith (p, "DC")) - return NULL; - if (nested) - { - if (end[-1] != 'E') - return NULL; - --end; - } - if (end[-1] != 'E') - return NULL; - *len = end - p; - return p; -} - /* "For the purposes of mangling, the name of an anonymous union is considered to be the name of the first named data member found by a pre-order, depth-first, declaration-order walk of the data members of the anonymous @@ -1465,17 +1420,7 @@ write_unqualified_name (tree decl) { found = true; gcc_assert (DECL_ASSEMBLER_NAME_SET_P (decl)); - const char *decomp_str = NULL; - size_t decomp_len = 0; - if (VAR_P (decl) - && DECL_DECOMPOSITION_P (decl) - && DECL_NAME (decl) == NULL_TREE - && DECL_NAMESPACE_SCOPE_P (decl)) - decomp_str = find_decomp_unqualified_name (decl, &decomp_len); - if (decomp_str) - write_chars (decomp_str, decomp_len); - else - write_source_name (DECL_ASSEMBLER_NAME (decl)); + write_source_name (DECL_ASSEMBLER_NAME (decl)); } else if (DECL_DECLARES_FUNCTION_P (decl)) { @@ -4373,6 +4318,7 @@ mangle_decomp (const tree decl, vec (%qD) and %<%s=%d%> (%qD)", + G.entity, fabi_version, warn_abi_version, id2, + fabi_version, save_ver, id); + else + warning_at (DECL_SOURCE_LOCATION (G.entity), OPT_Wabi, + "the mangled name of %qD changes between " + "%<%s=%d%> (%qD) and %<%s=%d%> (%qD)", + G.entity, fabi_version, save_ver, id, + fabi_version, warn_abi_version, id2); + } + return id; } @@ -4574,6 +4572,13 @@ write_guarded_var_name (const tree varia /* The name of a guard variable for a reference temporary should refer to the reference, not the temporary. */ write_string (IDENTIFIER_POINTER (DECL_NAME (variable)) + 4); + else if (DECL_DECOMPOSITION_P (variable) + && DECL_NAME (variable) == NULL_TREE + && startswith (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (variable)), + "_Z")) + /* The name of a guard variable for a structured binding needs special + casing. */ + write_string (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (variable)) + 2); else write_name (variable, /*ignore_local_scope=*/0); } @@ -4640,7 +4645,7 @@ mangle_ref_init_variable (const tree var start_mangling (variable); write_string ("_ZGR"); check_abi_tags (variable); - write_name (variable, /*ignore_local_scope=*/0); + write_guarded_var_name (variable); /* Avoid name clashes with aggregate initialization of multiple references at once. */ write_compact_number (current_ref_temp_count++); --- gcc/cp/parser.cc.jj 2023-08-28 10:33:10.985188932 +0200 +++ gcc/cp/parser.cc 2023-08-28 11:06:51.260457348 +0200 @@ -14182,15 +14182,20 @@ cp_convert_range_for (tree statement, tr tf_warning_or_error); finish_for_expr (expression, statement); + cp_decomp decomp_data, *decomp = nullptr; if (VAR_P (range_decl) && DECL_DECOMPOSITION_P (range_decl)) - cp_maybe_mangle_decomp (range_decl, decomp_first_name, decomp_cnt); + { + decomp_data.decl = decomp_first_name; + decomp_data.count = decomp_cnt; + decomp = &decomp_data; + } /* The declaration is initialized with *__begin inside the loop body. */ tree deref_begin = build_x_indirect_ref (input_location, begin, RO_UNARY_STAR, NULL_TREE, tf_warning_or_error); cp_finish_decl (range_decl, deref_begin, /*is_constant_init*/false, NULL_TREE, - LOOKUP_ONLYCONVERTING); + LOOKUP_ONLYCONVERTING, decomp); if (VAR_P (range_decl) && DECL_DECOMPOSITION_P (range_decl)) cp_finish_decomp (range_decl, decomp_first_name, decomp_cnt); @@ -15890,9 +15895,10 @@ cp_parser_decomposition_declaration (cp_ if (decl != error_mark_node) { - cp_maybe_mangle_decomp (decl, prev, v.length ()); + cp_decomp decomp = { prev, v.length () }; cp_finish_decl (decl, initializer, non_constant_p, NULL_TREE, - (is_direct_init ? LOOKUP_NORMAL : LOOKUP_IMPLICIT)); + (is_direct_init ? LOOKUP_NORMAL : LOOKUP_IMPLICIT), + &decomp); cp_finish_decomp (decl, prev, v.length ()); } } @@ -43697,27 +43703,26 @@ cp_finish_omp_range_for (tree orig, tree gcc_assert (TREE_CODE (orig) == TREE_LIST && TREE_CODE (TREE_CHAIN (orig)) == TREE_VEC); tree decl = TREE_VEC_ELT (TREE_CHAIN (orig), 2); - tree decomp_first_name = NULL_TREE; - unsigned int decomp_cnt = 0; + cp_decomp decomp_data, *decomp = nullptr; if (VAR_P (decl) && DECL_DECOMPOSITION_P (decl)) { - decomp_first_name = TREE_VEC_ELT (TREE_CHAIN (orig), 3); - decomp_cnt = TREE_VEC_LENGTH (TREE_CHAIN (orig)) - 3; + decomp_data.decl = TREE_VEC_ELT (TREE_CHAIN (orig), 3); + decomp_data.count = TREE_VEC_LENGTH (TREE_CHAIN (orig)) - 3; if (TREE_PUBLIC (TREE_CHAIN (orig))) { /* Undo temporary clearing of DECL_HAS_VALUE_EXPR_P done by cp_convert_omp_range_for above. */ TREE_PUBLIC (TREE_CHAIN (orig)) = 0; - tree d = decomp_first_name; - for (unsigned i = 0; i < decomp_cnt; i++) + tree d = decomp_data.decl; + for (unsigned i = 0; i < decomp_data.count; i++) { if (TREE_TYPE (d) != error_mark_node) DECL_HAS_VALUE_EXPR_P (d) = 1; d = DECL_CHAIN (d); } } - cp_maybe_mangle_decomp (decl, decomp_first_name, decomp_cnt); + decomp = &decomp_data; } /* The declaration is initialized with *__begin inside the loop body. */ @@ -43725,9 +43730,9 @@ cp_finish_omp_range_for (tree orig, tree build_x_indirect_ref (input_location, begin, RO_UNARY_STAR, NULL_TREE, tf_warning_or_error), /*is_constant_init*/false, NULL_TREE, - LOOKUP_ONLYCONVERTING); + LOOKUP_ONLYCONVERTING, decomp); if (VAR_P (decl) && DECL_DECOMPOSITION_P (decl)) - cp_finish_decomp (decl, decomp_first_name, decomp_cnt); + cp_finish_decomp (decl, decomp->decl, decomp->count); } /* Return true if next tokens contain a standard attribute that contains --- gcc/cp/pt.cc.jj 2023-08-28 10:33:11.045188137 +0200 +++ gcc/cp/pt.cc 2023-08-28 10:49:36.880140901 +0200 @@ -19043,8 +19043,8 @@ tsubst_expr (tree t, tree args, tsubst_f else { bool const_init = false; - unsigned int cnt = 0; - tree first = NULL_TREE, ndecl = error_mark_node; + cp_decomp decomp_data, *decomp = nullptr; + tree ndecl = error_mark_node; tree asmspec_tree = NULL_TREE; maybe_push_decl (decl); @@ -19056,9 +19056,13 @@ tsubst_expr (tree t, tree args, tsubst_f if (VAR_P (decl) && DECL_DECOMPOSITION_P (decl) && TREE_TYPE (pattern_decl) != error_mark_node) - ndecl = tsubst_decomp_names (decl, pattern_decl, args, - complain, in_decl, &first, - &cnt); + { + ndecl = tsubst_decomp_names (decl, pattern_decl, args, + complain, in_decl, + &decomp_data.decl, + &decomp_data.count); + decomp = &decomp_data; + } init = tsubst_init (init, decl, args, complain, in_decl); @@ -19066,9 +19070,6 @@ tsubst_expr (tree t, tree args, tsubst_f const_init = (DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (pattern_decl)); - if (ndecl != error_mark_node) - cp_maybe_mangle_decomp (ndecl, first, cnt); - /* In a non-template function, VLA type declarations are handled in grokdeclarator; for templates, handle them now. */ @@ -19085,10 +19086,11 @@ tsubst_expr (tree t, tree args, tsubst_f TREE_TYPE (asmspec_tree) = char_array_type_node; } - cp_finish_decl (decl, init, const_init, asmspec_tree, 0); + cp_finish_decl (decl, init, const_init, asmspec_tree, 0, + decomp); if (ndecl != error_mark_node) - cp_finish_decomp (ndecl, first, cnt); + cp_finish_decomp (ndecl, decomp->decl, decomp->count); } } } --- gcc/testsuite/g++.dg/cpp2a/decomp8.C.jj 2023-08-28 10:35:30.337342832 +0200 +++ gcc/testsuite/g++.dg/cpp2a/decomp8.C 2023-08-28 12:42:30.747030644 +0200 @@ -0,0 +1,74 @@ +// PR c++/111069 +// { dg-do compile { target c++11 } } +// { dg-options "" } + +extern int a[2]; +struct Y { int b, c, d; }; + +inline int +freddy () +{ + static auto [i, j] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + // { dg-warning "structured binding declaration can be 'static' only in" "" { target c++17_down } .-1 } + static auto [k, l] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + // { dg-warning "structured binding declaration can be 'static' only in" "" { target c++17_down } .-1 } + int ret = ++i + ++k; + { + static auto [i, j] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + // { dg-warning "structured binding declaration can be 'static' only in" "" { target c++17_down } .-1 } + static auto [k, l] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + // { dg-warning "structured binding declaration can be 'static' only in" "" { target c++17_down } .-1 } + ret += ++i + ++k; + } + { + static auto [i, j] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + // { dg-warning "structured binding declaration can be 'static' only in" "" { target c++17_down } .-1 } + static auto [k, l] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + // { dg-warning "structured binding declaration can be 'static' only in" "" { target c++17_down } .-1 } + ret += ++i + ++k; + } + return ret; +} + +namespace N +{ + namespace M + { + template + inline int + corge () + { + static auto [i, j] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + // { dg-warning "structured binding declaration can be 'static' only in" "" { target c++17_down } .-1 } + static auto && [u, v, w] = Y{}; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + // { dg-warning "structured binding declaration can be 'static' only in" "" { target c++17_down } .-1 } + int ret = ++i + ++u; + { + static auto && [u, v, w] = Y{}; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + // { dg-warning "structured binding declaration can be 'static' only in" "" { target c++17_down } .-1 } + ret += ++v; + } + return ret; + } + } +} + +int (*p) () = &freddy; +int (*q) () = N::M::corge<3>; + +// { dg-final { scan-assembler "_ZZ6freddyvEDC1i1jE" } } +// { dg-final { scan-assembler "_ZZ6freddyvEDC1i1jE_0" } } +// { dg-final { scan-assembler "_ZZ6freddyvEDC1i1jE_1" } } +// { dg-final { scan-assembler "_ZZ6freddyvEDC1k1lE" } } +// { dg-final { scan-assembler "_ZZ6freddyvEDC1k1lE_0" } } +// { dg-final { scan-assembler "_ZZ6freddyvEDC1k1lE_1" } } +// { dg-final { scan-assembler "_ZZN1N1M5corgeILi3EEEivEDC1i1jE" } } +// { dg-final { scan-assembler "_ZGVZ6freddyvEDC1i1jE" } } +// { dg-final { scan-assembler "_ZGVZ6freddyvEDC1i1jE_0" } } +// { dg-final { scan-assembler "_ZGVZ6freddyvEDC1i1jE_1" } } +// { dg-final { scan-assembler "_ZGVZ6freddyvEDC1k1lE" } } +// { dg-final { scan-assembler "_ZGVZ6freddyvEDC1k1lE_0" } } +// { dg-final { scan-assembler "_ZGVZ6freddyvEDC1k1lE_1" } } +// { dg-final { scan-assembler "_ZGVZN1N1M5corgeILi3EEEivEDC1i1jE" } } +// { dg-final { scan-assembler "_ZGRZN1N1M5corgeILi3EEEivEDC1u1v1wE_" } } +// { dg-final { scan-assembler "_ZGRZN1N1M5corgeILi3EEEivEDC1u1v1wE_0_" } } --- gcc/testsuite/g++.dg/cpp2a/decomp9.C.jj 2023-08-28 12:21:50.292919000 +0200 +++ gcc/testsuite/g++.dg/cpp2a/decomp9.C 2023-08-28 12:33:25.478452184 +0200 @@ -0,0 +1,82 @@ +// PR c++/111069 +// { dg-do compile { target c++11 } } +// { dg-options "" } + +struct [[gnu::abi_tag ("foobar")]] S { int i; }; +extern S a[2]; +struct [[gnu::abi_tag ("qux")]] T { int i; S j; int k; }; +extern T b[2]; + +namespace N { + auto [i, j] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + auto [k, l] = b; // { dg-warning "structured bindings only available with" "" { target c++14_down } } +} + +inline int +foo () +{ + static auto [m, n] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + // { dg-warning "structured binding declaration can be 'static' only in" "" { target c++17_down } .-1 } + static auto [o, p] = b; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + // { dg-warning "structured binding declaration can be 'static' only in" "" { target c++17_down } .-1 } + int ret = ++N::i.i + ++N::k.i; + { + static auto [m, n] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + // { dg-warning "structured binding declaration can be 'static' only in" "" { target c++17_down } .-1 } + + ret += ++n.i; + } + { + static auto [m, n] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + // { dg-warning "structured binding declaration can be 'static' only in" "" { target c++17_down } .-1 } + + ret += ++n.i; + } + ret += ++m.i + ++o.i; + return ret; +} + +template +inline int +bar () +{ + static auto [m, n] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + // { dg-warning "structured binding declaration can be 'static' only in" "" { target c++17_down } .-1 } + static auto [o, p] = b; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + // { dg-warning "structured binding declaration can be 'static' only in" "" { target c++17_down } .-1 } + int ret = 0; + { + static auto [m, n] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + // { dg-warning "structured binding declaration can be 'static' only in" "" { target c++17_down } .-1 } + ret += ++n.i; + } + { + static auto [m, n] = a; // { dg-warning "structured bindings only available with" "" { target c++14_down } } + // { dg-warning "structured binding declaration can be 'static' only in" "" { target c++17_down } .-1 } + ret += ++n.i; + } + ret += ++m.i + ++o.i; + return ret; +} + +int (*p) () = &foo; +int (*q) () = &bar; + +// { dg-final { scan-assembler "_ZZ3foovEDC1m1nEB6foobar" } } +// { dg-final { scan-assembler "_ZZ3foovEDC1m1nEB6foobar_0" } } +// { dg-final { scan-assembler "_ZZ3foovEDC1m1nEB6foobar_1" } } +// { dg-final { scan-assembler "_ZZ3foovEDC1o1pEB3qux" } } +// { dg-final { scan-assembler "_ZZ3barI1TB3quxEivEDC1m1nEB6foobar" } } +// { dg-final { scan-assembler "_ZZ3barI1TB3quxEivEDC1m1nEB6foobar_0" } } +// { dg-final { scan-assembler "_ZZ3barI1TB3quxEivEDC1m1nEB6foobar_1" } } +// { dg-final { scan-assembler "_ZZ3barI1TB3quxEivEDC1o1pEB3qux" } } +// { dg-final { scan-assembler "_ZN1NDC1i1jEB6foobarE" } } +// { dg-final { scan-assembler "_ZN1NDC1k1lEB3quxE" } } +// { dg-final { scan-assembler "_ZGVZ3foovEDC1m1nEB6foobar" } } +// { dg-final { scan-assembler "_ZGVZ3foovEDC1m1nEB6foobar_0" } } +// { dg-final { scan-assembler "_ZGVZ3foovEDC1m1nEB6foobar_1" } } +// { dg-final { scan-assembler "_ZGVZ3foovEDC1o1pEB3qux" } } +// { dg-final { scan-assembler "_ZGVZ3barI1TB3quxEivEDC1m1nEB6foobar" } } +// { dg-final { scan-assembler "_ZGVZ3barI1TB3quxEivEDC1m1nEB6foobar_0" } } +// { dg-final { scan-assembler "_ZGVZ3barI1TB3quxEivEDC1m1nEB6foobar_1" } } +// { dg-final { scan-assembler "_ZGVZ3barI1TB3quxEivEDC1o1pEB3qux" } } --- gcc/testsuite/g++.dg/abi/macro0.C.jj 2022-10-11 12:10:42.209890842 +0200 +++ gcc/testsuite/g++.dg/abi/macro0.C 2023-08-28 15:46:51.205462641 +0200 @@ -1,6 +1,6 @@ // This testcase will need to be kept in sync with c_common_post_options. // { dg-options "-fabi-version=0" } -#if __GXX_ABI_VERSION != 1018 +#if __GXX_ABI_VERSION != 1019 #error "Incorrect value of __GXX_ABI_VERSION" #endif