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

Reply via email to