aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2017-03-14 14:41:53 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2017-03-14 14:41:53 +0000
commit9b74f93310e3c0ff495dd8fb15b547b28e9be506 (patch)
treebd1f58aaa6bce2600e92e1cd3934e91363295269 /gcc
parent927595086615da94c52b164049a45ebf6e299623 (diff)
downloadgcc-9b74f93310e3c0ff495dd8fb15b547b28e9be506.zip
gcc-9b74f93310e3c0ff495dd8fb15b547b28e9be506.tar.gz
gcc-9b74f93310e3c0ff495dd8fb15b547b28e9be506.tar.bz2
PR c++/79393 DR 1658 workaround
PR c++/79393 DR 1658 workaround * method.c (synthesized_method_base_walk): Inihibit abstract class virtual base access check here. (synthesized_method_walk): Not here. From-SVN: r246126
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/method.c34
-rw-r--r--gcc/testsuite/g++.dg/cpp1y/pr79393-2.C22
3 files changed, 47 insertions, 16 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 00fb365..aa74b00 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2017-03-14 Nathan Sidwell <nathan@acm.org>
+
+ PR c++/79393 DR 1658 workaround
+ * method.c (synthesized_method_base_walk): Inihibit abstract class
+ virtual base access check here.
+ (synthesized_method_walk): Not here.
+
2017-03-13 Nathan Sidwell <nathan@acm.org>
PR c++/79393 DR 1658 workaround
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index 772a663..b4c1f60 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -1420,10 +1420,10 @@ walk_field_subobs (tree fields, tree fnname, special_function_kind sfk,
}
}
-// Base walker helper for synthesized_method_walk. Inspect a direct
-// or virtual base. BINFO is the parent type's binfo. BASE_BINFO is
-// the base binfo of interests. All other parms are as for
-// synthesized_method_walk, or its local vars.
+/* Base walker helper for synthesized_method_walk. Inspect a direct
+ or virtual base. BINFO is the parent type's binfo. BASE_BINFO is
+ the base binfo of interests. All other parms are as for
+ synthesized_method_walk, or its local vars. */
static tree
synthesized_method_base_walk (tree binfo, tree base_binfo,
@@ -1436,7 +1436,8 @@ synthesized_method_base_walk (tree binfo, tree base_binfo,
{
bool inherited_binfo = false;
tree argtype = NULL_TREE;
-
+ deferring_kind defer = dk_no_deferred;
+
if (copy_arg_p)
argtype = build_stub_type (BINFO_TYPE (base_binfo), quals, move_p);
else if ((inherited_binfo
@@ -1445,11 +1446,21 @@ synthesized_method_base_walk (tree binfo, tree base_binfo,
argtype = inherited_parms;
/* Don't check access on the inherited constructor. */
if (flag_new_inheriting_ctors)
- push_deferring_access_checks (dk_deferred);
+ 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
+ && BINFO_VIRTUAL_P (base_binfo)
+ && ABSTRACT_CLASS_TYPE_P (BINFO_TYPE (binfo)))
+ defer = dk_no_check;
+
+ if (defer != dk_no_deferred)
+ push_deferring_access_checks (defer);
tree rval = locate_fn_flags (base_binfo, fnname, argtype, flags,
diag ? tf_warning_or_error : tf_none);
- if (inherited_binfo && flag_new_inheriting_ctors)
+ if (defer != dk_no_deferred)
pop_deferring_access_checks ();
process_subob_fn (rval, spec_p, trivial_p, deleted_p,
@@ -1677,13 +1688,6 @@ synthesized_method_walk (tree ctype, special_function_kind sfk, bool const_p,
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,
@@ -1691,8 +1695,6 @@ 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-2.C b/gcc/testsuite/g++.dg/cpp1y/pr79393-2.C
new file mode 100644
index 0000000..ebd9d90
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp1y/pr79393-2.C
@@ -0,0 +1,22 @@
+// { dg-do compile { target c++14 } }
+
+// DR 1658, inaccessible dtor of virtual base doesn't affect an
+// abstract class. But we should stil check access to non-virtual bases.
+
+class C;
+
+struct A {
+private:
+ ~A (){ }
+ friend class C;
+};
+
+struct B : A { // { dg-error "is private" }
+ virtual bool Ok () = 0; // abstract
+};
+
+struct C : B {
+ ~C ()
+ { } // { dg-error "use of deleted" }
+ virtual bool Ok ();
+};