xref: /llvm-project/clang/test/SemaObjC/attr-designated-init.m (revision 0f1c1be1968076d6f96f8a7bcc4a15cf195ecd97)
1// RUN: %clang_cc1 -fsyntax-only -Wno-incomplete-implementation -verify -fblocks %s
2
3#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
4#define NS_UNAVAILABLE __attribute__((unavailable))
5
6void fnfoo(void) NS_DESIGNATED_INITIALIZER; // expected-error {{'objc_designated_initializer' attribute only applies to Objective-C methods}}
7
8@protocol P1
9-(id)init NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface or class extension declarations}}
10@end
11
12__attribute__((objc_root_class))
13@interface I1
14-(void)meth NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface or class extension declarations}}
15-(id)init NS_DESIGNATED_INITIALIZER;
16+(id)init NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface or class extension declarations}}
17@end
18
19@interface I1(cat)
20-(id)init2 NS_DESIGNATED_INITIALIZER; // expected-error {{only applies to init methods of interface or class extension declarations}}
21@end
22
23@interface I1()
24-(id)init3 NS_DESIGNATED_INITIALIZER;
25@end
26
27@implementation I1
28-(void)meth {}
29-(id)init NS_DESIGNATED_INITIALIZER { return 0; } // expected-error {{only applies to init methods of interface or class extension declarations}}
30+(id)init { return 0; }
31-(id)init3 { return 0; }
32-(id)init4 NS_DESIGNATED_INITIALIZER { return 0; } // expected-error {{only applies to init methods of interface or class extension declarations}} \
33									 			   // expected-warning {{convenience initializer missing a 'self' call to another initializer}}
34@end
35
36__attribute__((objc_root_class))
37@interface B1
38-(id)initB1 NS_DESIGNATED_INITIALIZER; // expected-note 6 {{method marked as designated initializer of the class here}}
39-(id)initB2;
40@end
41
42@interface B1()
43-(id)initB3 NS_DESIGNATED_INITIALIZER; // expected-note 4 {{method marked as designated initializer of the class here}}
44@end;
45
46@implementation B1
47-(id)initB1 { return 0; }
48-(id)initB2 { return 0; } // expected-warning {{convenience initializer missing a 'self' call to another initializer}}
49-(id)initB3 { return 0; }
50@end
51
52@interface S1 : B1
53-(id)initS1 NS_DESIGNATED_INITIALIZER; // expected-note {{method marked as designated initializer of the class here}}
54-(id)initS2 NS_DESIGNATED_INITIALIZER;
55-(id)initS3 NS_DESIGNATED_INITIALIZER; // expected-note 2 {{method marked as designated initializer of the class here}}
56-(id)initB1;
57@end
58
59@interface S1()
60-(id)initS4 NS_DESIGNATED_INITIALIZER; // expected-note 2 {{method marked as designated initializer of the class here}}
61@end
62
63@implementation S1
64-(id)initS1 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
65  return 0;
66}
67-(id)initS2 {
68  return [super initB1];
69}
70-(id)initS3 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
71  return [super initB2]; // expected-warning {{designated initializer invoked a non-designated initializer}}
72}
73-(id)initS4 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
74  return [self initB1]; // expected-warning {{designated initializer should only invoke a designated initializer on 'super'}}
75}
76-(id)initB1 {
77  return [self initS1];
78}
79-(id)initB3 {
80  return [self initS1];
81}
82@end
83
84@interface S2 : B1
85-(id)initB1;
86@end
87
88@interface SS2 : S2
89-(id)initSS1 NS_DESIGNATED_INITIALIZER;
90@end
91
92@implementation SS2 // expected-warning {{method override for the designated initializer of the superclass '-initB1' not found}} \
93                    // expected-warning {{method override for the designated initializer of the superclass '-initB3' not found}}
94-(id)initSS1 {
95  return [super initB1];
96}
97@end
98
99@interface S3 : B1
100-(id)initS1 NS_DESIGNATED_INITIALIZER; // expected-note {{method marked as designated initializer of the class here}}
101@end
102
103@interface SS3 : S3
104-(id)initSS1 NS_DESIGNATED_INITIALIZER; // expected-note 2 {{method marked as designated initializer of the class here}}
105@end
106
107@implementation SS3 // expected-warning {{method override for the designated initializer of the superclass '-initS1' not found}}
108-(id)initSS1 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
109  return [super initB1]; // expected-warning {{designated initializer invoked a non-designated initializer}}
110}
111@end
112
113@interface S4 : B1
114-(id)initB1;
115-(id)initB3;
116@end
117
118@implementation S4
119-(id)initB1 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
120  return 0;
121}
122-(id)initB3 {
123  return [super initB3];
124}
125@end
126
127@interface S5 : B1
128-(void)meth;
129@end
130
131@implementation S5
132-(id)initB1 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
133  return 0;
134}
135-(id)initB3 {
136  [self initB1]; // expected-warning {{designated initializer should only invoke a designated initializer on 'super'}}
137  S5 *s;
138  [s initB1];
139  [self meth];
140  void (^blk)(void) = ^{
141    [self initB1]; // expected-warning {{designated initializer should only invoke a designated initializer on 'super'}}
142  };
143  return [super initB3];
144}
145-(void)meth {}
146@end
147
148@interface S6 : B1
149-(id)initS1 NS_DESIGNATED_INITIALIZER;
150-(id)initS2;
151-(id)initS3;
152-(id)initS4;
153@end
154
155@implementation S6 // expected-warning {{method override for the designated initializer of the superclass '-initB1' not found}} \
156                   // expected-warning {{method override for the designated initializer of the superclass '-initB3' not found}}
157-(id)initS1 {
158  return [super initB1];
159}
160-(id)initS2 { // expected-warning {{convenience initializer missing a 'self' call to another initializer}}
161  return [super initB1]; // expected-warning {{convenience initializer should not invoke an initializer on 'super'}}
162}
163-(id)initS3 {
164  return [self initB1];
165}
166-(id)initS4 {
167  return [self initS1];
168}
169-(id)initS5 {
170  [super initB1]; // expected-warning {{convenience initializer should not invoke an initializer on 'super'}}
171  void (^blk)(void) = ^{
172    [super initB1]; // expected-warning {{convenience initializer should not invoke an initializer on 'super'}}
173  };
174  return [self initS1];
175}
176-(id)initS6 { // expected-warning {{convenience initializer missing a 'self' call to another initializer}}
177  S6 *s;
178  return [s initS1];
179}
180@end
181
182@interface SS4 : S4
183-(id)initB1;
184@end
185
186@implementation SS4
187-(id)initB1 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
188  return 0;
189}
190@end
191
192@interface S7 : B1
193-(id)initB1;
194-(id)initB3;
195-(id)initNewOne;
196@end
197
198@interface SS7 : S7
199-(id)initB1;
200@end
201
202@implementation SS7
203-(id)initB1 {
204  return 0;
205}
206@end
207
208__attribute__((objc_root_class))
209@interface B2
210-(id)init;
211@end
212
213@interface S8: B2
214-(id)initS8 NS_DESIGNATED_INITIALIZER;
215@end
216
217@implementation S8
218-(id)initS8
219{
220  return [super init];
221}
222@end
223
224@interface S9 : B1
225-(id)initB1;
226-(id)initB3;
227@end
228
229@interface S9(secondInit)
230-(id)initNewOne;
231@end
232
233@interface SS9 : S9
234-(id)initB1;
235@end
236
237@implementation SS9
238-(id)initB1 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
239  return 0;
240}
241@end
242
243@class GEOPDAnalyticMetadata; // expected-note {{forward declaration of class here}}
244
245@implementation GEOPDAnalyticMetadata (PlaceCardExtras) // expected-error {{cannot find interface declaration for 'GEOPDAnalyticMetadata'}}
246- (instancetype)initInProcess
247{
248    return ((void*)0);
249}
250@end
251
252__attribute__((objc_root_class))
253@interface MyObject
254- (instancetype)initWithStuff:(id)stuff __attribute__((objc_designated_initializer));
255- (instancetype)init NS_UNAVAILABLE;
256@end
257
258@implementation MyObject
259- (instancetype)init
260{
261   return ((void*)0);
262}
263@end
264
265__attribute__((objc_root_class))
266@interface B4
267-(id)initB4 NS_DESIGNATED_INITIALIZER; // expected-note 4 {{method marked as designated initializer of the class here}}
268-(id)initNonDI;
269@end
270
271@interface rdar16323233 : B4
272-(id)initS4 NS_DESIGNATED_INITIALIZER;
273@end
274
275@implementation rdar16323233
276-(id)initS4 {
277    static id sSharedObject = (void*)0;
278    (void)^(void) {
279        sSharedObject = [super initB4];
280    };
281    return 0;
282}
283-(id)initB4 {
284   return [self initS4];
285}
286@end
287
288@interface S1B4 : B4
289@end
290@implementation S1B4
291-(id)initB4 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
292   return [super initNonDI]; // expected-warning {{designated initializer invoked a non-designated initializer}}
293}
294@end
295
296@interface S2B4 : B4
297-(id)initB4;
298@end
299@implementation S2B4
300-(id)initB4 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
301   return [super initNonDI]; // expected-warning {{designated initializer invoked a non-designated initializer}}
302}
303@end
304
305@interface S3B4 : B4
306@end
307@implementation S3B4
308-(id)initNew {
309  return [super initB4];
310}
311-(id)initB4 {
312   return [self initNew];
313}
314@end
315
316@interface S4B4 : B4
317-(id)initNew;
318@end
319@implementation S4B4
320-(id)initNew {
321  return [super initB4];
322}
323-(id)initB4 {
324   return [self initNew];
325}
326@end
327
328@interface S5B4 : B4
329-(id)initB4;
330@end
331@implementation S5B4
332-(id)initNew {
333  return [super initB4];
334}
335-(id)initB4 {
336   return [self initNew];
337}
338@end
339
340@interface S6B4 : B4
341-(id)initNew;
342-(id)initB4;
343@end
344@implementation S6B4
345-(id)initNew {
346  return [super initB4];
347}
348-(id)initB4 {
349   return [self initNew];
350}
351@end
352
353__attribute__((objc_root_class))
354@interface NSObject
355-(instancetype) init NS_DESIGNATED_INITIALIZER; // expected-note {{method marked as designated initializer of the class here}}
356@end
357
358@interface Test3 : NSObject
359@end
360
361@implementation Test3
362-(instancetype) initWithBasePath:(id)path {
363  return [super init];
364}
365-(instancetype) init {
366  return [self initWithBasePath:0];
367}
368@end
369
370@interface Test1 : NSObject
371-(instancetype) init NS_DESIGNATED_INITIALIZER;
372@end
373@implementation Test1
374-(instancetype) init {
375  return self;
376}
377@end
378
379@interface SubTest1 : Test1
380-(instancetype)init NS_UNAVAILABLE;
381-(instancetype)initWithRequiredParameter:(id)foo NS_DESIGNATED_INITIALIZER;
382@end
383@implementation SubTest1
384-(instancetype)initWithRequiredParameter:(id)foo {
385  return [super init];
386}
387@end
388
389@interface SubTest1Ext : Test1
390-(instancetype)initWithRequiredParameter:(id)foo NS_DESIGNATED_INITIALIZER;
391@end
392// Mark 'init' as unavailable in the extension to silence warning.
393@interface SubTest1Ext()
394-(instancetype)init NS_UNAVAILABLE;
395@end
396@implementation SubTest1Ext
397-(instancetype)initWithRequiredParameter:(id)foo {
398  return [super init];
399}
400@end
401
402@interface Test2 : NSObject
403@end
404@interface SubTest2 : Test2
405@end
406@implementation SubTest2
407-(instancetype) init { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
408  return self;
409}
410@end
411
412__attribute__((objc_root_class))
413@interface RootNoDI
414-(id)init;
415@end
416
417@interface Base : RootNoDI
418@end
419
420@implementation Base
421@end
422
423@interface Derived : Base
424- (instancetype)initWithInt:(int)n NS_DESIGNATED_INITIALIZER;
425@end
426
427@implementation Derived
428- (instancetype)initWithInt:(int)n
429{
430  return [super init];
431}
432@end
433
434@interface ExtensionForMissingInterface() // expected-error{{cannot find interface declaration}}
435- (instancetype)init NS_DESIGNATED_INITIALIZER;
436@end
437
438@interface CategoryForMissingInterface(Cat) // expected-error{{cannot find interface declaration}}
439- (instancetype)init NS_DESIGNATED_INITIALIZER; // expected-error{{only applies to init methods of interface or class extension declarations}}
440@end
441
442@interface TwoAttrs
443-(instancetype)foo
444    __attribute__((objc_designated_initializer))
445    __attribute__((objc_method_family(init)));
446-(instancetype)bar
447    __attribute__((objc_method_family(init)))
448    __attribute__((objc_designated_initializer));
449-(instancetype)baz
450  __attribute__((objc_designated_initializer, objc_method_family(init)));
451-(instancetype)quux
452  __attribute__((objc_method_family(init), objc_designated_initializer));
453@end
454