libstdc++: Fix std::array<T, 0>::data() to be a constant expression [PR108258]

When I refactored the __array_traits helper I broke this.

libstdc++-v3/ChangeLog:

	PR libstdc++/108258
	* include/std/array (__array_traits<T, 0>::operator T*()): Add
	constexpr.
	* testsuite/23_containers/array/element_access/constexpr_c++17.cc: Check
	std::array<T, 0>::data().
This commit is contained in:
Jonathan Wakely 2023-01-04 11:49:19 +00:00
parent ebc4491194
commit 1530a9b1f4
2 changed files with 17 additions and 4 deletions

View File

@ -69,7 +69,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
// Conversion to a pointer produces a null pointer.
__attribute__((__always_inline__))
operator _Tp*() const noexcept { return nullptr; }
constexpr operator _Tp*() const noexcept { return nullptr; }
};
using _Is_swappable = true_type;

View File

@ -34,21 +34,34 @@ constexpr std::size_t test01()
auto v2 = a.at(2);
auto v3 = a.front();
auto v4 = a.back();
return v1 + v2 + v3 + v4;
auto v5 = *a.data();
return v1 + v2 + v3 + v4 + v5;
}
static_assert( test01() == (55 + 66 + 0 + 2) );
constexpr std::size_t test02()
{
// array
// const array
typedef std::array<std::size_t, 6> array_type;
const array_type a = { { 0, 55, 66, 99, 4115, 2 } };
auto v1 = a[1];
auto v2 = a.at(2);
auto v3 = a.front();
auto v4 = a.back();
return v1 + v2 + v3 + v4;
auto v5 = *a.data();
return v1 + v2 + v3 + v4 + v5;
}
static_assert( test02() == (55 + 66 + 0 + 2) );
constexpr bool test_zero()
{
// zero-sized array (PR libstdc++/108258)
std::array<int, 0> a{};
auto v4 = a.data();
// The standard says this is unspecified, it's null for our implementation:
return a.data() == nullptr;
}
static_assert( test_zero() );