File: p2.cpp

package info (click to toggle)
llvm-toolchain-14 1%3A14.0.6-16
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 1,496,368 kB
  • sloc: cpp: 5,593,980; ansic: 986,873; asm: 585,869; python: 184,223; objc: 72,530; lisp: 31,119; f90: 27,793; javascript: 9,780; pascal: 9,762; sh: 9,482; perl: 7,468; ml: 5,432; awk: 3,523; makefile: 2,547; xml: 953; cs: 573; fortran: 567
file content (133 lines) | stat: -rw-r--r-- 5,453 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// RUN: %clang_cc1 -std=c++2a -verify %s

struct A {};
struct B { bool operator==(B) const; };
struct C { int operator==(C) const; };
struct D {
  // expected-note@+2 {{candidate function not viable: 'this' argument has type 'const}}
  // expected-note@+1 {{candidate function (with reversed parameter order) not viable: 1st argument ('const}}
  bool operator==(D);
};
struct E {
  E(const E &) = delete; // expected-note {{deleted}}
  int operator==(E) const; // expected-note {{passing}}
};
struct F { void operator==(F) const; };
struct G { bool operator==(G) const = delete; }; // expected-note {{deleted here}}

struct H1 {
  bool operator==(const H1 &) const = default;
  bool operator<(const H1 &) const = default; // expected-warning {{implicitly deleted}}
  // expected-note@-1 {{because there is no viable three-way comparison function for 'H1'}}
  void (*x)();
};
struct H2 {
  bool operator==(const H2 &) const = default;
  bool operator<(const H2 &) const = default; // expected-warning {{implicitly deleted}}
  // expected-note@-1 {{because there is no viable three-way comparison function for 'H2'}}
  void (H2::*x)();
};
struct H3 {
  bool operator==(const H3 &) const = default;
  bool operator<(const H3 &) const = default; // expected-warning {{implicitly deleted}}
  // expected-note@-1 {{because there is no viable three-way comparison function for 'H3'}}
  int H3::*x;
};

template<typename T> struct X {
  X();
  bool operator==(const X&) const = default; // #x expected-note 4{{deleted here}}
  T t; // expected-note 3{{because there is no viable three-way comparison function for member 't'}}
       // expected-note@-1 {{because it would invoke a deleted comparison function for member 't'}}
};

struct Mutable {
  bool operator==(const Mutable&) const = default;
  mutable D d;
};

void test() {
  void(X<A>() == X<A>()); // expected-error {{cannot be compared because its 'operator==' is implicitly deleted}}
  void(X<B>() == X<B>());
  void(X<C>() == X<C>());
  void(X<D>() == X<D>()); // expected-error {{cannot be compared because its 'operator==' is implicitly deleted}}
  void(Mutable() == Mutable());

  // FIXME: We would benefit from a note identifying the member of 'X' we were comparing here and below.
  // expected-error@#x {{call to deleted constructor of 'E'}}
  void(X<E>() == X<E>()); // expected-note {{in defaulted equality comparison operator for 'X<E>' first required here}}

  // FIXME: We would benefit from a note pointing at the selected 'operator==' here.
  // expected-error@#x {{value of type 'void' is not contextually convertible to 'bool'}}
  void(X<F>() == X<F>()); // expected-note {{in defaulted equality comparison operator for 'X<F>' first required here}}

  void(X<G>() == X<G>()); // expected-error {{cannot be compared because its 'operator==' is implicitly deleted}}

  void(X<A[3]>() == X<A[3]>()); // expected-error {{cannot be compared because its 'operator==' is implicitly deleted}}
  void(X<B[3]>() == X<B[3]>());
}

namespace Access {
  class A {
    bool operator==(const A &) const; // expected-note 2{{implicitly declared private here}}
  };
  struct B : A { // expected-note 2{{because it would invoke a private 'operator==' to compare base class 'A'}}
    bool operator==(const B &) const = default; // expected-warning {{deleted}}
    friend bool operator==(const B &, const B &) = default; // expected-warning {{deleted}}
  };

  class C {
  protected:
    bool operator==(const C &) const; // expected-note 2{{declared protected here}}
  };
  struct D : C {
    bool operator==(const D &) const = default;
    friend bool operator==(const D &, const D&) = default;
  };
  struct E {
    C c; // expected-note 2{{because it would invoke a protected 'operator==' member of 'Access::C' to compare member 'c'}}
    bool operator==(const E &) const = default; // expected-warning {{deleted}}
    friend bool operator==(const E &, const E &) = default; // expected-warning {{deleted}}
  };

  struct F : C {
    using C::operator==;
  };
  struct G : F {
    bool operator==(const G&) const = default;
    friend bool operator==(const G&, const G&) = default;
  };

  struct H : C {
  private:
    using C::operator==; // expected-note 2{{declared private here}}
  };
  struct I : H { // expected-note 2{{private 'operator==' to compare base class 'H'}}
    bool operator==(const I&) const = default; // expected-warning {{deleted}}
    friend bool operator==(const I&, const I&) = default; // expected-warning {{deleted}}
  };

  class J {
    bool operator==(const J&) const;
    friend class K;
  };
  class K {
    J j;
    bool operator==(const K&) const = default;
    friend bool operator==(const K&, const K&) = default;
  };

  struct X {
    bool operator==(const X&) const; // expected-note {{ambiguity is between a regular call to this operator and a call with the argument order reversed}}
  };
  struct Y : private X { // expected-note {{private}}
    using X::operator==;
  };
  struct Z : Y {
    // Note: this function is not deleted. The selected operator== is
    // accessible. But the derived-to-base conversion involves an inaccessible
    // base class, which we don't check for until we define the function.
    bool operator==(const Z&) const = default; // expected-error {{cannot cast 'const Access::Y' to its private base class 'const Access::X'}} expected-warning {{ambiguous}}
  };
  bool z = Z() == Z(); // expected-note {{first required here}}
}