]>
Commit | Line | Data |
---|---|---|
9e8a7e85 | 1 | /* Check Class <protocol> types */ |
2 | /* Author: David Ayers <d.ayers@inode.at> */ | |
3 | /* { dg-do compile } */ | |
4 | ||
5 | #include <objc/objc.h> | |
5bceb3cd | 6 | #include "../objc-obj-c++-shared/runtime.h" |
9e8a7e85 | 7 | |
8 | @protocol MyProto1 | |
9 | +(void)doItClass1; | |
10 | -(void)doItInstance1; | |
11 | @end | |
12 | ||
13 | @protocol MyProto2 | |
14 | +(void)doItClass2; | |
15 | -(void)doItInstance2; | |
16 | @end | |
17 | ||
18 | @interface MyClass1 <MyProto1> | |
19 | { | |
20 | Class isa; | |
21 | } | |
22 | @end | |
23 | @implementation MyClass1 | |
24 | +(void)doItClass1{} | |
25 | -(void)doItInstance1{} | |
26 | @end | |
27 | ||
28 | @interface MyClass2 : MyClass1 <MyProto2> | |
29 | @end | |
30 | @implementation MyClass2 | |
31 | +(void)doItClass2{} | |
32 | -(void)doItInstance2{} | |
33 | @end | |
34 | ||
35 | @interface MyClass3 | |
36 | { | |
37 | Class isa; | |
38 | } | |
39 | @end | |
40 | @interface MyClass4 : MyClass3 <MyProto1> | |
41 | @end | |
42 | ||
43 | /*----------------------------------------*/ | |
44 | ||
45 | Class cls = 0; | |
46 | Class <MyProto1> clsP1 = 0; | |
47 | Class <MyProto2> clsP2 = 0; | |
48 | ||
49 | void | |
50 | testSimple(void) | |
51 | { | |
52 | [cls doItClass1]; | |
53 | [cls doItInstance1]; | |
54 | [cls doItClass2]; | |
55 | [cls doItInstance2]; | |
56 | ||
57 | [clsP1 doItClass1]; | |
58 | [clsP1 doItInstance1]; /* { dg-warning "instead of" } */ | |
59 | [clsP1 doItClass2]; /* { dg-warning "not found in protocol" } */ | |
60 | [clsP1 doItInstance2]; /* { dg-warning "not found in protocol" } */ | |
61 | ||
62 | [clsP2 doItClass1]; /* { dg-warning "not found in protocol" } */ | |
63 | [clsP2 doItInstance1]; /* { dg-warning "not found in protocol" } */ | |
64 | [clsP2 doItClass2]; | |
65 | [clsP2 doItInstance2]; /* { dg-warning "instead of" } */ | |
66 | ||
67 | [MyClass1 doItClass1]; | |
68 | [MyClass1 doItInstance1]; | |
69 | [MyClass1 doItClass2]; /* { dg-warning "may not respond to" } */ | |
70 | [MyClass1 doItInstance2]; /* { dg-warning "may not respond to" } */ | |
71 | ||
72 | [MyClass2 doItClass1]; | |
73 | [MyClass2 doItInstance1]; | |
74 | [MyClass2 doItClass2]; | |
75 | [MyClass2 doItInstance2]; /* { dg-warning "may not respond to" } */ | |
76 | ||
77 | [MyClass3 doItClass1]; /* { dg-warning "may not respond to" } */ | |
78 | [MyClass3 doItInstance1]; /* { dg-warning "may not respond to" } */ | |
79 | ||
80 | [MyClass4 doItClass1]; | |
81 | [MyClass4 doItInstance1]; /* { dg-warning "may not respond to" } */ | |
82 | } | |
83 | ||
84 | /*----------------------------------------*/ | |
85 | /* Protocols declared by categories */ | |
86 | ||
87 | @protocol MyProto3 | |
88 | +(void)doItClass3; | |
89 | -(void)doItInstance3; | |
90 | @end | |
91 | @protocol MyProto4 | |
92 | +(void)doItClass4; | |
93 | -(void)doItInstance4; | |
94 | @end | |
95 | ||
96 | @interface MyClass1 (Category1) <MyProto3> | |
97 | @end | |
98 | @interface MyClass2 (Category2) <MyProto4> | |
99 | @end | |
100 | ||
101 | void | |
102 | testCategory(void) | |
103 | { | |
104 | [cls doItClass3]; | |
105 | [cls doItInstance3]; | |
106 | [cls doItClass4]; | |
107 | [cls doItInstance4]; | |
108 | ||
109 | [MyClass1 doItClass3]; | |
110 | [MyClass1 doItInstance3]; | |
111 | [MyClass1 doItClass4]; /* { dg-warning "may not respond" } */ | |
112 | [MyClass1 doItInstance4]; /* { dg-warning "may not respond" } */ | |
113 | ||
114 | [MyClass2 doItClass3]; | |
115 | [MyClass2 doItInstance3]; | |
116 | [MyClass2 doItClass4]; | |
117 | [MyClass2 doItInstance4]; /* { dg-warning "may not respond" } */ | |
118 | ||
119 | } | |
120 | ||
121 | /*----------------------------------------*/ | |
122 | /* Inherited protocols declared by categories */ | |
123 | ||
124 | @protocol MyProto5 <MyProto1> | |
125 | +(void)doItClass5; | |
126 | -(void)doItInstance5; | |
127 | @end | |
128 | ||
129 | @protocol MyProto6 <MyProto2> | |
130 | +(void)doItClass6; | |
131 | -(void)doItInstance6; | |
132 | @end | |
133 | ||
134 | @interface MyClass1 (Category3) <MyProto5> | |
135 | @end | |
136 | @interface MyClass2 (Category4) <MyProto6> | |
137 | @end | |
138 | ||
139 | Class <MyProto5> clsP5 = 0; | |
140 | Class <MyProto6> clsP6 = 0; | |
141 | ||
142 | void | |
143 | testCategoryInherited(void) | |
144 | { | |
145 | [cls doItClass5]; | |
146 | [cls doItInstance5]; | |
147 | [cls doItClass6]; | |
148 | [cls doItInstance6]; | |
149 | ||
150 | [clsP5 doItClass1]; | |
151 | [clsP5 doItInstance1]; /* { dg-warning "instead of" } */ | |
152 | [clsP5 doItClass2]; /* { dg-warning "not found in protocol" } */ | |
153 | [clsP5 doItInstance2]; /* { dg-warning "not found in protocol" } */ | |
154 | ||
155 | [clsP6 doItClass1]; /* { dg-warning "not found in protocol" } */ | |
156 | [clsP6 doItInstance1]; /* { dg-warning "not found in protocol" } */ | |
157 | [clsP6 doItClass2]; | |
158 | [clsP6 doItInstance2]; /* { dg-warning "instead of" } */ | |
159 | ||
160 | ||
161 | [MyClass1 doItClass5]; | |
162 | [MyClass1 doItInstance5]; | |
163 | [MyClass1 doItClass6]; /* { dg-warning "may not respond" } */ | |
164 | [MyClass1 doItInstance6]; /* { dg-warning "may not respond" } */ | |
165 | ||
166 | [MyClass2 doItClass5]; | |
167 | [MyClass2 doItInstance5]; | |
168 | [MyClass2 doItClass6]; | |
169 | [MyClass2 doItInstance6]; /* { dg-warning "may not respond" } */ | |
170 | ||
171 | } | |
172 | ||
173 | /*----------------------------------------*/ | |
174 | /* Forward declared root protocols */ | |
175 | ||
176 | @protocol FwProto; | |
177 | ||
89e83a91 | 178 | @interface MyClass1 (Forward) <FwProto> /* { dg-warning "definition of protocol .FwProto. not found" } */ |
9e8a7e85 | 179 | @end |
180 | ||
181 | Class <FwProto> clsP7 = 0; | |
182 | ||
183 | void | |
184 | testForwardeDeclared1(void) | |
185 | { | |
186 | [cls doItClass7]; /* { dg-warning "no .\\+doItClass7. method found" } */ | |
187 | [cls doItInstance7]; /* { dg-warning "no .\\+doItInstance7. method found" } */ | |
188 | ||
189 | [clsP7 doItClass7]; /* { dg-warning "not found in protocol" } */ | |
f0ca6e0d | 190 | /* { dg-warning "no .\\+doItClass7. method found" "" { target *-*-* } .-1 } */ |
9e8a7e85 | 191 | [clsP7 doItInstance7]; /* { dg-warning "not found in protocol" } */ |
f0ca6e0d | 192 | /* { dg-warning "no .\\+doItInstance7. method found" "" { target *-*-* } .-1 } */ |
9e8a7e85 | 193 | |
194 | [MyClass1 doItClass7]; /* { dg-warning "may not respond" } */ | |
195 | [MyClass1 doItInstance7]; /* { dg-warning "may not respond" } */ | |
196 | ||
197 | [MyClass2 doItClass7]; /* { dg-warning "may not respond" } */ | |
198 | [MyClass2 doItInstance7]; /* { dg-warning "may not respond" } */ | |
199 | ||
200 | } | |
201 | ||
202 | @protocol FwProto | |
203 | +(void)doItClass7; | |
204 | -(void)doItInstance7; | |
205 | @end | |
206 | ||
207 | void | |
208 | testForwardeDeclared2(void) | |
209 | { | |
210 | [cls doItClass7]; | |
211 | [cls doItInstance7]; | |
212 | ||
213 | [clsP7 doItClass7]; | |
214 | [clsP7 doItInstance7]; /* { dg-warning "instead of" } */ | |
215 | ||
216 | [MyClass1 doItClass7]; | |
217 | [MyClass1 doItInstance7]; | |
218 | ||
219 | [MyClass2 doItClass7]; | |
220 | [MyClass2 doItInstance7]; | |
221 | } | |
222 | ||
223 | /*----------------------------------------*/ | |
224 | /* Inherited non root protocols */ | |
225 | ||
226 | @protocol MyProto8 | |
227 | +(void)doItClass8; | |
228 | -(void)doItInstance8; | |
229 | @end | |
230 | ||
231 | @protocol MyProto9 <MyProto8> | |
232 | +(void)doItClass9; | |
233 | -(void)doItInstance9; | |
234 | @end | |
235 | ||
236 | @interface MyClass1 (InheritedNonRoot) <MyProto9> | |
237 | @end | |
238 | ||
239 | Class <MyProto8> clsP8 = 0; | |
240 | Class <MyProto9> clsP9 = 0; | |
241 | ||
242 | void | |
243 | testInheritedNonRoot(void) | |
244 | { | |
245 | [cls doItClass8]; | |
246 | [cls doItInstance8]; | |
247 | [cls doItClass9]; | |
248 | [cls doItInstance9]; | |
249 | ||
250 | [clsP8 doItClass8]; | |
251 | [clsP8 doItInstance8]; /* { dg-warning "instead of" } */ | |
252 | [clsP8 doItClass9]; /* { dg-warning "not found in protocol" } */ | |
253 | [clsP8 doItInstance9]; /* { dg-warning "not found in protocol" } */ | |
254 | ||
255 | [clsP9 doItClass8]; | |
256 | [clsP9 doItInstance8]; /* { dg-warning "instead of" } */ | |
257 | [clsP9 doItClass9]; | |
258 | [clsP9 doItInstance9]; /* { dg-warning "instead of" } */ | |
259 | ||
260 | [MyClass1 doItClass8]; | |
261 | [MyClass1 doItInstance8]; | |
262 | [MyClass1 doItClass9]; | |
263 | [MyClass1 doItInstance9]; | |
264 | ||
265 | [MyClass2 doItClass8]; | |
266 | [MyClass2 doItInstance8]; | |
267 | [MyClass2 doItClass9]; | |
268 | [MyClass2 doItInstance9]; | |
269 | ||
270 | } | |
271 | ||
272 | /*----------------------------------------*/ | |
273 | /* Prototype mismatch */ | |
274 | ||
275 | @protocol MyOtherProto1 | |
276 | +(id)doItClass1; | |
277 | -(id)doItInstance1; | |
278 | @end | |
279 | @interface MyOtherClass1 <MyOtherProto1> | |
280 | @end | |
281 | ||
282 | Class <MyOtherProto1> oclsP1; | |
283 | ||
284 | void | |
285 | testPrototypeMismatch(void) | |
286 | { | |
287 | id tmp1 = [oclsP1 doItClass1]; | |
288 | id tmp2 = [oclsP1 doItInstance1]; /* { dg-warning "instead of" } */ | |
289 | ||
290 | [clsP1 doItClass1]; | |
291 | [clsP1 doItInstance1]; /* { dg-warning "instead of" } */ | |
292 | } | |
293 | ||
294 | id obj = nil; | |
295 | id <MyProto1> objP1 = nil; | |
296 | id <MyProto2> objP2 = nil; | |
297 | id <MyProto5> objP5 = nil; | |
298 | int num = 0; | |
299 | void *ptr = 0; | |
300 | ||
301 | MyClass1 *mc1 = nil; | |
302 | ||
303 | void | |
304 | testComptypes(void) | |
305 | { | |
306 | { /* id <protocol>, id <protocol> */ | |
307 | objP1 == objP2; /* { dg-warning "lacks a cast" } */ | |
308 | objP2 == objP1; /* { dg-warning "lacks a cast" } */ | |
309 | ||
310 | objP1 == objP5; | |
311 | objP5 == objP1; | |
312 | } | |
313 | { /* id <protocol>, SomeClass * */ | |
314 | mc1 == objP1; | |
315 | objP1 == mc1; | |
60e21b9a | 316 | |
317 | mc1 == objP2; /* { dg-warning "lacks a cast" } */ | |
318 | objP2 == mc1; /* { dg-warning "lacks a cast" } */ | |
9e8a7e85 | 319 | } |
320 | { /* id <protocol>, id */ | |
321 | obj == objP1; | |
322 | objP1 == obj; | |
323 | } | |
324 | { /* id <protocol>, Class */ | |
325 | cls == objP1; /* { dg-warning "lacks a cast" } */ | |
326 | objP1 == cls; /* { dg-warning "lacks a cast" } */ | |
327 | } | |
328 | { /* id <protocol>, non-ObjC */ | |
329 | num == objP1; /* { dg-warning "between pointer" } */ | |
330 | objP1 == num; /* { dg-warning "between pointer" } */ | |
331 | ||
332 | ptr == objP1; | |
333 | objP1 == ptr; | |
334 | } | |
335 | { /* Class <protocol>, Class <protocol> */ | |
336 | clsP1 == clsP2; /* { dg-warning "lacks a cast" } */ | |
337 | clsP2 == clsP1; /* { dg-warning "lacks a cast" } */ | |
338 | ||
339 | clsP1 == clsP5; | |
340 | clsP5 == clsP1; | |
341 | } | |
342 | { /* Class <protocol>, SomeClass * */ | |
343 | mc1 == clsP1; /* { dg-warning "lacks a cast" } */ | |
344 | clsP1 == mc1; /* { dg-warning "lacks a cast" } */ | |
345 | } | |
346 | { /* Class <protocol>, id */ | |
347 | obj == clsP1; | |
348 | clsP1 == obj; | |
349 | } | |
350 | { /* Class <protocol>, Class */ | |
351 | cls == clsP1; | |
352 | clsP1 == cls; | |
353 | } | |
354 | { /* Class <protocol>, non-ObjC */ | |
355 | num == clsP1; /* { dg-warning "between pointer" } */ | |
356 | clsP1 == num; /* { dg-warning "between pointer" } */ | |
357 | ||
358 | ptr == clsP1; | |
359 | clsP1 == ptr; | |
360 | } | |
361 | { /* Class <protocol>, id <protocol> */ | |
362 | clsP1 == objP1; /* { dg-warning "lacks a cast" } */ | |
363 | objP1 == clsP1; /* { dg-warning "lacks a cast" } */ | |
364 | } | |
365 | ||
366 | { /* id <protocol>, id <protocol> */ | |
367 | objP1 = objP2; /* { dg-warning "does not conform" } */ | |
368 | objP2 = objP1; /* { dg-warning "does not conform" } */ | |
369 | ||
370 | objP1 = objP5; | |
371 | objP5 = objP1; /* { dg-warning "does not conform" } */ | |
372 | } | |
373 | { /* id <protocol>, SomeClass * */ | |
60e21b9a | 374 | mc1 = objP1; |
9e8a7e85 | 375 | objP1 = mc1; |
60e21b9a | 376 | |
377 | mc1 = objP2; /* { dg-warning "does not conform" } */ | |
9e8a7e85 | 378 | objP2 = mc1; /* { dg-warning "does not implement" } */ |
379 | } | |
380 | { /* id <protocol>, id */ | |
381 | obj = objP1; | |
382 | objP1 = obj; | |
383 | } | |
384 | { /* id <protocol>, Class */ | |
60e21b9a | 385 | cls = objP1; /* { dg-warning "distinct Objective\\-C type" } */ |
386 | objP1 = cls; /* { dg-warning "distinct Objective\\-C type" } */ | |
9e8a7e85 | 387 | } |
388 | { /* id <protocol>, non-ObjC */ | |
389 | num = objP1; /* { dg-warning "makes integer" } */ | |
390 | objP1 = num; /* { dg-warning "makes pointer" } */ | |
391 | ||
392 | ptr = objP1; | |
393 | objP1 = ptr; | |
394 | } | |
395 | { /* Class <protocol>, Class <protocol> */ | |
396 | clsP1 = clsP2; /* { dg-warning "does not conform" } */ | |
397 | clsP2 = clsP1; /* { dg-warning "does not conform" } */ | |
398 | ||
399 | clsP1 = clsP5; | |
400 | clsP5 = clsP1; /* { dg-warning "does not conform" } */ | |
401 | } | |
402 | { /* Class <protocol>, SomeClass * */ | |
403 | /* These combinations should always elicit a warning. */ | |
60e21b9a | 404 | mc1 = clsP1; /* { dg-warning "distinct Objective\\-C type" } */ |
405 | clsP1 = mc1; /* { dg-warning "distinct Objective\\-C type" } */ | |
9e8a7e85 | 406 | |
60e21b9a | 407 | mc1 = clsP2; /* { dg-warning "distinct Objective\\-C type" } */ |
408 | clsP2 = mc1; /* { dg-warning "distinct Objective\\-C type" } */ | |
9e8a7e85 | 409 | } |
410 | { /* Class <protocol>, id */ | |
411 | obj = clsP1; | |
412 | clsP1 = obj; | |
413 | } | |
414 | { /* Class <protocol>, Class */ | |
415 | cls = clsP1; | |
416 | clsP1 = cls; | |
417 | } | |
418 | { /* Class <protocol>, non-ObjC */ | |
419 | num = clsP1; /* { dg-warning "makes integer" } */ | |
420 | clsP1 = num; /* { dg-warning "makes pointer" } */ | |
421 | ||
422 | ptr = clsP1; | |
423 | clsP1 = ptr; | |
424 | } | |
425 | { /* Class <protocol>, id <protocol> */ | |
60e21b9a | 426 | clsP1 = objP1; /* { dg-warning "distinct Objective\\-C type" } */ |
427 | objP1 = clsP1; /* { dg-warning "distinct Objective\\-C type" } */ | |
9e8a7e85 | 428 | } |
429 | } | |
430 | ||
431 | int main () | |
432 | { | |
433 | testSimple(); | |
434 | testCategory(); | |
435 | testCategoryInherited(); | |
436 | return(0); | |
437 | } | |
438 | ||
85b9be9b | 439 | /* { dg-warning "messages without a matching method signature will be assumed to return .id. and accept .\.\.\.. as arguments" "" { target *-*-* } 0 } */ |