]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/SemaObjC/unguarded-availability.m
Vendor import of clang trunk r351319 (just before the release_80 branch
[FreeBSD/FreeBSD.git] / test / SemaObjC / unguarded-availability.m
1 // RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -Wunguarded-availability -fblocks -fsyntax-only -verify %s
2 // RUN: %clang_cc1 -xobjective-c++ -std=c++11 -DOBJCPP -triple x86_64-apple-macosx10.9 -Wunguarded-availability -fblocks -fsyntax-only -verify %s
3
4 #define AVAILABLE_10_0  __attribute__((availability(macos, introduced = 10.0)))
5 #define AVAILABLE_10_11 __attribute__((availability(macos, introduced = 10.11)))
6 #define AVAILABLE_10_12 __attribute__((availability(macos, introduced = 10.12)))
7
8 typedef int AVAILABLE_10_12 new_int; // expected-note + {{'new_int' has been marked as being introduced in macOS 10.12 here, but the deployment target is macOS 10.9.0}}
9
10 int func_10_11() AVAILABLE_10_11; // expected-note 8 {{'func_10_11' has been marked as being introduced in macOS 10.11 here, but the deployment target is macOS 10.9.0}}
11
12 #ifdef OBJCPP
13 // expected-note@+2 6 {{'func_10_12' has been marked as being introduced in macOS 10.12 here, but the deployment target is macOS 10.9.0}}
14 #endif
15 int func_10_12() AVAILABLE_10_12; // expected-note 7 {{'func_10_12' has been marked as being introduced in macOS 10.12 here, but the deployment target is macOS 10.9.0}}
16
17 int func_10_0() AVAILABLE_10_0;
18
19 void use_func() {
20   func_10_11(); // expected-warning{{'func_10_11' is only available on macOS 10.11 or newer}} expected-note{{enclose 'func_10_11' in an @available check to silence this warning}}
21
22   if (@available(macos 10.11, *))
23     func_10_11();
24   else
25     func_10_11(); // expected-warning{{'func_10_11' is only available on macOS 10.11 or newer}} expected-note{{enclose 'func_10_11' in an @available check to silence this warning}}
26 }
27
28 void defn_10_11() AVAILABLE_10_11;
29
30 void defn_10_11() {
31   func_10_11();
32 }
33
34 void nested_ifs() {
35   if (@available(macos 10.12, *)) {
36     if (@available(macos 10.10, *)) {
37       func_10_12();
38     } else {
39       func_10_12();
40     }
41   } else {
42     func_10_12(); // expected-warning{{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{enclose 'func_10_12' in an @available check to silence this warning}}
43   }
44 }
45
46 void star_case() {
47   if (@available(ios 9, *)) {
48     func_10_11(); // expected-warning{{'func_10_11' is only available on macOS 10.11 or newer}} expected-note{{enclose 'func_10_11' in an @available check to silence this warning}}
49     func_10_0();
50   } else
51     func_10_11(); // expected-warning{{'func_10_11' is only available on macOS 10.11 or newer}} expected-note{{enclose 'func_10_11' in an @available check to silence this warning}}
52
53   if (@available(macOS 10.11, *)) {
54     if (@available(ios 8, *)) {
55       func_10_11();
56       func_10_12(); // expected-warning{{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{enclose}}
57     } else {
58       func_10_11();
59       func_10_12(); // expected-warning{{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{enclose}}
60     }
61   }
62 }
63
64 typedef int int_10_11 AVAILABLE_10_11; // expected-note {{'int_10_11' has been marked as being introduced in macOS 10.11 here, but the deployment target is macOS 10.9.0}}
65 #ifdef OBJCPP
66 // expected-note@+2 {{'int_10_12' has been marked as being introduced in macOS 10.12 here, but the deployment target is macOS 10.9.0}}
67 #endif
68 typedef int int_10_12 AVAILABLE_10_12; // expected-note 2 {{'int_10_12' has been marked as being introduced in macOS 10.12 here, but the deployment target is macOS 10.9.0}}
69
70 void use_typedef() {
71   int_10_11 x; // expected-warning{{'int_10_11' is only available on macOS 10.11 or newer}} expected-note{{enclose 'int_10_11' in an @available check to silence this warning}}
72 }
73
74 __attribute__((objc_root_class))
75 AVAILABLE_10_11 @interface Class_10_11 { // expected-note{{annotate 'Class_10_11' with an availability attribute to silence}}
76   int_10_11 foo;
77   int_10_12 bar; // expected-warning {{'int_10_12' is only available on macOS 10.12 or newer}}
78 }
79 - (void)method1;
80 - (void)method2;
81 @end
82
83 @implementation Class_10_11
84 - (void) method1 {
85   func_10_11();
86   func_10_12(); // expected-warning{{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{enclose 'func_10_12' in an @available check to silence this warning}}
87 }
88
89 - (void)method2 AVAILABLE_10_12 {
90   func_10_12();
91 }
92
93 @end
94
95 int protected_scope() {
96   if (@available(macos 10.20, *)) { // expected-note 2 {{jump enters controlled statement of if available}}
97   label1:
98     return 0;
99   } else {
100   label2:
101     goto label1; // expected-error{{cannot jump from this goto statement to its label}}
102   }
103
104   goto label2; // expected-error{{cannot jump from this goto statement to its label}}
105 }
106
107 struct S {
108   int m1;
109   int m2 __attribute__((availability(macos, introduced = 10.12))); // expected-note{{has been marked as being introduced in macOS 10.12 here, but the deployment target is macOS 10.9.0}}
110
111   struct Nested {
112     int nested_member __attribute__((availability(macos, introduced = 10.12))); // expected-note{{'nested_member' has been marked as being introduced in macOS 10.12 here, but the deployment target is macOS 10.9.0}}
113   } n;
114 };
115
116 int test_members() {
117   struct S s;
118   (void)s.m1;
119   (void)s.m2; // expected-warning{{'m2' is only available on macOS 10.12 or newer}} expected-note{{@available}}
120
121   (void)s.n.nested_member; // expected-warning{{'nested_member' is only available on macOS 10.12 or newer}} expected-note{{@available}}
122 }
123
124 void test_blocks() {
125   (void) ^{
126     func_10_12(); // expected-warning{{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{@available}}
127   };
128 }
129
130 void test_params(int_10_12 x); // expected-warning {{'int_10_12' is only available on macOS 10.12 or newer}} expected-note{{annotate 'test_params' with an availability attribute to silence this warning}}
131
132 void test_params2(int_10_12 x) AVAILABLE_10_12; // no warn
133
134 void (^topLevelBlockDecl)() = ^ {
135   func_10_12(); // expected-warning{{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{@available}}
136   if (@available(macos 10.12, *))
137     func_10_12();
138 };
139
140 AVAILABLE_10_12
141 __attribute__((objc_root_class))
142 @interface InterWithProp // expected-note 2 {{'InterWithProp' has been marked as being introduced in macOS 10.12 here, but the deployment target is macOS 10.9.0}}
143 @property(class) int x;
144 + (void) setX: (int)newX AVAILABLE_10_12; // expected-note{{'setX:' has been marked as being introduced in macOS 10.12 here, but the deployment target is macOS 10.9.0}}
145 @end
146 void test_property(void) {
147   int y = InterWithProp.x; // expected-warning{{'InterWithProp' is only available on macOS 10.12 or newer}} expected-note{{@available}}
148   InterWithProp.x = y; // expected-warning{{'InterWithProp' is only available on macOS 10.12 or newer}} expected-note{{@available}} expected-warning{{'setX:' is only available on macOS 10.12 or newer}} expected-note{{@available}}
149 }
150
151 __attribute__((objc_root_class))
152 @interface Subscriptable
153 - (id)objectAtIndexedSubscript:(int)sub AVAILABLE_10_12; // expected-note{{'objectAtIndexedSubscript:' has been marked as being introduced in macOS 10.12 here, but the deployment target is macOS 10.9.0}}
154 @end
155
156 void test_at(Subscriptable *x) {
157   id y = x[42]; // expected-warning{{'objectAtIndexedSubscript:' is only available on macOS 10.12 or newer}} expected-note{{@available}}
158 }
159
160 void uncheckAtAvailable() {
161   if (@available(macOS 10.12, *) || 0) // expected-warning {{@available does not guard availability here; use if (@available) instead}}
162     func_10_12(); // expected-warning {{'func_10_12' is only available on macOS 10.12 or newer}}
163   // expected-note@-1 {{enclose 'func_10_12' in an @available check to silence this warning}}
164 }
165
166 void justAtAvailable() {
167   int availability = @available(macOS 10.12, *); // expected-warning {{@available does not guard availability here; use if (@available) instead}}
168 }
169
170 #ifdef OBJCPP
171
172 int f(char) AVAILABLE_10_12;
173 int f(int);
174
175 template <class T> int use_f() {
176   // FIXME: We should warn here!
177   return f(T());
178 }
179
180 int a = use_f<int>();
181 int b = use_f<char>();
182
183 template <class> int use_at_available() {
184   if (@available(macos 10.12, *))
185     return func_10_12();
186   else
187     return func_10_12(); // expected-warning {{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{enclose}}
188 }
189
190 int instantiate_template() {
191   if (@available(macos 10.12, *)) {
192     use_at_available<char>();
193   } else {
194     use_at_available<float>();
195   }
196 }
197
198 template <class>
199 int with_availability_attr() AVAILABLE_10_11 { // expected-note 2 {{'with_availability_attr<int>' has been marked as being introduced in macOS 10.11 here, but the deployment target is macOS 10.9.0}}
200   return 0;
201 }
202
203 int instantiate_with_availability_attr() {
204   if (@available(macos 10.12, *))
205     with_availability_attr<char>();
206   else
207     with_availability_attr<int>(); // expected-warning {{'with_availability_attr<int>' is only available on macOS 10.11 or newer}} expected-note {{enclose}}
208 }
209
210 int instantiate_availability() {
211   if (@available(macOS 10.12, *))
212     with_availability_attr<int_10_12>();
213   else
214     with_availability_attr<int_10_12>(); // expected-warning{{'with_availability_attr<int>' is only available on macOS 10.11 or newer}} expected-warning{{'int_10_12' is only available on macOS 10.12 or newer}} expected-note 2 {{enclose}}
215 }
216
217 auto topLevelLambda = [] () {
218   func_10_12(); // expected-warning{{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{@available}}
219   if (@available(macos 10.12, *))
220     func_10_12();
221 };
222
223 void functionInFunction() {
224   func_10_12(); // expected-warning{{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{@available}}
225   struct DontWarnTwice {
226     void f() {
227       func_10_12(); // expected-warning{{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{@available}}
228     }
229   };
230   void([] () {
231     func_10_12(); // expected-warning{{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{@available}}
232   });
233   (void)(^ {
234     func_10_12(); // expected-warning{{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{@available}}
235   });
236 }
237
238 #endif
239
240 struct InStruct { // expected-note{{annotate 'InStruct' with an availability attribute to silence}}
241   new_int mem; // expected-warning{{'new_int' is only available on macOS 10.12 or newer}}
242
243   struct { new_int mem; } anon; // expected-warning{{'new_int' is only available on macOS 10.12 or newer}} expected-note{{annotate anonymous struct with an availability attribute to silence}}
244 };
245
246 #ifdef OBJCPP
247 static constexpr int AVAILABLE_10_12 SomeConstexprValue = 2; // expected-note{{'SomeConstexprValue' has been marked as being introduced in macOS 10.12 here, but the deployment target is macOS 10.9.0}}
248 typedef enum { // expected-note{{annotate anonymous enum with an availability attribute}}
249   SomeValue = SomeConstexprValue // expected-warning{{'SomeConstexprValue' is only available on macOS 10.12 or newer}} 
250 } SomeEnum;
251 #endif
252
253 @interface InInterface
254 -(new_int)meth; // expected-warning{{'new_int' is only available on macOS 10.12 or newer}} expected-note{{annotate 'meth' with an availability attribute}}
255 @end
256
257 @interface Proper // expected-note{{annotate 'Proper' with an availability attribute}}
258 @property (class) new_int x; // expected-warning{{'new_int' is only available}}
259 @end
260
261 void with_local_struct() {
262   struct local { // expected-note{{annotate 'local' with an availability attribute}}
263     new_int x; // expected-warning{{'new_int' is only available}}
264   };
265 }
266
267 // rdar://33156429:
268 // Avoid the warning on protocol requirements.
269
270 AVAILABLE_10_12
271 @protocol NewProtocol // expected-note {{'NewProtocol' has been marked as being introduced in macOS 10.12 here, but the deployment target is macOS 10.9.0}}
272 @end
273
274 @protocol ProtocolWithNewProtocolRequirement <NewProtocol> // expected-note {{annotate 'ProtocolWithNewProtocolRequirement' with an availability attribute to silence}}
275
276 @property(copy) id<NewProtocol> prop; // expected-warning {{'NewProtocol' is only available on macOS 10.12 or newer}}
277
278 @end
279
280 @interface BaseClass
281 @end
282
283 @interface ClassWithNewProtocolRequirement : BaseClass <NewProtocol>
284
285 @end
286
287 @interface BaseClass (CategoryWithNewProtocolRequirement) <NewProtocol>
288
289 @end
290
291 typedef enum {
292   AK_Dodo __attribute__((availability(macos, deprecated=10.3))), // expected-note 3 {{marked deprecated here}}
293   AK_Cat __attribute__((availability(macos, introduced=10.4))),
294   AK_CyborgCat __attribute__((availability(macos, introduced=10.12))), // expected-note {{'AK_CyborgCat' has been marked as being introduced in macOS 10.12 here, but the deployment target is macOS 10.9.0}}
295 } Animals;
296
297 void switchAnimals(Animals a) {
298   switch (a) {
299   case AK_Dodo: break; // expected-warning{{'AK_Dodo' is deprecated}}
300   case AK_Cat: break;
301   case AK_Cat|AK_CyborgCat: break; // expected-warning{{case value not in enum}}
302   case AK_CyborgCat: break; // no warn
303   }
304
305   switch (a) {
306   case AK_Dodo...AK_CyborgCat: // expected-warning {{'AK_Dodo' is depr}}
307     break;
308   }
309
310   (void)AK_Dodo; // expected-warning{{'AK_Dodo' is deprecated}}
311   (void)AK_Cat; // no warning
312   (void)AK_CyborgCat; // expected-warning{{'AK_CyborgCat' is only available on macOS 10.12 or newer}} expected-note {{@available}}
313 }
314
315
316 // test static initializers has the same availability as the deployment target and it cannot be overwritten.
317 @interface HasStaticInitializer : BaseClass
318 + (void)load AVAILABLE_10_11; // expected-warning{{ignoring availability attribute on '+load' method}}
319 @end
320
321 @implementation HasStaticInitializer
322 + (void)load {
323   func_10_11(); // expected-warning{{'func_10_11' is only available on macOS 10.11 or newer}} expected-note{{enclose 'func_10_11' in an @available check to silence this warning}}
324 }
325 @end
326
327 // test availability from interface is ignored when checking the unguarded availability in +load method.
328 AVAILABLE_10_11
329 @interface HasStaticInitializer1 : BaseClass
330 + (void)load;
331 + (void)load: (int)x; // no warning.
332 @end
333
334 @implementation HasStaticInitializer1
335 + (void)load {
336   func_10_11(); // expected-warning{{'func_10_11' is only available on macOS 10.11 or newer}} expected-note{{enclose 'func_10_11' in an @available check to silence this warning}}
337 }
338 + (void)load: (int)x {
339   func_10_11(); // no warning.
340 }
341 @end
342
343 __attribute__((constructor))
344 void is_constructor();
345
346 AVAILABLE_10_11 // expected-warning{{ignoring availability attribute with constructor attribute}}
347 void is_constructor() {
348   func_10_11(); // expected-warning{{'func_10_11' is only available on macOS 10.11 or newer}} expected-note{{enclose 'func_10_11' in an @available check to silence this warning}}
349 }
350
351 AVAILABLE_10_11 // expected-warning{{ignoring availability attribute with destructor attribute}}
352 __attribute__((destructor))
353 void is_destructor() {
354   func_10_11(); // expected-warning{{'func_10_11' is only available on macOS 10.11 or newer}} expected-note{{enclose 'func_10_11' in an @available check to silence this warning}}
355 }