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.

Reply via email to