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