[PATCH] libstdc++: bitset op[] check on _GLIBCXX_ASSERTIONS [PR118341]
Jonathan Wakely
jwakely@redhat.com
Thu Mar 5 09:46:32 GMT 2026
On Wed, 04 Mar 2026 at 13:21 -0500, Nathan Myers wrote:
>Perform __glibcxx_assert check on indices to bitset<>::op[] for
>const and non-const overloads.
>
>libstdc++-v3/ChangeLog
> PR libstdc++/118341
> * include/std/bitset (operator[] (2x)): Add assertion.
> * testsuite/20_util/bitset/118341_asrt_ix.cc: New smoke test.
> * testsuite/20_util/bitset/118341_asrt_ix_neg1.cc: New negative test.
> * testsuite/20_util/bitset/118341_asrt_ix_neg2.cc: New negative test.
>---
> libstdc++-v3/include/std/bitset | 10 ++++++++--
> .../testsuite/20_util/bitset/118341_asrt_ix.cc | 16 ++++++++++++++++
> .../20_util/bitset/118341_asrt_ix_neg1.cc | 13 +++++++++++++
> .../20_util/bitset/118341_asrt_ix_neg2.cc | 13 +++++++++++++
> 4 files changed, 50 insertions(+), 2 deletions(-)
> create mode 100644 libstdc++-v3/testsuite/20_util/bitset/118341_asrt_ix.cc
> create mode 100644 libstdc++-v3/testsuite/20_util/bitset/118341_asrt_ix_neg1.cc
> create mode 100644 libstdc++-v3/testsuite/20_util/bitset/118341_asrt_ix_neg2.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/118341_asrt_ix.cc b/libstdc++-v3/testsuite/20_util/bitset/118341_asrt_ix.cc
>new file mode 100644
>index 00000000000..bc5c7ece6df
>--- /dev/null
>+++ b/libstdc++-v3/testsuite/20_util/bitset/118341_asrt_ix.cc
"asrt_ix" is a bit cryptic, especially as it doesn't assert.
We have the 20_util/bitset/access subdirectory for the operator[]
members, so I think this test can be just
20_util/bitset/access/118341.cc
or even
20_util/bitset/access/subscript.cc
since it's not really testing the assertions, and somehow we don't
actually have a test for operator[] already! (We do have
20_util/bitset/access/constexpr.cc but not a runtime test).
Ideally we'd test it for bitsets of different sizes too, because we
have the _Bitset<1> partial specialization used for small bitsets (and
the _Bitset<0> one, but all indices are out-of-range for that one).
But adding those tests can be done separately, as it's not part of the
Bug 118341 changes.
>@@ -0,0 +1,16 @@
>+// { dg-do run { target c++26 } }
There's no need for this to be restricted to C++26.
>+// { dg-options "-D_GLIBCXX_ASSERTIONS" }
>+
>+#include <bitset>
>+#include <testsuite_hooks.h>
>+
>+int main()
>+{
>+ std::bitset<13> bs{"1010101010101"};
If you use () instead of {} then the test can run for C++98 and
doesn't need any { target xxx } selector.
>+ for (int i = 0; i < 13; ++i)
>+ VERIFY(bs[i] != (i & 1)); // op[], range check
>+
>+ const std::bitset<13> cbs{"1010101010101"};
Same here.
>+ for (int i = 0; i < 13; ++i)
>+ VERIFY(cbs[i] != (i & 1)); // op[] const, range check
>+}
>diff --git a/libstdc++-v3/testsuite/20_util/bitset/118341_asrt_ix_neg1.cc b/libstdc++-v3/testsuite/20_util/bitset/118341_asrt_ix_neg1.cc
>new file mode 100644
>index 00000000000..f22beab6afc
>--- /dev/null
>+++ b/libstdc++-v3/testsuite/20_util/bitset/118341_asrt_ix_neg1.cc
20_util/bitset/access/118341_neg1.cc
(and same changes to target selector and initialization)
>@@ -0,0 +1,13 @@
>+// { dg-do run { target c++26 xfail *-*-* } }
>+// { dg-options "-D_GLIBCXX_ASSERTIONS" }
>+
>+#include <bitset>
>+#include <testsuite_hooks.h>
>+
>+int main()
>+{
>+ std::bitset<13> bs{"1010101010101"};
>+ for (int i = 0; i < 13; ++i)
>+ VERIFY(bs[i] != (i & 1));
Our testsuite has no way to distinguish between this VERIFY failing
and the next line aborting, so I don't think there's any point in
checking with this loop. Other test fils should already be verifying
that op[] works when not out-of-range, so repeating it here isn't
needed.
>+ bs[13]; // aborts, 13 > 12, non-const
>+}
>diff --git a/libstdc++-v3/testsuite/20_util/bitset/118341_asrt_ix_neg2.cc b/libstdc++-v3/testsuite/20_util/bitset/118341_asrt_ix_neg2.cc
>new file mode 100644
>index 00000000000..273fbb7f592
>--- /dev/null
>+++ b/libstdc++-v3/testsuite/20_util/bitset/118341_asrt_ix_neg2.cc
>@@ -0,0 +1,13 @@
>+// { dg-do run { target c++26 xfail *-*-* } }
20_util/bitset/access/118341_neg2.cc
(and same changes as to the _neg1.cc test)
>+// { dg-options "-D_GLIBCXX_ASSERTIONS" }
>+
>+#include <bitset>
>+#include <testsuite_hooks.h>
>+
>+int main()
>+{
>+ const std::bitset<13> bs{"1010101010101"};
>+ for (int i = 0; i < 13; ++i)
>+ VERIFY(bs[i] != (i & 1));
>+ bs[13]; // aborts, 13 > 12, const
>+}
>--
>2.52.0
>
>
More information about the Libstdc++
mailing list