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// rdar://16261494
244@class GEOPDAnalyticMetadata; // expected-note {{forward declaration of class here}}
245
246@implementation GEOPDAnalyticMetadata (PlaceCardExtras) // expected-error {{cannot find interface declaration for 'GEOPDAnalyticMetadata'}}
247- (instancetype)initInProcess
248{
249    return ((void*)0);
250}
251@end
252
253// rdar://16305460
254__attribute__((objc_root_class))
255@interface MyObject
256- (instancetype)initWithStuff:(id)stuff __attribute__((objc_designated_initializer));
257- (instancetype)init NS_UNAVAILABLE;
258@end
259
260@implementation MyObject
261- (instancetype)init
262{
263   return ((void*)0);
264}
265@end
266
267// rdar://16323233
268__attribute__((objc_root_class))
269@interface B4
270-(id)initB4 NS_DESIGNATED_INITIALIZER; // expected-note 4 {{method marked as designated initializer of the class here}}
271-(id)initNonDI;
272@end
273
274@interface rdar16323233 : B4
275-(id)initS4 NS_DESIGNATED_INITIALIZER;
276@end
277
278@implementation rdar16323233
279-(id)initS4 {
280    static id sSharedObject = (void*)0;
281    (void)^(void) {
282        sSharedObject = [super initB4];
283    };
284    return 0;
285}
286-(id)initB4 {
287   return [self initS4];
288}
289@end
290
291@interface S1B4 : B4
292@end
293@implementation S1B4
294-(id)initB4 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
295   return [super initNonDI]; // expected-warning {{designated initializer invoked a non-designated initializer}}
296}
297@end
298
299@interface S2B4 : B4
300-(id)initB4;
301@end
302@implementation S2B4
303-(id)initB4 { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
304   return [super initNonDI]; // expected-warning {{designated initializer invoked a non-designated initializer}}
305}
306@end
307
308@interface S3B4 : B4
309@end
310@implementation S3B4
311-(id)initNew {
312  return [super initB4];
313}
314-(id)initB4 {
315   return [self initNew];
316}
317@end
318
319@interface S4B4 : B4
320-(id)initNew;
321@end
322@implementation S4B4
323-(id)initNew {
324  return [super initB4];
325}
326-(id)initB4 {
327   return [self initNew];
328}
329@end
330
331@interface S5B4 : B4
332-(id)initB4;
333@end
334@implementation S5B4
335-(id)initNew {
336  return [super initB4];
337}
338-(id)initB4 {
339   return [self initNew];
340}
341@end
342
343@interface S6B4 : B4
344-(id)initNew;
345-(id)initB4;
346@end
347@implementation S6B4
348-(id)initNew {
349  return [super initB4];
350}
351-(id)initB4 {
352   return [self initNew];
353}
354@end
355
356__attribute__((objc_root_class))
357@interface NSObject
358-(instancetype) init NS_DESIGNATED_INITIALIZER; // expected-note {{method marked as designated initializer of the class here}}
359@end
360
361@interface Test3 : NSObject
362@end
363
364@implementation Test3
365-(instancetype) initWithBasePath:(id)path {
366  return [super init];
367}
368-(instancetype) init {
369  return [self initWithBasePath:0];
370}
371@end
372
373@interface Test1 : NSObject
374-(instancetype) init NS_DESIGNATED_INITIALIZER;
375@end
376@implementation Test1
377-(instancetype) init {
378  return self;
379}
380@end
381
382@interface SubTest1 : Test1
383-(instancetype)init NS_UNAVAILABLE;
384-(instancetype)initWithRequiredParameter:(id)foo NS_DESIGNATED_INITIALIZER;
385@end
386@implementation SubTest1
387-(instancetype)initWithRequiredParameter:(id)foo {
388  return [super init];
389}
390@end
391
392@interface SubTest1Ext : Test1
393-(instancetype)initWithRequiredParameter:(id)foo NS_DESIGNATED_INITIALIZER;
394@end
395// Mark 'init' as unavailable in the extension to silence warning.
396@interface SubTest1Ext()
397-(instancetype)init NS_UNAVAILABLE;
398@end
399@implementation SubTest1Ext
400-(instancetype)initWithRequiredParameter:(id)foo {
401  return [super init];
402}
403@end
404
405@interface Test2 : NSObject
406@end
407@interface SubTest2 : Test2
408@end
409@implementation SubTest2
410-(instancetype) init { // expected-warning {{designated initializer missing a 'super' call to a designated initializer of the super class}}
411  return self;
412}
413@end
414
415__attribute__((objc_root_class))
416@interface RootNoDI
417-(id)init;
418@end
419
420@interface Base : RootNoDI
421@end
422
423@implementation Base
424@end
425
426@interface Derived : Base
427- (instancetype)initWithInt:(int)n NS_DESIGNATED_INITIALIZER;
428@end
429
430@implementation Derived
431- (instancetype)initWithInt:(int)n
432{
433  return [super init];
434}
435@end
436
437@interface ExtensionForMissingInterface() // expected-error{{cannot find interface declaration}}
438- (instancetype)init NS_DESIGNATED_INITIALIZER;
439@end
440
441@interface CategoryForMissingInterface(Cat) // expected-error{{cannot find interface declaration}}
442- (instancetype)init NS_DESIGNATED_INITIALIZER; // expected-error{{only applies to init methods of interface or class extension declarations}}
443@end
444
445@interface TwoAttrs
446-(instancetype)foo
447    __attribute__((objc_designated_initializer))
448    __attribute__((objc_method_family(init)));
449-(instancetype)bar
450    __attribute__((objc_method_family(init)))
451    __attribute__((objc_designated_initializer));
452-(instancetype)baz
453  __attribute__((objc_designated_initializer, objc_method_family(init)));
454-(instancetype)quux
455  __attribute__((objc_method_family(init), objc_designated_initializer));
456@end
457