1/* Check Class <protocol> types */
2/* Author: David Ayers <d.ayers@inode.at> */
3/* { dg-do compile } */
4
5#include <objc/objc.h>
6#include "../objc-obj-c++-shared/runtime.h"
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
45Class cls = 0;
46Class <MyProto1> clsP1 = 0;
47Class <MyProto2> clsP2 = 0;
48
49void
50testSimple(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
101void
102testCategory(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
139Class <MyProto5> clsP5 = 0;
140Class <MyProto6> clsP6 = 0;
141
142void
143testCategoryInherited(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
178@interface MyClass1 (Forward) <FwProto> /* { dg-warning "definition of protocol .FwProto. not found" } */
179@end
180
181Class <FwProto> clsP7 = 0;
182
183void
184testForwardeDeclared1(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" } */
190  /* { dg-warning "no .\\+doItClass7. method found" "" { target *-*-* } .-1 } */
191  [clsP7 doItInstance7];    /* { dg-warning "not found in protocol" } */
192  /* { dg-warning "no .\\+doItInstance7. method found" "" { target *-*-* } .-1 } */
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
207void
208testForwardeDeclared2(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
239Class <MyProto8> clsP8 = 0;
240Class <MyProto9> clsP9 = 0;
241
242void
243testInheritedNonRoot(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
282Class <MyOtherProto1> oclsP1;
283
284void
285testPrototypeMismatch(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
294id obj = nil;
295id <MyProto1> objP1 = nil;
296id <MyProto2> objP2 = nil;
297id <MyProto5> objP5 = nil;
298int num = 0;
299void *ptr = 0;
300
301MyClass1 *mc1 = nil;
302
303void
304testComptypes(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;
316
317    mc1 == objP2; /* { dg-warning "lacks a cast" } */
318    objP2 == mc1; /* { dg-warning "lacks a cast" } */
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-error "between pointer" } */
330    objP1 == num; /* { dg-error "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-error "between pointer" } */
356    clsP1 == num; /* { dg-error "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 *  */
374    mc1 = objP1;
375    objP1 = mc1;
376
377    mc1 = objP2; /* { dg-warning "does not conform" } */
378    objP2 = mc1; /* { dg-warning "does not implement" } */
379  }
380  { /* id <protocol>, id  */
381    obj = objP1;
382    objP1 = obj;
383  }
384  { /* id <protocol>, Class  */
385    cls = objP1; /* { dg-warning "distinct Objective\\-C type" } */
386    objP1 = cls; /* { dg-warning "distinct Objective\\-C type" } */
387  }
388  { /* id <protocol>, non-ObjC  */
389    num = objP1; /* { dg-error "invalid conversion" } */
390    objP1 = num; /* { dg-error "invalid conversion" } */
391
392    ptr = objP1;
393    objP1 = ptr; /* { dg-error "invalid conversion" } */
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.  */
404    mc1 = clsP1; /* { dg-warning "distinct Objective\\-C type" } */
405    clsP1 = mc1; /* { dg-warning "distinct Objective\\-C type" } */
406
407    mc1 = clsP2; /* { dg-warning "distinct Objective\\-C type" } */
408    clsP2 = mc1; /* { dg-warning "distinct Objective\\-C type" } */
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-error "invalid conversion" } */
420    clsP1 = num; /* { dg-error "invalid conversion" } */
421
422    ptr = clsP1;
423    clsP1 = ptr; /* { dg-error "invalid conversion" } */
424  }
425  { /* Class <protocol>, id <protocol> */
426    clsP1 = objP1; /* { dg-warning "distinct Objective\\-C type" } */
427    objP1 = clsP1; /* { dg-warning "distinct Objective\\-C type" } */
428  }
429}
430
431int main ()
432{
433  testSimple();
434  testCategory();
435  testCategoryInherited();
436  return(0);
437}
438
439/* { dg-warning "Messages without a matching method signature" "" { target *-*-* } 0 } */
440/* { dg-warning "will be assumed to return .id. and accept" "" { target *-*-* } 0 } */
441/* { dg-warning ".\.\.\.. as arguments" "" { target *-*-* } 0 } */
442