libstdc++: bitset subscript check when _GLIBCXX_ASSERTIONS [PR118341]

Changes in v3:
 - Delete redundant "dg" annotations.

Changes in v2:
 - Rejigger testing.
 - 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[].

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.
This commit is contained in:
Nathan Myers
2026-03-04 13:08:41 -05:00
parent dae387d2c8
commit 1b404c5744
6 changed files with 106 additions and 2 deletions

View File

@@ -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);
}
///@}
/**

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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();
}

View File

@@ -0,0 +1,26 @@
#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();
}

View File

@@ -0,0 +1,13 @@
#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();
}