public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [C++ DR 2336] virtual dtors, exception specs & abstract classes
@ 2018-11-15 15:50 Nathan Sidwell
  0 siblings, 0 replies; only message in thread
From: Nathan Sidwell @ 2018-11-15 15:50 UTC (permalink / raw)
  To: GCC Patches

[-- Attachment #1: Type: text/plain, Size: 751 bytes --]

This patch implements dr2336, a fix to dr1658

dr1658 made virtual bases of abstract classes ignored for synthesize 
cdtors -- there are no complete objects of such type, so the vbases will 
never be cdtored by such cdtors.

Except when virtual dtors are in play, such a dtor could override a 
virtual dtor in a virtual base, and thus must not have a stricter 
exception specification.  DR2336 addresses that.

I had nearly anticipated this resolution, but I was also looking into 
virtual bases in other cases, and ignoring access in different other 
cases.   This implements the DR2336 wording (it does not distinguish 
between virtual and non-virtual dtors of virtual bases).

booted on x6_64-linux, committing to trunk.

nathan
-- 
Nathan Sidwell

[-- Attachment #2: dr2336.diff --]
[-- Type: text/x-patch, Size: 5110 bytes --]

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.

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

Index: gcc/cp/cp-tree.h
===================================================================
--- gcc/cp/cp-tree.h	(revision 266180)
+++ gcc/cp/cp-tree.h	(working copy)
@@ -5099,7 +5099,8 @@ enum special_function_kind {
 			      deletes the object after it has been
 			      destroyed.  */
   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],
Index: gcc/cp/method.c
===================================================================
--- gcc/cp/method.c	(revision 266180)
+++ gcc/cp/method.c	(working copy)
@@ -402,6 +402,7 @@ type_has_trivial_fn (tree ctype, special
     case sfk_move_assignment:
       return !TYPE_HAS_COMPLEX_MOVE_ASSIGN (ctype);
     case sfk_destructor:
+    case sfk_virtual_destructor:
       return !TYPE_HAS_NONTRIVIAL_DESTRUCTOR (ctype);
     case sfk_inheriting_constructor:
       return false;
@@ -1287,7 +1288,7 @@ process_subob_fn (tree fn, tree *spec_p,
 #define SFK_CTOR_P(sfk) \
   ((sfk) >= sfk_constructor && (sfk) <= sfk_move_constructor)
 #define SFK_DTOR_P(sfk) \
-  ((sfk) == sfk_destructor)
+  ((sfk) == sfk_destructor || (sfk) == sfk_virtual_destructor)
 #define SFK_ASSIGN_P(sfk) \
   ((sfk) == sfk_copy_assignment || (sfk) == sfk_move_assignment)
 #define SFK_COPY_P(sfk) \
@@ -1481,12 +1482,11 @@ synthesized_method_base_walk (tree binfo
       if (flag_new_inheriting_ctors)
 	defer = dk_deferred;
     }
-  /* To be conservative, ignore access to the base dtor that
-     DR1658 instructs us to ignore.  See the comment in
-     synthesized_method_walk.  */
-  else if (cxx_dialect >= cxx14 && fnname == complete_dtor_identifier
+  else if (cxx_dialect >= cxx14 && sfk == sfk_virtual_destructor
 	   && BINFO_VIRTUAL_P (base_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;
 
   if (defer != dk_no_deferred)
@@ -1572,7 +1572,7 @@ synthesized_method_walk (tree ctype, spe
   bool check_vdtor = false;
   tree fnname;
 
-if (SFK_DTOR_P (sfk))
+  if (SFK_DTOR_P (sfk))
     {
       check_vdtor = true;
       /* The synthesized method will call base dtors, but check complete
@@ -1696,12 +1696,11 @@ if (SFK_DTOR_P (sfk))
   else if (vec_safe_is_empty (vbases))
     /* No virtual bases to worry about.  */;
   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)
+	   /* DR 1658 specifis that vbases of abstract classes are
+	      ignored for both ctors and dtors.  Except DR 2338
+	      overrides that skipping when determing the eh-spec of a
+	      virtual destructor.  */
+	   && sfk != sfk_virtual_destructor)
     /* Vbase cdtors are not relevant.  */;
   else
     {
@@ -1748,6 +1747,9 @@ get_defaulted_eh_spec (tree decl, tsubst
   tree spec = empty_except_spec;
   bool diag = !DECL_DELETED_FN (decl) && (complain & tf_error);
   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,
 			   NULL, diag, &inh, parms);
   return spec;
Index: gcc/testsuite/g++.dg/cpp1y/pr79393-3.C
===================================================================
--- gcc/testsuite/g++.dg/cpp1y/pr79393-3.C	(revision 0)
+++ gcc/testsuite/g++.dg/cpp1y/pr79393-3.C	(working copy)
@@ -0,0 +1,44 @@
+// 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;
+}

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2018-11-15 15:50 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-15 15:50 [C++ DR 2336] virtual dtors, exception specs & abstract classes Nathan Sidwell

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).