This patch fixes 79393, but I'm not 100% sure it's right.
[15.4]/8 says:
'The exception specification for an implicitly-declared destructor, or a
destructor without a noexcept-specifier, is potentially-throwing if and
only if any of the destructors for any of its potentially constructed
subojects is potentially throwing.'
'potentially constructed subobject' appears to be a term without
definition. I have interpreted it to mean all the bases of the object,
including virtual bases that are not deleted by a base destructor.
This we add the eh specs for both virtual and non-virtual dtors of
virtual bases.
An alternative approach might be to just add eh specs of virtual dtors
of virtual bases?
While working on this I discovered 79424. In this testcase we
synthesize A2::~A2's decl before we know A2 is abstract. By the time we
need its eh-spec, we have worked that out though.
Jason, wdyt?
nathan
--
Nathan Sidwell
2017-02-08 Nathan Sidwell <nat...@acm.org>
PR c++/79393
* method.c (synthesized_method_walk): Check vbases of abstract
classes for eh spec.
Index: cp/method.c
===================================================================
--- cp/method.c (revision 245277)
+++ cp/method.c (working copy)
@@ -1660,12 +1660,21 @@ 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
+ && !(sfk == sfk_destructor && spec_p))
/* Vbase cdtors are not relevant. */;
else
{
if (constexpr_p)
*constexpr_p = false;
+
+ /* We might not be concerned with access, just the eh-spec for each
+ potentially-constructed sub-object. */
+ 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,
@@ -1673,6 +1682,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;