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

Reply via email to