diff mbox

[C++PATCH] c++/79393 virtual base of abstract class

Message ID cb175885-cdeb-b6c9-0306-8f891183e21f@acm.org
State New
Headers show

Commit Message

Nathan Sidwell Feb. 8, 2017, 2:08 p.m. UTC
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

Comments

Tim Song Feb. 8, 2017, 2:33 p.m. UTC | #1
On Wed, Feb 8, 2017 at 10:08 PM, Nathan Sidwell <nathan@acm.org> wrote:
>
> 'potentially constructed subobject' appears to be a term without definition.

[special]/5:

For a class, its non-static data members, its non-virtual direct base
classes, and, if the class is not abstract, its virtual base classes
are called its potentially constructed subobjects.
Nathan Sidwell Feb. 8, 2017, 3:09 p.m. UTC | #2
On 02/08/2017 09:33 AM, Tim Song wrote:
> On Wed, Feb 8, 2017 at 10:08 PM, Nathan Sidwell <nathan@acm.org> wrote:
>>
>> 'potentially constructed subobject' appears to be a term without definition.
>
> [special]/5:
>
> For a class, its non-static data members, its non-virtual direct base
> classes, and, if the class is not abstract, its virtual base classes
> are called its potentially constructed subobjects.

thanks.  That suggests that this, pedantically, is not a defect.  It's 
certainly an unwelcome surprise though.

nathan
Jason Merrill Feb. 8, 2017, 5:53 p.m. UTC | #3
On Wed, Feb 8, 2017 at 10:09 AM, Nathan Sidwell <nathan@acm.org> wrote:
> On 02/08/2017 09:33 AM, Tim Song wrote:
>> On Wed, Feb 8, 2017 at 10:08 PM, Nathan Sidwell <nathan@acm.org> wrote:

>>> 'potentially constructed subobject' appears to be a term without
>>> definition.
>>
>> [special]/5:
>>
>> For a class, its non-static data members, its non-virtual direct base
>> classes, and, if the class is not abstract, its virtual base classes
>> are called its potentially constructed subobjects.
>
> thanks.  That suggests that this, pedantically, is not a defect.  It's
> certainly an unwelcome surprise though.

Perhaps the defect is in the standard.  Will you email core about it?

Jason
Nathan Sidwell Feb. 8, 2017, 7:11 p.m. UTC | #4
On 02/08/2017 12:53 PM, Jason Merrill wrote:

> Perhaps the defect is in the standard.  Will you email core about it?

Correct, done.

nathan
diff mbox

Patch

2017-02-08  Nathan Sidwell  <nathan@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;