Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion libcxx/include/bitset
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ template <size_t N> struct hash<std::bitset<N>>;
# include <__algorithm/fill.h>
# include <__algorithm/fill_n.h>
# include <__algorithm/find.h>
# include <__assert>
# include <__bit_reference>
# include <__config>
# include <__functional/hash.h>
Expand Down Expand Up @@ -682,13 +683,18 @@ public:

// element access:
# ifdef _LIBCPP_ABI_BITSET_VECTOR_BOOL_CONST_SUBSCRIPT_RETURN_BOOL
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator[](size_t __p) const { return __base::__make_ref(__p); }
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR bool operator[](size_t __p) const {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__p < _Size, "bitset::operator[] index out of bounds");
return __base::__make_ref(__p);
}
# else
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR const_reference operator[](size_t __p) const {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__p < _Size, "bitset::operator[] index out of bounds");
return __base::__make_ref(__p);
}
# endif
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 reference operator[](size_t __p) {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__p < _Size, "bitset::operator[] index out of bounds");
return __base::__make_ref(__p);
}
_LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX23 unsigned long to_ulong() const;
Expand Down
10 changes: 8 additions & 2 deletions libcxx/include/valarray
Original file line number Diff line number Diff line change
Expand Up @@ -821,9 +821,15 @@ public:
_LIBCPP_HIDE_FROM_ABI valarray& operator=(const __val_expr<_ValExpr>& __v);

// element access:
_LIBCPP_HIDE_FROM_ABI const value_type& operator[](size_t __i) const { return __begin_[__i]; }
_LIBCPP_HIDE_FROM_ABI const value_type& operator[](size_t __i) const {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__i < size(), "valarray::operator[] index out of bounds");
return __begin_[__i];
}

_LIBCPP_HIDE_FROM_ABI value_type& operator[](size_t __i) { return __begin_[__i]; }
_LIBCPP_HIDE_FROM_ABI value_type& operator[](size_t __i) {
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__i < size(), "valarray::operator[] index out of bounds");
return __begin_[__i];
}

// subset operations:
_LIBCPP_HIDE_FROM_ABI __val_expr<__slice_expr<const valarray&> > operator[](slice __s) const;
Expand Down
42 changes: 42 additions & 0 deletions libcxx/test/libcxx/numerics/numarray/assert.pass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//===----------------------------------------------------------------------===//
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: I found it easier to just test all the assertions in a single file (we have precedent in deque). We could split by hardening mode later, but I think having a separate test file per hardened function is more trouble than it's worth. No strong feelings, though -- please feel free to push back on this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this looks reasonable to me. I don't know that we want to elevate this choice into a policy, but I certainly won't push back on the way you've done it here.

//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// <valarray>

// Test hardening assertions for std::valarray.

// REQUIRES: has-unix-headers
// UNSUPPORTED: libcpp-hardening-mode=none
// UNSUPPORTED: c++03
// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing

#include <valarray>

#include "check_assertion.h"

int main(int, char**) {
{ // Empty valarray
std::valarray<int> c;
const auto& const_c = c;
TEST_LIBCPP_ASSERT_FAILURE(c[0], "valarray::operator[] index out of bounds");
TEST_LIBCPP_ASSERT_FAILURE(const_c[0], "valarray::operator[] index out of bounds");
TEST_LIBCPP_ASSERT_FAILURE(c[42], "valarray::operator[] index out of bounds");
TEST_LIBCPP_ASSERT_FAILURE(const_c[42], "valarray::operator[] index out of bounds");
}

{ // Non-empty valarray
std::valarray<int> c(4);
const auto& const_c = c;
(void)c[3]; // Check that there's no assertion on valid access.
TEST_LIBCPP_ASSERT_FAILURE(c[4], "valarray::operator[] index out of bounds");
(void)const_c[3]; // Check that there's no assertion on valid access.
TEST_LIBCPP_ASSERT_FAILURE(const_c[4], "valarray::operator[] index out of bounds");
}

return 0;
}
42 changes: 42 additions & 0 deletions libcxx/test/libcxx/utilities/template.bitset/assert.pass.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

// <bitset>

// Test hardening assertions for std::bitset.

// REQUIRES: has-unix-headers
// UNSUPPORTED: libcpp-hardening-mode=none
// UNSUPPORTED: c++03
// XFAIL: libcpp-hardening-mode=debug && availability-verbose_abort-missing

#include <bitset>

#include "check_assertion.h"

int main(int, char**) {
{ // Empty bitset
std::bitset<0> c;
const auto& const_c = c;
TEST_LIBCPP_ASSERT_FAILURE(c[0], "bitset::operator[] index out of bounds");
TEST_LIBCPP_ASSERT_FAILURE(const_c[0], "bitset::operator[] index out of bounds");
TEST_LIBCPP_ASSERT_FAILURE(c[42], "bitset::operator[] index out of bounds");
TEST_LIBCPP_ASSERT_FAILURE(const_c[42], "bitset::operator[] index out of bounds");
}

{ // Non-empty bitset
std::bitset<4> c(42);
const auto& const_c = c;
(void)c[3]; // Check that there's no assertion on valid access.
TEST_LIBCPP_ASSERT_FAILURE(c[4], "bitset::operator[] index out of bounds");
(void)const_c[3]; // Check that there's no assertion on valid access.
TEST_LIBCPP_ASSERT_FAILURE(const_c[4], "bitset::operator[] index out of bounds");
}

return 0;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
//
//===----------------------------------------------------------------------===//

// ADDITIONAL_COMPILE_FLAGS(has-fconstexpr-steps): -fconstexpr-steps=2000000

// bitset<N>& operator&=(const bitset<N>& rhs); // constexpr since C++23

#include <bitset>
Expand Down
Loading