blob: 8d39af10af0c37fc0a21f61b12b6f9f48fbf7c4b [file] [log] [blame]
Daniel Dunbara5728872009-12-15 20:14:24 +00001// RUN: %clang_cc1 -fsyntax-only -verify %s
Douglas Gregoreaebc752008-11-06 23:29:22 +00002class X { };
3
4X operator+(X, X);
5
6void f(X x) {
7 x = x + x;
8}
9
10struct Y;
11struct Z;
12
13struct Y {
14 Y(const Z&);
15};
16
17struct Z {
18 Z(const Y&);
19};
20
21Y operator+(Y, Y);
22bool operator-(Y, Y); // expected-note{{candidate function}}
23bool operator-(Z, Z); // expected-note{{candidate function}}
24
25void g(Y y, Z z) {
26 y = y + z;
Douglas Gregorae2cf762010-11-13 20:06:38 +000027 bool b = y - z; // expected-error{{use of overloaded operator '-' is ambiguous}}
Douglas Gregoreaebc752008-11-06 23:29:22 +000028}
29
Douglas Gregor96176b32008-11-18 23:14:02 +000030struct A {
Douglas Gregor33074752009-09-30 21:46:01 +000031 bool operator==(Z&); // expected-note 2{{candidate function}}
Douglas Gregor96176b32008-11-18 23:14:02 +000032};
Douglas Gregoreaebc752008-11-06 23:29:22 +000033
Douglas Gregor96176b32008-11-18 23:14:02 +000034A make_A();
35
Douglas Gregor33074752009-09-30 21:46:01 +000036bool operator==(A&, Z&); // expected-note 2{{candidate function}}
Douglas Gregor96176b32008-11-18 23:14:02 +000037
38void h(A a, const A ac, Z z) {
39 make_A() == z;
Douglas Gregorae2cf762010-11-13 20:06:38 +000040 a == z; // expected-error{{use of overloaded operator '==' is ambiguous}}
Chris Lattner0c42bb62010-09-05 00:17:29 +000041 ac == z; // expected-error{{invalid operands to binary expression ('const A' and 'Z')}}
Douglas Gregor96176b32008-11-18 23:14:02 +000042}
43
44struct B {
45 bool operator==(const B&) const;
46
47 void test(Z z) {
48 make_A() == z;
49 }
50};
Douglas Gregor447b69e2008-11-19 03:25:36 +000051
Douglas Gregord64fdd02010-06-08 19:50:34 +000052// we shouldn't see warnings about self-comparison,
53// this is a member function, we dunno what it'll do
54bool i(B b)
55{
56 return b == b;
57}
58
Douglas Gregor447b69e2008-11-19 03:25:36 +000059enum Enum1 { };
60enum Enum2 { };
61
62struct E1 {
63 E1(Enum1) { }
64};
65
66struct E2 {
67 E2(Enum2);
68};
69
70// C++ [over.match.oper]p3 - enum restriction.
71float& operator==(E1, E2);
72
Chandler Carruth543cb652011-02-17 08:37:06 +000073void enum_test(Enum1 enum1, Enum2 enum2, E1 e1, E2 e2, Enum1 next_enum1) {
Douglas Gregor447b69e2008-11-19 03:25:36 +000074 float &f1 = (e1 == e2);
75 float &f2 = (enum1 == e2);
76 float &f3 = (e1 == enum2);
Chandler Carruth543cb652011-02-17 08:37:06 +000077 float &f4 = (enum1 == next_enum1); // expected-error{{non-const lvalue reference to type 'float' cannot bind to a temporary of type 'bool'}}
Douglas Gregor447b69e2008-11-19 03:25:36 +000078}
Douglas Gregor74253732008-11-19 15:42:04 +000079
Sebastian Redl644be852009-10-23 19:23:15 +000080// PR5244 - Argument-dependent lookup would include the two operators below,
81// which would break later assumptions and lead to a crash.
82class pr5244_foo
83{
84 pr5244_foo(int);
85 pr5244_foo(char);
86};
87
88bool operator==(const pr5244_foo& s1, const pr5244_foo& s2);
89bool operator==(char c, const pr5244_foo& s);
90
91enum pr5244_bar
92{
93 pr5244_BAR
94};
95
96class pr5244_baz
97{
John McCall7002f4c2010-04-09 19:03:51 +000098public:
Sebastian Redl644be852009-10-23 19:23:15 +000099 pr5244_bar quux;
100};
101
102void pr5244_barbaz()
103{
104 pr5244_baz quuux;
105 (void)(pr5244_BAR == quuux.quux);
106}
107
108
Douglas Gregor74253732008-11-19 15:42:04 +0000109
110struct PostInc {
111 PostInc operator++(int);
112 PostInc& operator++();
113};
114
115struct PostDec {
116 PostDec operator--(int);
117 PostDec& operator--();
118};
119
120void incdec_test(PostInc pi, PostDec pd) {
121 const PostInc& pi1 = pi++;
122 const PostDec& pd1 = pd--;
123 PostInc &pi2 = ++pi;
124 PostDec &pd2 = --pd;
125}
126
127struct SmartPtr {
128 int& operator*();
Douglas Gregor1ca50c32008-11-21 15:36:28 +0000129 long& operator*() const volatile;
Douglas Gregor74253732008-11-19 15:42:04 +0000130};
131
Douglas Gregor1ca50c32008-11-21 15:36:28 +0000132void test_smartptr(SmartPtr ptr, const SmartPtr cptr,
133 const volatile SmartPtr cvptr) {
Douglas Gregor74253732008-11-19 15:42:04 +0000134 int &ir = *ptr;
Douglas Gregor1ca50c32008-11-21 15:36:28 +0000135 long &lr = *cptr;
136 long &lr2 = *cvptr;
Douglas Gregor74253732008-11-19 15:42:04 +0000137}
Douglas Gregor337c6b92008-11-19 17:17:41 +0000138
139
140struct ArrayLike {
141 int& operator[](int);
142};
143
144void test_arraylike(ArrayLike a) {
145 int& ir = a[17];
146}
147
148struct SmartRef {
149 int* operator&();
150};
151
152void test_smartref(SmartRef r) {
153 int* ip = &r;
154}
155
156bool& operator,(X, Y);
157
158void test_comma(X x, Y y) {
159 bool& b1 = (x, y);
Argyrios Kyrtzidis1b2ad2f2010-09-19 23:03:35 +0000160 X& xr = (x, x); // expected-warning {{expression result unused}}
Douglas Gregor337c6b92008-11-19 17:17:41 +0000161}
Douglas Gregorf9eb9052008-11-19 21:05:33 +0000162
Douglas Gregorf9eb9052008-11-19 21:05:33 +0000163struct Callable {
164 int& operator()(int, double = 2.71828); // expected-note{{candidate function}}
165 float& operator()(int, double, long, ...); // expected-note{{candidate function}}
Douglas Gregor518fda12009-01-13 05:10:00 +0000166
167 double& operator()(float); // expected-note{{candidate function}}
Douglas Gregorf9eb9052008-11-19 21:05:33 +0000168};
169
Douglas Gregor518fda12009-01-13 05:10:00 +0000170struct Callable2 {
171 int& operator()(int i = 0);
172 double& operator()(...) const;
173};
174
Douglas Gregor593564b2009-11-15 07:48:03 +0000175struct DerivesCallable : public Callable {
176};
177
178void test_callable(Callable c, Callable2 c2, const Callable2& c2c,
179 DerivesCallable dc) {
Douglas Gregorf9eb9052008-11-19 21:05:33 +0000180 int &ir = c(1);
181 float &fr = c(1, 3.14159, 17, 42);
182
John McCall7c2342d2010-03-10 11:27:22 +0000183 c(); // expected-error{{no matching function for call to object of type 'Callable'}}
Douglas Gregor518fda12009-01-13 05:10:00 +0000184
185 double &dr = c(1.0f);
186
187 int &ir2 = c2();
188 int &ir3 = c2(1);
189 double &fr2 = c2c();
Douglas Gregor593564b2009-11-15 07:48:03 +0000190
191 int &ir4 = dc(17);
192 double &fr3 = dc(3.14159f);
Douglas Gregorf9eb9052008-11-19 21:05:33 +0000193}
Douglas Gregor106c6eb2008-11-19 22:57:39 +0000194
Douglas Gregor621b3932008-11-21 02:54:28 +0000195typedef float FLOAT;
196typedef int& INTREF;
197typedef INTREF Func1(FLOAT, double);
Douglas Gregor106c6eb2008-11-19 22:57:39 +0000198typedef float& Func2(int, double);
199
200struct ConvertToFunc {
Douglas Gregor90073282010-01-11 19:36:35 +0000201 operator Func1*(); // expected-note 2{{conversion candidate of type 'INTREF (*)(FLOAT, double)'}}
202 operator Func2&(); // expected-note 2{{conversion candidate of type 'float &(&)(int, double)'}}
Douglas Gregor9ebae312008-11-19 22:59:19 +0000203 void operator()();
Douglas Gregor106c6eb2008-11-19 22:57:39 +0000204};
205
Douglas Gregor90073282010-01-11 19:36:35 +0000206struct ConvertToFuncDerived : ConvertToFunc { };
207
208void test_funcptr_call(ConvertToFunc ctf, ConvertToFuncDerived ctfd) {
Douglas Gregor106c6eb2008-11-19 22:57:39 +0000209 int &i1 = ctf(1.0f, 2.0);
Douglas Gregor90073282010-01-11 19:36:35 +0000210 float &f1 = ctf((short int)1, 1.0f);
John McCall7c2342d2010-03-10 11:27:22 +0000211 ctf((long int)17, 2.0); // expected-error{{call to object of type 'ConvertToFunc' is ambiguous}}
Douglas Gregor9ebae312008-11-19 22:59:19 +0000212 ctf();
Douglas Gregor90073282010-01-11 19:36:35 +0000213
214 int &i2 = ctfd(1.0f, 2.0);
215 float &f2 = ctfd((short int)1, 1.0f);
John McCall7c2342d2010-03-10 11:27:22 +0000216 ctfd((long int)17, 2.0); // expected-error{{call to object of type 'ConvertToFuncDerived' is ambiguous}}
Douglas Gregor90073282010-01-11 19:36:35 +0000217 ctfd();
Douglas Gregor106c6eb2008-11-19 22:57:39 +0000218}
Douglas Gregor8ba10742008-11-20 16:27:02 +0000219
220struct HasMember {
221 int m;
222};
223
224struct Arrow1 {
225 HasMember* operator->();
226};
227
228struct Arrow2 {
229 Arrow1 operator->(); // expected-note{{candidate function}}
230};
231
232void test_arrow(Arrow1 a1, Arrow2 a2, const Arrow2 a3) {
233 int &i1 = a1->m;
234 int &i2 = a2->m;
Sebastian Redle4c452c2008-11-22 13:44:36 +0000235 a3->m; // expected-error{{no viable overloaded 'operator->'; candidate is}}
Douglas Gregor8ba10742008-11-20 16:27:02 +0000236}
Douglas Gregore63ef482009-01-13 00:11:19 +0000237
238struct CopyConBase {
239};
240
241struct CopyCon : public CopyConBase {
242 CopyCon(const CopyConBase &Base);
243
244 CopyCon(const CopyConBase *Base) {
245 *this = *Base;
246 }
247};
Douglas Gregorfa047642009-02-04 00:32:51 +0000248
249namespace N {
250 struct X { };
251}
252
253namespace M {
254 N::X operator+(N::X, N::X);
255}
256
257namespace M {
258 void test_X(N::X x) {
Douglas Gregorf680a0f2009-02-04 16:44:47 +0000259 (void)(x + x);
Douglas Gregorfa047642009-02-04 00:32:51 +0000260 }
261}
Douglas Gregor8a5ae242009-08-27 23:35:55 +0000262
263struct AA { bool operator!=(AA&); };
264struct BB : AA {};
265bool x(BB y, BB z) { return y != z; }
Fariborz Jahanian4a4e3452009-09-30 00:19:41 +0000266
267
268struct AX {
Anders Carlssond1aa8002010-04-23 02:20:12 +0000269 AX& operator ->(); // expected-note {{declared here}}
Fariborz Jahanian4a4e3452009-09-30 00:19:41 +0000270 int b;
271};
272
273void m() {
274 AX a;
275 a->b = 0; // expected-error {{circular pointer delegation detected}}
276}
John McCallc4e83212009-09-30 01:01:30 +0000277
278struct CircA {
Anders Carlssond1aa8002010-04-23 02:20:12 +0000279 struct CircB& operator->(); // expected-note {{declared here}}
John McCallc4e83212009-09-30 01:01:30 +0000280 int val;
281};
282struct CircB {
Anders Carlssond1aa8002010-04-23 02:20:12 +0000283 struct CircC& operator->(); // expected-note {{declared here}}
John McCallc4e83212009-09-30 01:01:30 +0000284};
285struct CircC {
Anders Carlssond1aa8002010-04-23 02:20:12 +0000286 struct CircA& operator->(); // expected-note {{declared here}}
John McCallc4e83212009-09-30 01:01:30 +0000287};
288
289void circ() {
290 CircA a;
291 a->val = 0; // expected-error {{circular pointer delegation detected}}
292}
Sebastian Redla65b5512009-11-05 16:36:20 +0000293
294// PR5360: Arrays should lead to built-in candidates for subscript.
295typedef enum {
Douglas Gregor6d82ef42010-07-08 14:54:42 +0000296 LastReg = 23,
Sebastian Redla65b5512009-11-05 16:36:20 +0000297} Register;
298class RegAlloc {
299 int getPriority(Register r) {
300 return usepri[r];
301 }
302 int usepri[LastReg + 1];
303};
Sebastian Redla9efada2009-11-18 20:39:26 +0000304
305// PR5546: Don't generate incorrect and ambiguous overloads for multi-level
306// arrays.
307namespace pr5546
308{
309 enum { X };
310 extern const char *const sMoveCommands[][2][2];
311 const char* a() { return sMoveCommands[X][0][0]; }
312 const char* b() { return (*(sMoveCommands+X))[0][0]; }
313}
Sebastian Redl275c2b42009-11-18 23:10:33 +0000314
315// PR5512 and its discussion
316namespace pr5512 {
317 struct Y {
318 operator short();
319 operator float();
320 };
321 void g_test(Y y) {
322 short s = 0;
323 // DR507, this should be ambiguous, but we special-case assignment
324 s = y;
325 // Note: DR507, this is ambiguous as specified
326 //s += y;
327 }
328
329 struct S {};
330 void operator +=(int&, S);
331 void f(S s) {
332 int i = 0;
333 i += s;
334 }
335
336 struct A {operator int();};
337 int a;
338 void b(A x) {
339 a += x;
340 }
341}
John McCall1eb3e102010-01-07 02:04:15 +0000342
343// PR5900
344namespace pr5900 {
345 struct NotAnArray {};
346 void test0() {
347 NotAnArray x;
348 x[0] = 0; // expected-error {{does not provide a subscript operator}}
349 }
350
351 struct NonConstArray {
352 int operator[](unsigned); // expected-note {{candidate}}
353 };
354 int test1() {
Douglas Gregor9db7dbb2010-01-31 09:12:51 +0000355 const NonConstArray x = NonConstArray();
John McCall1eb3e102010-01-07 02:04:15 +0000356 return x[0]; // expected-error {{no viable overloaded operator[] for type}}
357 }
358
359 // Not really part of this PR, but implemented at the same time.
360 struct NotAFunction {};
361 void test2() {
362 NotAFunction x;
363 x(); // expected-error {{does not provide a call operator}}
364 }
365}
Douglas Gregor6bf356f2010-04-25 20:25:43 +0000366
367// Operator lookup through using declarations.
368namespace N {
369 struct X2 { };
370}
371
372namespace N2 {
373 namespace M {
374 namespace Inner {
375 template<typename T>
376 N::X2 &operator<<(N::X2&, const T&);
377 }
378 using Inner::operator<<;
379 }
380}
381
382void test_lookup_through_using() {
383 using namespace N2::M;
384 N::X2 x;
385 x << 17;
386}
Douglas Gregor60b3e382011-03-16 18:21:05 +0000387
388namespace rdar9136502 {
389 struct X {
John McCall1de4d4e2011-04-07 08:22:57 +0000390 int i(); // expected-note {{candidate function}}
391 int i(int); // expected-note {{candidate function}}
Douglas Gregor60b3e382011-03-16 18:21:05 +0000392 };
393
394 struct Y {
395 Y &operator<<(int); // expected-note{{candidate function not viable: no overload of 'i' matching 'int' for 1st argument}}
396 };
397
398 void f(X x, Y y) {
John McCall1de4d4e2011-04-07 08:22:57 +0000399 y << x.i; // expected-error{{cannot resolve overloaded function 'i' from context}}
Douglas Gregor60b3e382011-03-16 18:21:05 +0000400 }
401}