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.
