On Sat, 8 Nov 2025 at 13:52, ArktinenKarpalo <[email protected]> wrote: > > From: Karpalo Toivonen <[email protected]> > > According to the standard the first n characters of a bitset constructor > string need to be checked instead of only N. > > Tested on x86_64-linux. > > libstdc++-v3/ChangeLog: > PR libstdc++/121054 > * include/std/bitset: Add string check to constructor. > * testsuite/20_util/bitset/121054.cc: New test. > * testsuite/20_util/bitset/cons/constexpr_c++23.cc: Fix.
The patch looks good, thanks. As this is your first contribution to GCC and the change to the code is only a few lines, we can accept this without any legal paperwork. If you plan to contribute more to GCC then please read https://gcc.gnu.org/contribute.html#legal about our legal prerequisites. You can either contribute via a copyright assignment to the FSF, or via the terms described at https://gcc.gnu.org/dco.html Thanks again for the patch, I'll test it and push this to trunk. > --- > libstdc++-v3/include/std/bitset | 9 ++- > .../testsuite/20_util/bitset/121054.cc | 57 +++++++++++++++++++ > .../20_util/bitset/cons/constexpr_c++23.cc | 2 - > 3 files changed, 65 insertions(+), 3 deletions(-) > create mode 100644 libstdc++-v3/testsuite/20_util/bitset/121054.cc > > diff --git a/libstdc++-v3/include/std/bitset b/libstdc++-v3/include/std/bitset > index 92f11f19807..6fd32657863 100644 > --- a/libstdc++-v3/include/std/bitset > +++ b/libstdc++-v3/include/std/bitset > @@ -1549,7 +1549,14 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER > size_t __pos, size_t __n, _CharT __zero, _CharT __one) > { > reset(); > - const size_t __nbits = std::min(_Nb, std::min(__n, size_t(__len - > __pos))); > + const size_t __rlen = std::min(__n, size_t(__len - __pos)); > + const size_t __nbits = std::min(_Nb, __rlen); > + for (size_t __i = __rlen - __nbits; __i > 0; --__i) > + { > + const _CharT __c = __s[__pos + __rlen - __i]; > + if (!_Traits::eq(__c, __zero) && !_Traits::eq(__c, __one)) > + __throw_invalid_argument(__N("bitset::_M_copy_from_ptr")); > + } > for (size_t __i = __nbits; __i > 0; --__i) > { > const _CharT __c = __s[__pos + __nbits - __i]; > diff --git a/libstdc++-v3/testsuite/20_util/bitset/121054.cc > b/libstdc++-v3/testsuite/20_util/bitset/121054.cc > new file mode 100644 > index 00000000000..401d09d888b > --- /dev/null > +++ b/libstdc++-v3/testsuite/20_util/bitset/121054.cc > @@ -0,0 +1,57 @@ > +// PR libstdc++/121054 std::bitset<0>("zero") should throw > std::invalid_argument > +#include <bitset> > +#include <stdexcept> > +#include <testsuite_hooks.h> > + > +void test01(void) > +{ > + try { > + std::bitset<0>("x"); > + VERIFY( false ); > + } > + catch(std::invalid_argument& fail) { > + VERIFY( true ); > + } > + catch(...) { > + VERIFY( false ); > + } > + > + try { > + std::bitset<1>("0x", 2); > + VERIFY( false ); > + } > + catch(std::invalid_argument& fail) { > + VERIFY( true ); > + } > + catch(...) { > + VERIFY( false ); > + } > + > + try { > + std::bitset<1>("0x", 1); > + VERIFY( true ); > + } > + catch(std::invalid_argument& fail) { > + VERIFY( false ); > + } > + catch(...) { > + VERIFY( false ); > + } > + > + try { > + std::bitset<0>("01"); > + VERIFY( true ); > + } > + catch(std::invalid_argument& fail) { > + VERIFY( false ); > + } > + catch(...) { > + VERIFY( false ); > + } > +} > + > +int main() > +{ > + test01(); > + return 0; > +} > diff --git a/libstdc++-v3/testsuite/20_util/bitset/cons/constexpr_c++23.cc > b/libstdc++-v3/testsuite/20_util/bitset/cons/constexpr_c++23.cc > index 7e2eba5095d..0a940949d84 100644 > --- a/libstdc++-v3/testsuite/20_util/bitset/cons/constexpr_c++23.cc > +++ b/libstdc++-v3/testsuite/20_util/bitset/cons/constexpr_c++23.cc > @@ -18,8 +18,6 @@ constexpr bool test_ntbs() > VERIFY( std::bitset<0>("000").all() ); > VERIFY( std::bitset<0>("000", 2).all() ); > VERIFY( std::bitset<1>("100", 2).all() ); > - VERIFY( std::bitset<1>("z00", 2, 'z').none() ); > - VERIFY( std::bitset<2>("ab0", 3, 'a', 'b').count() == 1 ); > > return true; > } > -- > 2.51.2 >
