From patchwork Fri Oct 7 12:27:40 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 1687433 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=WLEOBrWM; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4MkSJb3bgYz1yqk for ; Fri, 7 Oct 2022 23:28:15 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 7FB9139484BB for ; Fri, 7 Oct 2022 12:28:12 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7FB9139484BB DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1665145692; bh=KDJLnm7T0WdJFsCQGPch5yI0e1iUSJphjYEtTiSFcNg=; h=Date:To:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=WLEOBrWM/rtCmjijv39Oz52u+Mg3dkI7Pw32KsTsetvA50Xlhqj7aMKuiz/zTCi1n vvyHyzcD2Kvgixm3X8ZP0yaBEUZ49m3LnZq8uq/eUQNk1oFvlGKnIffLHg7WTGyvfK UJ9DRvWOqfwMPkAG01plK2IRJIhujKMOwzMYrslM= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-qv1-xf36.google.com (mail-qv1-xf36.google.com [IPv6:2607:f8b0:4864:20::f36]) by sourceware.org (Postfix) with ESMTPS id 807343857372 for ; Fri, 7 Oct 2022 12:27:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org 807343857372 Received: by mail-qv1-xf36.google.com with SMTP id z18so2962868qvn.6 for ; Fri, 07 Oct 2022 05:27:43 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=subject:from:cc:to:content-language:user-agent:mime-version:date :message-id:sender:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=KDJLnm7T0WdJFsCQGPch5yI0e1iUSJphjYEtTiSFcNg=; b=KdgoRpwIK2N6ryDyuEUhsFHb8G8DJCQW/F7OHDpPTtf/Xfxk5J1Zt/w4HRTaYlaXZL ayZCQyRRMzifdp2HV/yM2DiwOXTTPkIAPs8tu14mMfhygX3IXs4H0mGs6Df3Ln20k7KN febUtAHw/uZAFrax79SyAR3aufgRW17JXBcNk6X35m+aKsePcF/nvQOAt0/deyIICbFE fuGP64usa+twGpHJIvkAkmxl5a9bi3zPbBGrug2kJcy6Al4j/dyORXjQtxl5CYhUadv4 a6nx7FpP5FdtQkh2FLoUK6fJe3qVABy0S1eYZKKlCHVqzkp5Ft3L1bF4/vWhyAM65G5n Ln4g== X-Gm-Message-State: ACrzQf1YiE60CxboQadUCPlX0ywJjuSp9ZcV21aLTLpije+SypdBjOOm 5rI5mifk3C13gQnx8fA4tTwG+vYygG8= X-Google-Smtp-Source: AMsMyM4m1zXu44HO1zVUV/UZCJ4y5+cpfJNkpxdlak5hjeT9+CZ98pwuWiT32HOZcTFPN65mPrSgxw== X-Received: by 2002:a05:6214:27e5:b0:4ac:c227:2111 with SMTP id jt5-20020a05621427e500b004acc2272111mr3881186qvb.127.1665145662596; Fri, 07 Oct 2022 05:27:42 -0700 (PDT) Received: from ?IPV6:2620:10d:c0a3:1407:942e:c420:cf80:2f69? ([2620:10d:c091:500::6:7323]) by smtp.googlemail.com with ESMTPSA id o19-20020a05620a2a1300b006cddf59a600sm1989384qkp.34.2022.10.07.05.27.40 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 07 Oct 2022 05:27:40 -0700 (PDT) Message-ID: <44fbc15f-6f48-94c0-a51a-e5b99190ffbc@acm.org> Date: Fri, 7 Oct 2022 08:27:40 -0400 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.3.1 Content-Language: en-US To: GCC Patches Subject: c++: Lambda context mangling X-Spam-Status: No, score=-3038.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, RCVD_IN_DNSWL_NONE, 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.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Nathan Sidwell via Gcc-patches From: Nathan Sidwell Reply-To: Nathan Sidwell Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" 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 compiler variance. The alternative I chose is to bump the ABI, and add them to the substitution table. I think this is the intent of the ABI. The other alternative would be for the demangler to pop off the most recent substitution when it saw the 'M'. But we'd have to change [at least] the libiberty demangler[*] and the clang demangler and the clang mangler, which seems a bigger challenge. I'll commit this next week, unless y'all have comments. We have other divergence from clang, with templated lambdas. Clang added new manglings [Ty, Tn, Tt] for the lambda's template head (Richard has a pull request, but it's not merged https://github.com/itanium-cxx-abi/cxx-abi/issues/31). Without that, we consider all the template args to be auto when demangling (which is going to look odd for non-type template args). This divergence in signature also affects the lambda numbering, as gcc & clang differ in their opinions about 'same lamda signature'. thoughts on addressing that to in this cycle? I have some demangler fixes coming up. nathan [*] the demangler already seems to have a bug with 'M' handling. From 6e943ec67fbe1f2bd09325eb6a2dc6405edfc00f Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Fri, 30 Sep 2022 08:43:10 -0700 Subject: [PATCH 1/3] 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. The alternative I chose is to bump the ABI, and add them to the substitution table. I think this is the intent of the ABI. The othe alternative would be for the demangler to pop off the most recent substitition when it saw the 'M'. But we'd have to change [at least] the libiberty demangler and the clang demangler and the clang mangler, which seems a bigger challenge. 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. --- 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(-) create mode 100644 gcc/testsuite/g++.dg/abi/lambda-ctx1-17.C create mode 100644 gcc/testsuite/g++.dg/abi/lambda-ctx1-18.C create mode 100644 gcc/testsuite/g++.dg/abi/lambda-ctx1-18vs17.C create mode 100644 gcc/testsuite/g++.dg/abi/lambda-ctx1.h 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 58dc1a0a780..c65efeeb8fc 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 a5dc6377835..2671ba7c1c1 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -2940,6 +2940,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 -- 2.30.2