On Fri, 11 Apr 2025 at 15:14, Tomasz Kaminski <tkami...@redhat.com> wrote:
>
>
>
> On Fri, Apr 11, 2025 at 2:25 PM Jonathan Wakely <jwak...@redhat.com> wrote:
>>
>> On Fri, 11 Apr 2025 at 08:23, Tomasz Kaminski <tkami...@redhat.com> wrote:
>> >
>> >
>> >
>> > On Thu, Apr 10, 2025 at 6:27 PM Jonathan Wakely <jwak...@redhat.com> wrote:
>> >>
>> >> The std::atomic constructor clears padding bits so that compare_exchange
>> >> will not fail due to differences in padding bits. But we can only do
>> >> that for C++14 and later, because in C++11 a constexpr constructor must
>> >> have an empty body. However, the code in compare_exchange_strong assumes
>> >> that padding is always cleared, and so it fails in C++11 due to non-zero
>> >> padding.
>> >>
>> >> Since we can't clear the padding in C++11 mode, we shouldn't assume it's
>> >> been cleared when in C++11 mode. This fixes the reported bug. However,
>> >> the fix fails to handle the case where the std::atomic is constructed in
>> >> C++11 code (and so doesn't zero padding) but the CAS happens in C++14
>> >> code (and so assumes padding has been zeroed). We might need to use the
>> >> same loop as atomic_ref::compare_exchange_strong to properly fix this
>> >> bug for that case.
>> >>
>> >> Although the mixed C++11 / C++14 case isn't fixed, this is still an
>> >> incremental improvement. It fixes the pure-C++11 case and doesn't
>> >> preclude a more comprehensive fix later.
>> >
>> > Wouldn't alternative comprehensive fix be equivalent to doing just:
>> > diff --git a/libstdc++-v3/include/std/atomic 
>> > b/libstdc++-v3/include/std/atomic
>> > index 9b1aca0fc09..238cf739161 100644
>> > --- a/libstdc++-v3/include/std/atomic
>> > +++ b/libstdc++-v3/include/std/atomic
>> > @@ -345,7 +345,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>> >        compare_exchange_weak(_Tp& __e, _Tp __i, memory_order __s,
>> >                             memory_order __f) noexcept
>> >        {
>> > -       return __atomic_impl::__compare_exchange(_M_i, __e, __i, true,
>> > +       return __atomic_impl::__compare_exchange<(__cplusplus < 
>> > 201402L)>(_M_i, __e, __i, true,
>> >                                                  __s, __f);
>>
>> If the std::atomic constructor happens in a translation unit compiled
>> as C++11 but the call to compare_exchange_weak happens in a
>> translation unit compiled as C++14, then padding won't be cleared, but
>> this will call __compare_exchange<false> which expects padding to have
>> been cleared.
>
> I see. This seems to be the same drawback as in case of the current fix, 
> however

Yes.

> my suggestion guarantees that padding bits are ignored/cleared in program
> compiled only in C++11 mode. As I understand the suggested change, make a 
> comparison exchange
> prone to fail due padding bits.

Yes, that's true. We would reliably ignore padding bits for C++11 too.
OK, I'll experiment with that next week.

Reply via email to