The resolution to DR 1658 causes vbases of abstract classes to be
ignored when building the cdtors. That made sense for ctors, when there
might be no default ctor available. But for dtors, there is only oe
dtor and they can be virtual. That can break virtual overriding, as
79393 discovered.
I've reported this as a DR, but so GCC 7 doesn't break currently working
code, I've committed this patch to skip that part of 1658's resolution.
The inhibiting of access checks was needed of pr66443-cxx14-3.C to
continue passing. That's a case where the vbase's dtor is inaccessible
from the abstract base. That seemed like the most conservative way to
inhibit 1658's impact by allowing the most code to be compiled, but of
course is speculative.
nathan
--
Nathan Sidwell
2017-03-13 Nathan Sidwell <nat...@acm.org>
PR c++/79393 DR 1658 workaround
* method.c (synthesized_method_walk): Check vbases of abstract
classes for dtor walk.
Index: cp/method.c
===================================================================
--- cp/method.c (revision 246084)
+++ cp/method.c (working copy)
@@ -1664,12 +1664,26 @@ synthesized_method_walk (tree ctype, spe
/* Already examined vbases above. */;
else if (vec_safe_is_empty (vbases))
/* No virtual bases to worry about. */;
- else if (ABSTRACT_CLASS_TYPE_P (ctype) && cxx_dialect >= cxx14)
+ else if (ABSTRACT_CLASS_TYPE_P (ctype) && cxx_dialect >= cxx14
+ /* DR 1658 specifies that vbases of abstract classes are
+ ignored for both ctors and dtors. However, that breaks
+ virtual dtor overriding when the ignored base has a
+ throwing destructor. So, ignore that piece of 1658. A
+ defect has been filed (no number yet). */
+ && sfk != sfk_destructor)
/* Vbase cdtors are not relevant. */;
else
{
if (constexpr_p)
*constexpr_p = false;
+
+ /* To be conservative, ignore access to the base dtor that
+ DR1658 instructs us to ignore. */
+ bool no_access_check = (cxx_dialect >= cxx14
+ && ABSTRACT_CLASS_TYPE_P (ctype));
+
+ if (no_access_check)
+ push_deferring_access_checks (dk_no_check);
FOR_EACH_VEC_ELT (*vbases, i, base_binfo)
synthesized_method_base_walk (binfo, base_binfo, quals,
copy_arg_p, move_p, ctor_p,
@@ -1677,6 +1691,8 @@ synthesized_method_walk (tree ctype, spe
fnname, flags, diag,
spec_p, trivial_p,
deleted_p, constexpr_p);
+ if (no_access_check)
+ pop_deferring_access_checks ();
}
/* Now handle the non-static data members. */
Index: testsuite/g++.dg/cpp1y/pr79393.C
===================================================================
--- testsuite/g++.dg/cpp1y/pr79393.C (revision 0)
+++ testsuite/g++.dg/cpp1y/pr79393.C (working copy)
@@ -0,0 +1,21 @@
+// { dg-do compile { target c++14 } }
+// PR c++/79393 deduced eh spec, deleted dtors and vbases
+
+struct A3;
+
+struct VDT {
+ virtual ~VDT () noexcept (false);
+};
+
+struct A1 : virtual VDT {
+ virtual void abstract () = 0;
+};
+
+struct A2 : A1 { };
+
+struct A3 : A2
+{
+ virtual void abstract ();
+};
+
+A3 a3;