From 9ccd03dee4c35a24c6699a58a7251a5277a91cf5 Mon Sep 17 00:00:00 2001 From: Nathaniel Shead Date: Thu, 7 Mar 2024 23:09:03 +1100 Subject: [PATCH] c++: Redetermine whether to write vtables on stream-in [PR114229] We currently always stream DECL_INTERFACE_KNOWN, which is needed since many kinds of declarations already have their interface determined at parse time. But for vtables and type-info declarations we need to re-evaluate on stream-in as whether they need to be emitted or not changes in each TU, so this patch clears DECL_INTERFACE_KNOWN on these kinds of declarations so that they can go through 'import_export_decl' again. Note that the precise details of the virt-2 tests will need to change when we implement the resolution of [1], for now I just updated the test to not fail with the new (current) semantics. [1]: https://github.com/itanium-cxx-abi/cxx-abi/pull/171 PR c++/114229 gcc/cp/ChangeLog: * module.cc (trees_out::core_bools): Redetermine DECL_INTERFACE_KNOWN on stream-in for vtables and tinfo. * decl2.cc (import_export_decl): Add fixme for ABI changes with module vtables and tinfo. gcc/testsuite/ChangeLog: * g++.dg/modules/virt-2_b.C: Update test to acknowledge that we now emit vtables here too. * g++.dg/modules/virt-3_a.C: New test. * g++.dg/modules/virt-3_b.C: New test. * g++.dg/modules/virt-3_c.C: New test. * g++.dg/modules/virt-3_d.C: New test. Signed-off-by: Nathaniel Shead --- gcc/cp/decl2.cc | 4 ++++ gcc/cp/module.cc | 12 +++++++++++- gcc/testsuite/g++.dg/modules/virt-2_b.C | 5 ++--- gcc/testsuite/g++.dg/modules/virt-3_a.C | 9 +++++++++ gcc/testsuite/g++.dg/modules/virt-3_b.C | 6 ++++++ gcc/testsuite/g++.dg/modules/virt-3_c.C | 3 +++ gcc/testsuite/g++.dg/modules/virt-3_d.C | 7 +++++++ 7 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/modules/virt-3_a.C create mode 100644 gcc/testsuite/g++.dg/modules/virt-3_b.C create mode 100644 gcc/testsuite/g++.dg/modules/virt-3_c.C create mode 100644 gcc/testsuite/g++.dg/modules/virt-3_d.C diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc index 1dddbaab38b..6c9fd415d40 100644 --- a/gcc/cp/decl2.cc +++ b/gcc/cp/decl2.cc @@ -3398,6 +3398,10 @@ import_export_decl (tree decl) unit. */ import_p = false; + /* FIXME: Since https://github.com/itanium-cxx-abi/cxx-abi/pull/171, + the ABI specifies that classes attached to named modules should + have their vtables uniquely emitted in the object for the module + unit in which it is defined. And similarly for RTTI structures. */ if (VAR_P (decl) && DECL_VTABLE_OR_VTT_P (decl)) { class_type = DECL_CONTEXT (decl); diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc index 53104753737..99055523d91 100644 --- a/gcc/cp/module.cc +++ b/gcc/cp/module.cc @@ -5376,7 +5376,17 @@ trees_out::core_bools (tree t) WB (t->decl_common.lang_flag_2); WB (t->decl_common.lang_flag_3); WB (t->decl_common.lang_flag_4); - WB (t->decl_common.lang_flag_5); + + { + /* This is DECL_INTERFACE_KNOWN: We should redetermine whether + we need to import or export any vtables or typeinfo objects + on stream-in. */ + bool interface_known = t->decl_common.lang_flag_5; + if (VAR_P (t) && (DECL_VTABLE_OR_VTT_P (t) || DECL_TINFO_P (t))) + interface_known = false; + WB (interface_known); + } + WB (t->decl_common.lang_flag_6); WB (t->decl_common.lang_flag_7); WB (t->decl_common.lang_flag_8); diff --git a/gcc/testsuite/g++.dg/modules/virt-2_b.C b/gcc/testsuite/g++.dg/modules/virt-2_b.C index e041f0721f9..2bc5eced013 100644 --- a/gcc/testsuite/g++.dg/modules/virt-2_b.C +++ b/gcc/testsuite/g++.dg/modules/virt-2_b.C @@ -21,8 +21,7 @@ int main () return !(Visit (&me) == 1); } -// We do not emit Visitor vtable -// but we do emit rtti here -// { dg-final { scan-assembler-not {_ZTVW3foo7Visitor:} } } +// Again, we emit Visitor vtable and rtti here +// { dg-final { scan-assembler {_ZTVW3foo7Visitor:} } } // { dg-final { scan-assembler {_ZTIW3foo7Visitor:} } } // { dg-final { scan-assembler {_ZTSW3foo7Visitor:} } } diff --git a/gcc/testsuite/g++.dg/modules/virt-3_a.C b/gcc/testsuite/g++.dg/modules/virt-3_a.C new file mode 100644 index 00000000000..a7eae7f9d35 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/virt-3_a.C @@ -0,0 +1,9 @@ +// PR c++/114229 +// { dg-additional-options "-fmodules-ts -Wno-global-module" } +// { dg-module-cmi modA } + +module; +template struct basic_streambuf { virtual void overflow() { } }; +extern template struct basic_streambuf; +export module modA; +export basic_streambuf *p; diff --git a/gcc/testsuite/g++.dg/modules/virt-3_b.C b/gcc/testsuite/g++.dg/modules/virt-3_b.C new file mode 100644 index 00000000000..4d87b965bbf --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/virt-3_b.C @@ -0,0 +1,6 @@ +// PR c++/114229 +// { dg-additional-options "-fmodules-ts -fno-module-lazy" } +// { dg-module-cmi modB } + +export module modB; +import modA; diff --git a/gcc/testsuite/g++.dg/modules/virt-3_c.C b/gcc/testsuite/g++.dg/modules/virt-3_c.C new file mode 100644 index 00000000000..224bb4aed49 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/virt-3_c.C @@ -0,0 +1,3 @@ +// PR c++/114229 +template struct basic_streambuf { virtual void overflow() { } }; +template struct basic_streambuf; diff --git a/gcc/testsuite/g++.dg/modules/virt-3_d.C b/gcc/testsuite/g++.dg/modules/virt-3_d.C new file mode 100644 index 00000000000..b3a0aad7abe --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/virt-3_d.C @@ -0,0 +1,7 @@ +// PR c++/114229 +// { dg-module-do link } +// { dg-additional-options "-fmodules-ts -fno-module-lazy" } + +import modA; +import modB; +int main() { }