https://gcc.gnu.org/g:6713f05a2aeb852c3f4d738c8c5dbad816624323

commit r15-4619-g6713f05a2aeb852c3f4d738c8c5dbad816624323
Author: Nathaniel Shead <nathanielosh...@gmail.com>
Date:   Wed Aug 21 00:42:42 2024 +1000

    c++: Handle ABI for non-polymorphic dynamic classes
    
    The Itanium ABI has specific rules for when virtual tables for dynamic
    classes should be emitted.  However we didn't consider structures with
    virtual inheritance but no virtual members as dynamic classes for ABI
    purposes; this patch fixes this.
    
    gcc/cp/ChangeLog:
    
            * decl2.cc (import_export_class): Use TYPE_CONTAINS_VPTR_P
            instead of TYPE_POLYMORPHIC_P.
            (import_export_decl): Likewise.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/modules/virt-5_a.C: New test.
            * g++.dg/modules/virt-5_b.C: New test.
    
    Signed-off-by: Nathaniel Shead <nathanielosh...@gmail.com>

Diff:
---
 gcc/cp/decl2.cc                         |  4 ++--
 gcc/testsuite/g++.dg/modules/virt-5_a.C | 16 ++++++++++++++++
 gcc/testsuite/g++.dg/modules/virt-5_b.C | 11 +++++++++++
 3 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/gcc/cp/decl2.cc b/gcc/cp/decl2.cc
index a455eb481b1a..fa32ce35c8c4 100644
--- a/gcc/cp/decl2.cc
+++ b/gcc/cp/decl2.cc
@@ -2434,7 +2434,7 @@ import_export_class (tree ctype)
        translation unit, then export the class; otherwise, import
        it.  */
       import_export = -1;
-  else if (TYPE_POLYMORPHIC_P (ctype))
+  else if (TYPE_CONTAINS_VPTR_P (ctype))
     {
       tree cdecl = TYPE_NAME (ctype);
       if (DECL_LANG_SPECIFIC (cdecl) && DECL_MODULE_ATTACH_P (cdecl))
@@ -3530,7 +3530,7 @@ import_export_decl (tree decl)
          class_type = type;
          import_export_class (type);
          if (CLASSTYPE_INTERFACE_KNOWN (type)
-             && TYPE_POLYMORPHIC_P (type)
+             && TYPE_CONTAINS_VPTR_P (type)
              && CLASSTYPE_INTERFACE_ONLY (type)
              /* If -fno-rtti was specified, then we cannot be sure
                 that RTTI information will be emitted with the
diff --git a/gcc/testsuite/g++.dg/modules/virt-5_a.C 
b/gcc/testsuite/g++.dg/modules/virt-5_a.C
new file mode 100644
index 000000000000..f4c6abe85ef6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/virt-5_a.C
@@ -0,0 +1,16 @@
+// { dg-additional-options "-fmodules-ts" }
+// { dg-module-cmi M }
+
+export module M;
+
+struct C {};
+struct B : virtual C {};
+
+// Despite no non-inline key function, this is still a dynamic class
+// and so by the Itanium ABI 5.2.3 should be uniquely emitted in this TU
+export struct A : B {
+  inline A (int) {}
+};
+
+// { dg-final { scan-assembler {_ZTTW1M1A:} } }
+// { dg-final { scan-assembler {_ZTVW1M1A:} } }
diff --git a/gcc/testsuite/g++.dg/modules/virt-5_b.C 
b/gcc/testsuite/g++.dg/modules/virt-5_b.C
new file mode 100644
index 000000000000..785dd92ac1ee
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/virt-5_b.C
@@ -0,0 +1,11 @@
+// { dg-module-do link }
+// { dg-additional-options "-fmodules-ts" }
+
+import M;
+
+int main() {
+  A a(0);
+}
+
+// { dg-final { scan-assembler-not {_ZTTW1M1A:} } }
+// { dg-final { scan-assembler-not {_ZTVW1M1A:} } }

Reply via email to