[libcxx-commits] [libcxxabi] [libc++abi] Handle null pointer-to-object: Issue #64593 (PR #68076)
via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Oct 3 01:27:11 PDT 2023
github-actions[bot] wrote:
<!--LLVM CODE FORMAT COMMENT: {clang-format}-->
:warning: C/C++ code formatter, clang-format found issues in your code. :warning:
<details>
<summary>
You can test this locally with the following command:
</summary>
``````````bash
git-clang-format --diff 864beb179280f9b2e81b303462dfff90c283c8be 459ea8dcdc722391de3b17a20f14fb8022411c70 -- libcxxabi/test/catch_null_pointer_to_object_pr64953.pass.cpp libcxxabi/src/private_typeinfo.cpp libcxxabi/src/private_typeinfo.h
``````````
</details>
<details>
<summary>
View the diff from clang-format here.
</summary>
``````````diff
diff --git a/libcxxabi/src/private_typeinfo.cpp b/libcxxabi/src/private_typeinfo.cpp
index 197ea2ab8..34c340fdd 100644
--- a/libcxxabi/src/private_typeinfo.cpp
+++ b/libcxxabi/src/private_typeinfo.cpp
@@ -161,15 +161,11 @@ const void* dyn_cast_to_derived(const void* static_ptr,
// Fallback to the slow path to check that static_type is a public
// base type of dynamic_type.
// Using giant short cut. Add that information to info.
- __dynamic_cast_info info = {
- dst_type,
- static_ptr,
- static_type,
- src2dst_offset,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 1, // number_of_dst_type
- false, false, false, true
- };
+ __dynamic_cast_info info = {dst_type, static_ptr, static_type, src2dst_offset,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 1, // number_of_dst_type
+ false, false, false, true};
// Do the search
dst_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path, false);
#ifdef _LIBCXXABI_FORGIVING_DYNAMIC_CAST
@@ -188,13 +184,8 @@ const void* dyn_cast_to_derived(const void* static_ptr,
"should have public visibility. At least one of them is hidden. %s"
", %s.\n", 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
- };
+ info = {dst_type, static_ptr, static_type, src2dst_offset, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, false, false, false, true};
info.number_of_dst_type = 1;
dst_type->search_above_dst(&info, dynamic_ptr, dynamic_ptr, public_path, true);
}
@@ -233,15 +224,23 @@ const void* dyn_cast_try_downcast(const void* static_ptr,
}
// Try to search a path from dynamic_type to dst_type.
- __dynamic_cast_info dynamic_to_dst_info = {
- dynamic_type,
- dst_ptr_to_static,
- dst_type,
- src2dst_offset,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 1, // number_of_dst_type
- false, false, false, true
- };
+ __dynamic_cast_info dynamic_to_dst_info = {dynamic_type,
+ dst_ptr_to_static,
+ dst_type,
+ src2dst_offset,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1, // number_of_dst_type
+ false,
+ false,
+ false,
+ true};
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
@@ -262,13 +261,8 @@ const void* dyn_cast_slow(const void* static_ptr,
// 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
- };
+ __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};
dynamic_type->search_below_dst(&info, dynamic_ptr, public_path, false);
#ifdef _LIBCXXABI_FORGIVING_DYNAMIC_CAST
@@ -288,13 +282,8 @@ const void* dyn_cast_slow(const void* static_ptr,
"%s, %s, %s.\n", static_type->name(), 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
- };
+ info = {dst_type, static_ptr, static_type, src2dst_offset, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, false, false, false, true};
dynamic_type->search_below_dst(&info, dynamic_ptr, public_path, true);
}
#endif // _LIBCXXABI_FORGIVING_DYNAMIC_CAST
@@ -482,9 +471,8 @@ __class_type_info::can_catch(const __shim_type_info* thrown_type,
if (thrown_class_type == 0)
return false;
// bullet 2
- 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};
+ 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};
info.number_of_dst_type = 1;
thrown_class_type->has_unambiguous_public_base(&info, adjustedPtr, nullptr, public_path);
if (info.path_dst_ptr_to_static_ptr == public_path)
@@ -515,123 +503,90 @@ __class_type_info::can_catch(const __shim_type_info* thrown_type,
// 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,
- const void* virtualBase,
- int path_below) const
-{
- if (info->number_to_static_ptr == 0)
- {
- // First time here
- info->dst_ptr_leading_to_static_ptr = adjustedPtr;
- info->path_dst_ptr_to_static_ptr = path_below;
- // re-purpose this pointer.
- info->dst_ptr_not_leading_to_static_ptr = virtualBase;
- info->number_to_static_ptr = 1;
- }
- else if (info->dst_ptr_not_leading_to_static_ptr == virtualBase &&
- info->dst_ptr_leading_to_static_ptr == adjustedPtr)
- {
- // We've been here before. Update path to "most public"
- if (info->path_dst_ptr_to_static_ptr == not_public_path)
- info->path_dst_ptr_to_static_ptr = path_below;
- }
- else
- {
- // We've detected an ambiguous cast from (thrown_class_type, adjustedPtr)
- // to a static_type
- info->number_to_static_ptr += 1;
- info->path_dst_ptr_to_static_ptr = not_public_path;
- info->search_done = true;
- }
+void __class_type_info::process_found_base_class(__dynamic_cast_info* info, void* adjustedPtr, const void* virtualBase,
+ int path_below) const {
+ if (info->number_to_static_ptr == 0) {
+ // First time here
+ info->dst_ptr_leading_to_static_ptr = adjustedPtr;
+ info->path_dst_ptr_to_static_ptr = path_below;
+ // re-purpose this pointer.
+ info->dst_ptr_not_leading_to_static_ptr = virtualBase;
+ info->number_to_static_ptr = 1;
+ } else if (info->dst_ptr_not_leading_to_static_ptr == virtualBase &&
+ info->dst_ptr_leading_to_static_ptr == adjustedPtr) {
+ // We've been here before. Update path to "most public"
+ if (info->path_dst_ptr_to_static_ptr == not_public_path)
+ info->path_dst_ptr_to_static_ptr = path_below;
+ } else {
+ // We've detected an ambiguous cast from (thrown_class_type, adjustedPtr)
+ // to a static_type
+ info->number_to_static_ptr += 1;
+ info->path_dst_ptr_to_static_ptr = not_public_path;
+ info->search_done = true;
+ }
}
-void
-__class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info,
- void* adjustedPtr,
- const void* virtualBase,
- int path_below) const
-{
- if (is_equal(this, info->static_type, false))
- process_found_base_class(info, adjustedPtr, virtualBase, path_below);
+void __class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info, void* adjustedPtr,
+ const void* virtualBase, int path_below) const {
+ if (is_equal(this, info->static_type, false))
+ process_found_base_class(info, adjustedPtr, virtualBase, path_below);
}
-void
-__si_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info,
- void* adjustedPtr,
- const void* virtualBase,
- int path_below) const
-{
- if (is_equal(this, info->static_type, false))
- process_found_base_class(info, adjustedPtr, virtualBase, path_below);
- else
- __base_type->has_unambiguous_public_base(info, adjustedPtr, virtualBase, path_below);
+void __si_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info, void* adjustedPtr,
+ const void* virtualBase, int path_below) const {
+ if (is_equal(this, info->static_type, false))
+ process_found_base_class(info, adjustedPtr, virtualBase, path_below);
+ else
+ __base_type->has_unambiguous_public_base(info, adjustedPtr, virtualBase, path_below);
}
-void
-__base_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info,
- void* adjustedPtr,
- const void* virtualBase,
- int path_below) const
-{
- bool is_virtual = __offset_flags & __virtual_mask;
- ptrdiff_t offset_to_base = 0;
- if (info->have_object)
- {
- /* We have an object to inspect, we can look through its vtables to
+void __base_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info, void* adjustedPtr,
+ const void* virtualBase, int path_below) const {
+ bool is_virtual = __offset_flags & __virtual_mask;
+ ptrdiff_t offset_to_base = 0;
+ if (info->have_object) {
+ /* We have an object to inspect, we can look through its vtables to
find the layout. */
- offset_to_base = __offset_flags >> __offset_shift;
- if (is_virtual)
- {
- const char* vtable = *static_cast<const char*const*>(adjustedPtr);
- offset_to_base = update_offset_to_base(vtable, offset_to_base);
- }
- } else if (! is_virtual) {
- /* We have no object - so we cannot use it for determining layout when
+ offset_to_base = __offset_flags >> __offset_shift;
+ if (is_virtual) {
+ const char* vtable = *static_cast<const char* const*>(adjustedPtr);
+ offset_to_base = update_offset_to_base(vtable, offset_to_base);
+ }
+ } else if (!is_virtual) {
+ /* We have no object - so we cannot use it for determining layout when
we have a virtual base (since we cannot indirect through the vtable
to find the actual object offset). However, for non-virtual bases,
we can pretend to have an object based at '0' */
- offset_to_base = __offset_flags >> __offset_shift;
- } else {
- // no object to inspect, and the next base is virtual.
- // we want to update virtualBase to the new innermost virtual base.
- // using the pointer to the typeinfo name as a key.
- virtualBase = static_cast<const void*>(__base_type->name ());
- // .. and reset the pointer.
- adjustedPtr = nullptr;
- }
- __base_type->has_unambiguous_public_base(
- info,
- static_cast<char*>(adjustedPtr) + offset_to_base,
- virtualBase,
- (__offset_flags & __public_mask) ? path_below : not_public_path);
+ offset_to_base = __offset_flags >> __offset_shift;
+ } else {
+ // no object to inspect, and the next base is virtual.
+ // we want to update virtualBase to the new innermost virtual base.
+ // using the pointer to the typeinfo name as a key.
+ virtualBase = static_cast<const void*>(__base_type->name());
+ // .. and reset the pointer.
+ adjustedPtr = nullptr;
+ }
+ __base_type->has_unambiguous_public_base(info, static_cast<char*>(adjustedPtr) + offset_to_base, virtualBase,
+ (__offset_flags & __public_mask) ? path_below : not_public_path);
}
-void
-__vmi_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info,
- void* adjustedPtr,
- const void* virtualBase,
- int path_below) const
-{
- if (is_equal(this, info->static_type, false))
- process_found_base_class(info, adjustedPtr, virtualBase, path_below);
- else
- {
- typedef const __base_class_type_info* Iter;
- const Iter e = __base_info + __base_count;
- Iter p = __base_info;
+void __vmi_class_type_info::has_unambiguous_public_base(__dynamic_cast_info* info, void* adjustedPtr,
+ const void* virtualBase, int path_below) const {
+ if (is_equal(this, info->static_type, false))
+ process_found_base_class(info, adjustedPtr, virtualBase, path_below);
+ else {
+ typedef const __base_class_type_info* Iter;
+ const Iter e = __base_info + __base_count;
+ Iter p = __base_info;
+ p->has_unambiguous_public_base(info, adjustedPtr, virtualBase, path_below);
+ if (++p < e) {
+ do {
p->has_unambiguous_public_base(info, adjustedPtr, virtualBase, path_below);
- if (++p < e)
- {
- do
- {
- p->has_unambiguous_public_base(info, adjustedPtr, virtualBase, path_below);
- if (info->search_done)
- break;
- } while (++p < e);
- }
+ if (info->search_done)
+ break;
+ } while (++p < e);
}
+ }
}
// Handles bullet 1 for both pointers and member pointers
@@ -724,22 +679,21 @@ __pointer_type_info::can_catch(const __shim_type_info* thrown_type,
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 };
+ __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};
info.number_of_dst_type = 1;
thrown_class_type->has_unambiguous_public_base(&info, adjustedPtr, nullptr, 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
- // well have computed the offset to where a public sub-object would be.
- // However, we do not want to return that offset to the user; we still
- // want them to catch a null ptr.
- if (have_object)
- adjustedPtr = const_cast<void*>(info.dst_ptr_leading_to_static_ptr);
- else
- adjustedPtr = nullptr;
- return true;
+ // In the case of a thrown null pointer, we have no object but we might
+ // well have computed the offset to where a public sub-object would be.
+ // However, we do not want to return that offset to the user; we still
+ // want them to catch a null ptr.
+ if (have_object)
+ adjustedPtr = const_cast<void*>(info.dst_ptr_leading_to_static_ptr);
+ else
+ adjustedPtr = nullptr;
+ return true;
}
return false;
}
``````````
</details>
https://github.com/llvm/llvm-project/pull/68076
More information about the libcxx-commits
mailing list