On Thu, 10 Sept 2026 at 13:00, Jonathan Wakely <[email protected]> wrote: > > 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.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=11856 for the record
