[libcxx-commits] [libcxx] 4c4606a - [libc++] Add missing assertion in std::span constructor (#118396)
via libcxx-commits
libcxx-commits at lists.llvm.org
Mon Dec 9 08:51:10 PST 2024
Author: Louis Dionne
Date: 2024-12-09T11:51:07-05:00
New Revision: 4c4606a743d26ebe5fdd84e953254627a459a991
URL: https://github.com/llvm/llvm-project/commit/4c4606a743d26ebe5fdd84e953254627a459a991
DIFF: https://github.com/llvm/llvm-project/commit/4c4606a743d26ebe5fdd84e953254627a459a991.diff
LOG: [libc++] Add missing assertion in std::span constructor (#118396)
The (iterator, size) constructor should ensure that it gets passed a
valid range when the size is not 0.
Fixes #107789
Added:
Modified:
libcxx/include/span
libcxx/test/libcxx/containers/views/views.span/span.cons/assert.iter_size.pass.cpp
Removed:
################################################################################
diff --git a/libcxx/include/span b/libcxx/include/span
index 896a3cd890186c..097efbd50a00fd 100644
--- a/libcxx/include/span
+++ b/libcxx/include/span
@@ -267,6 +267,8 @@ public:
_LIBCPP_HIDE_FROM_ABI constexpr explicit span(_It __first, size_type __count) : __data_{std::to_address(__first)} {
(void)__count;
_LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(_Extent == __count, "size mismatch in span's constructor (iterator, len)");
+ _LIBCPP_ASSERT_VALID_INPUT_RANGE(__count == 0 || std::to_address(__first) != nullptr,
+ "passed nullptr with non-zero length in span's constructor (iterator, len)");
}
template <__span_compatible_iterator<element_type> _It, __span_compatible_sentinel_for<_It> _End>
@@ -441,7 +443,10 @@ public:
template <__span_compatible_iterator<element_type> _It>
_LIBCPP_HIDE_FROM_ABI constexpr span(_It __first, size_type __count)
- : __data_{std::to_address(__first)}, __size_{__count} {}
+ : __data_{std::to_address(__first)}, __size_{__count} {
+ _LIBCPP_ASSERT_VALID_INPUT_RANGE(__count == 0 || std::to_address(__first) != nullptr,
+ "passed nullptr with non-zero length in span's constructor (iterator, len)");
+ }
template <__span_compatible_iterator<element_type> _It, __span_compatible_sentinel_for<_It> _End>
_LIBCPP_HIDE_FROM_ABI constexpr span(_It __first, _End __last)
diff --git a/libcxx/test/libcxx/containers/views/views.span/span.cons/assert.iter_size.pass.cpp b/libcxx/test/libcxx/containers/views/views.span/span.cons/assert.iter_size.pass.cpp
index 4461bad8ff5047..c8c6e3743bd211 100644
--- a/libcxx/test/libcxx/containers/views/views.span/span.cons/assert.iter_size.pass.cpp
+++ b/libcxx/test/libcxx/containers/views/views.span/span.cons/assert.iter_size.pass.cpp
@@ -25,13 +25,48 @@
#include "check_assertion.h"
int main(int, char**) {
- std::array<int, 3> array{0, 1, 2};
+ std::array<int, 3> array{0, 1, 2};
- auto too_large = [&] { std::span<int, 3> const s(array.data(), 4); (void)s; };
- TEST_LIBCPP_ASSERT_FAILURE(too_large(), "size mismatch in span's constructor (iterator, len)");
+ // Input range too large (exceeds the span extent)
+ {
+ auto f = [&] {
+ std::span<int, 3> const s(array.data(), 4);
+ (void)s;
+ };
+ TEST_LIBCPP_ASSERT_FAILURE(f(), "size mismatch in span's constructor (iterator, len)");
+ }
- auto too_small = [&] { std::span<int, 3> const s(array.data(), 2); (void)s; };
- TEST_LIBCPP_ASSERT_FAILURE(too_small(), "size mismatch in span's constructor (iterator, len)");
+ // Input range too small (doesn't fill the span)
+ {
+ auto f = [&] {
+ std::span<int, 3> const s(array.data(), 2);
+ (void)s;
+ };
+ TEST_LIBCPP_ASSERT_FAILURE(f(), "size mismatch in span's constructor (iterator, len)");
+ }
- return 0;
+ // Input range is non-empty but starts with a null pointer
+ {
+ // static extent
+ {
+ auto f = [&] {
+ int* p = nullptr;
+ std::span<int, 3> const s(p, 3);
+ (void)s;
+ };
+ TEST_LIBCPP_ASSERT_FAILURE(f(), "passed nullptr with non-zero length in span's constructor (iterator, len)");
+ }
+
+ // dynamic extent
+ {
+ auto f = [&] {
+ int* p = nullptr;
+ std::span<int, std::dynamic_extent> const s(p, 1);
+ (void)s;
+ };
+ TEST_LIBCPP_ASSERT_FAILURE(f(), "passed nullptr with non-zero length in span's constructor (iterator, len)");
+ }
+ }
+
+ return 0;
}
More information about the libcxx-commits
mailing list