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.
