diff mbox series

[pushed] c++: Emit as-base 'tor symbols for final class. [PR95428]

Message ID 20200824190811.12666-1-jason@redhat.com
State New
Headers show
Series [pushed] c++: Emit as-base 'tor symbols for final class. [PR95428] | expand

Commit Message

Jason Merrill Aug. 24, 2020, 7:08 p.m. UTC
For PR70462 I stopped emitting the as-base constructor and destructor
variants for final classes, because they can never be called.  Except that
it turns out that clang calls base variants from complete variants, even for
classes with virtual bases, and in some cases inlines them such that the
calls to the base variant are exposed.  So we need to continue to emit the
as-base symbols, even though they're unreachable by G++-compiled code.

Tested x86_64-pc-linux-gnu, applying to trunk and 10.

gcc/cp/ChangeLog:

	PR c++/95428
	* optimize.c (populate_clone_array): Revert PR70462 change.
	(maybe_clone_body): Likewise.

gcc/testsuite/ChangeLog:

	* g++.dg/other/final8.C: Adjust expected output.
---
 gcc/cp/optimize.c                   | 10 ++--------
 gcc/testsuite/g++.dg/other/final8.C |  8 ++++++--
 2 files changed, 8 insertions(+), 10 deletions(-)


base-commit: 259d072067997ab8f55afcf735c91b6740fd0425
diff mbox series

Patch

diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c
index abdcd7fa19f..00621d636bf 100644
--- a/gcc/cp/optimize.c
+++ b/gcc/cp/optimize.c
@@ -244,19 +244,13 @@  populate_clone_array (tree fn, tree *fns)
   fns[1] = NULL_TREE;
   fns[2] = NULL_TREE;
 
-  tree ctx = DECL_CONTEXT (fn);
-
   FOR_EACH_CLONE (clone, fn)
     if (DECL_NAME (clone) == complete_dtor_identifier
 	|| DECL_NAME (clone) == complete_ctor_identifier)
       fns[1] = clone;
     else if (DECL_NAME (clone) == base_dtor_identifier
 	     || DECL_NAME (clone) == base_ctor_identifier)
-      {
-	/* We don't need to define the base variants for a final class.  */
-	if (!CLASSTYPE_FINAL (ctx))
-	  fns[0] = clone;
-      }
+      fns[0] = clone;
     else if (DECL_NAME (clone) == deleting_dtor_identifier)
       fns[2] = clone;
     else
@@ -481,7 +475,7 @@  maybe_clone_body (tree fn)
 
   /* Remember if we can't have multiple clones for some reason.  We need to
      check this before we remap local static initializers in clone_body.  */
-  if (!tree_versionable_function_p (fn) && fns[0] && fns[1])
+  if (!tree_versionable_function_p (fn))
     need_alias = true;
 
   /* We know that any clones immediately follow FN in the TYPE_FIELDS
diff --git a/gcc/testsuite/g++.dg/other/final8.C b/gcc/testsuite/g++.dg/other/final8.C
index f90f94e9ea0..67c87112353 100644
--- a/gcc/testsuite/g++.dg/other/final8.C
+++ b/gcc/testsuite/g++.dg/other/final8.C
@@ -1,6 +1,10 @@ 
+// PR c++/70462
+// PR c++/95428
 // { dg-do compile { target c++11 } }
-// { dg-final { scan-assembler-not "_ZN1BC2Ev" } }
-// { dg-final { scan-assembler-not "_ZN1BD2Ev" } }
+// { dg-final { scan-assembler "_ZN1BC1Ev" } }
+// { dg-final { scan-assembler "_ZN1BC2Ev" } }
+// { dg-final { scan-assembler "_ZN1BD2Ev" } }
+// { dg-final { scan-assembler "_ZN1BD1Ev" } }
 
 struct A { int i; A(); virtual ~A() = 0; };
 struct B final: public virtual A { int j; B(); ~B(); };