1 // RUN: %clang_cc1 -std=c++2a -verify %s
2 
3 struct B {};
4 bool operator==(const B&, const B&) = default; // expected-error {{equality comparison operator can only be defaulted in a class definition}}
5 bool operator<=>(const B&, const B&) = default; // expected-error {{three-way comparison operator can only be defaulted in a class definition}}
6 
7 template<typename T = void>
8   bool operator<(const B&, const B&) = default; // expected-error {{comparison operator template cannot be defaulted}}
9 
10 struct A {
11   friend bool operator==(const A&, const A&) = default;
12   friend bool operator!=(const A&, const B&) = default; // expected-error {{invalid parameter type for defaulted equality comparison}}
13   friend bool operator!=(const B&, const B&) = default; // expected-error {{invalid parameter type for defaulted equality comparison}}
14   friend bool operator<(const A&, const A&);
15   friend bool operator<(const B&, const B&) = default; // expected-error {{invalid parameter type for defaulted relational comparison}}
16   friend bool operator>(A, A) = default; // expected-error {{invalid parameter type for defaulted relational comparison}}
17 
18   bool operator<(const A&) const;
19   bool operator<=(const A&) const = default;
20   bool operator==(const A&) const volatile && = default; // surprisingly, OK
21   bool operator<=>(const A&) = default; // expected-error {{defaulted member three-way comparison operator must be const-qualified}}
22   bool operator>=(const B&) const = default; // expected-error {{invalid parameter type for defaulted relational comparison}}
23   static bool operator>(const B&) = default; // expected-error {{overloaded 'operator>' cannot be a static member function}}
24 
25   template<typename T = void>
26     friend bool operator==(const A&, const A&) = default; // expected-error {{comparison operator template cannot be defaulted}}
27   template<typename T = void>
28     bool operator==(const A&) const = default; // expected-error {{comparison operator template cannot be defaulted}}
29 };
30 
31 // FIXME: The wording is not clear as to whether these are valid, but the
32 // intention is that they are not.
33 bool operator<(const A&, const A&) = default; // expected-error {{relational comparison operator can only be defaulted in a class definition}}
34 bool A::operator<(const A&) const = default; // expected-error {{can only be defaulted in a class definition}}
35 
36 template<typename T> struct Dependent {
37   using U = typename T::type;
38   bool operator==(U) const = default; // expected-error {{found 'Dependent<Bad>::U'}}
39   friend bool operator==(U, U) = default; // expected-error {{found 'Dependent<Bad>::U'}}
40 };
41 
42 struct Good { using type = const Dependent<Good>&; };
43 template struct Dependent<Good>;
44 
45 struct Bad { using type = Dependent<Bad>&; };
46 template struct Dependent<Bad>; // expected-note {{in instantiation of}}
47