On Thu, 10 Sept 2026 at 11:30, Tomasz Kaminski <[email protected]> wrote:
>
>
>
> On Tue, Sep 1, 2026 at 9:35 AM Jakub Jelinek <[email protected]> wrote:
>>
>> On Mon, Aug 31, 2026 at 04:53:49PM +0200, Jakub Jelinek wrote:
>> > The following patch implements the <bit> part of
>> > C++29 P3793R2 - Better shifting
>> > paper.
>>
>> Full bootstrap/regtest on x86_64-linux and i686-linux revealed a bug,
>> I forgot preprocessor guards around shl/shr, so
>> +FAIL: g++.dg/plugin/std-module-exports-c++20.C 
>> -fplugin=./std_module_exports_plugin.so (test for excess errors)
>> +FAIL: g++.dg/plugin/std-module-exports-c++23.C 
>> -fplugin=./std_module_exports_plugin.so (test for excess errors)
>> +FAIL: g++.dg/plugin/std-module-exports-c++26.C 
>> -fplugin=./std_module_exports_plugin.so (test for excess errors)
>> failed because of that.
>>
>> The following patch adds those and slightly improves the tests,
>> doesn't call test_negative_shifts at all if SInt is unsigned type
>> instead of checking for signedness in every loop iteration, small formatting
>> nit and adds
>> static_assert( std::shl(-1, 0x7fffffff00000001LL) == 0 );
>> static_assert( std::shl(2, 0x7fffffff00000001LL) == 0 );
>> static_assert( std::shl(-1, -0x7fffffff00000001LL) == -1 );
>> static_assert( std::shl(2, -0x7fffffff00000001LL) == 0 );
>> and
>> static_assert( std::shr(-1, 0x7fffffff00000001LL) == -1 );
>> static_assert( std::shr(2, 0x7fffffff00000001LL) == 0 );
>> static_assert( std::shr(-1, -0x7fffffff00000001LL) == 0 );
>> static_assert( std::shr(2, -0x7fffffff00000001LL) == 0 );
>> tests to verify nothing truncates the shift counts to say int or unsigned
>> int.
>>
>> 2026-09-01  Jakub Jelinek  <[email protected]>
>>
>>         * include/std/bit: Implement C++29 P3793R2 - Better shifting.
>>         (std::__signed_or_unsigned_integer): New concept.
>>         (std::shl, std::shr): New function templates.
>>         * include/bits/version.def (bitops): Add different value for C++29.
>>         * include/bits/version.h: Regenerate.
>>         * src/c++23/std.cc.in (std::shl, std::shr): Export for C++29.
>>         * testsuite/26_numerics/bit/bit.shift/shl.cc: New test.
>>         * testsuite/26_numerics/bit/bit.shift/shr.cc: New test.
>>
>> --- a/libstdc++-v3/include/std/bit      2026-08-19 22:18:21.873878488 +0200
>> +++ b/libstdc++-v3/include/std/bit      2026-09-01 09:03:56.393613654 +0200
>> @@ -407,9 +407,46 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>>    /// @cond undocumented
>>    template<typename _Tp>
>>      concept __unsigned_integer = __is_unsigned_integer<_Tp>::value;
>> +
>> +  template<typename _Tp>
>> +    concept __signed_or_unsigned_integer
>> +      = __is_signed_or_unsigned_integer<_Tp>::value;
>>    /// @endcond
>>
>> -  // [bit.rot], rotating
>> +#if __cpp_lib_bitops >= 202606L // >= C++29
>> +  // [bit.shift], shifting
>> +  template<__signed_or_unsigned_integer _Tp, __signed_or_unsigned_integer 
>> _Sp>
>> +    [[nodiscard]] constexpr _Tp
>> +    shl(_Tp __x, _Sp __s) noexcept
>> +    {
>> +      constexpr auto _Nd = __gnu_cxx::__int_traits<_Tp>::__digits
>> +                          + is_signed_v<_Tp>;
>> +      if constexpr (is_signed_v<_Sp>)
>> +       {
>
> We do not need these braces.
>>
>> +         if (__s < 0)
>> +           return (__s > -_Nd
>> +                   ? __x >> -__s
>> +                   : static_cast<_Tp>(__x < 0 ? -1 : 0));
>
> Does this (and one below) produces an warning about meaningless comparsion if 
> _Tp is unsigned?

It shouldn't do, because _Tp is a template parameter.

The -Wtype-limits warning was fixed many years ago to not warn for
template parameters, because it just makes you add unnecessary noise
to suppress warnings in generic code.

Reply via email to