Tested x86_64-linux.

-- >8 --

This change also requires implementing the proposed resolution of LWG
3216 so that std::make_shared and std::allocate_shared still work, and
the proposed resolution of LWG 3891 so that std::expected still works.

libstdc++-v3/ChangeLog:

        * include/bits/shared_ptr_base.h: Remove cv-qualifiers from
        type managed by _Sp_counted_ptr_inplace, as per LWG 3210.
        * include/bits/stl_construct.h: Do not cast away cv-qualifiers
        when passing pointer to placement new.
        * include/std/expected: Use remove_cv_t for union member, as per
        LWG 3891.
        * testsuite/20_util/allocator/void.cc: Do not test construction
        via const pointer.
---
 libstdc++-v3/include/bits/shared_ptr_base.h      | 15 ++++++++-------
 libstdc++-v3/include/bits/stl_construct.h        |  6 +++---
 libstdc++-v3/include/std/expected                |  2 +-
 libstdc++-v3/testsuite/20_util/allocator/void.cc | 15 ---------------
 4 files changed, 12 insertions(+), 26 deletions(-)

diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h 
b/libstdc++-v3/include/bits/shared_ptr_base.h
index 3d0b74ba1c6..ef0658f6182 100644
--- a/libstdc++-v3/include/bits/shared_ptr_base.h
+++ b/libstdc++-v3/include/bits/shared_ptr_base.h
@@ -591,7 +591,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
        _Alloc& _M_alloc() noexcept { return _A_base::_S_get(*this); }
 
-       __gnu_cxx::__aligned_buffer<_Tp> _M_storage;
+       __gnu_cxx::__aligned_buffer<__remove_cv_t<_Tp>> _M_storage;
       };
 
     public:
@@ -633,7 +633,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       virtual void*
       _M_get_deleter(const std::type_info& __ti) noexcept override
       {
-       auto __ptr = const_cast<typename remove_cv<_Tp>::type*>(_M_ptr());
        // Check for the fake type_info first, so we don't try to access it
        // as a real type_info object. Otherwise, check if it's the real
        // type_info for this class. With RTTI enabled we can check directly,
@@ -646,11 +645,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
            _Sp_make_shared_tag::_S_eq(__ti)
 #endif
           )
-         return __ptr;
+         return _M_ptr();
        return nullptr;
       }
 
-      _Tp* _M_ptr() noexcept { return _M_impl._M_storage._M_ptr(); }
+      __remove_cv_t<_Tp>*
+      _M_ptr() noexcept { return _M_impl._M_storage._M_ptr(); }
 
       _Impl _M_impl;
     };
@@ -674,13 +674,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       [[no_unique_address]] _Alloc _M_alloc;
 
       union {
-       _Tp _M_obj;
+       remove_cv_t<_Tp> _M_obj;
        char _M_unused;
       };
 
       friend class __shared_count<_Lp>; // To be able to call _M_ptr().
 
-      _Tp* _M_ptr() noexcept { return std::__addressof(_M_obj); }
+      auto _M_ptr() noexcept { return std::__addressof(_M_obj); }
 
     public:
       using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_ptr_inplace>;
@@ -962,7 +962,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        __shared_count(_Tp*& __p, _Sp_alloc_shared_tag<_Alloc> __a,
                       _Args&&... __args)
        {
-         typedef _Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp> _Sp_cp_type;
+         using _Tp2 = __remove_cv_t<_Tp>;
+         using _Sp_cp_type = _Sp_counted_ptr_inplace<_Tp2, _Alloc, _Lp>;
          typename _Sp_cp_type::__allocator_type __a2(__a._M_a);
          auto __guard = std::__allocate_guarded(__a2);
          _Sp_cp_type* __mem = __guard.get();
diff --git a/libstdc++-v3/include/bits/stl_construct.h 
b/libstdc++-v3/include/bits/stl_construct.h
index 146ea14e99a..9d6111396e1 100644
--- a/libstdc++-v3/include/bits/stl_construct.h
+++ b/libstdc++-v3/include/bits/stl_construct.h
@@ -96,7 +96,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     construct_at(_Tp* __location, _Args&&... __args)
     noexcept(noexcept(::new((void*)0) _Tp(std::declval<_Args>()...)))
     {
-      void* __loc = const_cast<remove_cv_t<_Tp>*>(__location);
+      void* __loc = __location;
       // _GLIBCXX_RESOLVE_LIB_DEFECTS
       // 3436. std::construct_at should support arrays
       if constexpr (is_array_v<_Tp>)
@@ -130,7 +130,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
          return;
        }
 #endif
-      ::new((void*)__p) _Tp(std::forward<_Args>(__args)...);
+      ::new(static_cast<void*>(__p)) _Tp(std::forward<_Args>(__args)...);
     }
 #else
   template<typename _T1, typename _T2>
@@ -146,7 +146,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   template<typename _T1>
     inline void
     _Construct_novalue(_T1* __p)
-    { ::new((void*)__p) _T1; }
+    { ::new(static_cast<void*>(__p)) _T1; }
 
   template<typename _ForwardIterator>
     _GLIBCXX20_CONSTEXPR void
diff --git a/libstdc++-v3/include/std/expected 
b/libstdc++-v3/include/std/expected
index 9e92339e406..d4a4bc17541 100644
--- a/libstdc++-v3/include/std/expected
+++ b/libstdc++-v3/include/std/expected
@@ -1261,7 +1261,7 @@ namespace __expected
        { }
 
       union {
-       _Tp _M_val;
+       remove_cv_t<_Tp> _M_val;
        _Er _M_unex;
       };
 
diff --git a/libstdc++-v3/testsuite/20_util/allocator/void.cc 
b/libstdc++-v3/testsuite/20_util/allocator/void.cc
index e50bf993294..04cd2094776 100644
--- a/libstdc++-v3/testsuite/20_util/allocator/void.cc
+++ b/libstdc++-v3/testsuite/20_util/allocator/void.cc
@@ -88,23 +88,8 @@ static_assert( 
std::is_same<std::allocator<void>::const_pointer, const void*>(),
     "const_pointer is const void*" );
 #endif // C++20
 
-void
-test02()
-{
-  std::allocator<void> av;
-  int* p = std::allocator<int>().allocate(1);
-  const int* c = p;
-  std::allocator_traits<std::allocator<void>>::construct(av, c, 0);
-  volatile int* v = p;
-  std::allocator_traits<std::allocator<void>>::construct(av, v, 0);
-  const volatile int* cv = p;
-  std::allocator_traits<std::allocator<void>>::construct(av, cv, 0);
-  std::allocator<int>().deallocate(p, 1);
-}
-
 int
 main()
 {
   test01();
-  test02();
 }
-- 
2.46.1

Reply via email to