]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: Emit as-base 'tor symbols for final class. [PR95428]
authorJason Merrill <jason@redhat.com>
Fri, 21 Aug 2020 20:23:03 +0000 (16:23 -0400)
committerJason Merrill <jason@redhat.com>
Mon, 24 Aug 2020 21:44:18 +0000 (17:44 -0400)
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.

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
gcc/testsuite/g++.dg/other/final8.C

index d4f12dbb84db4050742b26a4ae5d4efdf367e84a..e112a4b4f82118dfe74a9805e19181b0d40b8f62 100644 (file)
@@ -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
index f90f94e9ea0f3c33f2a32ef47b6ceec66a45dbef..67c8711235372ecf36881fd23a13966fb183768f 100644 (file)
@@ -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(); };