1// RUN: %clang_cc1 -triple x86_64-apple-darwin9.0.0 -fsyntax-only -verify %s
2// RUN: %clang_cc1 -D WARN_PARTIAL -Wpartial-availability -triple x86_64-apple-darwin9.0.0 -fsyntax-only -verify %s
3
4@protocol P
5- (void)proto_method __attribute__((availability(macosx,introduced=10.1,deprecated=10.2))); // expected-note 2 {{'proto_method' has been explicitly marked deprecated here}}
6
7#if defined(WARN_PARTIAL)
8// expected-note@+2 2 {{'partial_proto_method' has been marked as being introduced in macOS 10.8 here, but the deployment target is macOS 10.5.0}}
9#endif
10- (void)partial_proto_method __attribute__((availability(macosx,introduced=10.8)));
11@end
12
13@interface A <P>
14- (void)method __attribute__((availability(macosx,introduced=10.1,deprecated=10.2))); // expected-note {{'method' has been explicitly marked deprecated here}}
15#if defined(WARN_PARTIAL)
16// expected-note@+2 2 {{'partialMethod' has been marked as being introduced in macOS 10.8 here, but the deployment target is macOS 10.5.0}}
17#endif
18- (void)partialMethod __attribute__((availability(macosx,introduced=10.8)));
19
20- (void)overridden __attribute__((availability(macosx,introduced=10.3))); // expected-note{{overridden method is here}}
21- (void)overridden2 __attribute__((availability(macosx,introduced=10.3)));
22- (void)overridden3 __attribute__((availability(macosx,deprecated=10.3)));
23- (void)overridden4 __attribute__((availability(macosx,deprecated=10.3))); // expected-note{{overridden method is here}}
24- (void)overridden5 __attribute__((availability(macosx,unavailable)));
25- (void)overridden6 __attribute__((availability(macosx,introduced=10.3))); // expected-note{{overridden method is here}}
26- (void)unavailableMethod __attribute__((unavailable));
27@end
28
29// rdar://11475360
30@interface B : A
31- (void)method; // NOTE: we expect 'method' to *not* inherit availability.
32- (void)partialMethod; // Likewise.
33- (void)overridden __attribute__((availability(macosx,introduced=10.4))); // expected-warning{{overriding method introduced after overridden method on macOS (10.4 vs. 10.3)}}
34- (void)overridden2 __attribute__((availability(macosx,introduced=10.2)));
35- (void)overridden3 __attribute__((availability(macosx,deprecated=10.4)));
36- (void)overridden4 __attribute__((availability(macosx,deprecated=10.2))); // expected-warning{{overriding method deprecated before overridden method on macOS (10.3 vs. 10.2)}}
37- (void)overridden5 __attribute__((availability(macosx,introduced=10.3)));
38- (void)overridden6 __attribute__((availability(macosx,unavailable))); // expected-warning{{overriding method cannot be unavailable on macOS when its overridden method is available}}
39- (void)unavailableMethod; // does *not* inherit unavailability
40@end
41
42void f(A *a, B *b) {
43  [a method]; // expected-warning{{'method' is deprecated: first deprecated in macOS 10.2}}
44  [b method]; // no-warning
45  [a proto_method]; // expected-warning{{'proto_method' is deprecated: first deprecated in macOS 10.2}}
46  [b proto_method]; // expected-warning{{'proto_method' is deprecated: first deprecated in macOS 10.2}}
47
48#if defined(WARN_PARTIAL)
49  // expected-warning@+2 {{'partialMethod' is only available on macOS 10.8 or newer}} expected-note@+2 {{enclose 'partialMethod' in an @available check to silence this warning}}
50#endif
51  [a partialMethod];
52  [b partialMethod];  // no warning
53#if defined(WARN_PARTIAL)
54  // expected-warning@+2 {{'partial_proto_method' is only available on macOS 10.8 or newer}} expected-note@+2 {{enclose 'partial_proto_method' in an @available check to silence this warning}}
55#endif
56  [a partial_proto_method];
57#if defined(WARN_PARTIAL)
58  // expected-warning@+2 {{'partial_proto_method' is only available on macOS 10.8 or newer}} expected-note@+2 {{enclose 'partial_proto_method' in an @available check to silence this warning}}
59#endif
60  [b partial_proto_method];
61}
62
63@interface A (NewAPI)
64- (void)partialMethod;
65- (void)partial_proto_method;
66@end
67
68void f_after_redecl(A *a, B *b) {
69#ifdef WARN_PARTIAL
70  // expected-warning@+2{{'partialMethod' is only available on macOS 10.8 or newer}} expected-note@+2 {{@available}}
71#endif
72  [a partialMethod];
73  [b partialMethod]; // no warning
74  [a partial_proto_method]; // no warning
75  [b partial_proto_method]; // no warning
76}
77
78// Test case for <rdar://problem/11627873>.  Warn about
79// using a deprecated method when that method is re-implemented in a
80// subclass where the redeclared method is not deprecated.
81@interface C
82- (void) method __attribute__((availability(macosx,introduced=10.1,deprecated=10.2))); // expected-note {{'method' has been explicitly marked deprecated here}}
83@end
84
85@interface D : C
86- (void) method;
87@end
88
89@interface E : D
90- (void) method;
91@end
92
93@implementation D
94- (void) method {
95  [super method]; // expected-warning {{'method' is deprecated: first deprecated in macOS 10.2}}
96}
97@end
98
99@implementation E
100- (void) method {
101  [super method]; // no-warning
102}
103@end
104
105// rdar://18059669
106@class NSMutableArray;
107
108@interface NSDictionary
109+ (instancetype)dictionaryWithObjectsAndKeys:(id)firstObject, ... __attribute__((sentinel(0,1)));
110@end
111
112@class NSString;
113
114extern NSString *NSNibTopLevelObjects __attribute__((availability(macosx,introduced=10.0 ,deprecated=10.8,message="" )));
115id NSNibOwner, topNibObjects;
116
117@interface AppDelegate (SIEImport) // expected-error {{cannot find interface declaration for 'AppDelegate'}}
118
119-(void)__attribute__((ibaction))importFromSIE:(id)sender;
120
121@end
122
123@implementation AppDelegate (SIEImport) // expected-error {{cannot find interface declaration for 'AppDelegate'}}
124
125-(void)__attribute__((ibaction))importFromSIE:(id)sender {
126
127 NSMutableArray *topNibObjects;
128 NSDictionary *nibLoadDict = [NSDictionary dictionaryWithObjectsAndKeys:self, NSNibOwner, topNibObjects, NSNibTopLevelObjects, ((void *)0)];
129}
130
131@end
132
133@protocol PartialProt
134- (void)ppartialMethod __attribute__((availability(macosx,introduced=10.8)));
135+ (void)ppartialMethod __attribute__((availability(macosx,introduced=10.8)));
136@end
137
138@interface PartialI <PartialProt>
139#ifdef WARN_PARTIAL
140// expected-note@+3{{'partialMethod' has been marked as being introduced in macOS 10.8 here, but the deployment target is macOS 10.5.0}}
141// expected-note@+3{{'partialMethod' has been marked as being introduced in macOS 10.8 here, but the deployment target is macOS 10.5.0}}
142#endif
143- (void)partialMethod __attribute__((availability(macosx,introduced=10.8)));
144+ (void)partialMethod __attribute__((availability(macosx,introduced=10.8)));
145@end
146
147@interface PartialI ()
148- (void)ipartialMethod1 __attribute__((availability(macosx,introduced=10.8)));
149#if defined(WARN_PARTIAL)
150// expected-note@+2 {{'ipartialMethod2' has been marked as being introduced in macOS 10.8 here, but the deployment target is macOS 10.5.0}}
151#endif
152- (void)ipartialMethod2 __attribute__((availability(macosx,introduced=10.8)));
153+ (void)ipartialMethod1 __attribute__((availability(macosx,introduced=10.8)));
154#if defined(WARN_PARTIAL)
155// expected-note@+2 {{'ipartialMethod2' has been marked as being introduced in macOS 10.8 here, but the deployment target is macOS 10.5.0}}
156#endif
157+ (void)ipartialMethod2 __attribute__((availability(macosx,introduced=10.8)));
158@end
159
160@interface PartialI (Redecls)
161- (void)partialMethod;
162- (void)ipartialMethod1;
163- (void)ppartialMethod;
164+ (void)partialMethod;
165+ (void)ipartialMethod1;
166+ (void)ppartialMethod;
167@end
168
169void partialfun(PartialI* a) {
170#ifdef WARN_PARTIAL
171  // expected-warning@+2 {{'partialMethod' is only available on macOS 10.8 or newer}} expected-note@+2{{@available}}
172#endif
173  [a partialMethod];
174  [a ipartialMethod1]; // no warning
175#if defined(WARN_PARTIAL)
176  // expected-warning@+2 {{'ipartialMethod2' is only available on macOS 10.8 or newer}} expected-note@+2 {{enclose 'ipartialMethod2' in an @available check to silence this warning}}
177#endif
178  [a ipartialMethod2];
179  [a ppartialMethod]; // no warning
180#ifdef WARN_PARTIAL
181  // expected-warning@+2 {{'partialMethod' is only available on macOS 10.8 or newer}} expected-note@+2 {{@available}}
182#endif
183  [PartialI partialMethod];
184  [PartialI ipartialMethod1]; // no warning
185#if defined(WARN_PARTIAL)
186  // expected-warning@+2 {{'ipartialMethod2' is only available on macOS 10.8 or newer}} expected-note@+2 {{enclose 'ipartialMethod2' in an @available check to silence this warning}}
187#endif
188  [PartialI ipartialMethod2];
189  [PartialI ppartialMethod]; // no warning
190}
191
192#if defined(WARN_PARTIAL)
193// expected-note@+2 2 {{'PartialI2' has been marked as being introduced in macOS 10.8 here, but the deployment target is macOS 10.5.0}}
194#endif
195__attribute__((availability(macosx, introduced = 10.8))) @interface PartialI2
196@end
197
198#if defined(WARN_PARTIAL)
199// expected-warning@+2 {{'PartialI2' is only available on macOS 10.8 or newer}} expected-note@+2 {{annotate 'partialinter1' with an availability attribute to silence}}
200#endif
201void partialinter1(PartialI2* p) {
202}
203
204@class PartialI2;
205
206#ifdef WARN_PARTIAL
207// expected-warning@+2 {{'PartialI2' is only available on macOS 10.8 or newer}} expected-note@+2 {{annotate 'partialinter2' with an availability attribute to silence}}
208#endif
209void partialinter2(PartialI2* p) {
210}
211
212
213// Test that both the use of the 'typedef' and the enum constant
214// produces an error. rdar://problem/20903588
215#define UNAVAILABLE __attribute__((unavailable("not available")))
216
217typedef enum MyEnum : int MyEnum;
218enum MyEnum : int { // expected-note {{'MyEnum' has been explicitly marked unavailable here}}
219  MyEnum_Blah UNAVAILABLE, // expected-note {{'MyEnum_Blah' has been explicitly marked unavailable here}}
220} UNAVAILABLE;
221
222void use_myEnum() {
223  // expected-error@+2 {{'MyEnum' is unavailable: not available}}
224  // expected-error@+1 {{MyEnum_Blah' is unavailable: not available}}
225  MyEnum e = MyEnum_Blah;
226}
227
228// Test that the availability of (optional) protocol methods is not
229// inherited be implementations of those protocol methods.
230@protocol AvailabilityP2
231@optional
232-(void)methodA __attribute__((availability(macosx,introduced=10.1,deprecated=10.2))); // expected-note 4{{'methodA' has been explicitly marked deprecated here}} \
233// expected-note 2{{protocol method is here}}
234-(void)methodB __attribute__((unavailable)); // expected-note 4{{'methodB' has been explicitly marked unavailable here}}
235-(void)methodC;
236@end
237
238void testAvailabilityP2(id<AvailabilityP2> obj) {
239  [obj methodA]; // expected-warning{{'methodA' is deprecated: first deprecated in macOS 10.2}}
240  [obj methodB]; // expected-error{{'methodB' is unavailable}}
241}
242
243@interface ImplementsAvailabilityP2a <AvailabilityP2>
244-(void)methodA;
245-(void)methodB;
246@end
247
248void testImplementsAvailabilityP2a(ImplementsAvailabilityP2a *obj) {
249  [obj methodA]; // okay: availability not inherited
250  [obj methodB]; // okay: unavailability not inherited
251}
252
253__attribute__((objc_root_class))
254@interface ImplementsAvailabilityP2b <AvailabilityP2>
255@end
256
257@implementation ImplementsAvailabilityP2b
258-(void)methodA {
259  // Make sure we're not inheriting availability.
260  id<AvailabilityP2> obj = self;
261  [obj methodA]; // expected-warning{{'methodA' is deprecated: first deprecated in macOS 10.2}}
262  [obj methodB]; // expected-error{{'methodB' is unavailable}}
263}
264-(void)methodB {
265  // Make sure we're not inheriting unavailability.
266  id<AvailabilityP2> obj = self;
267  [obj methodA]; // expected-warning{{'methodA' is deprecated: first deprecated in macOS 10.2}}
268  [obj methodB]; // expected-error{{'methodB' is unavailable}}
269}
270
271@end
272
273void testImplementsAvailabilityP2b(ImplementsAvailabilityP2b *obj) {
274  // still get warnings/errors because we see the protocol version.
275
276  [obj methodA]; // expected-warning{{'methodA' is deprecated: first deprecated in macOS 10.2}}
277  [obj methodB]; // expected-error{{'methodB' is unavailable}}
278}
279
280__attribute__((objc_root_class))
281@interface ImplementsAvailabilityP2c <AvailabilityP2>
282-(void)methodA __attribute__((availability(macosx,introduced=10.2))); // expected-warning{{method introduced after the protocol method it implements on macOS (10.2 vs. 10.1)}}
283-(void)methodB __attribute__((unavailable));
284@end
285
286__attribute__((objc_root_class))
287@interface ImplementsAvailabilityP2d <AvailabilityP2>
288@end
289
290@implementation ImplementsAvailabilityP2d
291-(void)methodA __attribute__((availability(macosx,introduced=10.2))) // expected-warning{{method introduced after the protocol method it implements on macOS (10.2 vs. 10.1)}}
292{
293}
294-(void)methodB __attribute__((unavailable)) {
295}
296@end
297
298__attribute__((objc_root_class))
299@interface InheritUnavailableSuper
300-(void)method __attribute__((unavailable)); // expected-note{{'method' has been explicitly marked unavailable here}}
301@end
302
303@interface InheritUnavailableSub : InheritUnavailableSuper
304-(void)method;
305@end
306
307@implementation InheritUnavailableSub
308-(void)method {
309  InheritUnavailableSuper *obj = self;
310  [obj method]; // expected-error{{'method' is unavailable}}
311}
312@end
313
314#if defined(WARN_PARTIAL)
315
316int fn_10_5() __attribute__((availability(macosx, introduced=10.5)));
317int fn_10_7() __attribute__((availability(macosx, introduced=10.7))); // expected-note{{'fn_10_7' has been marked as being introduced in macOS 10.7 here, but the deployment target is macOS 10.5.0}}
318int fn_10_8() __attribute__((availability(macosx, introduced=10.8))) { // expected-note{{'fn_10_8' has been marked as being introduced in macOS 10.8 here, but the deployment target is macOS 10.5.0}}
319  return fn_10_7();
320}
321
322__attribute__((objc_root_class))
323@interface LookupAvailabilityBase
324-(void) method1;
325@end
326
327@implementation LookupAvailabilityBase
328-(void)method1 { fn_10_7(); } // expected-warning{{only available on macOS 10.7}} expected-note{{@available}}
329@end
330
331__attribute__((availability(macosx, introduced=10.7)))
332@interface LookupAvailability : LookupAvailabilityBase
333- (void)method2;
334- (void)method3;
335- (void)method4 __attribute__((availability(macosx, introduced=10.8)));
336@end
337
338@implementation LookupAvailability
339-(void)method2 { fn_10_7(); }
340-(void)method3 { fn_10_8(); } // expected-warning{{only available on macOS 10.8}} expected-note{{@available}}
341-(void)method4 { fn_10_8(); }
342@end
343
344int old_func() __attribute__((availability(macos, introduced=10.4))) {
345  fn_10_5();
346}
347
348#endif
349