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