Tested x86_64-pc-linux-gnu, applying to trunk.
-- 8< --
We've recently had adjustments to can_convert_eh and
handler_match_for_exception_type, two separate functions answering the same
question. The latter is newer and better matches the current standard, so
let's retain it. But it still needed some fixes to avoid regressions: the
lookup_base was missing ba_ignore_scope, and wasn't being done for pointers.
gcc/cp/ChangeLog:
* cp-tree.h (can_convert_eh): Remove declaration.
* except.cc (can_convert_eh): Remove.
(check_handlers_1): Use handler_match_for_exception_type instead.
* cp-lang.cc (LANG_HOOKS_EXCEPTION_MATCHES_TYPE_P): Likewise.
* call.cc (handler_match_for_exception_type): Allow type argument,
fix private base handling.
---
gcc/cp/cp-tree.h | 1 -
gcc/cp/call.cc | 20 +++++++++++---------
gcc/cp/cp-lang.cc | 2 +-
gcc/cp/except.cc | 39 ++-------------------------------------
4 files changed, 14 insertions(+), 48 deletions(-)
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 69ce5e2e8e7..a8af4d38945 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7872,7 +7872,6 @@ extern tree build_exc_ptr (void);
extern tree build_throw (location_t, tree,
tsubst_flags_t);
extern int nothrow_libfn_p (const_tree);
-extern bool can_convert_eh (tree, tree);
extern void check_handlers (tree);
extern tree finish_noexcept_expr (tree, tsubst_flags_t);
extern bool expr_noexcept_p (tree, tsubst_flags_t);
diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index 1c4662c79cc..45c108e9e91 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -1734,21 +1734,16 @@ involves_qualification_conversion_p (tree to, tree from)
per [except.handle]/3. */
bool
-handler_match_for_exception_type (tree handler, tree except_type)
+handler_match_for_exception_type (tree handler_type, tree except_type)
{
- tree handler_type = HANDLER_TYPE (handler);
+ if (handler_type && TREE_CODE (handler_type) == HANDLER)
+ handler_type = TREE_TYPE (handler_type);
if (handler_type == NULL_TREE)
return true; /* ... */
if (same_type_ignoring_top_level_qualifiers_p (handler_type, except_type))
return true;
if (CLASS_TYPE_P (except_type) && CLASS_TYPE_P (handler_type))
- {
- base_kind b_kind;
- tree binfo = lookup_base (except_type, handler_type, ba_check, &b_kind,
- tf_none);
- if (binfo && binfo != error_mark_node)
- return true;
- }
+ return publicly_uniquely_derived_p (handler_type, except_type);
if (TYPE_PTR_P (handler_type) || TYPE_PTRMEM_P (handler_type))
{
if (TREE_CODE (except_type) == NULLPTR_TYPE)
@@ -1768,6 +1763,13 @@ handler_match_for_exception_type (tree handler, tree
except_type)
switch (t->kind)
{
case ck_ptr:
+ /* ...not involving conversions to pointers to private or
+ protected or ambiguous classes, */
+ if (CLASS_TYPE_P (TREE_TYPE (handler_type)))
+ return (publicly_uniquely_derived_p
+ (TREE_TYPE (handler_type),
+ TREE_TYPE (except_type)));
+ gcc_fallthrough ();
case ck_fnptr:
case ck_qual:
case ck_identity:
diff --git a/gcc/cp/cp-lang.cc b/gcc/cp/cp-lang.cc
index 60fd114d35c..7cef17fc603 100644
--- a/gcc/cp/cp-lang.cc
+++ b/gcc/cp/cp-lang.cc
@@ -79,7 +79,7 @@ static const char *cp_get_sarif_source_language (const char
*);
#undef LANG_HOOKS_EH_RUNTIME_TYPE
#define LANG_HOOKS_EH_RUNTIME_TYPE build_eh_type_type
#undef LANG_HOOKS_EXCEPTION_MATCHES_TYPE_P
-#define LANG_HOOKS_EXCEPTION_MATCHES_TYPE_P can_convert_eh
+#define LANG_HOOKS_EXCEPTION_MATCHES_TYPE_P handler_match_for_exception_type
#undef LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE
#define LANG_HOOKS_ENUM_UNDERLYING_BASE_TYPE cxx_enum_underlying_base_type
#undef LANG_HOOKS_PREPROCESS_MAIN_FILE
diff --git a/gcc/cp/except.cc b/gcc/cp/except.cc
index 9ec635af74d..c1d31b99219 100644
--- a/gcc/cp/except.cc
+++ b/gcc/cp/except.cc
@@ -970,42 +970,6 @@ nothrow_libfn_p (const_tree fn)
}
}
-/* Returns nonzero if an exception of type FROM will be caught by a
- handler for type TO, as per [except.handle]. */
-
-bool
-can_convert_eh (tree to, tree from)
-{
- to = non_reference (to);
- from = non_reference (from);
-
- if (same_type_ignoring_top_level_qualifiers_p (to, from))
- return true;
-
- if (NULLPTR_TYPE_P (from) && TYPE_PTR_OR_PTRMEM_P (to))
- return true;
-
- if (TYPE_PTR_P (to) && TYPE_PTR_P (from))
- {
- to = TREE_TYPE (to);
- from = TREE_TYPE (from);
-
- if (! at_least_as_qualified_p (to, from))
- return false;
-
- if (VOID_TYPE_P (to))
- return true;
-
- /* Else fall through. */
- }
-
- if (CLASS_TYPE_P (to) && CLASS_TYPE_P (from)
- && publicly_uniquely_derived_p (to, from))
- return true;
-
- return false;
-}
-
/* Check whether any of the handlers in I are shadowed by another handler
accepting TYPE. Note that the shadowing may not be complete; even if
an exception of type B would be caught by a handler for A, there could
@@ -1020,7 +984,8 @@ check_handlers_1 (tree master, tree_stmt_iterator i)
for (; !tsi_end_p (i); tsi_next (&i))
{
tree handler = tsi_stmt (i);
- if (TREE_TYPE (handler) && can_convert_eh (type, TREE_TYPE (handler)))
+ if (TREE_TYPE (handler)
+ && handler_match_for_exception_type (type, TREE_TYPE (handler)))
{
auto_diagnostic_group d;
if (warning_at (EXPR_LOCATION (handler), OPT_Wexceptions,
base-commit: c93461a16d650eaa56f7e80225807569f50bc6a0
--
2.55.0