musllvm

A pure LLVM/Clang cross compiler toolchain targeting musl C
git clone git://git.daat.foo/musllvm.git
Log | Files | Refs | README | LICENSE

769c42f4a552a75c8c38870ddc1b50d2ea874e4e.patch (3927B)


      1 From 769c42f4a552a75c8c38870ddc1b50d2ea874e4e Mon Sep 17 00:00:00 2001
      2 From: "A. Jiang" <de34@live.cn>
      3 Date: Tue, 3 Jun 2025 23:54:49 +0800
      4 Subject: [PATCH] [libc++] Fix padding calculation for function reference types
      5  (#142125)
      6 
      7 #109028 caused `sizeof` to be sometimes applied to function reference
      8 types, which makes a program ill-formed. This PR handles reference types
      9 by specializations to prevent such bogus `sizeof` expression to be
     10 instantiated.
     11 
     12 Fixes #142118.
     13 ---
     14  libcxx/include/__memory/compressed_pair.h     | 15 +++++++++++----
     15  .../unique.ptr.ctor/pointer_deleter.pass.cpp  | 19 +++++++++++++++++++
     16  2 files changed, 30 insertions(+), 4 deletions(-)
     17 
     18 diff --git a/libcxx/include/__memory/compressed_pair.h b/libcxx/include/__memory/compressed_pair.h
     19 index 38798a21fa3c9..fb7b7b7afcc8c 100644
     20 --- a/libcxx/include/__memory/compressed_pair.h
     21 +++ b/libcxx/include/__memory/compressed_pair.h
     22 @@ -15,7 +15,6 @@
     23  #include <__type_traits/datasizeof.h>
     24  #include <__type_traits/is_empty.h>
     25  #include <__type_traits/is_final.h>
     26 -#include <__type_traits/is_reference.h>
     27  
     28  #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
     29  #  pragma GCC system_header
     30 @@ -63,9 +62,17 @@ inline const size_t __compressed_pair_alignment = _LIBCPP_ALIGNOF(_Tp);
     31  template <class _Tp>
     32  inline const size_t __compressed_pair_alignment<_Tp&> = _LIBCPP_ALIGNOF(void*);
     33  
     34 -template <class _ToPad,
     35 -          bool _Empty = ((is_empty<_ToPad>::value && !__libcpp_is_final<_ToPad>::value) ||
     36 -                         is_reference<_ToPad>::value || sizeof(_ToPad) == __datasizeof_v<_ToPad>)>
     37 +template <class _ToPad>
     38 +inline const bool __is_reference_or_unpadded_object =
     39 +    (is_empty<_ToPad>::value && !__libcpp_is_final<_ToPad>::value) || sizeof(_ToPad) == __datasizeof_v<_ToPad>;
     40 +
     41 +template <class _Tp>
     42 +inline const bool __is_reference_or_unpadded_object<_Tp&> = true;
     43 +
     44 +template <class _Tp>
     45 +inline const bool __is_reference_or_unpadded_object<_Tp&&> = true;
     46 +
     47 +template <class _ToPad, bool _Empty = __is_reference_or_unpadded_object<_ToPad> >
     48  class __compressed_pair_padding {
     49    char __padding_[sizeof(_ToPad) - __datasizeof_v<_ToPad>] = {};
     50  };
     51 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
     52 index a91abc856fb19..a438bfb58ce44 100644
     53 --- a/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.pass.cpp
     54 +++ b/libcxx/test/std/utilities/smartptr/unique.ptr/unique.ptr.class/unique.ptr.ctor/pointer_deleter.pass.cpp
     55 @@ -32,6 +32,8 @@ bool my_free_called = false;
     56  
     57  void my_free(void*) { my_free_called = true; }
     58  
     59 +TEST_CONSTEXPR_CXX23 void deleter_function(A*) {}
     60 +
     61  #if TEST_STD_VER >= 11
     62  struct DeleterBase {
     63    TEST_CONSTEXPR_CXX23 void operator()(void*) const {}
     64 @@ -325,6 +327,21 @@ TEST_CONSTEXPR_CXX23 void test_nullptr() {
     65  #endif
     66  }
     67  
     68 +template <bool IsArray>
     69 +TEST_CONSTEXPR_CXX23 void test_function_reference() {
     70 +  typedef typename std::conditional<!IsArray, A, A[]>::type VT;
     71 +  {
     72 +    std::unique_ptr<VT, void (&)(A*)> u(nullptr, deleter_function);
     73 +    assert(u.get() == nullptr);
     74 +    assert(u.get_deleter() == deleter_function);
     75 +  }
     76 +  {
     77 +    std::unique_ptr<VT, void (&)(A*)> u(nullptr, deleter_function);
     78 +    assert(u.get() == nullptr);
     79 +    assert(u.get_deleter() == deleter_function);
     80 +  }
     81 +}
     82 +
     83  TEST_CONSTEXPR_CXX23 bool test() {
     84    {
     85      test_basic</*IsArray*/ false>();
     86 @@ -332,6 +349,7 @@ TEST_CONSTEXPR_CXX23 bool test() {
     87      test_basic_single();
     88      test_sfinae<false>();
     89      test_noexcept<false>();
     90 +    test_function_reference<false>();
     91    }
     92    {
     93      test_basic</*IsArray*/ true>();
     94 @@ -339,6 +357,7 @@ TEST_CONSTEXPR_CXX23 bool test() {
     95      test_sfinae<true>();
     96      test_sfinae_runtime();
     97      test_noexcept<true>();
     98 +    test_function_reference<true>();
     99    }
    100  
    101    return true;