brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.6 KiB · 7ff827e Raw
134 lines · cpp
1// RUN: %clang_cc1 -std=c++2a -verify %s2 3struct A {};4struct B { bool operator==(B) const; };5struct C { int operator==(C) const; };6struct D {7  // expected-note@+2 {{candidate function not viable: 'this' argument has type 'const}}8  // expected-note@+1 {{candidate function (with reversed parameter order) not viable: 1st argument ('const}}9  bool operator==(D);10};11struct E {12  E(const E &) = delete; // expected-note {{deleted}}13  int operator==(E) const; // expected-note {{passing}}14};15struct F { void operator==(F) const; };16struct G { bool operator==(G) const = delete; }; // expected-note {{deleted here}}17 18struct H1 {19  bool operator==(const H1 &) const = default;20  bool operator<(const H1 &) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}21  // expected-note@-1 {{because there is no viable three-way comparison function for 'H1'}}22  void (*x)();23};24struct H2 {25  bool operator==(const H2 &) const = default;26  bool operator<(const H2 &) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}27  // expected-note@-1 {{because there is no viable three-way comparison function for 'H2'}}28  void (H2::*x)();29};30struct H3 {31  bool operator==(const H3 &) const = default;32  bool operator<(const H3 &) const = default; // expected-warning {{implicitly deleted}} expected-note{{replace 'default'}}33  // expected-note@-1 {{because there is no viable three-way comparison function for 'H3'}}34  int H3::*x;35};36 37template<typename T> struct X {38  X();39  bool operator==(const X&) const = default; // #x expected-note 4{{deleted here}}40  T t; // expected-note 3{{because there is no viable 'operator==' for member 't'}}41       // expected-note@-1 {{because it would invoke a deleted comparison function for member 't'}}42};43 44struct Mutable {45  bool operator==(const Mutable&) const = default;46  mutable D d;47};48 49void test() {50  void(X<A>() == X<A>()); // expected-error {{cannot be compared because its 'operator==' is implicitly deleted}}51  void(X<B>() == X<B>());52  void(X<C>() == X<C>());53  void(X<D>() == X<D>()); // expected-error {{cannot be compared because its 'operator==' is implicitly deleted}}54  void(Mutable() == Mutable());55 56  // FIXME: We would benefit from a note identifying the member of 'X' we were comparing here and below.57  // expected-error@#x {{call to deleted constructor of 'E'}}58  void(X<E>() == X<E>()); // expected-note {{in defaulted equality comparison operator for 'X<E>' first required here}}59 60  // FIXME: We would benefit from a note pointing at the selected 'operator==' here.61  // expected-error@#x {{value of type 'void' is not contextually convertible to 'bool'}}62  void(X<F>() == X<F>()); // expected-note {{in defaulted equality comparison operator for 'X<F>' first required here}}63 64  void(X<G>() == X<G>()); // expected-error {{cannot be compared because its 'operator==' is implicitly deleted}}65 66  void(X<A[3]>() == X<A[3]>()); // expected-error {{cannot be compared because its 'operator==' is implicitly deleted}}67  void(X<B[3]>() == X<B[3]>());68}69 70namespace Access {71  class A {72    bool operator==(const A &) const; // expected-note 2{{implicitly declared private here}}73  };74  struct B : A { // expected-note 2{{because it would invoke a private 'operator==' to compare base class 'A'}}75    bool operator==(const B &) const = default; // expected-warning {{deleted}} expected-note{{replace 'default'}}76    friend bool operator==(const B &, const B &) = default; // expected-warning {{deleted}} expected-note{{replace 'default'}}77  };78 79  class C {80  protected:81    bool operator==(const C &) const; // expected-note 2{{declared protected here}}82  };83  struct D : C {84    bool operator==(const D &) const = default;85    friend bool operator==(const D &, const D&) = default;86  };87  struct E {88    C c; // expected-note 2{{because it would invoke a protected 'operator==' member of 'Access::C' to compare member 'c'}}89    bool operator==(const E &) const = default; // expected-warning {{deleted}} expected-note{{replace 'default'}}90    friend bool operator==(const E &, const E &) = default; // expected-warning {{deleted}} expected-note{{replace 'default'}}91  };92 93  struct F : C {94    using C::operator==;95  };96  struct G : F {97    bool operator==(const G&) const = default;98    friend bool operator==(const G&, const G&) = default;99  };100 101  struct H : C {102  private:103    using C::operator==; // expected-note 2{{declared private here}}104  };105  struct I : H { // expected-note 2{{private 'operator==' to compare base class 'H'}}106    bool operator==(const I&) const = default; // expected-warning {{deleted}} expected-note{{replace 'default'}}107    friend bool operator==(const I&, const I&) = default; // expected-warning {{deleted}} expected-note{{replace 'default'}}108  };109 110  class J {111    bool operator==(const J&) const;112    friend class K;113  };114  class K {115    J j;116    bool operator==(const K&) const = default;117    friend bool operator==(const K&, const K&) = default;118  };119 120  struct X {121    bool operator==(const X&) const; // expected-note {{ambiguity is between a regular call to this operator and a call with the argument order reversed}}122  };123  struct Y : private X { // expected-note {{private}}124    using X::operator==;125  };126  struct Z : Y {127    // Note: this function is not deleted. The selected operator== is128    // accessible. But the derived-to-base conversion involves an inaccessible129    // base class, which we don't check for until we define the function.130    bool operator==(const Z&) const = default; // expected-error {{cannot cast 'const Y' to its private base class 'const X'}} expected-warning {{ambiguous}}131  };132  bool z = Z() == Z(); // expected-note {{first required here}}133}134