mirror of
https://github.com/gcc-mirror/gcc.git
synced 2024-11-21 13:40:47 +00:00
libstdc++: Do not cast away const-ness in std::construct_at (LWG 3870)
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.
This commit is contained in:
parent
993deb3a9a
commit
2eaae1bd69
@ -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();
|
||||
|
@ -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
|
||||
|
@ -1261,7 +1261,7 @@ namespace __expected
|
||||
{ }
|
||||
|
||||
union {
|
||||
_Tp _M_val;
|
||||
remove_cv_t<_Tp> _M_val;
|
||||
_Er _M_unex;
|
||||
};
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user