diff mbox series

[2/2] libstdc++: Do not cast away const-ness in std::construct_at (LWG 3870)

Message ID 20241002200503.3359969-2-jwakely@redhat.com
State New
Headers show
Series [1/2] libstdc++: Make std::construct_at support arrays (LWG 3436) | expand

Commit Message

Jonathan Wakely Oct. 2, 2024, 7:37 p.m. UTC
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 mbox series

Patch

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();
 }