From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1059) id E868E3858289; Mon, 10 Oct 2022 22:13:54 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org E868E3858289 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1665440034; bh=jFG4a0tqKJYRwbLSYLr9+N8F4X0Ma4kNmrIjPTB1jBA=; h=From:To:Subject:Date:From; b=EdQtkeJ4o57v+0yVTiWpeWKY9ocDuvICcNTsbgHq7D7fn/gL1kl+M/smlthdO5LpW qyG/20H01z8hgN10UTatNJRjibfhiXsO9Ggfkfv5MXpAhOKCIZlVnnzPPjCnxCHGbs MzGf1N0raoPm0BgZCh7yh26BndlWMD6SKIfHntJ8= MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="utf-8" From: Nathan Sidwell To: gcc-cvs@gcc.gnu.org Subject: [gcc r13-3206] c++: Lambda context mangling X-Act-Checkin: gcc X-Git-Author: Nathan Sidwell X-Git-Refname: refs/heads/master X-Git-Oldrev: 29b0fe393859729215b0db5d28f2faea30c6ec32 X-Git-Newrev: c7cb239f51788dbe3148368942b208934707b6a7 Message-Id: <20221010221354.E868E3858289@sourceware.org> Date: Mon, 10 Oct 2022 22:13:54 +0000 (GMT) List-Id: https://gcc.gnu.org/g:c7cb239f51788dbe3148368942b208934707b6a7 commit r13-3206-gc7cb239f51788dbe3148368942b208934707b6a7 Author: Nathan Sidwell Date: Mon Oct 10 17:55:04 2022 -0400 c++: Lambda context mangling VAR and FIELD decls can become part of a lambda context, when the lambda is 'attached' to that entity (It's a C++20 ODR thing that was discovered with modules, but is actually separate.) We were not marking those decls as substitution candidates, leading to demangling failures and variance from other compilers. This patch bumps the ABI, and adds the contexts them to the substitution table. This is the intent of the ABI. gcc/ * common.opt (-fabi-version=): Document 18. * doc/invoke.texi (-fabi-version): Document 18. gcc/c-family/ * c-opts.cc (c_common_post_options): Bump abi to 18. gcc/cp/ * mangle.cc (write_prefix): Add VAR_DECL & FIELD_DECL to substitution table under abi=18. Note possible mismatch. gcc/testsuite/ * g++.dg/abi/lambda-ctx1-17.C: New. * g++.dg/abi/lambda-ctx1-18.C: New. * g++.dg/abi/lambda-ctx1-18vs17.C: New. * g++.dg/abi/lambda-ctx1.h: New. * g++.dg/abi/lambda-vis.C: Adjust expected mangles. * g++.dg/abi/macro0.C: Adjust. Diff: --- gcc/c-family/c-opts.cc | 2 +- gcc/common.opt | 3 +++ gcc/cp/mangle.cc | 9 ++++++++- gcc/doc/invoke.texi | 3 +++ gcc/testsuite/g++.dg/abi/lambda-ctx1-17.C | 10 ++++++++++ gcc/testsuite/g++.dg/abi/lambda-ctx1-18.C | 11 +++++++++++ gcc/testsuite/g++.dg/abi/lambda-ctx1-18vs17.C | 9 +++++++++ gcc/testsuite/g++.dg/abi/lambda-ctx1.h | 20 ++++++++++++++++++++ gcc/testsuite/g++.dg/abi/lambda-vis.C | 8 +++++--- gcc/testsuite/g++.dg/abi/macro0.C | 2 +- 10 files changed, 71 insertions(+), 6 deletions(-) diff --git a/gcc/c-family/c-opts.cc b/gcc/c-family/c-opts.cc index babaa2fc157..55cebf68f9c 100644 --- a/gcc/c-family/c-opts.cc +++ b/gcc/c-family/c-opts.cc @@ -975,7 +975,7 @@ c_common_post_options (const char **pfilename) /* 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 = 17; + const int latest_abi_version = 18; /* Generate compatibility aliases for ABI v13 (8.2) by default. */ const int abi_compat_default = 13; diff --git a/gcc/common.opt b/gcc/common.opt index 3a97e6782ce..bce3e514f65 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -1004,6 +1004,9 @@ Driver Undocumented ; member initializers in C++14 and up. ; Default in G++ 12. ; +; 18: Corrects errors in mangling of lambdas with additional context. +; Default in G++ 13. +; ; Additional positive integers will be assigned as new versions of ; the ABI become the default version of the ABI. fabi-version= diff --git a/gcc/cp/mangle.cc b/gcc/cp/mangle.cc index f051e76466a..1215463089b 100644 --- a/gcc/cp/mangle.cc +++ b/gcc/cp/mangle.cc @@ -1252,7 +1252,14 @@ write_prefix (const tree node) { /* := M */ write_char ('M'); - return; + + /* Before ABI 18, we did not count these as substitution + candidates. This leads to incorrect demanglings (and + ABI divergence to other compilers). */ + if (abi_warn_or_compat_version_crosses (18)) + G.need_abi_warning = true; + if (!abi_version_at_least (18)) + return; } } diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 278c55d5a19..271c8bb8468 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -2973,6 +2973,9 @@ Version 17, which first appeared in G++ 12, fixes layout of classes that inherit from aggregate classes with default member initializers in C++14 and up. +Version 18, which first appeard in G++ 13, fixes manglings of lambdas +that have additional context. + See also @option{-Wabi}. @item -fabi-compat-version=@var{n} diff --git a/gcc/testsuite/g++.dg/abi/lambda-ctx1-17.C b/gcc/testsuite/g++.dg/abi/lambda-ctx1-17.C new file mode 100644 index 00000000000..42f277a2117 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/lambda-ctx1-17.C @@ -0,0 +1,10 @@ +// { dg-do compile { target c++20 } } +// { dg-options -fabi-version=17 } + +#include "lambda-ctx1.h" + +// These demangle incorrectly, due to a missed substitution candidate +// { dg-final { scan-assembler {_ZNK1C1fMUlT_E_clIMS_iEEDaS0_:} } } +// { dg-final { scan-assembler {_ZNK2L2MUlT_T0_E_clIifEEvS_S0_:} } } +// { dg-final { scan-assembler {_ZNK1B2L3MUlT_T0_E_clIjdEEvS0_S1_:} } } +// { dg-final { scan-assembler {_Z3fooIN1qMUlvE_EN1qMUlvE0_EEiOT_OT0_:} } } diff --git a/gcc/testsuite/g++.dg/abi/lambda-ctx1-18.C b/gcc/testsuite/g++.dg/abi/lambda-ctx1-18.C new file mode 100644 index 00000000000..c1c9e274d7f --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/lambda-ctx1-18.C @@ -0,0 +1,11 @@ +// { dg-do compile { target c++20 } } +// { dg-options -fabi-version=18 } + +#include "lambda-ctx1.h" + +// These correctly include the lambda's extra context as a +// substitution candidate, and thus demangle as expected +// { dg-final { scan-assembler {_ZNK1C1fMUlT_E_clIMS_iEEDaS1_:} } } +// { dg-final { scan-assembler {_ZNK2L2MUlT_T0_E_clIifEEvS0_S1_:} } } +// { dg-final { scan-assembler {_ZNK1B2L3MUlT_T0_E_clIjdEEvS1_S2_:} } } +// { dg-final { scan-assembler {_Z3fooIN1qMUlvE_ENS0_UlvE0_EEiOT_OT0_:} } } diff --git a/gcc/testsuite/g++.dg/abi/lambda-ctx1-18vs17.C b/gcc/testsuite/g++.dg/abi/lambda-ctx1-18vs17.C new file mode 100644 index 00000000000..f5ec905dec3 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/lambda-ctx1-18vs17.C @@ -0,0 +1,9 @@ +// { dg-do compile { target c++20 } } +// { dg-options {-fabi-version=18 -Wabi=17} } + +#include "lambda-ctx1.h" + +// { dg-regexp {[^\n]*lambda-ctx1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZNK1B2L3MUlT_T0_E_clIjdEEvS0_S1_'\) and '-fabi-version=18' \('_ZNK1B2L3MUlT_T0_E_clIjdEEvS1_S2_'\) [^\n]*\n} } +// { dg-regexp {[^\n]*lambda-ctx1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZNK2L2MUlT_T0_E_clIifEEvS_S0_'\) and '-fabi-version=18' \('_ZNK2L2MUlT_T0_E_clIifEEvS0_S1_'\) [^\n]*\n} } +// { dg-regexp {[^\n]*lambda-ctx1.h:[:0-9]* warning: the mangled name [^\n]* \('_ZNK1C1fMUlT_E_clIMS_iEEDaS0_'\) and '-fabi-version=18' \('_ZNK1C1fMUlT_E_clIMS_iEEDaS1_'\) [^\n]*\n} } +// { dg-regexp {[^\n]*lambda-ctx1.h:[:0-9]* warning: the mangled name [^\n]* \('_Z3fooIN1qMUlvE_EN1qMUlvE0_EEiOT_OT0_'\) and '-fabi-version=18' \('_Z3fooIN1qMUlvE_ENS0_UlvE0_EEiOT_OT0_'\) [^\n]*\n} } diff --git a/gcc/testsuite/g++.dg/abi/lambda-ctx1.h b/gcc/testsuite/g++.dg/abi/lambda-ctx1.h new file mode 100644 index 00000000000..9afb66aae76 --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/lambda-ctx1.h @@ -0,0 +1,20 @@ +inline auto L2 = [] (T, U) -> void {}; +namespace B +{ + inline auto L3 = [] (T, U) -> void {}; +} + +struct C +{ + int f = [] (auto){ return 1;}(&C::f); + C (); +}; + +C::C () +{ + L2 (1, 1.2f); + B::L3 (1u, 1.2); +} + +template int foo (A&&, B&&) {return 0;} +inline int q = foo ([](){}, [](){}); diff --git a/gcc/testsuite/g++.dg/abi/lambda-vis.C b/gcc/testsuite/g++.dg/abi/lambda-vis.C index c1033f501a3..81cffcbe5a6 100644 --- a/gcc/testsuite/g++.dg/abi/lambda-vis.C +++ b/gcc/testsuite/g++.dg/abi/lambda-vis.C @@ -13,9 +13,11 @@ int gvar = gfoo (capture ([]{})); inline int ivar = ifoo (capture ([]{})); -// { dg-final { scan-assembler {_?_Z7captureINL4svarMUlvE_EE7WrapperIT_EOS2_:} } } -// { dg-final { scan-assembler {_?_Z7captureIN4gvarMUlvE_EE7WrapperIT_EOS2_:} } } -// { dg-final { scan-assembler {_?_Z7captureIN4ivarMUlvE_EE7WrapperIT_EOS2_:} } } +// These manglings change between ABIs 17 and 18 (the final +// substitution number). +// { dg-final { scan-assembler {_?_Z7captureINL4svarMUlvE_EE7WrapperIT_EOS3_:} } } +// { dg-final { scan-assembler {_?_Z7captureIN4gvarMUlvE_EE7WrapperIT_EOS3_:} } } +// { dg-final { scan-assembler {_?_Z7captureIN4ivarMUlvE_EE7WrapperIT_EOS3_:} } } // Calls to the foos are emitted. // { dg-final { scan-assembler {call[ \t]*_?_Z4sfooI7WrapperINL4svarMUlvE_EEEiT_} { target { i?86-*-* x86_64-*-* } } } } diff --git a/gcc/testsuite/g++.dg/abi/macro0.C b/gcc/testsuite/g++.dg/abi/macro0.C index 2d07fcdc631..4a0e9d06ca0 100644 --- a/gcc/testsuite/g++.dg/abi/macro0.C +++ b/gcc/testsuite/g++.dg/abi/macro0.C @@ -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 != 1017 +#if __GXX_ABI_VERSION != 1018 #error "Incorrect value of __GXX_ABI_VERSION" #endif