From: Jason Merrill Date: Wed, 26 Jun 2019 04:56:07 +0000 (-0400) Subject: PR c++/70462 - unnecessary base ctor variant with final. X-Git-Tag: upstream/12.2.0~23691 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=09039e9c723456cd008c7fa94ea772ee796cda2c;p=platform%2Fupstream%2Fgcc.git PR c++/70462 - unnecessary base ctor variant with final. As pointed out in the PR, we don't need base 'tor variants for a final class, since it can never be a base. I tried also dropping complete variants for abstract classes, but that runs into ABI compatibility problems with older releases that refer to those symbols. * optimize.c (populate_clone_array): Skip base variant if CLASSTYPE_FINAL. (maybe_clone_body): We don't need an alias if we are only defining one clone. From-SVN: r272669 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index dee69b8..9d89ccb 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,11 @@ 2019-06-25 Jason Merrill + PR c++/70462 - unnecessary base ctor variant with final. + * optimize.c (populate_clone_array): Skip base variant if + CLASSTYPE_FINAL. + (maybe_clone_body): We don't need an alias if we are only defining + one clone. + * class.c (resolves_to_fixed_type_p): Check CLASSTYPE_FINAL. 2019-06-25 Jakub Jelinek diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c index aace7de..0774857 100644 --- a/gcc/cp/optimize.c +++ b/gcc/cp/optimize.c @@ -247,15 +247,19 @@ populate_clone_array (tree fn, tree *fns) fns[1] = NULL_TREE; fns[2] = NULL_TREE; - /* Look for the complete destructor which may be used to build the - delete destructor. */ + 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) - fns[0] = clone; + { + /* We don't need to define the base variants for a final class. */ + if (!CLASSTYPE_FINAL (ctx)) + fns[0] = clone; + } else if (DECL_NAME (clone) == deleting_dtor_identifier) fns[2] = clone; else @@ -480,7 +484,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)) + if (!tree_versionable_function_p (fn) && fns[0] && fns[1]) 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 new file mode 100644 index 0000000..f90f94e --- /dev/null +++ b/gcc/testsuite/g++.dg/other/final8.C @@ -0,0 +1,9 @@ +// { dg-do compile { target c++11 } } +// { dg-final { scan-assembler-not "_ZN1BC2Ev" } } +// { dg-final { scan-assembler-not "_ZN1BD2Ev" } } + +struct A { int i; A(); virtual ~A() = 0; }; +struct B final: public virtual A { int j; B(); ~B(); }; + +B::B() {} +B::~B() {}