From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-ed1-x534.google.com (mail-ed1-x534.google.com [IPv6:2a00:1450:4864:20::534]) by sourceware.org (Postfix) with ESMTPS id 5F4B4385BF9E for ; Tue, 23 Mar 2021 16:27:42 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 5F4B4385BF9E Received: by mail-ed1-x534.google.com with SMTP id h10so24119471edt.13 for ; Tue, 23 Mar 2021 09:27:42 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to :content-transfer-encoding; bh=bIbxCgXzGjBtrMw4y7z7fw1V1RjOCKy58cRiQep5azo=; b=LExyR78BLvBmS1VoQnfz/MjwypbqXP9aFKXvc4kO53DouTyIh9YeW4wcOv0Aupxh3d QHNAfze4pIhvlRVmq37AKWb/U39iR+/CYILr6BJ9qmJ0NoBThhEmq+no1lKKFsHm50kZ 6QeADXg3H63Rlh5yBTMfK1RrZEDhDsR612yd/D0XUKIaH1n3rwpjFhFDchCrXr3Rb2I3 ABMvybVgwj4TKVjHmg79b8zcS4VyRMzj/b/i/dJ7Gl90wn03QF9ADSEiaCLUEybfYbZk JvfqrcsAmaFr1JnfLXqiqydFcAX5C4aPtYzuFAourskRrimbqedzwtVzcwgppHdejp0Y MyXQ== X-Gm-Message-State: AOAM532VUcJec7ughUPdTEQYFF9whe8tQSsVp2LN/49f/E0OcMos66O6 lGntkG8HaIEDC68+zfktsHCbiKtP5+RRM0amJJcup0Rs3yA= X-Google-Smtp-Source: ABdhPJxHubfw+MNxSP8vw1BjIfyX1O0/dMitOx56e5vyBHgiXQhgh7z20DKnGXALVqBMSp6+zq9AKHG1T63WpKd1Ed4= X-Received: by 2002:a05:6402:3587:: with SMTP id y7mr295264edc.54.1616516861114; Tue, 23 Mar 2021 09:27:41 -0700 (PDT) MIME-Version: 1.0 From: =?UTF-8?B?TWFya3VzIELDtmNr?= Date: Tue, 23 Mar 2021 17:27:30 +0100 Message-ID: Subject: [PATCH][PR94156] Split COMDAT groups on target that do not support them To: GCC Patches Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Spam-Status: No, score=-8.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, FREEMAIL_ENVFROM_END_DIGIT, FREEMAIL_FROM, GIT_PATCH_0, KAM_SHORT, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) 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-List-Received-Date: Tue, 23 Mar 2021 16:27:45 -0000 GCC at the moment uses COMDAT groups for things like virtual thunks, even on targets that do not support COMDAT groups. This has not been a problem as on platforms not supporting these (such as PE COFF on Windows), the backend handled it through directives to GAS. GCC would simply use a .linkonce directive telling the assembler that this symbol may occur multiple times, and GAS would translate that into a "select any" COMDAT, containing only the symbol itself (as Windows does support COMDAT, just not groups). When using LTO on Windows however, a few problems occur: The COMDAT group is transmitted as part of the IR and the linker (ld) will try to resolve symbols. On Windows the COMDAT information is put into the symbol table, instead of in sections, leading to the linker to error out with a multiple reference error before even calling the lto-wrapper and LTRANS on the IR, which would otherwise resolve the use of COMDAT groups. This patch removes comdat groups for symbols in the ipa-visibility pass and instead puts them into their own comdat. An exception to this rule are aliases which (at least on Windows) are also allowed to be in the same comdat group as the symbol they are referencing. This fixes PR94156: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D94156 A previous discussion on the problems this patch attempts to fix were had here: https://gcc.gnu.org/pipermail/gcc-patches/2020-July/550148.html I tested this patch with a x86_64-w64-mingw32 target on a Linux host. No regressions between before and after of this patch were noted. The Test cases provided with this patch have been confirmed to reproduce before this patch, and link and work after the application of the patch. Feedback is very welcome, especially on implications I might not be aware o= f. gcc/ChangeLog: 2020-03-23 Markus B=C3=B6ck * ipa-visibility.c (function_and_variable_visibility): Split COMDAT groups on targets not supporting them gcc/testsuite/ChangeLog: 2020-03-23 Markus B=C3=B6ck * g++.dg/lto/pr94156.h: New test. * g++.dg/lto/pr94156_0.C: New test. * g++.dg/lto/pr94156_1.C: New test. -------------- diff --git a/gcc/ipa-visibility.c b/gcc/ipa-visibility.c index eb0ebf770e3..76f1a8ff72a 100644 --- a/gcc/ipa-visibility.c +++ b/gcc/ipa-visibility.c @@ -709,6 +709,14 @@ function_and_variable_visibility (bool whole_program) } node->dissolve_same_comdat_group_list (); } + + if (!HAVE_COMDAT_GROUP && node->same_comdat_group + && !node->alias && !node->has_aliases_p()) + { + node->remove_from_same_comdat_group(); + node->set_comdat_group(DECL_ASSEMBLER_NAME_RAW(node->decl)); + } + gcc_assert ((!DECL_WEAK (node->decl) && !DECL_COMDAT (node->decl)) || TREE_PUBLIC (node->decl) @@ -742,8 +750,11 @@ function_and_variable_visibility (bool whole_program) { gcc_checking_assert (DECL_COMDAT (node->decl) =3D=3D DECL_COMDAT (decl_node->decl)); - gcc_checking_assert (node->in_same_comdat_group_p (decl_node)); - gcc_checking_assert (node->same_comdat_group); + if (HAVE_COMDAT_GROUP) + { + gcc_checking_assert (node->in_same_comdat_group_p (decl_node)); + gcc_checking_assert (node->same_comdat_group); + } } node->forced_by_abi =3D decl_node->forced_by_abi; if (DECL_EXTERNAL (decl_node->decl)) diff --git a/gcc/testsuite/g++.dg/lto/pr94156.h b/gcc/testsuite/g++.dg/lto/pr94156.h new file mode 100644 index 00000000000..3990ac46fcb --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/pr94156.h @@ -0,0 +1,20 @@ +class Base0 { +public: + virtual ~Base0() {} +}; + +class Base1 { +public: + virtual void foo() =3D 0; +}; + +class Base2 { +public: + virtual void foo() =3D 0; +}; + +class Derived : public Base0, public Base1, public Base2 { +public: + virtual ~Derived(); + virtual void foo() override {} +}; diff --git a/gcc/testsuite/g++.dg/lto/pr94156_0.C b/gcc/testsuite/g++.dg/lto/pr94156_0.C new file mode 100644 index 00000000000..1a2e30badc7 --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/pr94156_0.C @@ -0,0 +1,6 @@ +// { dg-lto-do link } +#include "pr94156.h" + +Derived::~Derived() {} + +int main() {} diff --git a/gcc/testsuite/g++.dg/lto/pr94156_1.C b/gcc/testsuite/g++.dg/lto/pr94156_1.C new file mode 100644 index 00000000000..d7a40efa96c --- /dev/null +++ b/gcc/testsuite/g++.dg/lto/pr94156_1.C @@ -0,0 +1,6 @@ +#include "pr94156.h" + +void bar(Derived* p) +{ + p->foo(); +}