]> git.ipfire.org Git - thirdparty/gcc.git/commit
libstdc++: Make atomicity helpers use unsigned arithmetic [PR121148]
authorJonathan Wakely <jwakely@redhat.com>
Thu, 17 Jul 2025 21:02:45 +0000 (22:02 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Thu, 11 Sep 2025 13:43:55 +0000 (14:43 +0100)
commit6456da6bab8a2c43e7899afda991589065d96595
treeaf9ca6dfa459fdf31f0322c0cfa054067df10c78
parent46028a2f40329bbc6a7d7638b5bab6b3bb282009
libstdc++: Make atomicity helpers use unsigned arithmetic [PR121148]

The standard requires that std::atomic<integral-type>::fetch_add does
not have undefined behaviour for signed overflow, instead it wraps like
unsigned integers. The compiler ensures this is true for the atomic
built-ins that std::atomic uses, but it's not currently true for the
__gnu_cxx::__exchange_and_add and __gnu_cxx::__atomic_add functions
defined in libstdc++, which operate on type _Atomic_word.

For the inline __exchange_and_add_single function (used when there's
only one thread in the process), we can copy the value to an unsigned
long and do the addition on that, then assign it back to the
_Atomic_word variable.

The __exchange_and_add in config/cpu/generic/atomicity_mutex/atomicity.h
locks a mutex and then performs exactly the same steps as
__exchange_and_add_single.  Calling __exchange_and_add_single instead of
duplicating the code benefits from the fix just made to
__exchange_and_add_single.

For the remaining config/cpu/$arch/atomicity.h implementations, they
either use inline assembly which uses wrapping instructions (so no
changes needed), or we can fix them by compiling with -fwrapv.

After ths change, UBsan no longer gives an error for:

  _Atomic_word i = INT_MAX;
  __gnu_cxx::__exchange_and_add_dispatch(&i, 1);

/usr/include/c++/14/ext/atomicity.h:85:12: runtime error: signed integer overflow: 2147483647 + 1 cannot be represented in type 'int'

libstdc++-v3/ChangeLog:

PR libstdc++/121148
* config/cpu/generic/atomicity_mutex/atomicity.h
(__exchange_and_add): Call __exchange_and_add_single.
* include/ext/atomicity.h (__exchange_and_add_single): Use an
unsigned type for the addition.
* libsupc++/Makefile.am (atomicity.o): Compile with -fwrapv.
* libsupc++/Makefile.in: Regenerate.

Reviewed-by: Tomasz KamiƄski <tkaminsk@redhat.com>
libstdc++-v3/config/cpu/generic/atomicity_mutex/atomicity.h
libstdc++-v3/include/ext/atomicity.h
libstdc++-v3/libsupc++/Makefile.am
libstdc++-v3/libsupc++/Makefile.in