[libcxx-commits] [libcxxabi] [libc++abi] Split catch_info from __dynamic_cast_info (PR #223744)

Nikolas Klauser via libcxx-commits libcxx-commits at lists.llvm.org
Wed Sep 16 03:24:29 PDT 2026


https://github.com/philnik777 updated https://github.com/llvm/llvm-project/pull/223744

>From b6cdd754f1ee6240693c95f961b827f741481442 Mon Sep 17 00:00:00 2001
From: Nikolas Klauser <nikolasklauser at berlin.de>
Date: Tue, 15 Sep 2026 17:38:52 +0200
Subject: [PATCH] [libc++abi] Split catch_info from __dynamic_cast_info

---
 libcxxabi/src/private_typeinfo.cpp | 76 +++++-------------------------
 libcxxabi/src/private_typeinfo.h   | 44 +++++++++++------
 2 files changed, 42 insertions(+), 78 deletions(-)

diff --git a/libcxxabi/src/private_typeinfo.cpp b/libcxxabi/src/private_typeinfo.cpp
index 1b74bd28435db..74d9a7b358352 100644
--- a/libcxxabi/src/private_typeinfo.cpp
+++ b/libcxxabi/src/private_typeinfo.cpp
@@ -171,7 +171,6 @@ const void* dyn_cast_to_derived(
       dst_type,
       static_ptr,
       static_type,
-      src2dst_offset,
       0,
       0,
       0,
@@ -183,9 +182,7 @@ const void* dyn_cast_to_derived(
       1, // number_of_dst_type
       false,
       false,
-      false,
-      true,
-      nullptr};
+      false};
   // Do the  search
   dst_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path, false);
 #ifdef _LIBCXXABI_FORGIVING_DYNAMIC_CAST
@@ -206,25 +203,7 @@ const void* dyn_cast_to_derived(
              static_type->name(),
              dst_type->name());
     // Redo the search comparing type_info's using strcmp
-    info = {
-        dst_type,
-        static_ptr,
-        static_type,
-        src2dst_offset,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        false,
-        false,
-        false,
-        true,
-        nullptr};
+    info                    = {dst_type, static_ptr, static_type, 0, 0, 0, 0, 0, 0, 0, 0, 0, false, false, false};
     info.number_of_dst_type = 1;
     dst_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path, true);
   }
@@ -265,7 +244,6 @@ const void* dyn_cast_try_downcast(
       dynamic_type,
       dst_ptr_to_static,
       dst_type,
-      src2dst_offset,
       0,
       0,
       0,
@@ -277,9 +255,7 @@ const void* dyn_cast_try_downcast(
       1, // number_of_dst_type
       false,
       false,
-      false,
-      true,
-      nullptr};
+      false};
   dynamic_type->search_above_dst(&dynamic_to_dst_info, dynamic_ptr, dynamic_ptr, public_path, false);
   if (dynamic_to_dst_info.path_dst_ptr_to_static_ptr != unknown) {
     // We have found at least one path from dynamic_ptr to dst_ptr. The
@@ -300,8 +276,7 @@ const void* dyn_cast_slow(
   // Not using giant short cut.  Do the search
 
   // Initialize info struct for this search.
-  __dynamic_cast_info info = {
-      dst_type, static_ptr, static_type, src2dst_offset, 0, 0, 0, 0, 0, 0, 0, 0, 0, false, false, false, true, nullptr};
+  __dynamic_cast_info info = {dst_type, static_ptr, static_type, 0, 0, 0, 0, 0, 0, 0, 0, 0, false, false, false};
 
   dynamic_type->search_below_dst(&info, dynamic_ptr, public_path, false);
 #ifdef _LIBCXXABI_FORGIVING_DYNAMIC_CAST
@@ -322,25 +297,7 @@ const void* dyn_cast_slow(
              dynamic_type->name(),
              dst_type->name());
     // Redo the search comparing type_info's using strcmp
-    info = {
-        dst_type,
-        static_ptr,
-        static_type,
-        src2dst_offset,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        0,
-        false,
-        false,
-        false,
-        true,
-        nullptr};
+    info = {dst_type, static_ptr, static_type, 0, 0, 0, 0, 0, 0, 0, 0, 0, false, false, false};
     dynamic_type->search_below_dst(&info, dynamic_ptr, public_path, true);
   }
 #endif // _LIBCXXABI_FORGIVING_DYNAMIC_CAST
@@ -487,8 +444,7 @@ bool __class_type_info::can_catch(const __shim_type_info* thrown_type, void*& ad
     return false;
   // bullet 2
   _LIBCXXABI_ASSERT(adjustedPtr, "catching a class without an object?");
-  __dynamic_cast_info info = {thrown_class_type, 0, this, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, true, nullptr};
-  info.number_of_dst_type  = 1;
+  catch_info info = {this, nullptr, nullptr, 0, 0, false, true, nullptr};
   thrown_class_type->has_unambiguous_public_base(&info, adjustedPtr, public_path);
   if (info.path_dst_ptr_to_static_ptr == public_path) {
     adjustedPtr = const_cast<void*>(info.dst_ptr_leading_to_static_ptr);
@@ -517,7 +473,7 @@ bool __class_type_info::can_catch(const __shim_type_info* thrown_type, void*& ad
 // different offset (adjustedPtr) from any previously recorded, this indicates
 // an ambiguous case within the virtual base.
 
-void __class_type_info::process_found_base_class(__dynamic_cast_info* info, void* adjustedPtr, int path_below) const {
+void __class_type_info::process_found_base_class(catch_info* info, void* adjustedPtr, int path_below) const {
   if (info->number_to_static_ptr == 0) {
     // First time we found this base
     info->dst_ptr_leading_to_static_ptr = adjustedPtr;
@@ -539,22 +495,19 @@ void __class_type_info::process_found_base_class(__dynamic_cast_info* info, void
   }
 }
 
-void __class_type_info::has_unambiguous_public_base(
-    __dynamic_cast_info* info, void* adjustedPtr, int path_below) const {
+void __class_type_info::has_unambiguous_public_base(catch_info* info, void* adjustedPtr, int path_below) const {
   if (is_equal(this, info->static_type, false))
     process_found_base_class(info, adjustedPtr, path_below);
 }
 
-void __si_class_type_info::has_unambiguous_public_base(
-    __dynamic_cast_info* info, void* adjustedPtr, int path_below) const {
+void __si_class_type_info::has_unambiguous_public_base(catch_info* info, void* adjustedPtr, int path_below) const {
   if (is_equal(this, info->static_type, false))
     process_found_base_class(info, adjustedPtr, path_below);
   else
     __base_type->has_unambiguous_public_base(info, adjustedPtr, path_below);
 }
 
-void __base_class_type_info::has_unambiguous_public_base(
-    __dynamic_cast_info* info, void* adjustedPtr, int path_below) const {
+void __base_class_type_info::has_unambiguous_public_base(catch_info* info, void* adjustedPtr, int path_below) const {
   bool is_virtual          = __offset_flags & __virtual_mask;
   ptrdiff_t offset_to_base = 0;
   if (info->have_object) {
@@ -585,8 +538,7 @@ void __base_class_type_info::has_unambiguous_public_base(
       (__offset_flags & __public_mask) ? path_below : not_public_path);
 }
 
-void __vmi_class_type_info::has_unambiguous_public_base(
-    __dynamic_cast_info* info, void* adjustedPtr, int path_below) const {
+void __vmi_class_type_info::has_unambiguous_public_base(catch_info* info, void* adjustedPtr, int path_below) const {
   if (is_equal(this, info->static_type, false))
     process_found_base_class(info, adjustedPtr, path_below);
   else {
@@ -682,10 +634,8 @@ bool __pointer_type_info::can_catch(const __shim_type_info* thrown_type, void*&
   const __class_type_info* thrown_class_type = dynamic_cast<const __class_type_info*>(thrown_pointer_type->__pointee);
   if (thrown_class_type == 0)
     return false;
-  bool have_object         = adjustedPtr != nullptr;
-  __dynamic_cast_info info = {
-      thrown_class_type, 0, catch_class_type, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, have_object, nullptr};
-  info.number_of_dst_type = 1;
+  bool have_object = adjustedPtr != nullptr;
+  catch_info info  = {catch_class_type, nullptr, nullptr, 0, 0, false, have_object, nullptr};
   thrown_class_type->has_unambiguous_public_base(&info, adjustedPtr, public_path);
   if (info.path_dst_ptr_to_static_ptr == public_path) {
     // In the case of a thrown null pointer, we have no object but we might
diff --git a/libcxxabi/src/private_typeinfo.h b/libcxxabi/src/private_typeinfo.h
index ad5a8e57ae25b..63270f136bb5d 100644
--- a/libcxxabi/src/private_typeinfo.h
+++ b/libcxxabi/src/private_typeinfo.h
@@ -61,6 +61,30 @@ enum
 
 class _LIBCXXABI_TYPE_VIS __class_type_info;
 
+struct catch_info {
+  const __class_type_info* static_type;
+
+  // pointer to a dst_type which has (static_ptr, static_type) above it
+  const void* dst_ptr_leading_to_static_ptr;
+  // pointer to a dst_type which does not have (static_ptr, static_type) above it
+  const void* dst_ptr_not_leading_to_static_ptr;
+
+  // The following three paths are either unknown, public_path or not_public_path.
+  // access of path from dst_ptr_leading_to_static_ptr to (static_ptr, static_type)
+  int path_dst_ptr_to_static_ptr;
+
+  // Number of dst_types below (static_ptr, static_type)
+  int number_to_static_ptr;
+
+  // Set whenever a search can be stopped
+  bool search_done;
+
+  // There is no object (seen when we throw a null pointer to object).
+  bool have_object;
+  // Virtual base
+  const void* vbase_cookie;
+};
+
 struct _LIBCXXABI_HIDDEN __dynamic_cast_info
 {
 // const data supplied to the search:
@@ -68,7 +92,6 @@ struct _LIBCXXABI_HIDDEN __dynamic_cast_info
     const __class_type_info* dst_type;
     const void* static_ptr;
     const __class_type_info* static_type;
-    ptrdiff_t src2dst_offset;
 
 // Data that represents the answer:
 
@@ -106,13 +129,6 @@ struct _LIBCXXABI_HIDDEN __dynamic_cast_info
     bool found_any_static_type;
     // Set whenever a search can be stopped
     bool search_done;
-
-    // Data that modifies the search mechanism.
-
-    // There is no object (seen when we throw a null pointer to object).
-    bool have_object;
-    // Virtual base
-    const void* vbase_cookie;
 };
 
 // Has no base class
@@ -125,16 +141,14 @@ class _LIBCXXABI_TYPE_VIS __class_type_info : public __shim_type_info {
                                                        const void *, int) const;
   _LIBCXXABI_HIDDEN void process_static_type_below_dst(__dynamic_cast_info *,
                                                        const void *, int) const;
-  _LIBCXXABI_HIDDEN void process_found_base_class(__dynamic_cast_info *, void *,
-                                                  int) const;
+  _LIBCXXABI_HIDDEN void process_found_base_class(catch_info*, void*, int) const;
   _LIBCXXABI_HIDDEN virtual void search_above_dst(__dynamic_cast_info *,
                                                   const void *, const void *,
                                                   int, bool) const;
   _LIBCXXABI_HIDDEN virtual void
   search_below_dst(__dynamic_cast_info *, const void *, int, bool) const;
   _LIBCXXABI_HIDDEN bool can_catch(const __shim_type_info*, void*&) const final;
-  _LIBCXXABI_HIDDEN virtual void
-  has_unambiguous_public_base(__dynamic_cast_info *, void *, int) const;
+  _LIBCXXABI_HIDDEN virtual void has_unambiguous_public_base(catch_info*, void*, int) const;
 };
 
 // Has one non-virtual public base class at offset zero
@@ -146,7 +160,7 @@ class _LIBCXXABI_TYPE_VIS __si_class_type_info final : public __class_type_info
 
   _LIBCXXABI_HIDDEN void search_above_dst(__dynamic_cast_info*, const void*, const void*, int, bool) const final;
   _LIBCXXABI_HIDDEN void search_below_dst(__dynamic_cast_info*, const void*, int, bool) const final;
-  _LIBCXXABI_HIDDEN void has_unambiguous_public_base(__dynamic_cast_info*, void*, int) const final;
+  _LIBCXXABI_HIDDEN void has_unambiguous_public_base(catch_info*, void*, int) const final;
 };
 
 struct _LIBCXXABI_HIDDEN __base_class_type_info
@@ -164,7 +178,7 @@ struct _LIBCXXABI_HIDDEN __base_class_type_info
 
     void search_above_dst(__dynamic_cast_info*, const void*, const void*, int, bool) const;
     void search_below_dst(__dynamic_cast_info*, const void*, int, bool) const;
-    void has_unambiguous_public_base(__dynamic_cast_info*, void*, int) const;
+    void has_unambiguous_public_base(catch_info*, void*, int) const;
 };
 
 // Has one or more base classes
@@ -185,7 +199,7 @@ class _LIBCXXABI_TYPE_VIS __vmi_class_type_info final : public __class_type_info
 
   _LIBCXXABI_HIDDEN void search_above_dst(__dynamic_cast_info*, const void*, const void*, int, bool) const final;
   _LIBCXXABI_HIDDEN void search_below_dst(__dynamic_cast_info*, const void*, int, bool) const final;
-  _LIBCXXABI_HIDDEN void has_unambiguous_public_base(__dynamic_cast_info*, void*, int) const final;
+  _LIBCXXABI_HIDDEN void has_unambiguous_public_base(catch_info*, void*, int) const final;
 };
 
 class _LIBCXXABI_TYPE_VIS __pbase_type_info : public __shim_type_info {



More information about the libcxx-commits mailing list