https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106644
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #1 from Jakub Jelinek <jakub at gcc dot gnu.org> --- FYI, clang trunk now implements this DR. Rough testcase distilled from the paper + some extra tests from the LLVM test coverage of the paper, with just // ERR to mark expected diagnostics (details to be filled only once it is implemented). // P2468R2 - The Equality Operator You Are Looking For // { dg-do compile { target c++20 } } struct A { bool operator== (const A &) { return true; } bool operator!= (const A &) { return false; } }; bool a = A{} != A{}; template <typename T> struct B { bool operator== (const T &) const; bool operator!= (const T &) const; }; struct B1 : B<B1> { }; bool b1 = B1{} == B1{}; bool b2 = B1{} != B1{}; template <bool> struct C { using C1 = C<true>; using C2 = C<false>; C () = default; C (const C2 &); bool operator== (C1) const; bool operator!= (C1) const; }; using C3 = C<false>; bool c = C3{} == C3{}; struct D { D (); D (int *); bool operator== (const D &) const; operator int * () const; }; bool d = nullptr != D{}; // ERR struct E { operator bool () const; }; unsigned char operator== (E, E); unsigned char e = E{} != E{}; // ERR struct F {}; template <typename T> bool operator== (F, T); bool f1 = 0 == F (); template <typename T> bool operator!= (F, T); bool f2 = 0 == F (); // ERR struct G { bool operator== (const G &); }; struct G1 : G { G1 (); G1 (G); bool operator!= (const G &); }; bool g1 = G () == G1 (); bool g2 = G1 () == G (); // ERR struct H {}; template <typename T> bool operator== (H, T); inline namespace H1 { template <typename T> bool operator!= (H, T); } bool h = 0 == H (); template <class T> struct I { int operator== (const double &) const; friend inline int operator== (const double &, const T &) { return 1; } }; struct I1 : I<I1> { }; bool i = I1{} == 0.; // ERR struct J { bool operator== (const J &) const; bool operator!= (const J &) const; }; struct J1 : J { J1 (const J &); bool operator== (const J1 &x) const { return static_cast<const J &> (*this) == x; // ERR } }; struct K { bool operator== (const K &); }; bool k = K{} == K{}; // ERR struct L { bool operator== (const L &) const; }; bool l = L{} == L{}; struct M { bool operator== (M); }; bool m = M () == M (); struct N { virtual bool operator== (const N &) const; }; struct N1 : N { bool operator== (const N &) const override; }; bool n = N1 () == N1 (); // ERR struct O { virtual signed char operator== (const O &) const; signed char operator!= (const O &x) const { return !operator== (x); } }; struct O1 : O { signed char operator== (const O &) const override; }; bool o = O1 () != O1 (); // ERR template <class T> bool foo (T x, T y) requires requires { x == y; } { return x == y; } bool b3 = foo (B1 (), B1 ()); struct P {}; template <typename T, class U = int> bool operator== (P, T); template <class T> bool operator!= (P, T); bool p = 0 == P (); struct Q {}; template <typename T> bool operator== (Q, T); template <typename U> bool operator!= (Q, U); bool q = 0 == Q (); // ERR struct R { template <typename T> bool operator== (const T &); }; bool r = R () == R (); // ERR struct S { template <typename T> bool operator== (const T &) const; bool operator!= (const S &); }; bool s = S () == S (); struct T {}; template <class U = int> bool operator== (T, int); bool operator!= (T, int); bool t = 0 == T (); struct U {}; bool operator== (U, int); bool u1 = 0 == U (); namespace U1 { bool operator!= (U, int); } bool u2 = 0 == U (); using U1::operator!=; bool u3 = 0 == U (); // ERR struct V {}; template <typename T> bool operator== (V, T); bool v1 = 0 == V (); namespace V1 { template <typename T> bool operator!= (V, T); } bool v2 = 0 == V (); using V1::operator!=; bool v3 = 0 == V (); // ERR template <int N> struct W { bool operator== (int) requires (N == 1); bool operator!= (int) requires (N == 2); }; int w = 0 == W<1> (); struct X { bool operator== (X const &); static bool operator!= (X const &, X const &); }; bool x = X () == X (); // ERR