On Fri, 12 Sept 2025 at 15:49, Jonathan Wakely <[email protected]> wrote: > > On Fri, 12 Sept 2025 at 13:37, H.J. Lu <[email protected]> wrote: > > > > On Mon, Sep 8, 2025 at 5:54 AM Jonathan Wakely <[email protected]> wrote: > >> > >> 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. > >> --- > > > > > > This caused: > > > > Running > > /export/gnu/import/git/sources/gcc/gcc/testsuite/g++.dg/analyzer/analyzer.exp > > ... > > FAIL: g++.dg/analyzer/fanalyzer-show-events-in-system-headers-no.C > > -std=c++14 at line 13 (test for warnings, line 12) > > FAIL: g++.dg/analyzer/fanalyzer-show-events-in-system-headers-no.C > > -std=c++14 at line 18 (test for warnings, line 11) > > FAIL: g++.dg/analyzer/fanalyzer-show-events-in-system-headers-no.C > > -std=c++14 at line 19 (test for warnings, line 12) > > FAIL: g++.dg/analyzer/fanalyzer-show-events-in-system-headers-no.C > > -std=c++14 at line 20 (test for warnings, line 12) > > FAIL: g++.dg/analyzer/fanalyzer-show-events-in-system-headers-no.C > > -std=c++14 at line 21 (test for warnings, line 12) > > FAIL: g++.dg/analyzer/fanalyzer-show-events-in-system-headers-no.C > > -std=c++17 at line 13 (test for warnings, line 12) > > FAIL: g++.dg/analyzer/fanalyzer-show-events-in-system-headers-no.C > > -std=c++17 at line 19 (test for warnings, line 12) > > FAIL: g++.dg/analyzer/fanalyzer-show-events-in-system-headers-no.C > > -std=c++17 at line 20 (test for warnings, line 12) > > FAIL: g++.dg/analyzer/fanalyzer-show-events-in-system-headers-no.C > > -std=c++17 at line 21 (test for warnings, line 12) > > > > on Linux/x86-64. > > I can't understand what's going on here. > > The analyzer still finds the problems, but the > -fanalyzer-call-summaries option used by analyzer.exp seems to cause > no output to be given. I don't see how that's related to my change.
This looks like a latent analyzer bug which my change happened to trigger. More details in PR 121148 (and I'll try to reduce it further).
