-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[libc++] Disallow character types being index types of extents
#105832
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
@llvm/pr-subscribers-libcxx Author: A. Jiang (frederick-vs-ja) Changes#78086 provided the IMO exact approach - Full diff: https://github.com/llvm/llvm-project/pull/105832.diff 2 Files Affected:
diff --git a/libcxx/include/__mdspan/extents.h b/libcxx/include/__mdspan/extents.h
index 95082ef3d11ac9..54577f2c581dff 100644
--- a/libcxx/include/__mdspan/extents.h
+++ b/libcxx/include/__mdspan/extents.h
@@ -19,6 +19,7 @@
#include <__assert>
#include <__config>
+#include <__concepts/arithmetic.h>
#include <__type_traits/common_type.h>
#include <__type_traits/is_convertible.h>
#include <__type_traits/is_nothrow_constructible.h>
@@ -282,8 +283,7 @@ class extents {
using size_type = make_unsigned_t<index_type>;
using rank_type = size_t;
- static_assert(is_integral<index_type>::value && !is_same<index_type, bool>::value,
- "extents::index_type must be a signed or unsigned integer type");
+ static_assert(__libcpp_integer<index_type>, "extents::index_type must be a signed or unsigned integer type");
static_assert(((__mdspan_detail::__is_representable_as<index_type>(_Extents) || (_Extents == dynamic_extent)) && ...),
"extents ctor: arguments must be representable as index_type and nonnegative");
diff --git a/libcxx/test/std/containers/views/mdspan/extents/index_type.verify.cpp b/libcxx/test/std/containers/views/mdspan/extents/index_type.verify.cpp
new file mode 100644
index 00000000000000..ef28c456925df8
--- /dev/null
+++ b/libcxx/test/std/containers/views/mdspan/extents/index_type.verify.cpp
@@ -0,0 +1,51 @@
+//
+// 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, c++20
+
+// <mdspan>
+
+// template<class IndexType, size_t... Extents>
+// class extents;
+//
+// Mandates:
+// - IndexType is a signed or unsigned integer type, and
+// - each element of Extents is either equal to dynamic_extent, or is representable as a value of type IndexType.
+
+#include <cstddef>
+#include <climits>
+#include <mdspan>
+
+void invalid_index_types() {
+ // expected-error-re@*:* {{static assertion failed {{.*}}extents::index_type must be a signed or unsigned integer type}}
+ [[maybe_unused]] std::extents<bool, true> eb;
+ // expected-error-re@*:* {{static assertion failed {{.*}}extents::index_type must be a signed or unsigned integer type}}
+ [[maybe_unused]] std::extents<char, '*'> ec;
+#ifndef TEST_HAS_NO_CHAR8_T
+ // expected-error-re@*:* {{static assertion failed {{.*}}extents::index_type must be a signed or unsigned integer type}}
+ [[maybe_unused]] std::extents<char8_t, u8'*'> ec8;
+#endif
+ // expected-error-re@*:* {{static assertion failed {{.*}}extents::index_type must be a signed or unsigned integer type}}
+ [[maybe_unused]] std::extents<char16_t, u'*'> ec16;
+ // expected-error-re@*:* {{static assertion failed {{.*}}extents::index_type must be a signed or unsigned integer type}}
+ [[maybe_unused]] std::extents<char32_t, U'*'> ec32;
+#ifndef TEST_HAS_NO_WIDE_CHARACTERS
+ // expected-error-re@*:* {{static assertion failed {{.*}}extents::index_type must be a signed or unsigned integer type}}
+ [[maybe_unused]] std::extents<wchar_t, L'*'> ewc;
+#endif
+}
+
+void invalid_extent_values() {
+ // expected-error-re@*:* {{static assertion failed {{.*}}extents ctor: arguments must be representable as index_type and nonnegative}}
+ [[maybe_unused]] std::extents<signed char, static_cast<std::size_t>(SCHAR_MAX) + 1> esc1;
+ // expected-error-re@*:* {{static assertion failed {{.*}}extents ctor: arguments must be representable as index_type and nonnegative}}
+ [[maybe_unused]] std::extents<signed char, std::dynamic_extent - 1> esc2;
+ // expected-error-re@*:* {{static assertion failed {{.*}}extents ctor: arguments must be representable as index_type and nonnegative}}
+ [[maybe_unused]] std::extents<unsigned char, static_cast<std::size_t>(UCHAR_MAX) + 1> euc1;
+ // expected-error-re@*:* {{static assertion failed {{.*}}extents ctor: arguments must be representable as index_type and nonnegative}}
+ [[maybe_unused]] std::extents<unsigned char, std::dynamic_extent - 1> euc2;
+}
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
9cf646f
to
c098d0d
Compare
This comment was marked as resolved.
This comment was marked as resolved.
Sorry I lost track of this. Its fine i don't need to do the work if soneone else takes the initiative ;-). I can review though. |
PR 78086 (bddd8f4) provided the IMO exact approach - `__libcpp_integer` - for this.
c098d0d
to
e33f05f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks fine too me, I do not understand why on some builds the verification test fails. The expected and observed message seem to me to match, and this seems to look like what we did in other places?
|
||
void invalid_index_types() { | ||
// expected-error-re@*:* {{static assertion failed {{.*}}extents::index_type must be a signed or unsigned integer type}} | ||
[[maybe_unused]] std::extents<char, '*'> ec; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'd just add the appropriate -Wno-whatever
flag to avoid the [[maybe_unused]]
. They are quite noisy IMO.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd still like to see this addressed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I might have merged a bit too hastily. @frederick-vs-ja do you think you can make a follow-up PR?
libcxx/test/std/containers/views/mdspan/extents/index_type.verify.cpp
Outdated
Show resolved
Hide resolved
// expected-error-re@*:* {{static assertion failed {{.*}}extents ctor: arguments must be representable as index_type and nonnegative}} | ||
[[maybe_unused]] std::extents<signed char, static_cast<std::size_t>(SCHAR_MAX) + 1> esc1; | ||
// expected-error-re@*:* {{static assertion failed {{.*}}extents ctor: arguments must be representable as index_type and nonnegative}} | ||
[[maybe_unused]] std::extents<signed char, std::dynamic_extent - 1> esc2; | ||
// expected-error-re@*:* {{static assertion failed {{.*}}extents ctor: arguments must be representable as index_type and nonnegative}} | ||
[[maybe_unused]] std::extents<unsigned char, static_cast<std::size_t>(UCHAR_MAX) + 1> euc1; | ||
// expected-error-re@*:* {{static assertion failed {{.*}}extents ctor: arguments must be representable as index_type and nonnegative}} | ||
[[maybe_unused]] std::extents<unsigned char, std::dynamic_extent - 1> euc2; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// expected-error-re@*:* {{static assertion failed {{.*}}extents ctor: arguments must be representable as index_type and nonnegative}} | |
[[maybe_unused]] std::extents<signed char, static_cast<std::size_t>(SCHAR_MAX) + 1> esc1; | |
// expected-error-re@*:* {{static assertion failed {{.*}}extents ctor: arguments must be representable as index_type and nonnegative}} | |
[[maybe_unused]] std::extents<signed char, std::dynamic_extent - 1> esc2; | |
// expected-error-re@*:* {{static assertion failed {{.*}}extents ctor: arguments must be representable as index_type and nonnegative}} | |
[[maybe_unused]] std::extents<unsigned char, static_cast<std::size_t>(UCHAR_MAX) + 1> euc1; | |
// expected-error-re@*:* {{static assertion failed {{.*}}extents ctor: arguments must be representable as index_type and nonnegative}} | |
[[maybe_unused]] std::extents<unsigned char, std::dynamic_extent - 1> euc2; | |
// expected-error-re@*:* 4 {{static assertion failed {{.*}}extents ctor: arguments must be representable as index_type and nonnegative}} | |
[[maybe_unused]] std::extents<signed char, static_cast<std::size_t>(SCHAR_MAX) + 1> esc1; | |
[[maybe_unused]] std::extents<signed char, std::dynamic_extent - 1> esc2; | |
[[maybe_unused]] std::extents<unsigned char, static_cast<std::size_t>(UCHAR_MAX) + 1> euc1; | |
[[maybe_unused]] std::extents<unsigned char, std::dynamic_extent - 1> euc2; |
I don't know whether this is actually better. Just a thought.
#78086 provided the IMO exact approach -
__libcpp_integer
- for this. Fixes #73715.In some
libcxx/containers/views/mdspan
tests, improper uses ofchar
are replaced withsigned char
.