https://gcc.gnu.org/g:29efc621b7c66ec67d10fc87cddbb3f1ab709fb2
commit r15-4621-g29efc621b7c66ec67d10fc87cddbb3f1ab709fb2 Author: Nathaniel Shead <nathanielosh...@gmail.com> Date: Wed Aug 21 01:08:36 2024 +1000 c++/modules: Support decloned cdtors When compiling with '-fdeclone-ctor-dtor' (enabled by default with -Os), we run into issues where we don't correctly emit the underlying functions. We also need to ensure that COMDAT constructors are marked as such before 'maybe_clone_body' attempts to propagate COMDAT groups to the new thunks. gcc/cp/ChangeLog: * module.cc (post_load_processing): Mark COMDAT as needed, emit declarations if maybe_clone_body fails. gcc/testsuite/ChangeLog: * g++.dg/modules/clone-2_a.C: New test. * g++.dg/modules/clone-2_b.C: New test. * g++.dg/modules/clone-3_a.C: New test. * g++.dg/modules/clone-3_b.C: New test. Signed-off-by: Nathaniel Shead <nathanielosh...@gmail.com> Diff: --- gcc/cp/module.cc | 20 ++++++++++++++++---- gcc/testsuite/g++.dg/modules/clone-2_a.C | 7 +++++++ gcc/testsuite/g++.dg/modules/clone-2_b.C | 5 +++++ gcc/testsuite/g++.dg/modules/clone-3_a.C | 9 +++++++++ gcc/testsuite/g++.dg/modules/clone-3_b.C | 8 ++++++++ 5 files changed, 45 insertions(+), 4 deletions(-) diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index d7494cc813a0..90ad67daf72b 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -17959,10 +17959,22 @@ post_load_processing () dump () && dump ("Post-load processing of %N", decl); gcc_checking_assert (DECL_MAYBE_IN_CHARGE_CDTOR_P (decl)); - /* Cloning can cause loading -- specifically operator delete for - the deleting dtor. */ - if (!TREE_ASM_WRITTEN (decl) && maybe_clone_body (decl)) - TREE_ASM_WRITTEN (decl) = 1; + + if (DECL_COMDAT (decl)) + comdat_linkage (decl); + if (!TREE_ASM_WRITTEN (decl)) + { + /* Cloning can cause loading -- specifically operator delete for + the deleting dtor. */ + if (maybe_clone_body (decl)) + TREE_ASM_WRITTEN (decl) = 1; + else + { + /* We didn't clone the cdtor, make sure we emit it. */ + note_vague_linkage_fn (decl); + cgraph_node::finalize_function (decl, true); + } + } } cfun = old_cfun; diff --git a/gcc/testsuite/g++.dg/modules/clone-2_a.C b/gcc/testsuite/g++.dg/modules/clone-2_a.C new file mode 100644 index 000000000000..47e21581fdc5 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/clone-2_a.C @@ -0,0 +1,7 @@ +// { dg-additional-options "-fmodules-ts -fdeclone-ctor-dtor" } +// { dg-module-cmi M } + +export module M; +export struct S { + inline S(int) {} +}; diff --git a/gcc/testsuite/g++.dg/modules/clone-2_b.C b/gcc/testsuite/g++.dg/modules/clone-2_b.C new file mode 100644 index 000000000000..80c1e149518b --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/clone-2_b.C @@ -0,0 +1,5 @@ +// { dg-additional-options "-fmodules-ts -fdeclone-ctor-dtor" } + +import M; + +S s(0); diff --git a/gcc/testsuite/g++.dg/modules/clone-3_a.C b/gcc/testsuite/g++.dg/modules/clone-3_a.C new file mode 100644 index 000000000000..87de746f5c2c --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/clone-3_a.C @@ -0,0 +1,9 @@ +// { dg-additional-options "-fmodules-ts -fdeclone-ctor-dtor" } +// { dg-module-cmi M } + +export module M; + +struct A {}; +export struct B : virtual A { + inline B (int) {} +}; diff --git a/gcc/testsuite/g++.dg/modules/clone-3_b.C b/gcc/testsuite/g++.dg/modules/clone-3_b.C new file mode 100644 index 000000000000..23c9ac4a8046 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/clone-3_b.C @@ -0,0 +1,8 @@ +// { dg-module-do link } +// { dg-additional-options "-fmodules-ts -fdeclone-ctor-dtor" } + +import M; + +int main() { + B b(0); +}