diff --git a/libcxx/include/span b/libcxx/include/span index 2d43d1d1079e4..f05a0383a3c6a 100644 --- a/libcxx/include/span +++ b/libcxx/include/span @@ -369,12 +369,12 @@ public: # endif _LIBCPP_HIDE_FROM_ABI constexpr reference front() const noexcept { - _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span::front() on empty span"); + static_assert(_Extent >= 1, "span::front() on empty span"); return __data_[0]; } _LIBCPP_HIDE_FROM_ABI constexpr reference back() const noexcept { - _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(!empty(), "span::back() on empty span"); + static_assert(_Extent >= 1, "span::back() on empty span"); return __data_[size() - 1]; } diff --git a/libcxx/test/libcxx/containers/views/views.span/span.elem/assert.back.pass.cpp b/libcxx/test/libcxx/containers/views/views.span/span.elem/assert.back.pass.cpp index ea98fe81ee2f8..8d30f9659afe2 100644 --- a/libcxx/test/libcxx/containers/views/views.span/span.elem/assert.back.pass.cpp +++ b/libcxx/test/libcxx/containers/views/views.span/span.elem/assert.back.pass.cpp @@ -5,6 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// + // UNSUPPORTED: c++03, c++11, c++14, c++17 // @@ -23,17 +24,13 @@ #include "check_assertion.h" int main(int, char**) { - { - std::array array{0, 1, 2}; - std::span const s(array.data(), 0); - TEST_LIBCPP_ASSERT_FAILURE(s.back(), "span::back() on empty span"); - } - - { - std::array array{0, 1, 2}; - std::span const s(array.data(), 0); - TEST_LIBCPP_ASSERT_FAILURE(s.back(), "span::back() on empty span"); - } - - return 0; + { + std::array array{0, 1, 2}; + std::span const s(array.data(), 0); + TEST_LIBCPP_ASSERT_FAILURE(s.back(), "span::back() on empty span"); + } + + // back() on a span with a static extent is caught statically and tested in front.verify.cpp + + return 0; } diff --git a/libcxx/test/libcxx/containers/views/views.span/span.elem/assert.front.pass.cpp b/libcxx/test/libcxx/containers/views/views.span/span.elem/assert.front.pass.cpp index 2660ca1f90c14..6e5a4157ba6df 100644 --- a/libcxx/test/libcxx/containers/views/views.span/span.elem/assert.front.pass.cpp +++ b/libcxx/test/libcxx/containers/views/views.span/span.elem/assert.front.pass.cpp @@ -5,6 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// + // UNSUPPORTED: c++03, c++11, c++14, c++17 // @@ -23,17 +24,13 @@ #include "check_assertion.h" int main(int, char**) { - { - std::array array{0, 1, 2}; - std::span const s(array.data(), 0); - TEST_LIBCPP_ASSERT_FAILURE(s.front(), "span::front() on empty span"); - } - - { - std::array array{0, 1, 2}; - std::span const s(array.data(), 0); - TEST_LIBCPP_ASSERT_FAILURE(s.front(), "span::front() on empty span"); - } - - return 0; + { + std::array array{0, 1, 2}; + std::span const s(array.data(), 0); + TEST_LIBCPP_ASSERT_FAILURE(s.front(), "span::front() on empty span"); + } + + // front() on a span with a static extent is caught statically and tested in front.verify.cpp + + return 0; } diff --git a/libcxx/test/libcxx/containers/views/views.span/span.elem/back.verify.cpp b/libcxx/test/libcxx/containers/views/views.span/span.elem/back.verify.cpp new file mode 100644 index 0000000000000..3060db0402a5b --- /dev/null +++ b/libcxx/test/libcxx/containers/views/views.span/span.elem/back.verify.cpp @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// +// +// constexpr reference back() const noexcept; + +// Make sure that accessing a statically-sized span out-of-bounds triggers a +// compile-time error. + +#include +#include + +int main(int, char**) { + std::array array{0, 1, 2}; + { + std::span const s(array.data(), 0); + s.back(); // expected-error@span:* {{span::back() on empty span}} + } + { + std::span const s(array.data(), 3); + s.back(); // nothing + } + + return 0; +} diff --git a/libcxx/test/libcxx/containers/views/views.span/span.elem/front.verify.cpp b/libcxx/test/libcxx/containers/views/views.span/span.elem/front.verify.cpp new file mode 100644 index 0000000000000..793eb70259f70 --- /dev/null +++ b/libcxx/test/libcxx/containers/views/views.span/span.elem/front.verify.cpp @@ -0,0 +1,33 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +// UNSUPPORTED: c++03, c++11, c++14, c++17 + +// +// +// constexpr reference front() const noexcept; + +// Make sure that accessing a statically-sized span out-of-bounds triggers a +// compile-time error. + +#include +#include + +int main(int, char**) { + std::array array{0, 1, 2}; + { + std::span const s(array.data(), 0); + s.front(); // expected-error@span:* {{span::front() on empty span}} + } + { + std::span const s(array.data(), 3); + s.front(); // nothing + } + + return 0; +}