diff --git a/libcxx/include/__iterator/bounded_iter.h b/libcxx/include/__iterator/bounded_iter.h index 4811b0dde7f77..ae6fbb6b59bcf 100644 --- a/libcxx/include/__iterator/bounded_iter.h +++ b/libcxx/include/__iterator/bounded_iter.h @@ -47,8 +47,11 @@ _LIBCPP_BEGIN_NAMESPACE_STD // pointer, it is undefined at the language level (see [expr.add]). If // bounded iterators exhibited this undefined behavior, we risk compiler // optimizations deleting non-redundant bounds checks. -template ::value > > +template struct __bounded_iter { + static_assert(__libcpp_is_contiguous_iterator<_Iterator>::value, + "Only contiguous iterators can be adapted by __bounded_iter."); + using value_type = typename iterator_traits<_Iterator>::value_type; using difference_type = typename iterator_traits<_Iterator>::difference_type; using pointer = typename iterator_traits<_Iterator>::pointer; @@ -247,7 +250,7 @@ struct __bounded_iter { private: template friend struct pointer_traits; - template + template friend struct __bounded_iter; _Iterator __current_; // current iterator _Iterator __begin_, __end_; // valid range represented as [begin, end] diff --git a/libcxx/include/__iterator/static_bounded_iter.h b/libcxx/include/__iterator/static_bounded_iter.h index 2b80507cf56a0..9794c220384f5 100644 --- a/libcxx/include/__iterator/static_bounded_iter.h +++ b/libcxx/include/__iterator/static_bounded_iter.h @@ -70,8 +70,11 @@ struct __static_bounded_iter_storage<_Iterator, 0> { // it can be computed from the start of the range. // // The operations on which this iterator wrapper traps are the same as `__bounded_iter`. -template ::value> > +template struct __static_bounded_iter { + static_assert(__libcpp_is_contiguous_iterator<_Iterator>::value, + "Only contiguous iterators can be adapted by __static_bounded_iter."); + using value_type = typename iterator_traits<_Iterator>::value_type; using difference_type = typename iterator_traits<_Iterator>::difference_type; using pointer = typename iterator_traits<_Iterator>::pointer; diff --git a/libcxx/test/libcxx/iterators/contiguous_iterators.verify.cpp b/libcxx/test/libcxx/iterators/contiguous_iterators.verify.cpp new file mode 100644 index 0000000000000..479d40a5eb088 --- /dev/null +++ b/libcxx/test/libcxx/iterators/contiguous_iterators.verify.cpp @@ -0,0 +1,25 @@ +//===----------------------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// +// + +// + +// __bounded_iter<_Iter> + +// Verify that __bounded_iter does not accept non-contiguous iterators as determined by __libcpp_is_contiguous_iterator. +// static_assert should be used, see https://github.com/llvm/llvm-project/issues/115002. +// __wrap_iter cannot be so handled because it may directly wrap user-defined fancy pointers in libc++'s vector. + +#include +#include +#include + +// expected-error-re@*:* {{static assertion failed due to requirement {{.*}}Only contiguous iterators can be adapted by __bounded_iter.}} +std::__bounded_iter::iterator> bounded_iter; +// expected-error-re@*:* {{static assertion failed due to requirement {{.*}}Only contiguous iterators can be adapted by __static_bounded_iter.}} +std::__static_bounded_iter::iterator, 42> statically_bounded_iter;