https://gcc.gnu.org/bugzilla/show_bug.cgi?id=123176
--- Comment #2 from Luc Grosheintz <luc.grosheintz at gmail dot com> ---
Let's look at the first failure on 117:
/var/gcc/regression/master/11.4-gcc/build/i386-pc-solaris2.11/libstdc++-v3/include/mdspan:
In instantiation of 'struct std::strided_slice<char, int, int>':
/vol/gcc/src/hg/master/local/libstdc++-v3/testsuite/23_containers/mdspan/submdspan/submdspan_canonicalize_slices_neg.cc:108:
required from 'constexpr bool test_over2(Offset, Extent, Stride, Extents)
[with Offset = char; Extent = int; Stride = int; Extents =
std::extents<unsigned char, 4294967295>]'
/vol/gcc/src/hg/master/local/libstdc++-v3/testsuite/23_containers/mdspan/submdspan/submdspan_canonicalize_slices_neg.cc:117:
required from here
/var/gcc/regression/master/11.4-gcc/build/i386-pc-solaris2.11/libstdc++-v3/include/mdspan:356:
error: static assertion failed
/var/gcc/regression/master/11.4-gcc/build/i386-pc-solaris2.11/libstdc++-v3/include/mdspan:356:
note: '(((bool)std::integral_constant<bool, false>::value) ||
__integral_constant_like<char>)' evaluates to false
/vol/gcc/src/hg/master/local/libstdc++-v3/testsuite/23_containers/mdspan/submdspan/submdspan_canonicalize_slices_neg.cc:117:
error: non-constant condition for static assertion
The interesting lines of <mdpsan>:
352 template<typename _OffsetType, typename _ExtentType, typename _StrideType>
353 struct strided_slice
354 {
355 static_assert(__is_signed_or_unsigned_integer<_OffsetType>::value
356 || __detail::__integral_constant_like<_OffsetType>);
If we track in the above, it makes sense because it's:
struct std::strided_slice<char, int, int>
and the code that leads to this is (kinda):
std::strided_slice{std::int8_t{6}, 0, 1};
Now we need to look at the different definitions surrounding integers:
Fact 1: A `char` is neither a "signed integer" nor an "unsigned integer", see
https://eel.is/c++draft/basic.fundamental#1
https://eel.is/c++draft/basic.fundamental#2
Fact 2: Both `signed char` and `unsigned char` are "signed (unsigned) integer
types" (respectively), see same two links as for Fact 1.
Fact 3: A `char` is distinct from `signed char` and `unsigned char`, see
https://eel.is/c++draft/basic.fundamental#7
Fact 4: The IndexType must be a signed or unsigned integer:
https://eel.is/c++draft/mdspan.sub.strided.slice#3
Therefore, as far as I can tell, the issue is that std::int8_t is the same as
`char`, which is neither a signed nor unsigned integer type, and therefore not
a valid IndexType. Moreover, this is not what this test is checking, it assumes
that int8_t is valid. The test then fails, but with "required from" not with
"expansion of".
The question is now is `int8_t` allowed to be `char`? There's
https://eel.is/c++draft/cstdint.syn
which isn't very explicit, but it does state:
using int8_t = signed integer type; // optional
There's also cppreference:
> std::int8_t may be signed char and std::uint8_t may be unsigned char, but
neither can be char regardless of its signedness (because char is not
considered a "signed integer type" or "unsigned integer type").
https://en.cppreference.com/w/cpp/types/integer.html
Even if Solaris where wrong about typedeffing int8_t as `char` (and not `signed
char`), I doubt that will be fixed to make `mdspan` work. In those tests, the
use of int8_t isn't important, it's just any type that's different from `int`.
Hence, I can easily change it to `signed char`; and the test would still work
as intended and would hopefully fails as intended on Solaris too (they're neg
tests, so failing is good).
It feels like we're not testing sufficiently rigorously with all named integer
types: {u,}int{8,16,32,64}_t because if my argument is correct, we should have
noticed after std::extents, when trying to instantiate `std::extents<int8_t>`.