https://gcc.gnu.org/g:a7ad4bee6fe7cd77aceb6e86380dcaeb6da82791
commit r17-2080-ga7ad4bee6fe7cd77aceb6e86380dcaeb6da82791 Author: Jonathan Wakely <[email protected]> Date: Wed Jul 1 19:44:41 2026 +0100 libstdc++: Use atomic store for num_leap_seconds in tzdb.cc Although NumLeapSeconds::set_locked is always called with list_mutex() locked, if ATOMIC_INT_LOCK_FREE == 2 then readers ofthe variable will be loading it without list_mutex() locked. We need to use an atomic store even if the lock is held. Also simplify the non-atomic version of NumLeapSeconds::set to just set the variable instead of indirecting via set_locked. libstdc++-v3/ChangeLog: * src/c++20/tzdb.cc (_Node::NumLeapSeconds::set_locked) [ATOMIC_INT_LOCK_FREE == 2]: Use atomic store. (_Node::NumLeapSeconds::set) [ATOMIC_INT_LOCK_FREE != 2]: Set value directly instead of calling set_locked. Reviewed-by: Tomasz KamiĆski <[email protected]> Diff: --- libstdc++-v3/src/c++20/tzdb.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libstdc++-v3/src/c++20/tzdb.cc b/libstdc++-v3/src/c++20/tzdb.cc index 1aae07033f73..998a363151dc 100644 --- a/libstdc++-v3/src/c++20/tzdb.cc +++ b/libstdc++-v3/src/c++20/tzdb.cc @@ -1463,16 +1463,22 @@ struct tzdb_list::_Node::NumLeapSeconds ref.store(val, memory_order::release); #else lock_guard<mutex> l(list_mutex()); - set_locked(val, l); + count = val; #endif } void set_locked(unsigned val, const lock_guard<mutex>&) { +#if ATOMIC_INT_LOCK_FREE == 2 + // Even though the caller locked the mutex, we still need to use an + // atomic store in this case, because there could be concurrent loads. + set(val); +#else // The only caller of this function locks list_mutex() so we would // deadlock if we locked it again here. count = val; +#endif } private:
