-
Notifications
You must be signed in to change notification settings - Fork 14k
[libc++] Fix padding calculation for function reference types #142125
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-libcxx Author: A. Jiang (frederick-vs-ja) Changes#109028 caused Fixes #142118. Full diff: https://github.com/llvm/llvm-project/pull/142125.diff 2 Files Affected:
diff --git a/libcxx/include/__memory/compressed_pair.h b/libcxx/include/__memory/compressed_pair.h
index 38798a21fa3c9..fb7b7b7afcc8c 100644
--- a/libcxx/include/__memory/compressed_pair.h
+++ b/libcxx/include/__memory/compressed_pair.h
@@ -15,7 +15,6 @@
#include <__type_traits/datasizeof.h>
#include <__type_traits/is_empty.h>
#include <__type_traits/is_final.h>
-#include <__type_traits/is_reference.h>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# pragma GCC system_header
@@ -63,9 +62,17 @@ inline const size_t __compressed_pair_alignment = _LIBCPP_ALIGNOF(_Tp);
template <class _Tp>
inline const size_t __compressed_pair_alignment<_Tp&> = _LIBCPP_ALIGNOF(void*);
-template <class _ToPad,
- bool _Empty = ((is_empty<_ToPad>::value && !__libcpp_is_final<_ToPad>::value) ||
- is_reference<_ToPad>::value || sizeof(_ToPad) == __datasizeof_v<_ToPad>)>
+template <class _ToPad>
+inline const bool __is_reference_or_unpadded_object =
+ (is_empty<_ToPad>::value && !__libcpp_is_final<_ToPad>::value) || sizeof(_ToPad) == __datasizeof_v<_ToPad>;
+
+template <class _Tp>
+inline const bool __is_reference_or_unpadded_object<_Tp&> = true;
+
+template <class _Tp>
+inline const bool __is_reference_or_unpadded_object<_Tp&&> = true;
+
+template <class _ToPad, bool _Empty = __is_reference_or_unpadded_object<_ToPad> >
class __compressed_pair_padding {
char __padding_[sizeof(_ToPad) - __datasizeof_v<_ToPad>] = {};
};
diff --git a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.pass.cpp b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.pass.cpp
index a91abc856fb19..a438bfb58ce44 100644
--- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.pass.cpp
+++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.pass.cpp
@@ -32,6 +32,8 @@ bool my_free_called = false;
void my_free(void*) { my_free_called = true; }
+TEST_CONSTEXPR_CXX23 void deleter_function(A*) {}
+
#if TEST_STD_VER >= 11
struct DeleterBase {
TEST_CONSTEXPR_CXX23 void operator()(void*) const {}
@@ -325,6 +327,21 @@ TEST_CONSTEXPR_CXX23 void test_nullptr() {
#endif
}
+template <bool IsArray>
+TEST_CONSTEXPR_CXX23 void test_function_reference() {
+ typedef typename std::conditional<!IsArray, A, A[]>::type VT;
+ {
+ std::unique_ptr<VT, void (&)(A*)> u(nullptr, deleter_function);
+ assert(u.get() == nullptr);
+ assert(u.get_deleter() == deleter_function);
+ }
+ {
+ std::unique_ptr<VT, void (&)(A*)> u(nullptr, deleter_function);
+ assert(u.get() == nullptr);
+ assert(u.get_deleter() == deleter_function);
+ }
+}
+
TEST_CONSTEXPR_CXX23 bool test() {
{
test_basic</*IsArray*/ false>();
@@ -332,6 +349,7 @@ TEST_CONSTEXPR_CXX23 bool test() {
test_basic_single();
test_sfinae<false>();
test_noexcept<false>();
+ test_function_reference<false>();
}
{
test_basic</*IsArray*/ true>();
@@ -339,6 +357,7 @@ TEST_CONSTEXPR_CXX23 bool test() {
test_sfinae<true>();
test_sfinae_runtime();
test_noexcept<true>();
+ test_function_reference<true>();
}
return true;
|
template <class _ToPad, | ||
bool _Empty = ((is_empty<_ToPad>::value && !__libcpp_is_final<_ToPad>::value) || | ||
is_reference<_ToPad>::value || sizeof(_ToPad) == __datasizeof_v<_ToPad>)> | ||
template <class _ToPad> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do this have to be updated as well?
llvm-project/lldb/packages/Python/lldbsuite/test/make/libcxx-simulators-common/compressed_pair.h
Lines 75 to 81 in 18e5131
template <class _ToPad> class __compressed_pair_padding { | |
char __padding_[((is_empty<_ToPad>::value && | |
!__lldb_is_final<_ToPad>::value) || | |
is_reference<_ToPad>::value) | |
? 0 | |
: sizeof(_ToPad) - __datasizeof_v<_ToPad>]; | |
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like that changes in lldbsuite should belong to another PR. I've opened #142516.
…42125) llvm#109028 caused `sizeof` to be sometimes applied to function reference types, which makes a program ill-formed. This PR handles reference types by specializations to prevent such bogus `sizeof` expression to be instantiated. Fixes llvm#142118.
…42125) llvm#109028 caused `sizeof` to be sometimes applied to function reference types, which makes a program ill-formed. This PR handles reference types by specializations to prevent such bogus `sizeof` expression to be instantiated. Fixes llvm#142118.
#109028 caused
sizeof
to be sometimes applied to function reference types, which makes a program ill-formed. This PR handles reference types by specializations to prevent such bogussizeof
expression to be instantiated.Fixes #142118.