From 890043314a7f405081990ea9d0cb577dd44f883f Mon Sep 17 00:00:00 2001 From: Jason Merrill <jason@redhat.com> Date: Fri, 17 Mar 2023 15:27:10 -0400 Subject: [PATCH] c++: throw and private destructor [PR109172] Since we aren't going through the normal call machinery, we need to check the dtor access specifically. PR c++/109172 gcc/cp/ChangeLog: * except.cc (build_throw): Check dtor access. gcc/testsuite/ChangeLog: * g++.dg/eh/dtor4.C: New test. --- gcc/cp/except.cc | 10 ++++++++-- gcc/testsuite/g++.dg/eh/dtor4.C | 15 +++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/g++.dg/eh/dtor4.C diff --git a/gcc/cp/except.cc b/gcc/cp/except.cc index 916e8189db6f..91a5e0498601 100644 --- a/gcc/cp/except.cc +++ b/gcc/cp/except.cc @@ -639,6 +639,8 @@ build_throw (location_t loc, tree exp) tree object, ptr; tree allocate_expr; + tsubst_flags_t complain = tf_warning_or_error; + /* The CLEANUP_TYPE is the internal type of a destructor. */ if (!cleanup_type) { @@ -759,11 +761,15 @@ build_throw (location_t loc, tree exp) cleanup = NULL_TREE; if (type_build_dtor_call (TREE_TYPE (object))) { - tree dtor_fn = lookup_fnfields (TYPE_BINFO (TREE_TYPE (object)), + tree binfo = TYPE_BINFO (TREE_TYPE (object)); + tree dtor_fn = lookup_fnfields (binfo, complete_dtor_identifier, 0, tf_warning_or_error); dtor_fn = BASELINK_FUNCTIONS (dtor_fn); - mark_used (dtor_fn); + if (!mark_used (dtor_fn) + || !perform_or_defer_access_check (binfo, dtor_fn, + dtor_fn, complain)) + return error_mark_node; if (TYPE_HAS_NONTRIVIAL_DESTRUCTOR (TREE_TYPE (object))) { cxx_mark_addressable (dtor_fn); diff --git a/gcc/testsuite/g++.dg/eh/dtor4.C b/gcc/testsuite/g++.dg/eh/dtor4.C new file mode 100644 index 000000000000..6c0e804fe8a6 --- /dev/null +++ b/gcc/testsuite/g++.dg/eh/dtor4.C @@ -0,0 +1,15 @@ +// PR c++/109172 + +class Demo +{ + ~Demo(); +}; + +int main() +{ + try + { + throw *new Demo; // { dg-error private } + } + catch(const Demo& e) { } +} -- GitLab