aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2020-08-21 16:23:03 -0400
committerJason Merrill <jason@redhat.com>2020-08-24 22:43:39 -0400
commit6b958ee0fd0e1b2a2b22784ffbe531ed74358a22 (patch)
tree5a5489ac95c1e2eaa04e9c2ef06dc58a01cbead8 /gcc
parentb2b24d30bbf7496986fee3a7f201b69ba973d3b0 (diff)
downloadgcc-6b958ee0fd0e1b2a2b22784ffbe531ed74358a22.zip
gcc-6b958ee0fd0e1b2a2b22784ffbe531ed74358a22.tar.gz
gcc-6b958ee0fd0e1b2a2b22784ffbe531ed74358a22.tar.bz2
c++: Emit as-base 'tor symbols for final class. [PR95428]
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.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/optimize.c10
-rw-r--r--gcc/testsuite/g++.dg/other/final8.C8
2 files changed, 8 insertions, 10 deletions
diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c
index abdcd7f..00621d6 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 f90f94e..67c8711 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(); };