Skip to content

Commit 74e70ba

Browse files
[libc++] Disallow character types being index types of extents (#105832)
#78086 provided the trait we want to use for this: `__libcpp_integer`. In some `libcxx/containers/views/mdspan` tests, improper uses of `char` are replaced with `signed char`. Fixes #73715
1 parent ee764a2 commit 74e70ba

18 files changed

+114
-56
lines changed

libcxx/include/__mdspan/extents.h

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

2020
#include <__assert>
2121
#include <__config>
22+
23+
#include <__concepts/arithmetic.h>
2224
#include <__type_traits/common_type.h>
2325
#include <__type_traits/is_convertible.h>
2426
#include <__type_traits/is_nothrow_constructible.h>
@@ -282,8 +284,7 @@ class extents {
282284
using size_type = make_unsigned_t<index_type>;
283285
using rank_type = size_t;
284286

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");
287+
static_assert(__libcpp_integer<index_type>, "extents::index_type must be a signed or unsigned integer type");
287288
static_assert(((__mdspan_detail::__is_representable_as<index_type>(_Extents) || (_Extents == dynamic_extent)) && ...),
288289
"extents ctor: arguments must be representable as index_type and nonnegative");
289290

libcxx/test/libcxx/containers/views/mdspan/extents/assert.conversion.pass.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ int main(int, char**) {
5050
}
5151
// value out of range
5252
{
53-
TEST_LIBCPP_ASSERT_FAILURE(([=] { std::extents<char, D, 5> e(arg); }()),
53+
TEST_LIBCPP_ASSERT_FAILURE(([=] { std::extents<signed char, D, 5> e(arg); }()),
5454
"extents ctor: arguments must be representable as index_type and nonnegative");
5555
}
5656
return 0;

libcxx/test/libcxx/containers/views/mdspan/extents/assert.ctor_from_array.pass.cpp

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -51,19 +51,13 @@ int main(int, char**) {
5151
}
5252
// value out of range
5353
{
54-
TEST_LIBCPP_ASSERT_FAILURE(
55-
([] {
56-
std::extents<char, D, 5> e1(std::array{1000, 5});
57-
}()),
58-
"extents ctor: arguments must be representable as index_type and nonnegative");
54+
TEST_LIBCPP_ASSERT_FAILURE(([] { std::extents<signed char, D, 5> e1(std::array{1000, 5}); }()),
55+
"extents ctor: arguments must be representable as index_type and nonnegative");
5956
}
6057
// negative value
6158
{
62-
TEST_LIBCPP_ASSERT_FAILURE(
63-
([] {
64-
std::extents<char, D, 5> e1(std::array{-1, 5});
65-
}()),
66-
"extents ctor: arguments must be representable as index_type and nonnegative");
59+
TEST_LIBCPP_ASSERT_FAILURE(([] { std::extents<signed char, D, 5> e1(std::array{-1, 5}); }()),
60+
"extents ctor: arguments must be representable as index_type and nonnegative");
6761
}
6862
return 0;
6963
}

libcxx/test/libcxx/containers/views/mdspan/extents/assert.ctor_from_integral.pass.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,12 @@ int main(int, char**) {
5050
}
5151
// value out of range
5252
{
53-
TEST_LIBCPP_ASSERT_FAILURE(([] { std::extents<char, D, 5> e1(1000, 5); }()),
53+
TEST_LIBCPP_ASSERT_FAILURE(([] { std::extents<signed char, D, 5> e1(1000, 5); }()),
5454
"extents ctor: arguments must be representable as index_type and nonnegative");
5555
}
5656
// negative value
5757
{
58-
TEST_LIBCPP_ASSERT_FAILURE(([] { std::extents<char, D, 5> e1(-1, 5); }()),
58+
TEST_LIBCPP_ASSERT_FAILURE(([] { std::extents<signed char, D, 5> e1(-1, 5); }()),
5959
"extents ctor: arguments must be representable as index_type and nonnegative");
6060
}
6161
return 0;

libcxx/test/libcxx/containers/views/mdspan/extents/assert.ctor_from_span.pass.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,13 +49,13 @@ int main(int, char**) {
4949
// value out of range
5050
{
5151
std::array args{1000, 5};
52-
TEST_LIBCPP_ASSERT_FAILURE(([=] { std::extents<char, D, 5> e1(std::span{args}); }()),
52+
TEST_LIBCPP_ASSERT_FAILURE(([=] { std::extents<signed char, D, 5> e1(std::span{args}); }()),
5353
"extents ctor: arguments must be representable as index_type and nonnegative");
5454
}
5555
// negative value
5656
{
5757
std::array args{-1, 5};
58-
TEST_LIBCPP_ASSERT_FAILURE(([=] { std::extents<char, D, 5> e1(std::span{args}); }()),
58+
TEST_LIBCPP_ASSERT_FAILURE(([=] { std::extents<signed char, D, 5> e1(std::span{args}); }()),
5959
"extents ctor: arguments must be representable as index_type and nonnegative");
6060
}
6161
return 0;

libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.conversion.pass.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,20 @@ int main(int, char**) {
4242
}
4343
// non-representability of extents itself
4444
{
45-
TEST_LIBCPP_ASSERT_FAILURE(([=] { std::layout_left::mapping<std::extents<char, D>> m(
46-
std::layout_left::mapping<std::extents<int, D>>(std::extents<int, D>(500))); }()),
47-
"extents ctor: arguments must be representable as index_type and nonnegative");
45+
TEST_LIBCPP_ASSERT_FAILURE(
46+
([=] {
47+
std::layout_left::mapping<std::extents<signed char, D>> m(
48+
std::layout_left::mapping<std::extents<int, D>>(std::extents<int, D>(500)));
49+
}()),
50+
"extents ctor: arguments must be representable as index_type and nonnegative");
4851
}
4952
// required_span_size not representable, while individual extents are
5053
{
5154
// check extents would be constructible
52-
[[maybe_unused]] std::extents<char, D, 5> e(arg_exts);
55+
[[maybe_unused]] std::extents<signed char, D, 5> e(arg_exts);
5356
// but the product is not, so we can't use it for layout_left
5457
TEST_LIBCPP_ASSERT_FAILURE(
55-
([=] { std::layout_left::mapping<std::extents<char, D, 5>> m(arg); }()),
58+
([=] { std::layout_left::mapping<std::extents<signed char, D, 5>> m(arg); }()),
5659
"layout_left::mapping converting ctor: other.required_span_size() must be representable as index_type.");
5760
}
5861
return 0;

libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.ctor.extents.pass.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@
1313

1414
// <mdspan>
1515

16-
1716
// constexpr mapping(const extents_type& e) noexcept;
1817
//
1918
// Preconditions: The size of the multidimensional index space e is representable as a value of type index_type ([basic.fundamental]).
@@ -32,7 +31,7 @@ int main(int, char**) {
3231
{
3332
// the extents are representable but the product is not, so we can't use it for layout_left
3433
TEST_LIBCPP_ASSERT_FAILURE(
35-
([=] { std::layout_left::mapping<std::extents<char, D, 5>> m(std::extents<char, D, 5>(100)); }()),
34+
([=] { std::layout_left::mapping<std::extents<signed char, D, 5>> m(std::extents<signed char, D, 5>(100)); }()),
3635
"layout_left::mapping extents ctor: product of extents must be representable as index_type.");
3736
}
3837
return 0;

libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.ctor.layout_right.pass.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,12 @@ int main(int, char**) {
4444
}
4545
// non-representability of extents itself
4646
{
47-
TEST_LIBCPP_ASSERT_FAILURE(([=] { std::layout_left::mapping<std::extents<char, D>> m(
48-
std::layout_right::mapping<std::extents<int, D>>(std::extents<int, D>(500))); }()),
49-
"extents ctor: arguments must be representable as index_type and nonnegative");
47+
TEST_LIBCPP_ASSERT_FAILURE(
48+
([=] {
49+
std::layout_left::mapping<std::extents<signed char, D>> m(
50+
std::layout_right::mapping<std::extents<int, D>>(std::extents<int, D>(500)));
51+
}()),
52+
"extents ctor: arguments must be representable as index_type and nonnegative");
5053
}
5154

5255
// Can't trigger required_span_size() representability assertion, since for rank-1 the above check will trigger first,

libcxx/test/libcxx/containers/views/mdspan/layout_left/assert.ctor.layout_stride.pass.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,14 @@ int main(int, char**) {
5454
// non-representability of extents itself
5555
{
5656
std::layout_stride::mapping arg(std::extents<int, D>(500), std::array<int, 1>{1});
57-
TEST_LIBCPP_ASSERT_FAILURE(([=] { std::layout_left::mapping<std::extents<char, D>> m(arg); }()),
57+
TEST_LIBCPP_ASSERT_FAILURE(([=] { std::layout_left::mapping<std::extents<signed char, D>> m(arg); }()),
5858
"extents ctor: arguments must be representable as index_type and nonnegative");
5959
}
6060
// non-representability of required span size
6161
{
6262
std::layout_stride::mapping arg(std::extents<int, D, D>(100, 3), std::array<int, 2>{1, 100});
6363
TEST_LIBCPP_ASSERT_FAILURE(
64-
([=] { std::layout_left::mapping<std::extents<char, D, D>> m(arg); }()),
64+
([=] { std::layout_left::mapping<std::extents<signed char, D, D>> m(arg); }()),
6565
"layout_left::mapping from layout_stride ctor: other.required_span_size() must be "
6666
"representable as index_type.");
6767
}

libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.conversion.pass.cpp

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,20 @@ int main(int, char**) {
4242
}
4343
// non-representability of extents itself
4444
{
45-
TEST_LIBCPP_ASSERT_FAILURE(([=] { std::layout_right::mapping<std::extents<char, D>> m(
46-
std::layout_right::mapping<std::extents<int, D>>(std::extents<int, D>(500))); }()),
47-
"extents ctor: arguments must be representable as index_type and nonnegative");
45+
TEST_LIBCPP_ASSERT_FAILURE(
46+
([=] {
47+
std::layout_right::mapping<std::extents<signed char, D>> m(
48+
std::layout_right::mapping<std::extents<int, D>>(std::extents<int, D>(500)));
49+
}()),
50+
"extents ctor: arguments must be representable as index_type and nonnegative");
4851
}
4952
// required_span_size not representable, while individual extents are
5053
{
5154
// check extents would be constructible
52-
[[maybe_unused]] std::extents<char, D, 5> e(arg_exts);
55+
[[maybe_unused]] std::extents<signed char, D, 5> e(arg_exts);
5356
// but the product is not, so we can't use it for layout_right
5457
TEST_LIBCPP_ASSERT_FAILURE(
55-
([=] { std::layout_right::mapping<std::extents<char, D, 5>> m(arg); }()),
58+
([=] { std::layout_right::mapping<std::extents<signed char, D, 5>> m(arg); }()),
5659
"layout_right::mapping converting ctor: other.required_span_size() must be representable as index_type.");
5760
}
5861
return 0;

libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.ctor.extents.pass.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ int main(int, char**) {
3131
{
3232
// the extents are representable but the product is not, so we can't use it for layout_right
3333
TEST_LIBCPP_ASSERT_FAILURE(
34-
([=] { std::layout_right::mapping<std::extents<char, D, 5>> m(std::extents<char, D, 5>(100)); }()),
34+
([=] {
35+
std::layout_right::mapping<std::extents<signed char, D, 5>> m(std::extents<signed char, D, 5>(100));
36+
}()),
3537
"layout_right::mapping extents ctor: product of extents must be representable as index_type.");
3638
}
3739
return 0;

libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.ctor.layout_left.pass.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,12 @@ int main(int, char**) {
4444
}
4545
// non-representability of extents itself
4646
{
47-
TEST_LIBCPP_ASSERT_FAILURE(([=] { std::layout_right::mapping<std::extents<char, D>> m(
48-
std::layout_left::mapping<std::extents<int, D>>(std::extents<int, D>(500))); }()),
49-
"extents ctor: arguments must be representable as index_type and nonnegative");
47+
TEST_LIBCPP_ASSERT_FAILURE(
48+
([=] {
49+
std::layout_right::mapping<std::extents<signed char, D>> m(
50+
std::layout_left::mapping<std::extents<int, D>>(std::extents<int, D>(500)));
51+
}()),
52+
"extents ctor: arguments must be representable as index_type and nonnegative");
5053
}
5154

5255
// Can't trigger required_span_size() representability assertion, since for rank-1 the above check will trigger first,

libcxx/test/libcxx/containers/views/mdspan/layout_right/assert.ctor.layout_stride.pass.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,14 @@ int main(int, char**) {
5454
// non-representability of extents itself
5555
{
5656
std::layout_stride::mapping arg(std::extents<int, D>(500), std::array<int, 1>{1});
57-
TEST_LIBCPP_ASSERT_FAILURE(([=] { std::layout_right::mapping<std::extents<char, D>> m(arg); }()),
57+
TEST_LIBCPP_ASSERT_FAILURE(([=] { std::layout_right::mapping<std::extents<signed char, D>> m(arg); }()),
5858
"extents ctor: arguments must be representable as index_type and nonnegative");
5959
}
6060
// non-representability of required span size
6161
{
6262
std::layout_stride::mapping arg(std::extents<int, D, D>(100, 3), std::array<int, 2>{3, 1});
6363
TEST_LIBCPP_ASSERT_FAILURE(
64-
([=] { std::layout_right::mapping<std::extents<char, D, D>> m(arg); }()),
64+
([=] { std::layout_right::mapping<std::extents<signed char, D, D>> m(arg); }()),
6565
"layout_right::mapping from layout_stride ctor: other.required_span_size() must be "
6666
"representable as index_type.");
6767
}

libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.conversion.pass.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,26 +65,26 @@ int main(int, char**) {
6565
{
6666
TEST_LIBCPP_ASSERT_FAILURE(
6767
([=] {
68-
std::layout_stride::mapping<std::extents<char, D>> m(
68+
std::layout_stride::mapping<std::extents<signed char, D>> m(
6969
std::layout_stride::mapping<std::extents<int, D>>(std::extents<int, D>(500), std::array<int, 1>{1}));
7070
}()),
7171
"extents ctor: arguments must be representable as index_type and nonnegative");
7272
}
7373
// all strides must be larger than zero
7474
{
7575
always_convertible_layout::mapping<std::dextents<int, 2>> offset_map(std::dextents<int, 2>{10, 10}, 100, -1);
76-
TEST_LIBCPP_ASSERT_FAILURE(([=] { std::layout_stride::mapping<std::extents<char, D, D>> m(offset_map); }()),
76+
TEST_LIBCPP_ASSERT_FAILURE(([=] { std::layout_stride::mapping<std::extents<signed char, D, D>> m(offset_map); }()),
7777
"layout_stride::mapping converting ctor: all strides must be greater than 0");
7878
}
7979
// required_span_size not representable, while individual extents are
8080
{
8181
std::extents<int, D, D> arg_exts{100, 5};
8282
std::layout_stride::mapping<std::extents<int, D, D>> arg(arg_exts, std::array<int, 2>{1, 100});
8383
// check extents would be constructible
84-
[[maybe_unused]] std::extents<char, D, 5> e(arg_exts);
84+
[[maybe_unused]] std::extents<signed char, D, 5> e(arg_exts);
8585
// but the product is not, so we can't use it for layout_stride
8686
TEST_LIBCPP_ASSERT_FAILURE(
87-
([=] { std::layout_stride::mapping<std::extents<char, D, 5>> m(arg); }()),
87+
([=] { std::layout_stride::mapping<std::extents<signed char, D, 5>> m(arg); }()),
8888
"layout_stride::mapping converting ctor: other.required_span_size() must be representable as index_type.");
8989
}
9090
// required_span_size not representable, while individual extents are, edge case
@@ -104,7 +104,7 @@ int main(int, char**) {
104104
// base offset must be 0 (i.e. mapping(0,...,0)==0) for a strided layout with positive strides
105105
{
106106
always_convertible_layout::mapping<std::dextents<int, 2>> offset_map(std::dextents<int, 2>{10, 10}, 3);
107-
TEST_LIBCPP_ASSERT_FAILURE(([=] { std::layout_stride::mapping<std::extents<char, D, D>> m(offset_map); }()),
107+
TEST_LIBCPP_ASSERT_FAILURE(([=] { std::layout_stride::mapping<std::extents<signed char, D, D>> m(offset_map); }()),
108108
"layout_stride::mapping converting ctor: base offset of mapping must be zero.");
109109
}
110110
return 0;

libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.ctor.extents_array.pass.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,8 @@ int main(int, char**) {
4141
// the extents are representable but the product with strides is not, so we can't use it for layout_stride
4242
TEST_LIBCPP_ASSERT_FAILURE(
4343
([=] {
44-
std::layout_stride::mapping<std::extents<char, D, 5>> m(
45-
std::extents<char, D, 5>(20), std::array<int, 2>{20, 1});
44+
std::layout_stride::mapping<std::extents<signed char, D, 5>> m(
45+
std::extents<signed char, D, 5>(20), std::array<int, 2>{20, 1});
4646
}()),
4747
"layout_stride::mapping ctor: required span size is not representable as index_type.");
4848

libcxx/test/libcxx/containers/views/mdspan/layout_stride/assert.ctor.extents_span.pass.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ int main(int, char**) {
4444
TEST_LIBCPP_ASSERT_FAILURE(
4545
([=] {
4646
std::array<int, 2> strides{20, 1};
47-
std::layout_stride::mapping<std::extents<char, D, 5>> m(std::extents<char, D, 5>(20), std::span(strides));
47+
std::layout_stride::mapping<std::extents<signed char, D, 5>> m(
48+
std::extents<signed char, D, 5>(20), std::span(strides));
4849
}()),
4950
"layout_stride::mapping ctor: required span size is not representable as index_type.");
5051

libcxx/test/libcxx/containers/views/mdspan/mdspan/assert.size.pass.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,18 +29,18 @@ int main(int, char**) {
2929
std::array<float, 10> data;
3030
// make sure we are not failing because of using index_type instead of size_type
3131
{
32-
layout_wrapping_integral<4>::mapping<std::dextents<char, 2>> map(
33-
std::dextents<char, 2>(100, 2), not_extents_constructible_tag());
34-
std::mdspan<float, std::dextents<char, 2>, layout_wrapping_integral<4>> mds(data.data(), map);
35-
assert(map.required_span_size() == char(8));
32+
layout_wrapping_integral<4>::mapping<std::dextents<signed char, 2>> map(
33+
std::dextents<signed char, 2>(100, 2), not_extents_constructible_tag());
34+
std::mdspan<float, std::dextents<signed char, 2>, layout_wrapping_integral<4>> mds(data.data(), map);
35+
assert(map.required_span_size() == static_cast<signed char>(8));
3636
assert((static_cast<unsigned char>(200) == mds.size()));
3737
}
3838
{
39-
layout_wrapping_integral<4>::mapping<std::dextents<char, 2>> map(
40-
std::dextents<char, 2>(100, 3), not_extents_constructible_tag());
41-
std::mdspan<float, std::dextents<char, 2>, layout_wrapping_integral<4>> mds(data.data(), map);
39+
layout_wrapping_integral<4>::mapping<std::dextents<signed char, 2>> map(
40+
std::dextents<signed char, 2>(100, 3), not_extents_constructible_tag());
41+
std::mdspan<float, std::dextents<signed char, 2>, layout_wrapping_integral<4>> mds(data.data(), map);
4242
// sanity check
43-
assert(map.required_span_size() == char(12));
43+
assert(map.required_span_size() == static_cast<signed char>(12));
4444
// 100 x 3 exceeds 256
4545
{
4646
TEST_LIBCPP_ASSERT_FAILURE(([=] { mds.size(); }()), "mdspan: size() is not representable as size_type");
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
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@*:* {{static assertion failed: extents::index_type must be a signed or unsigned integer type}}
25+
[[maybe_unused]] std::extents<char, '*'> ec;
26+
#ifndef TEST_HAS_NO_CHAR8_T
27+
// expected-error@*:* {{static assertion failed: extents::index_type must be a signed or unsigned integer type}}
28+
[[maybe_unused]] std::extents<char8_t, u8'*'> ec8;
29+
#endif
30+
// expected-error@*:* {{static assertion failed: extents::index_type must be a signed or unsigned integer type}}
31+
[[maybe_unused]] std::extents<char16_t, u'*'> ec16;
32+
// expected-error@*:* {{static assertion failed: extents::index_type must be a signed or unsigned integer type}}
33+
[[maybe_unused]] std::extents<char32_t, U'*'> ec32;
34+
#ifndef TEST_HAS_NO_WIDE_CHARACTERS
35+
// expected-error@*:* {{static assertion failed: extents::index_type must be a signed or unsigned integer type}}
36+
[[maybe_unused]] std::extents<wchar_t, L'*'> ewc;
37+
#endif
38+
}
39+
40+
void invalid_extent_values() {
41+
// expected-error-re@*:* {{static assertion failed {{.*}}extents ctor: arguments must be representable as index_type and nonnegative}}
42+
[[maybe_unused]] std::extents<signed char, static_cast<std::size_t>(SCHAR_MAX) + 1> esc1;
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, std::dynamic_extent - 1> esc2;
45+
// expected-error-re@*:* {{static assertion failed {{.*}}extents ctor: arguments must be representable as index_type and nonnegative}}
46+
[[maybe_unused]] std::extents<unsigned char, static_cast<std::size_t>(UCHAR_MAX) + 1> euc1;
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, std::dynamic_extent - 1> euc2;
49+
}

0 commit comments

Comments
 (0)