mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-10 13:31:04 +08:00
libstdc++: Make std::compare_three_way check if <=> is valid (PR 93479)
Currently types that cannot be compared using <=> but which are convertible to pointers will be compared by converting to pointers first. They should not be comparable. PR libstdc++/93479 * libsupc++/compare (__3way_builtin_ptr_cmp): Require <=> to be valid. * testsuite/18_support/comparisons/object/93479.cc: New test.
This commit is contained in:
parent
5cd2e126f5
commit
83b0201035
@ -1,5 +1,9 @@
|
||||
2020-01-29 Jonathan Wakely <jwakely@redhat.com>
|
||||
|
||||
PR libstdc++/93479
|
||||
* libsupc++/compare (__3way_builtin_ptr_cmp): Require <=> to be valid.
|
||||
* testsuite/18_support/comparisons/object/93479.cc: New test.
|
||||
|
||||
* testsuite/std/ranges/access/end.cc: Do not assume test_range::end()
|
||||
returns the same type as test_range::begin(). Add comments.
|
||||
* testsuite/std/ranges/access/rbegin.cc: Likewise.
|
||||
|
@ -525,7 +525,9 @@ namespace std
|
||||
// BUILTIN-PTR-THREE-WAY(T, U)
|
||||
template<typename _Tp, typename _Up>
|
||||
concept __3way_builtin_ptr_cmp
|
||||
= convertible_to<_Tp, const volatile void*>
|
||||
= requires(_Tp&& __t, _Up&& __u)
|
||||
{ static_cast<_Tp&&>(__t) <=> static_cast<_Up&&>(__u); }
|
||||
&& convertible_to<_Tp, const volatile void*>
|
||||
&& convertible_to<_Up, const volatile void*>
|
||||
&& ! requires(_Tp&& __t, _Up&& __u)
|
||||
{ operator<=>(static_cast<_Tp&&>(__t), static_cast<_Up&&>(__u)); }
|
||||
|
@ -0,0 +1,44 @@
|
||||
// Copyright (C) 2020 Free Software Foundation, Inc.
|
||||
//
|
||||
// This file is part of the GNU ISO C++ Library. This library is free
|
||||
// software; you can redistribute it and/or modify it under the
|
||||
// terms of the GNU General Public License as published by the
|
||||
// Free Software Foundation; either version 3, or (at your option)
|
||||
// any later version.
|
||||
|
||||
// This library is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License along
|
||||
// with this library; see the file COPYING3. If not see
|
||||
// <http://www.gnu.org/licenses/>.
|
||||
|
||||
// { dg-options "-std=gnu++2a" }
|
||||
// { dg-do compile { target c++2a } }
|
||||
|
||||
#include <compare>
|
||||
|
||||
void
|
||||
test01()
|
||||
{
|
||||
// PR libstdc++/93479
|
||||
int i[1];
|
||||
int j[1];
|
||||
std::compare_three_way{}(i, j); // { dg-error "no match" }
|
||||
}
|
||||
|
||||
void
|
||||
test02()
|
||||
{
|
||||
struct X
|
||||
{
|
||||
operator const char*() const noexcept { return "!"; }
|
||||
void operator<=>(X) const = delete;
|
||||
void operator<=>(const void*) const = delete;
|
||||
} x;
|
||||
std::compare_three_way{}(x, x); // { dg-error "no match" }
|
||||
std::compare_three_way{}(x, ""); // { dg-error "no match" }
|
||||
std::compare_three_way{}("", x); // { dg-error "no match" }
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user