blob: 6f24c59e3a73a5a953831822801ed50759b47f9c [file] [log] [blame]
Patrick Beardb2f68202012-04-06 18:12:22 +00001// RUN: %clang_cc1 -fsyntax-only -verify -Wno-objc-root-class %s
Douglas Gregordda78892008-12-18 23:43:31 +00002@interface Foo
3@end
4
5@implementation Foo
6
7void func(id);
8
9+ zone {
10 func(self);
11 return self;
12}
Douglas Gregora46969d2008-12-19 19:16:37 +000013@end
Douglas Gregordda78892008-12-18 23:43:31 +000014
Douglas Gregor7ca09762008-11-27 01:19:21 +000015@protocol P0
16@end
17
18@protocol P1
19@end
20
21@interface A <P0>
Douglas Gregorcb7de522008-11-26 23:31:11 +000022@end
23
24@interface B : A
25@end
26
Douglas Gregor7ca09762008-11-27 01:19:21 +000027@interface C <P1>
28@end
29
John McCall6d09da02010-10-26 06:23:29 +000030int& f(A*); // expected-note {{candidate}}
31float& f(B*); // expected-note {{candidate}}
Douglas Gregorcb7de522008-11-26 23:31:11 +000032void g(A*);
33
Douglas Gregor395cc372011-01-31 18:51:41 +000034int& h(A*);
35float& h(id);
Douglas Gregorcb7de522008-11-26 23:31:11 +000036
John McCall6d09da02010-10-26 06:23:29 +000037void test0(A* a, B* b, id val) {
Douglas Gregorcb7de522008-11-26 23:31:11 +000038 int& i1 = f(a);
39 float& f1 = f(b);
John McCall6d09da02010-10-26 06:23:29 +000040
41 // GCC succeeds here, which is clearly ridiculous.
42 float& f2 = f(val); // expected-error {{ambiguous}}
43
Douglas Gregorcb7de522008-11-26 23:31:11 +000044 g(a);
45 g(b);
46 g(val);
47 int& i2 = h(a);
48 float& f3 = h(val);
Douglas Gregorda80f742010-12-01 21:43:58 +000049
Douglas Gregor395cc372011-01-31 18:51:41 +000050 int& i3 = h(b);
Douglas Gregorcb7de522008-11-26 23:31:11 +000051}
52
John McCall6d09da02010-10-26 06:23:29 +000053void test1(A* a) {
Fariborz Jahanian84950c72011-03-21 19:08:42 +000054 B* b = a; // expected-warning{{incompatible pointer types initializing 'B *' with an expression of type 'A *'}}
Douglas Gregor8cf0d222011-06-11 04:42:12 +000055 B *c; c = a; // expected-warning{{incompatible pointer types assigning to 'B *' from 'A *'}}
Douglas Gregor45920e82008-12-19 17:40:08 +000056}
57
John McCall6d09da02010-10-26 06:23:29 +000058void test2(A** ap) {
Fariborz Jahanian84950c72011-03-21 19:08:42 +000059 B** bp = ap; // expected-warning{{incompatible pointer types initializing 'B **' with an expression of type 'A **'}}
Douglas Gregor8cf0d222011-06-11 04:42:12 +000060 bp = ap; // expected-warning{{incompatible pointer types assigning to 'B **' from 'A **'}}
John McCall6d09da02010-10-26 06:23:29 +000061}
62
63// FIXME: we should either allow overloading here or give a better diagnostic
64int& cv(A*); // expected-note {{previous declaration}} expected-note 2 {{not viable}}
65float& cv(const A*); // expected-error {{cannot be overloaded}}
66
Douglas Gregorda80f742010-12-01 21:43:58 +000067int& cv2(void*);
68float& cv2(const void*);
Douglas Gregorcb7de522008-11-26 23:31:11 +000069
70void cv_test(A* a, B* b, const A* ac, const B* bc) {
71 int &i1 = cv(a);
72 int &i2 = cv(b);
John McCall6d09da02010-10-26 06:23:29 +000073 float &f1 = cv(ac); // expected-error {{no matching function}}
74 float &f2 = cv(bc); // expected-error {{no matching function}}
Douglas Gregorda80f742010-12-01 21:43:58 +000075 int& i3 = cv2(a);
76 float& f3 = cv2(ac);
Douglas Gregorcb7de522008-11-26 23:31:11 +000077}
Douglas Gregor7ca09762008-11-27 01:19:21 +000078
John McCall6d09da02010-10-26 06:23:29 +000079// We agree with GCC that these can't be overloaded.
80int& qualid(id<P0>); // expected-note {{previous declaration}} expected-note {{not viable}}
81float& qualid(id<P1>); // expected-error {{cannot be overloaded}}
Douglas Gregor7ca09762008-11-27 01:19:21 +000082
83void qualid_test(A *a, B *b, C *c) {
84 int& i1 = qualid(a);
85 int& i2 = qualid(b);
John McCall6d09da02010-10-26 06:23:29 +000086
87 // This doesn't work only because the overload was rejected above.
88 float& f1 = qualid(c); // expected-error {{no matching function}}
Douglas Gregor27b09ac2008-12-22 20:51:52 +000089
90 id<P0> p1 = 0;
91 p1 = 0;
Douglas Gregor7ca09762008-11-27 01:19:21 +000092}
Douglas Gregorc7887512008-12-19 19:13:09 +000093
94
95@class NSException;
96typedef struct {
97 void (*throw_exc)(id);
98}
99objc_exception_functions_t;
100
101void (*_NSExceptionRaiser(void))(NSException *) {
102 objc_exception_functions_t exc_funcs;
Douglas Gregora3998bd2010-12-02 21:47:04 +0000103 return exc_funcs.throw_exc; // expected-warning{{incompatible pointer types returning 'void (*)(id)' from a function with result type 'void (*)(NSException *)'}}
Douglas Gregorc7887512008-12-19 19:13:09 +0000104}
John McCallddb0ce72010-06-11 10:04:22 +0000105
106namespace test5 {
107 void foo(bool);
108 void foo(void *);
109
110 void test(id p) {
111 foo(p);
112 }
113}
John McCall6d09da02010-10-26 06:23:29 +0000114
115// rdar://problem/8592139
116namespace test6 {
Douglas Gregor395cc372011-01-31 18:51:41 +0000117 void foo(id); // expected-note{{candidate function}}
John McCall6d09da02010-10-26 06:23:29 +0000118 void foo(A*) __attribute__((unavailable)); // expected-note {{explicitly made unavailable}}
119
120 void test(B *b) {
Douglas Gregor395cc372011-01-31 18:51:41 +0000121 foo(b); // expected-error {{call to unavailable function 'foo'}}
John McCall6d09da02010-10-26 06:23:29 +0000122 }
123}
Douglas Gregorda80f742010-12-01 21:43:58 +0000124
125namespace rdar8714395 {
126 int &f(const void*);
127 float &f(const Foo*);
128
129 int &f2(const void*);
130 float &f2(Foo const* const *);
131
132 int &f3(const void*);
133 float &f3(Foo const**);
134
135 void g(Foo *p) {
136 float &fr = f(p);
137 float &fr2 = f2(&p);
138 int &ir = f3(&p);
139 }
140
141
142}
Douglas Gregor143c7ac2010-12-06 22:09:19 +0000143
144namespace rdar8734046 {
145 void f1(id);
146 void f2(id<P0>);
147 void g(const A *a) {
148 f1(a);
149 f2(a);
150 }
151}
Douglas Gregorf9af5242011-04-15 20:45:44 +0000152
153namespace PR9735 {
154 int &f3(const A*);
155 float &f3(const void*);
156
157 void test_f(B* b, const B* bc) {
158 int &ir1 = f3(b);
159 int &ir2 = f3(bc);
160 }
161}
Douglas Gregor0f7b3dc2011-04-27 00:01:52 +0000162
163@interface D : B
164@end
165
166namespace rdar9327203 {
167 int &f(void* const&, int);
168 float &f(void* const&, long);
169
170 void g(id x) {
171 int &fr = (f)(x, 0);
172 }
173}
Douglas Gregor7ab8ef92011-12-15 17:20:18 +0000174
175namespace class_id {
176 // it's okay to overload Class with id.
177 void f(Class) { }
178 void f(id) { }
179}