Commit 2bd652d2 by Nathan Sidwell Committed by Nathan Sidwell

[C++ DR 2336] virtual dtors, exception specs & abstract classes

https://gcc.gnu.org/ml/gcc-patches/2018-11/msg01389.html
	DR 2336
	* cp-tree.h (enum special_function_kind): Add sfk_virtual_destructor.
	* method.c (type_has_trivial_fn): Add it.
	(SFK_DTOR_P): Likewise.
	(synthesized_method_base_walk): Don't check access of vbases of
	abstract classes when sfk_virtual_destructor.
	(synthesized_method_walk): Skip vbases of abstract classes except
	when sfk_virtual_destructor.
	(get_defaulted_eh_spec): Set sfk_virtual_destructor as needed.

	* g++.dg/cpp1y/pr79393-3.C: New.

From-SVN: r266188
parent 1a50c428
2018-11-15 Nathan Sidwell <nathan@acm.org> 2018-11-15 Nathan Sidwell <nathan@acm.org>
DR 2336
* cp-tree.h (enum special_function_kind): Add sfk_virtual_destructor.
* method.c (type_has_trivial_fn): Add it.
(SFK_DTOR_P): Likewise.
(synthesized_method_base_walk): Don't check access of vbases of
abstract classes when sfk_virtual_destructor.
(synthesized_method_walk): Skip vbases of abstract classes except
when sfk_virtual_destructor.
(get_defaulted_eh_spec): Set sfk_virtual_destructor as needed.
* cp-tree.h (enum special_function_kind): Reorder and comment. * cp-tree.h (enum special_function_kind): Reorder and comment.
* method.c (SFK_CTOR_P, SFK_DTOR_P, SFK_ASSIGN_P, SFK_COPY_P) * method.c (SFK_CTOR_P, SFK_DTOR_P, SFK_ASSIGN_P, SFK_COPY_P)
(SFK_MOVE_P): New predicates. (SFK_MOVE_P): New predicates.
......
...@@ -5099,7 +5099,8 @@ enum special_function_kind { ...@@ -5099,7 +5099,8 @@ enum special_function_kind {
deletes the object after it has been deletes the object after it has been
destroyed. */ destroyed. */
sfk_conversion, /* A conversion operator. */ sfk_conversion, /* A conversion operator. */
sfk_deduction_guide /* A class template deduction guide. */ sfk_deduction_guide, /* A class template deduction guide. */
sfk_virtual_destructor /* Used by member synthesis fns. */
}; };
/* The various kinds of linkage. From [basic.link], /* The various kinds of linkage. From [basic.link],
......
...@@ -402,6 +402,7 @@ type_has_trivial_fn (tree ctype, special_function_kind sfk) ...@@ -402,6 +402,7 @@ type_has_trivial_fn (tree ctype, special_function_kind sfk)
case sfk_move_assignment: case sfk_move_assignment:
return !TYPE_HAS_COMPLEX_MOVE_ASSIGN (ctype); return !TYPE_HAS_COMPLEX_MOVE_ASSIGN (ctype);
case sfk_destructor: case sfk_destructor:
case sfk_virtual_destructor:
return !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype); return !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype);
case sfk_inheriting_constructor: case sfk_inheriting_constructor:
return false; return false;
...@@ -1287,7 +1288,7 @@ process_subob_fn (tree fn, tree *spec_p, bool *trivial_p, ...@@ -1287,7 +1288,7 @@ process_subob_fn (tree fn, tree *spec_p, bool *trivial_p,
#define SFK_CTOR_P(sfk) \ #define SFK_CTOR_P(sfk) \
((sfk) >= sfk_constructor && (sfk) <= sfk_move_constructor) ((sfk) >= sfk_constructor && (sfk) <= sfk_move_constructor)
#define SFK_DTOR_P(sfk) \ #define SFK_DTOR_P(sfk) \
((sfk) == sfk_destructor) ((sfk) == sfk_destructor || (sfk) == sfk_virtual_destructor)
#define SFK_ASSIGN_P(sfk) \ #define SFK_ASSIGN_P(sfk) \
((sfk) == sfk_copy_assignment || (sfk) == sfk_move_assignment) ((sfk) == sfk_copy_assignment || (sfk) == sfk_move_assignment)
#define SFK_COPY_P(sfk) \ #define SFK_COPY_P(sfk) \
...@@ -1481,12 +1482,11 @@ synthesized_method_base_walk (tree binfo, tree base_binfo, ...@@ -1481,12 +1482,11 @@ synthesized_method_base_walk (tree binfo, tree base_binfo,
if (flag_new_inheriting_ctors) if (flag_new_inheriting_ctors)
defer = dk_deferred; defer = dk_deferred;
} }
/* To be conservative, ignore access to the base dtor that else if (cxx_dialect >= cxx14 && sfk == sfk_virtual_destructor
DR1658 instructs us to ignore. See the comment in
synthesized_method_walk. */
else if (cxx_dialect >= cxx14 && fnname == complete_dtor_identifier
&& BINFO_VIRTUAL_P (base_binfo) && BINFO_VIRTUAL_P (base_binfo)
&& ABSTRACT_CLASS_TYPE_P (BINFO_TYPE (binfo))) && ABSTRACT_CLASS_TYPE_P (BINFO_TYPE (binfo)))
/* Don't check access when looking at vbases of abstract class's
virtual destructor. */
defer = dk_no_check; defer = dk_no_check;
if (defer != dk_no_deferred) if (defer != dk_no_deferred)
...@@ -1572,7 +1572,7 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p, ...@@ -1572,7 +1572,7 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
bool check_vdtor = false; bool check_vdtor = false;
tree fnname; tree fnname;
if (SFK_DTOR_P (sfk)) if (SFK_DTOR_P (sfk))
{ {
check_vdtor = true; check_vdtor = true;
/* The synthesized method will call base dtors, but check complete /* The synthesized method will call base dtors, but check complete
...@@ -1696,12 +1696,11 @@ if (SFK_DTOR_P (sfk)) ...@@ -1696,12 +1696,11 @@ if (SFK_DTOR_P (sfk))
else if (vec_safe_is_empty (vbases)) else if (vec_safe_is_empty (vbases))
/* No virtual bases to worry about. */; /* 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 /* DR 1658 specifis that vbases of abstract classes are
ignored for both ctors and dtors. However, that breaks ignored for both ctors and dtors. Except DR 2338
virtual dtor overriding when the ignored base has a overrides that skipping when determing the eh-spec of a
throwing destructor. So, ignore that piece of 1658. A virtual destructor. */
defect has been filed (no number yet). */ && sfk != sfk_virtual_destructor)
&& sfk != sfk_destructor)
/* Vbase cdtors are not relevant. */; /* Vbase cdtors are not relevant. */;
else else
{ {
...@@ -1748,6 +1747,9 @@ get_defaulted_eh_spec (tree decl, tsubst_flags_t complain) ...@@ -1748,6 +1747,9 @@ get_defaulted_eh_spec (tree decl, tsubst_flags_t complain)
tree spec = empty_except_spec; tree spec = empty_except_spec;
bool diag = !DECL_DELETED_FN (decl) && (complain & tf_error); bool diag = !DECL_DELETED_FN (decl) && (complain & tf_error);
tree inh = DECL_INHERITED_CTOR (decl); tree inh = DECL_INHERITED_CTOR (decl);
if (SFK_DTOR_P (sfk) && DECL_VIRTUAL_P (decl))
/* We have to examine virtual bases even if abstract. */
sfk = sfk_virtual_destructor;
synthesized_method_walk (ctype, sfk, const_p, &spec, NULL, NULL, synthesized_method_walk (ctype, sfk, const_p, &spec, NULL, NULL,
NULL, diag, &inh, parms); NULL, diag, &inh, parms);
return spec; return spec;
......
2018-11-15 Nathan Sidwell <nathan@acm.org>
DR 2336
* g++.dg/cpp1y/pr79393-3.C: New.
2018-11-15 David Malcolm <dmalcolm@redhat.com> 2018-11-15 David Malcolm <dmalcolm@redhat.com>
PR other/19165 PR other/19165
......
// pr c++/79393
// { dg-do compile { target c++14 } }
struct A
{
friend class C;
private:
~A () noexcept (false);
};
A::~A () noexcept(false) {}
struct B : virtual A
{
// non-virtual, abstract, ignores A
~B ();
virtual void abs () = 0;
};
B::~B () {
throw 1; // { dg-warning "will always call terminate" }
}
struct C : virtual A
{
// non-virtual, non-abstract, considers A
~C ();
virtual void abs ();
};
C::~C () {
throw 1;
}
struct D : virtual A
{
// virtual, abstract, considers A
virtual ~D ();
virtual void abs () = 0;
};
D::~D () {
throw 1;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment