[Bug c++/67324] Failures in Assignable concept's requires-expression
pinskia at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Sat Dec 25 01:52:26 GMT 2021
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67324
Andrew Pinski <pinskia at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|NEW |RESOLVED
Keywords| |rejects-valid
Resolution|--- |FIXED
Target Milestone|--- |10.0
--- Comment #2 from Andrew Pinski <pinskia at gcc dot gnu.org> ---
Note this is a fixed up testcase for GCC 10 with -std=c++17 -fconcepts (I don't
know how to fix it up to C++20 syntax though):
template< typename T, typename U >
concept bool
Same( )
{
return __is_same_as(T, U);
}
template< class T >
struct remove_reference { using type = T; };
template< class U >
struct remove_reference<U& > { using type = U; };
template< class U >
struct remove_reference<U&&> { using type = U; };
template< class T >
using remove_reference_t = typename remove_reference<T>::type;
template< typename T >
constexpr T&&
forward( remove_reference_t<T>& t) noexcept
{ return static_cast<T&&>(t); }
template< typename T >
constexpr T&&
forward( remove_reference_t<T>&& t) noexcept
{ return static_cast<T&&>(t); }
template< class T, class U = T >
concept bool
Assignable( )
{
return
requires( T&& a, U&& b ) {
{ forward<T>(a) = forward<U>(b) } -> Same<T&>; // #1
requires Same<T&, decltype(forward<T>(a) = forward<U>(b))>(); // #2
};
}
template< typename T, typename U = T >
constexpr bool
test( ) { return false; }
template< typename T, typename U = T >
requires Assignable<T, U>()
constexpr bool
test( ) { return true; }
struct A { };
struct B { B& operator = ( B const& ) = delete; };
struct C { C& operator = ( C&& ) = delete; };
struct D { D& operator = ( D const& ) = delete; D& operator = ( D&& ) =
default; };
struct E { E& operator = ( E const & ); };
struct F { A& operator = ( F const & ); };
int
main( )
{
static_assert( not test<void>(), "" );
static_assert( test<bool&>(), "" );
static_assert( not test<int>(), "" );
static_assert( test<int&>(), "" );
static_assert( test<int*&>(), "" );
static_assert( not test<int const&>(), "" );
static_assert( test<char&>(), "" );
static_assert( test<unsigned&>(), "" );
static_assert( test<unsigned long&>(), "" );
static_assert( test<A&>(), "" );
static_assert( test<A&,A>(), "" );
static_assert( not test<B&>(), "" );
static_assert( not test<B&,B>(), "" );
static_assert( not test<C&>(), "" );
static_assert( not test<C&,C>(), "" );
static_assert( test<D&,D>(), "" );
static_assert( test<E&,E>(), "" );
static_assert( not test<F&,F>(), "" );
return 0;
}
Oh and it is fixed in GCC 10+, most likely by the rewrite of concepts to be
complaint with the C++20 standard.
More information about the Gcc-bugs
mailing list