Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion libcxx/docs/Hardening.rst
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ Hardened containers status
- Partial
- N/A
* - ``bitset``
-
-
Copy link
Member Author

Choose a reason for hiding this comment

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

I'm still hesitant to list valarray as fully hardened given the numerous helper classes -- that would require some investigation!

- N/A

Note: for ``vector`` and ``string``, the iterator does not check for
Expand Down
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