Skip to content

Commit 9cf646f

Browse files
[libc++] Disallow character types being index types of extents
llvm#78086 provided the IMO exact approach - `__libcpp_integer` - for this.
1 parent f142f8a commit 9cf646f

File tree

2 files changed

+53
-2
lines changed

2 files changed

+53
-2
lines changed

libcxx/include/__mdspan/extents.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include <__assert>
2121
#include <__config>
22+
#include <__concepts/arithmetic.h>
2223
#include <__type_traits/common_type.h>
2324
#include <__type_traits/is_convertible.h>
2425
#include <__type_traits/is_nothrow_constructible.h>
@@ -282,8 +283,7 @@ class extents {
282283
using size_type = make_unsigned_t<index_type>;
283284
using rank_type = size_t;
284285

285-
static_assert(is_integral<index_type>::value && !is_same<index_type, bool>::value,
286-
"extents::index_type must be a signed or unsigned integer type");
286+
static_assert(__libcpp_integer<index_type>, "extents::index_type must be a signed or unsigned integer type");
287287
static_assert(((__mdspan_detail::__is_representable_as<index_type>(_Extents) || (_Extents == dynamic_extent)) && ...),
288288
"extents ctor: arguments must be representable as index_type and nonnegative");
289289

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//
2+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
3+
// See https://llvm.org/LICENSE.txt for license information.
4+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5+
//
6+
//===----------------------------------------------------------------------===//
7+
8+
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
9+
10+
// <mdspan>
11+
12+
// template<class IndexType, size_t... Extents>
13+
// class extents;
14+
//
15+
// Mandates:
16+
// - IndexType is a signed or unsigned integer type, and
17+
// - each element of Extents is either equal to dynamic_extent, or is representable as a value of type IndexType.
18+
19+
#include <cstddef>
20+
#include <climits>
21+
#include <mdspan>
22+
23+
void invalid_index_types() {
24+
// expected-error-re@*:* {{static assertion failed {{.*}}extents::index_type must be a signed or unsigned integer type}}
25+
[[maybe_unused]] std::extents<bool, true> eb;
26+
// expected-error-re@*:* {{static assertion failed {{.*}}extents::index_type must be a signed or unsigned integer type}}
27+
[[maybe_unused]] std::extents<char, '*'> ec;
28+
#ifndef TEST_HAS_NO_CHAR8_T
29+
// expected-error-re@*:* {{static assertion failed {{.*}}extents::index_type must be a signed or unsigned integer type}}
30+
[[maybe_unused]] std::extents<char8_t, u8'*'> ec8;
31+
#endif
32+
// expected-error-re@*:* {{static assertion failed {{.*}}extents::index_type must be a signed or unsigned integer type}}
33+
[[maybe_unused]] std::extents<char16_t, u'*'> ec16;
34+
// expected-error-re@*:* {{static assertion failed {{.*}}extents::index_type must be a signed or unsigned integer type}}
35+
[[maybe_unused]] std::extents<char32_t, U'*'> ec32;
36+
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
37+
// expected-error-re@*:* {{static assertion failed {{.*}}extents::index_type must be a signed or unsigned integer type}}
38+
[[maybe_unused]] std::extents<wchar_t, L'*'> ewc;
39+
#endif
40+
}
41+
42+
void invalid_extent_values() {
43+
// expected-error-re@*:* {{static assertion failed {{.*}}extents ctor: arguments must be representable as index_type and nonnegative}}
44+
[[maybe_unused]] std::extents<signed char, static_cast<std::size_t>(SCHAR_MAX) + 1> esc1;
45+
// expected-error-re@*:* {{static assertion failed {{.*}}extents ctor: arguments must be representable as index_type and nonnegative}}
46+
[[maybe_unused]] std::extents<signed char, std::dynamic_extent - 1> esc2;
47+
// expected-error-re@*:* {{static assertion failed {{.*}}extents ctor: arguments must be representable as index_type and nonnegative}}
48+
[[maybe_unused]] std::extents<unsigned char, static_cast<std::size_t>(UCHAR_MAX) + 1> euc1;
49+
// expected-error-re@*:* {{static assertion failed {{.*}}extents ctor: arguments must be representable as index_type and nonnegative}}
50+
[[maybe_unused]] std::extents<unsigned char, std::dynamic_extent - 1> euc2;
51+
}

0 commit comments

Comments
 (0)