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); }
|
_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:
|
public:
|
||||||
@ -633,7 +633,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
virtual void*
|
virtual void*
|
||||||
_M_get_deleter(const std::type_info& __ti) noexcept override
|
_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
|
// 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
|
// 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,
|
// 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)
|
_Sp_make_shared_tag::_S_eq(__ti)
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
return __ptr;
|
return _M_ptr();
|
||||||
return nullptr;
|
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;
|
_Impl _M_impl;
|
||||||
};
|
};
|
||||||
@ -674,13 +674,13 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
[[no_unique_address]] _Alloc _M_alloc;
|
[[no_unique_address]] _Alloc _M_alloc;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
_Tp _M_obj;
|
remove_cv_t<_Tp> _M_obj;
|
||||||
char _M_unused;
|
char _M_unused;
|
||||||
};
|
};
|
||||||
|
|
||||||
friend class __shared_count<_Lp>; // To be able to call _M_ptr().
|
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:
|
public:
|
||||||
using __allocator_type = __alloc_rebind<_Alloc, _Sp_counted_ptr_inplace>;
|
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,
|
__shared_count(_Tp*& __p, _Sp_alloc_shared_tag<_Alloc> __a,
|
||||||
_Args&&... __args)
|
_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);
|
typename _Sp_cp_type::__allocator_type __a2(__a._M_a);
|
||||||
auto __guard = std::__allocate_guarded(__a2);
|
auto __guard = std::__allocate_guarded(__a2);
|
||||||
_Sp_cp_type* __mem = __guard.get();
|
_Sp_cp_type* __mem = __guard.get();
|
||||||
|
@ -96,7 +96,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
construct_at(_Tp* __location, _Args&&... __args)
|
construct_at(_Tp* __location, _Args&&... __args)
|
||||||
noexcept(noexcept(::new((void*)0) _Tp(std::declval<_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
|
// _GLIBCXX_RESOLVE_LIB_DEFECTS
|
||||||
// 3436. std::construct_at should support arrays
|
// 3436. std::construct_at should support arrays
|
||||||
if constexpr (is_array_v<_Tp>)
|
if constexpr (is_array_v<_Tp>)
|
||||||
@ -130,7 +130,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
::new((void*)__p) _Tp(std::forward<_Args>(__args)...);
|
::new(static_cast<void*>(__p)) _Tp(std::forward<_Args>(__args)...);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
template<typename _T1, typename _T2>
|
template<typename _T1, typename _T2>
|
||||||
@ -146,7 +146,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
|
|||||||
template<typename _T1>
|
template<typename _T1>
|
||||||
inline void
|
inline void
|
||||||
_Construct_novalue(_T1* __p)
|
_Construct_novalue(_T1* __p)
|
||||||
{ ::new((void*)__p) _T1; }
|
{ ::new(static_cast<void*>(__p)) _T1; }
|
||||||
|
|
||||||
template<typename _ForwardIterator>
|
template<typename _ForwardIterator>
|
||||||
_GLIBCXX20_CONSTEXPR void
|
_GLIBCXX20_CONSTEXPR void
|
||||||
|
@ -1261,7 +1261,7 @@ namespace __expected
|
|||||||
{ }
|
{ }
|
||||||
|
|
||||||
union {
|
union {
|
||||||
_Tp _M_val;
|
remove_cv_t<_Tp> _M_val;
|
||||||
_Er _M_unex;
|
_Er _M_unex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -88,23 +88,8 @@ static_assert( std::is_same<std::allocator<void>::const_pointer, const void*>(),
|
|||||||
"const_pointer is const void*" );
|
"const_pointer is const void*" );
|
||||||
#endif // C++20
|
#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
|
int
|
||||||
main()
|
main()
|
||||||
{
|
{
|
||||||
test01();
|
test01();
|
||||||
test02();
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user