This patch fixes 66443, a defect introduced by a C++14 change concerning virtual bases of abstract classes.

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66443 points at DR1611 & 1658, which describe the issue. Essentially, an abstract class type can only exist as a base of some other (non-abstract) class. Any virtual bases of the abstract class will be constructed by the containing class itself. In this specific instance, a deleted default ctor of such a virtual base should not delete the abstract class's default dtor.

built &  tested on x6-64-linux, ok?

nathan
2015-06-29  Nathan Sidwell  <nat...@acm.org>

	PR c++/66443
	* init.c (emit_mem_initializers): Do not emit initializers for
	virtual bases of abstract classes.
	* method.c (synthesized_method_walk): Skip virtual bases of
	abstract classes in C++14 mode.

	PR c++/66443
	* cpp1y/pr66443.C: New test.

Index: cp/init.c
===================================================================
--- cp/init.c	(revision 225103)
+++ cp/init.c	(working copy)
@@ -1139,9 +1139,7 @@ emit_mem_initializers (tree mem_inits)
 	}
 
       /* Initialize the base.  */
-      if (BINFO_VIRTUAL_P (subobject))
-	construct_virtual_base (subobject, arguments);
-      else
+      if (!BINFO_VIRTUAL_P (subobject))
 	{
 	  tree base_addr;
 
@@ -1155,6 +1153,8 @@ emit_mem_initializers (tree mem_inits)
                               tf_warning_or_error);
 	  expand_cleanup_for_base (subobject, NULL_TREE);
 	}
+      else if (!ABSTRACT_CLASS_TYPE_P (current_class_type))
+	construct_virtual_base (subobject, arguments);
     }
   in_base_initializer = 0;
 
Index: cp/method.c
===================================================================
--- cp/method.c	(revision 225103)
+++ cp/method.c	(working copy)
@@ -1505,7 +1505,10 @@ synthesized_method_walk (tree ctype, spe
   vbases = CLASSTYPE_VBASECLASSES (ctype);
   if (vec_safe_is_empty (vbases))
     /* No virtual bases to worry about.  */;
-  else if (!assign_p)
+  else if (!assign_p
+	   /* C++14 ignores virtual bases of abstract classes, as they
+	      can never be directly called.  */
+	   && (cxx_dialect < cxx14 || !ABSTRACT_CLASS_TYPE_P (ctype)))
     {
       if (constexpr_p)
 	*constexpr_p = false;
Index: testsuite/g++.dg/cpp1y/pr66443.C
===================================================================
--- testsuite/g++.dg/cpp1y/pr66443.C	(revision 0)
+++ testsuite/g++.dg/cpp1y/pr66443.C	(working copy)
@@ -0,0 +1,22 @@
+// PR c++/66443
+// { dg-do compile { target c++14 } }
+
+class A {
+public:
+    A( int ) {  }
+};
+
+// B's virtual base is ignored for default ctor determination as B is
+// abstract.  DR1611 &  DR1658
+
+class B: virtual public A {
+public:
+    virtual void do_something() = 0;
+};
+
+class C: public B {
+public:
+    C(): A( 1 ) {  }
+    virtual void do_something() {  }
+};
+

Reply via email to