On Thu, 5 Mar 2026 at 16:51, Jonathan Wakely <[email protected]> wrote:
>
> On Thu, 5 Mar 2026 at 15:59, Nathan Myers wrote:
> >
> > Changes in v2:
> >  - Rejigger testing, test on c++98 et al.
> >  - Add tests for regular bitset<>::op[].
> >
> > Perform __glibcxx_assert bounds check on indices to bitset<>::op[]
> > for const and non-const overloads.
> >
> > Also, add previously neglected regular tests for bitset<>::op[].
>
> OK for trunk, thanks.
>
>
> >
> > libstdc++-v3/ChangeLog
> >         PR libstdc++/118341
> >         * include/std/bitset (operator[] (2x)): Add assertion.
> >         * testsuite/20_util/bitset/access/118341_neg1.cc: New test.
> >         * testsuite/20_util/bitset/access/118341_neg2.cc: Same.
> >         * testsuite/20_util/bitset/access/118341_smoke.cc: Same.
> >         * testsuite/20_util/bitset/access/subscript.cc: Same.
> >         * testsuite/20_util/bitset/access/subscript_const_neg.cc: Same.
> > ---
> >  libstdc++-v3/include/std/bitset               | 10 ++++--
> >  .../20_util/bitset/access/118341_neg1.cc      | 14 +++++++++
> >  .../20_util/bitset/access/118341_neg2.cc      | 14 +++++++++
> >  .../20_util/bitset/access/118341_smoke.cc     | 31 +++++++++++++++++++
> >  .../20_util/bitset/access/subscript.cc        | 28 +++++++++++++++++
> >  .../bitset/access/subscript_const_neg.cc      | 15 +++++++++
> >  6 files changed, 110 insertions(+), 2 deletions(-)
> >  create mode 100644 
> > libstdc++-v3/testsuite/20_util/bitset/access/118341_neg1.cc
> >  create mode 100644 
> > libstdc++-v3/testsuite/20_util/bitset/access/118341_neg2.cc
> >  create mode 100644 
> > libstdc++-v3/testsuite/20_util/bitset/access/118341_smoke.cc
> >  create mode 100644 
> > libstdc++-v3/testsuite/20_util/bitset/access/subscript.cc
> >  create mode 100644 
> > libstdc++-v3/testsuite/20_util/bitset/access/subscript_const_neg.cc
> >
> > diff --git a/libstdc++-v3/include/std/bitset 
> > b/libstdc++-v3/include/std/bitset
> > index 331d0894342..eb200ab9246 100644
> > --- a/libstdc++-v3/include/std/bitset
> > +++ b/libstdc++-v3/include/std/bitset
> > @@ -1290,11 +1290,17 @@ _GLIBCXX_BEGIN_NAMESPACE_CONTAINER
> >        _GLIBCXX23_CONSTEXPR
> >        reference
> >        operator[](size_t __position)
> > -      { return reference(*this, __position); }
> > +      {
> > +       __glibcxx_assert(__position < _Nb);
> > +       return reference(*this, __position);
> > +      }
> >
> >        _GLIBCXX_CONSTEXPR bool
> >        operator[](size_t __position) const
> > -      { return _Unchecked_test(__position); }
> > +      {
> > +       __glibcxx_assert(__position < _Nb);
> > +       return _Unchecked_test(__position);
> > +      }
> >        ///@}
> >
> >        /**
> > diff --git a/libstdc++-v3/testsuite/20_util/bitset/access/118341_neg1.cc 
> > b/libstdc++-v3/testsuite/20_util/bitset/access/118341_neg1.cc
> > new file mode 100644
> > index 00000000000..22991ffac91
> > --- /dev/null
> > +++ b/libstdc++-v3/testsuite/20_util/bitset/access/118341_neg1.cc
> > @@ -0,0 +1,14 @@
> > +// { dg-do run { xfail *-*-* } }
> > +// { dg-options "-D_GLIBCXX_ASSERTIONS" }
> > +
> > +#include <bitset>
> > +#include <testsuite_hooks.h>
> > +
> > +// Check bitset<>::op[] hardening, non-const.
> > +
> > +int main()
> > +{
> > +  std::bitset<13> bs(0x1555ull);
> > +  bs[12];  // OK
> > +  bs[13];  // aborts, 13 > 12, non-const
> > +}
> > diff --git a/libstdc++-v3/testsuite/20_util/bitset/access/118341_neg2.cc 
> > b/libstdc++-v3/testsuite/20_util/bitset/access/118341_neg2.cc
> > new file mode 100644
> > index 00000000000..fa8942ec510
> > --- /dev/null
> > +++ b/libstdc++-v3/testsuite/20_util/bitset/access/118341_neg2.cc
> > @@ -0,0 +1,14 @@
> > +// { dg-do run { xfail *-*-* } }
> > +// { dg-options "-D_GLIBCXX_ASSERTIONS" }
> > +
> > +#include <bitset>
> > +#include <testsuite_hooks.h>
> > +
> > +// Check bitset<>::op[] hardening, const.
> > +
> > +int main()
> > +{
> > +  const std::bitset<13> bs(0x1555ull);
> > +  bs[12];  // OK
> > +  bs[13];  // aborts, 13 > 12, const
> > +}
> > diff --git a/libstdc++-v3/testsuite/20_util/bitset/access/118341_smoke.cc 
> > b/libstdc++-v3/testsuite/20_util/bitset/access/118341_smoke.cc
> > new file mode 100644
> > index 00000000000..0a525c1b3fa
> > --- /dev/null
> > +++ b/libstdc++-v3/testsuite/20_util/bitset/access/118341_smoke.cc
> > @@ -0,0 +1,31 @@
> > +// { dg-do run }
> > +// { dg-options "-D_GLIBCXX_ASSERTIONS" }
> > +
> > +// Smoke test, op[] hardening.
> > +
> > +#include <bitset>
> > +#include <testsuite_hooks.h>
> > +
> > +void test_non_const_subscript()
> > +{
> > +  std::bitset<13> bs(0x1555ull);
> > +  for (int i = 0; i < 13; ++i)
> > +    {
> > +      VERIFY(bs[i] != (i & 1)); // Check op[] proxy result rvalue.
> > +      bs[i] = not bs[i];        // Assign via op[] proxy result lvalue.
> > +      VERIFY(bs[i] == (i & 1)); // Check modified.
> > +    }
> > +}
> > +
> > +void test_const_subscript()
> > +{
> > +  const std::bitset<13> cbs(0x1555ull);
> > +  for (int i = 0; i < 13; ++i)
> > +    VERIFY(cbs[i] != (i & 1));  // Check op[] proxy result const rvalue.
> > +}
> > +
> > +int main()
> > +{
> > +  test_non_const_subscript();
> > +  test_const_subscript();
> > +}
> > diff --git a/libstdc++-v3/testsuite/20_util/bitset/access/subscript.cc 
> > b/libstdc++-v3/testsuite/20_util/bitset/access/subscript.cc
> > new file mode 100644
> > index 00000000000..4bcf6e3d530
> > --- /dev/null
> > +++ b/libstdc++-v3/testsuite/20_util/bitset/access/subscript.cc
> > @@ -0,0 +1,28 @@
> > +// { dg-do run }
> > +
> > +#include <bitset>
> > +#include <testsuite_hooks.h>
> > +
> > +void test_non_const_subscript()
> > +{
> > +  std::bitset<13> bs(0x1555ull);
> > +  for (int i = 0; i < 13; ++i)
> > +    {
> > +      VERIFY(bs[i] != (i & 1)); // Check op[] proxy result rvalue.
> > +      bs[i] = not bs[i];        // Assign via op[] proxy result lvalue.
> > +      VERIFY(bs[i] == (i & 1)); // Check modified.
> > +    }
> > +}
> > +
> > +void test_const_subscript()
> > +{
> > +  const std::bitset<13> cbs(0x1555ull);
> > +  for (int i = 0; i < 13; ++i)
> > +    VERIFY(cbs[i] != (i & 1));  // Check op[] proxy result const rvalue.
> > +}
> > +
> > +int main()
> > +{
> > +  test_non_const_subscript();
> > +  test_const_subscript();
> > +}
> > diff --git 
> > a/libstdc++-v3/testsuite/20_util/bitset/access/subscript_const_neg.cc 
> > b/libstdc++-v3/testsuite/20_util/bitset/access/subscript_const_neg.cc
> > new file mode 100644
> > index 00000000000..00ed36196f8
> > --- /dev/null
> > +++ b/libstdc++-v3/testsuite/20_util/bitset/access/subscript_const_neg.cc
> > @@ -0,0 +1,15 @@
> > +// { dg-do compile

Oh hang on, this line looks mangled.

Since it doesn't end with a } I think dejagnu ignores it, so this will
be a dg-do run test instead, which is probably what was intended
anyway?

> > +
> > +#include <bitset>
> > +
> > +void test_const_subscript_assignment()
> > +{
> > +  const std::bitset<13> bs(0x1555ull);
> > +  for (int i = 0; i < 13; ++i)
> > +    bs[i] = not bs[i];  // { dg-error "lvalue required" }
> > +}
> > +
> > +int main()
> > +{
> > +  test_const_subscript_assignment();
> > +}
> > --
> > 2.52.0
> >

Reply via email to