From d74db8ff1c8f126c3d45ab9e72458ead0422865b Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Wed, 26 Mar 2014 12:50:26 -0400 Subject: [PATCH] re PR c++/60566 (r208573 omits needed thunks) PR c++/60566 PR c++/58678 * class.c (build_vtbl_initializer): Handle abstract dtors here. * search.c (get_pure_virtuals): Not here. From-SVN: r208845 --- gcc/cp/ChangeLog | 5 +++++ gcc/cp/class.c | 10 ++++++++++ gcc/cp/search.c | 16 ---------------- gcc/ipa-devirt.c | 2 +- gcc/testsuite/g++.dg/abi/thunk6.C | 18 ++++++++++++++++++ gcc/testsuite/g++.dg/ipa/devirt-21.C | 2 +- gcc/testsuite/g++.dg/ipa/devirt-23.C | 2 +- 7 files changed, 36 insertions(+), 19 deletions(-) create mode 100644 gcc/testsuite/g++.dg/abi/thunk6.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 23a2c8fc3f35..518eb22bb39e 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,10 @@ 2014-03-25 Jason Merrill + PR c++/60566 + PR c++/58678 + * class.c (build_vtbl_initializer): Handle abstract dtors here. + * search.c (get_pure_virtuals): Not here. + PR c++/60375 * parser.c (cp_parser_lambda_expression): Don't parse the body of a lambda in unevaluated context. diff --git a/gcc/cp/class.c b/gcc/cp/class.c index b46391be1552..d277e0758eea 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -9017,6 +9017,16 @@ build_vtbl_initializer (tree binfo, if (!TARGET_VTABLE_USES_DESCRIPTORS) init = fold_convert (vfunc_ptr_type_node, build_fold_addr_expr (fn)); + /* Don't refer to a virtual destructor from a constructor + vtable or a vtable for an abstract class, since destroying + an object under construction is undefined behavior and we + don't want it to be considered a candidate for speculative + devirtualization. But do create the thunk for ABI + compliance. */ + if (DECL_DESTRUCTOR_P (fn_original) + && (CLASSTYPE_PURE_VIRTUALS (DECL_CONTEXT (fn_original)) + || orig_binfo != binfo)) + init = size_zero_node; } } diff --git a/gcc/cp/search.c b/gcc/cp/search.c index d99e18215faf..c3eed90f6c36 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -2115,22 +2115,6 @@ get_pure_virtuals (tree type) which it is a primary base will contain vtable entries for the pure virtuals in the base class. */ dfs_walk_once (TYPE_BINFO (type), NULL, dfs_get_pure_virtuals, type); - - /* Treat a virtual destructor in an abstract class as pure even if it - isn't declared as pure; there is no way it would be called through the - vtable except during construction, which causes undefined behavior. */ - if (CLASSTYPE_PURE_VIRTUALS (type) - && TYPE_HAS_NONTRIVIAL_DESTRUCTOR (type)) - { - tree dtor = CLASSTYPE_DESTRUCTORS (type); - if (dtor && DECL_VIRTUAL_P (dtor) && !DECL_PURE_VIRTUAL_P (dtor)) - { - tree clone; - DECL_PURE_VIRTUAL_P (dtor) = true; - FOR_EACH_CLONE (clone, dtor) - DECL_PURE_VIRTUAL_P (clone) = true; - } - } } /* Debug info for C++ classes can get very large; try to avoid diff --git a/gcc/ipa-devirt.c b/gcc/ipa-devirt.c index 2f84f177d192..6fb14492a609 100644 --- a/gcc/ipa-devirt.c +++ b/gcc/ipa-devirt.c @@ -1261,7 +1261,7 @@ get_polymorphic_call_info (tree fndecl, } /* If the function is constructor or destructor, then - the type is possibly in consturction, but we know + the type is possibly in construction, but we know it is not derived type. */ if (DECL_CXX_CONSTRUCTOR_P (fndecl) || DECL_CXX_DESTRUCTOR_P (fndecl)) diff --git a/gcc/testsuite/g++.dg/abi/thunk6.C b/gcc/testsuite/g++.dg/abi/thunk6.C new file mode 100644 index 000000000000..e3d07f2aca0e --- /dev/null +++ b/gcc/testsuite/g++.dg/abi/thunk6.C @@ -0,0 +1,18 @@ +// PR c++/60566 +// We need to emit the construction vtable thunk for ~C even if we aren't +// going to use it. + +struct A +{ + virtual void f() = 0; + virtual ~A() {} +}; + +struct B: virtual A { int i; }; +struct C: virtual A { int i; ~C(); }; + +C::~C() {} + +int main() {} + +// { dg-final { scan-assembler "_ZTv0_n32_N1CD1Ev" } } diff --git a/gcc/testsuite/g++.dg/ipa/devirt-21.C b/gcc/testsuite/g++.dg/ipa/devirt-21.C index 99f60afe33c5..675bd08d782b 100644 --- a/gcc/testsuite/g++.dg/ipa/devirt-21.C +++ b/gcc/testsuite/g++.dg/ipa/devirt-21.C @@ -37,5 +37,5 @@ main() { class C c; } -/* { dg-final { scan-ipa-dump "Discovered a virtual call to" "cp" } } */ +/* { dg-final { scan-ipa-dump "Discovered a virtual call to" "cp" { xfail *-*-* } } } */ /* { dg-final { cleanup-ipa-dump "cp" } } */ diff --git a/gcc/testsuite/g++.dg/ipa/devirt-23.C b/gcc/testsuite/g++.dg/ipa/devirt-23.C index a32c7d674837..98d86aee8e04 100644 --- a/gcc/testsuite/g++.dg/ipa/devirt-23.C +++ b/gcc/testsuite/g++.dg/ipa/devirt-23.C @@ -45,5 +45,5 @@ main() { class C c; } -/* { dg-final { scan-ipa-dump "Discovered a virtual call to" "cp" } } */ +/* { dg-final { scan-ipa-dump "Discovered a virtual call to" "cp" { xfail *-*-* } } } */ /* { dg-final { cleanup-ipa-dump "cp" } } */ -- 2.47.2