]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: Stream virtual dtor vtable indices
authorNathaniel Shead <nathanieloshead@gmail.com>
Tue, 14 Nov 2023 16:26:03 +0000 (11:26 -0500)
committerNathan Sidwell <nathan@acm.org>
Tue, 14 Nov 2023 19:43:20 +0000 (14:43 -0500)
Virtual cloned functions have distinct vtable indices, stream them
explicitly.

As such, this patch ensures that DECL_VINDEX is properly passed on for
cloned functions as well to prevent this from causing issues.

PR c++/103499

gcc/cp/ChangeLog:

* module.cc (trees_out::decl_node): Write DECL_VINDEX for
virtual clones.
(trees_in::tree_node): Read DECL_VINDEX for virtual clones.

gcc/testsuite/ChangeLog:

* g++.dg/modules/pr103499_a.C: New test.
* g++.dg/modules/pr103499_b.C: New test.

Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
Signed-off-by: Nathan Sidwell <nathan@acm.org>
gcc/cp/module.cc
gcc/testsuite/g++.dg/modules/pr103499_a.C [new file with mode: 0644]
gcc/testsuite/g++.dg/modules/pr103499_b.C [new file with mode: 0644]

index c1c8c226bc1ec36bcd4b0ee1f491dc10b7d2b111..4f5b6e2747a7de3b5187ebbea5306e77966a1b1a 100644 (file)
@@ -8648,6 +8648,8 @@ trees_out::decl_node (tree decl, walk_kind ref)
 
       tree_node (target);
       tree_node (DECL_NAME (decl));
+      if (DECL_VIRTUAL_P (decl))
+       tree_node (DECL_VINDEX (decl));
       int tag = insert (decl);
       if (streaming_p ())
        dump (dumper::TREE)
@@ -9869,6 +9871,10 @@ trees_in::tree_node (bool is_use)
                }
          }
 
+       /* A clone might have a different vtable entry.  */
+       if (res && DECL_VIRTUAL_P (res))
+         DECL_VINDEX (res) = tree_node ();
+
        if (!res)
          set_overrun ();
        int tag = insert (res);
diff --git a/gcc/testsuite/g++.dg/modules/pr103499_a.C b/gcc/testsuite/g++.dg/modules/pr103499_a.C
new file mode 100644 (file)
index 0000000..0497c2c
--- /dev/null
@@ -0,0 +1,12 @@
+// PR c++/103499
+// { dg-module-do compile }
+// { dg-additional-options "-fmodules-ts" }
+// { dg-module-cmi pr103499 }
+
+export module pr103499;
+
+export struct base {
+  virtual ~base() = default;
+};
+
+export struct derived : base {};
diff --git a/gcc/testsuite/g++.dg/modules/pr103499_b.C b/gcc/testsuite/g++.dg/modules/pr103499_b.C
new file mode 100644 (file)
index 0000000..b746856
--- /dev/null
@@ -0,0 +1,8 @@
+// PR c++/103499
+// { dg-additional-options "-fmodules-ts" }
+
+import pr103499;
+
+void test(derived* p) {
+  delete p;
+}