On Wed, 6 May 2026 at 13:12, Jonathan Wakely <[email protected]> wrote: > > On Wed, 6 May 2026 at 12:52, Tomasz Kaminski <[email protected]> wrote: > > > > > > > > On Wed, May 6, 2026 at 12:13 PM Jonathan Wakely <[email protected]> wrote: > >> > >> Clang 9 added support for [[__no_unique_address__]] and we don't support > >> Intel icc any longer, so we can remove the code in <tuple> that works > >> around the absence of that attribute. We can also address a FIXME in > >> <bits/shared_ptr_base.h> and replace uses of EBO with the attribute. > >> > >> libstdc++-v3/ChangeLog: > >> > >> * include/bits/shared_ptr_base.h (_Sp_ebo_helper): Simplify by > >> using [[__no_unique_address__]] instead of EBO. Use the > >> attribute unconditionally for the unstable ABI. > >> (_Sp_counted_deleter::_Impl): Adjust uses of _Sp_ebo_helper. > >> (_Sp_counted_ptr_inplace::_Impl): Likewise. > >> * include/std/tuple (_Head_base): Remove implementation for > >> compilers that don't support [[__no_unique_address__]]. Use the > >> attribute unconditionally for the unstable ABI. > >> --- > >> > >> v2: Add the attribute to the data members of _Impl as well as to the > >> _M_obj data member of _Sp_ebo_helper. Otherwise the _M_obj subobject is > >> potentially overlapping, but the _M_ and _M_d ones are not. We need both > >> to be marked with the attribute. > >> > >> What we *really* want is [[no_unique_address(expr)]] so that we can get > >> rid of _Sp_ebo_helper entirely, and just do: > >> > >> #if ! _GLIBCXX_INLINE_VERSION // Stable ABI > >> template<typename T> __can_overlap = !__is_final(T) && __is_empty(T); > >> #else // Unstable ABI > >> template<typename T> __can_overlap = true; > >> #endif > >> [[no_unique_address(__can_overlap<_Del>)]] _M_del; > >> > >> I should propose that to WG21, and if rejected just get it added to GCC > >> and Clang. > > > > > >> > >> > >> Tested x86_64-linux. > > > > LGTM with one suggestion. > >> > >> > >> libstdc++-v3/include/bits/shared_ptr_base.h | 65 +++++++++---------- > >> libstdc++-v3/include/std/tuple | 69 ++++----------------- > >> 2 files changed, 43 insertions(+), 91 deletions(-) > >> > >> diff --git a/libstdc++-v3/include/bits/shared_ptr_base.h > >> b/libstdc++-v3/include/bits/shared_ptr_base.h > >> index b92e3a4c90e4..3ab73f6e4a0d 100644 > >> --- a/libstdc++-v3/include/bits/shared_ptr_base.h > >> +++ b/libstdc++-v3/include/bits/shared_ptr_base.h > >> @@ -513,57 +513,52 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > >> inline void > >> _Sp_counted_ptr<nullptr_t, _S_atomic>::_M_dispose() noexcept { } > >> > >> - // FIXME: once __has_cpp_attribute(__no_unique_address__)) is true for > >> - // all supported compilers we can greatly simplify _Sp_ebo_helper. > >> +#if ! __has_cpp_attribute(__no_unique_address__) > >> +#error "support for [[__no_unique_address__]] attribute is required" > >> +#endif > >> + > >> +#if ! _GLIBCXX_INLINE_VERSION > >> // N.B. unconditionally applying the attribute could change layout for > >> // final types, which currently cannot use EBO so have a unique address. > >> - > >> - template<int _Nm, typename _Tp, > >> - bool __use_ebo = !__is_final(_Tp) && __is_empty(_Tp)> > >> + template<typename _Tp, bool = !__is_final(_Tp) && __is_empty(_Tp)> > >> struct _Sp_ebo_helper; > >> +#else > >> + template<typename _Tp, bool = true> > >> + struct _Sp_ebo_helper; > > > > The name "EBO helper" no longer seems accurate, but > > I have no better suggestion. > > Yes, I had the same thought. Something like "_Alloc_overlapping" could
Oops, I meant "_Allow_overlapping" not Alloc. > work, but is longer and unless you already understand what that means, > it isn't any more understandable than "EBO helper". >
