https://gcc.gnu.org/g:9ccd03dee4c35a24c6699a58a7251a5277a91cf5

commit r14-9375-g9ccd03dee4c35a24c6699a58a7251a5277a91cf5
Author: Nathaniel Shead <nathanielosh...@gmail.com>
Date:   Thu Mar 7 23:09:03 2024 +1100

    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 <nathanielosh...@gmail.com>

Diff:
---
 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(-)

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<class> struct basic_streambuf { virtual void overflow() { } };
+extern template struct basic_streambuf<long>;
+export module modA;
+export basic_streambuf<long> *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<class> struct basic_streambuf { virtual void overflow() { } };
+template struct basic_streambuf<long>;
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() { }

Reply via email to