PR c++/79393 DR 1658 workaround
authorNathan Sidwell <nathan@acm.org>
Mon, 13 Mar 2017 11:58:15 +0000 (11:58 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Mon, 13 Mar 2017 11:58:15 +0000 (11:58 +0000)
PR c++/79393 DR 1658 workaround
* method.c (synthesized_method_walk): Check vbases of abstract
classes for dtor walk.

From-SVN: r246085

gcc/cp/ChangeLog
gcc/cp/method.c
gcc/testsuite/g++.dg/cpp1y/pr79393.C [new file with mode: 0644]

index ac7a46e79df942ce20056e702de96c59e456e56c..00fb3651959b8b43ea0c4b92432f0a972ef9b7da 100644 (file)
@@ -1,3 +1,9 @@
+2017-03-13  Nathan Sidwell  <nathan@acm.org>
+
+       PR c++/79393 DR 1658 workaround
+       * method.c (synthesized_method_walk): Check vbases of abstract
+       classes for dtor walk.
+
 2017-03-10  David Malcolm  <dmalcolm@redhat.com>
 
        PR translation/79848
index f6024cda28a97ffb385664372e6a638debf3ad87..772a6638c60de89862528d86d5cd8a53fea97803 100644 (file)
@@ -1664,12 +1664,26 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
     /* 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
+          /* 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)
     /* Vbase cdtors are not relevant.  */;
   else
     {
       if (constexpr_p)
        *constexpr_p = false;
+
+      /* To be conservative, ignore access to the base dtor that
+        DR1658 instructs us to ignore.  */
+      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,
@@ -1677,6 +1691,8 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
                                      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.  */
diff --git a/gcc/testsuite/g++.dg/cpp1y/pr79393.C b/gcc/testsuite/g++.dg/cpp1y/pr79393.C
new file mode 100644 (file)
index 0000000..a9e07d1
--- /dev/null
@@ -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;