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-(void)methodB __attribute__((unavailable)); // expected-note 4{{'methodB' has been explicitly marked unavailable here}}
234-(void)methodC;
235@end
236
237void testAvailabilityP2(id<AvailabilityP2> obj) {
238  [obj methodA]; // expected-warning{{'methodA' is deprecated: first deprecated in macOS 10.2}}
239  [obj methodB]; // expected-error{{'methodB' is unavailable}}
240}
241
242@interface ImplementsAvailabilityP2a <AvailabilityP2>
243-(void)methodA;
244-(void)methodB;
245@end
246
247void testImplementsAvailabilityP2a(ImplementsAvailabilityP2a *obj) {
248  [obj methodA]; // okay: availability not inherited
249  [obj methodB]; // okay: unavailability not inherited
250}
251
252__attribute__((objc_root_class))
253@interface ImplementsAvailabilityP2b <AvailabilityP2>
254@end
255
256@implementation ImplementsAvailabilityP2b
257-(void)methodA {
258  // Make sure we're not inheriting availability.
259  id<AvailabilityP2> obj = self;
260  [obj methodA]; // expected-warning{{'methodA' is deprecated: first deprecated in macOS 10.2}}
261  [obj methodB]; // expected-error{{'methodB' is unavailable}}
262}
263-(void)methodB {
264  // Make sure we're not inheriting unavailability.
265  id<AvailabilityP2> obj = self;
266  [obj methodA]; // expected-warning{{'methodA' is deprecated: first deprecated in macOS 10.2}}
267  [obj methodB]; // expected-error{{'methodB' is unavailable}}
268}
269
270@end
271
272void testImplementsAvailabilityP2b(ImplementsAvailabilityP2b *obj) {
273  // still get warnings/errors because we see the protocol version.
274
275  [obj methodA]; // expected-warning{{'methodA' is deprecated: first deprecated in macOS 10.2}}
276  [obj methodB]; // expected-error{{'methodB' is unavailable}}
277}
278
279__attribute__((objc_root_class))
280@interface ImplementsAvailabilityP2c <AvailabilityP2>
281-(void)methodA __attribute__((availability(macosx,introduced=10.2)));
282-(void)methodB __attribute__((unavailable));
283@end
284
285__attribute__((objc_root_class))
286@interface ImplementsAvailabilityP2d <AvailabilityP2>
287@end
288
289@implementation ImplementsAvailabilityP2d
290-(void)methodA __attribute__((availability(macosx,introduced=10.2)))
291{
292}
293-(void)methodB __attribute__((unavailable)) {
294}
295@end
296
297__attribute__((objc_root_class))
298@interface InheritUnavailableSuper
299-(void)method __attribute__((unavailable)); // expected-note{{'method' has been explicitly marked unavailable here}}
300@end
301
302@interface InheritUnavailableSub : InheritUnavailableSuper
303-(void)method;
304@end
305
306@implementation InheritUnavailableSub
307-(void)method {
308  InheritUnavailableSuper *obj = self;
309  [obj method]; // expected-error{{'method' is unavailable}}
310}
311@end
312
313#if defined(WARN_PARTIAL)
314
315int fn_10_5() __attribute__((availability(macosx, introduced=10.5)));
316int 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}}
317int 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}}
318  return fn_10_7();
319}
320
321__attribute__((objc_root_class))
322@interface LookupAvailabilityBase
323-(void) method1;
324@end
325
326@implementation LookupAvailabilityBase
327-(void)method1 { fn_10_7(); } // expected-warning{{only available on macOS 10.7}} expected-note{{@available}}
328@end
329
330__attribute__((availability(macosx, introduced=10.7)))
331@interface LookupAvailability : LookupAvailabilityBase
332- (void)method2;
333- (void)method3;
334- (void)method4 __attribute__((availability(macosx, introduced=10.8)));
335@end
336
337@implementation LookupAvailability
338-(void)method2 { fn_10_7(); }
339-(void)method3 { fn_10_8(); } // expected-warning{{only available on macOS 10.8}} expected-note{{@available}}
340-(void)method4 { fn_10_8(); }
341@end
342
343int old_func() __attribute__((availability(macos, introduced=10.4))) {
344  fn_10_5();
345}
346
347#endif
348