150
|
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 };
|
207
|
128
|
|
129 if (@available(macos 10.12, *))
|
|
130 (void) ^{
|
|
131 func_10_12();
|
|
132 (void) ^{
|
|
133 func_10_12();
|
|
134 };
|
|
135 };
|
150
|
136 }
|
|
137
|
|
138 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}}
|
|
139
|
|
140 void test_params2(int_10_12 x) AVAILABLE_10_12; // no warn
|
|
141
|
|
142 void (^topLevelBlockDecl)() = ^ {
|
|
143 func_10_12(); // expected-warning{{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{@available}}
|
|
144 if (@available(macos 10.12, *))
|
|
145 func_10_12();
|
|
146 };
|
|
147
|
|
148 AVAILABLE_10_12
|
|
149 __attribute__((objc_root_class))
|
|
150 @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}}
|
|
151 @property(class) int x;
|
|
152 + (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}}
|
|
153 @end
|
|
154 void test_property(void) {
|
|
155 int y = InterWithProp.x; // expected-warning{{'InterWithProp' is only available on macOS 10.12 or newer}} expected-note{{@available}}
|
|
156 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}}
|
|
157 }
|
|
158
|
|
159 __attribute__((objc_root_class))
|
|
160 @interface Subscriptable
|
|
161 - (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}}
|
|
162 @end
|
|
163
|
|
164 void test_at(Subscriptable *x) {
|
|
165 id y = x[42]; // expected-warning{{'objectAtIndexedSubscript:' is only available on macOS 10.12 or newer}} expected-note{{@available}}
|
|
166 }
|
|
167
|
|
168 void uncheckAtAvailable() {
|
|
169 if (@available(macOS 10.12, *) || 0) // expected-warning {{@available does not guard availability here; use if (@available) instead}}
|
|
170 func_10_12(); // expected-warning {{'func_10_12' is only available on macOS 10.12 or newer}}
|
|
171 // expected-note@-1 {{enclose 'func_10_12' in an @available check to silence this warning}}
|
|
172 }
|
|
173
|
|
174 void justAtAvailable() {
|
|
175 int availability = @available(macOS 10.12, *); // expected-warning {{@available does not guard availability here; use if (@available) instead}}
|
|
176 }
|
|
177
|
|
178 #ifdef OBJCPP
|
|
179
|
|
180 int f(char) AVAILABLE_10_12;
|
|
181 int f(int);
|
|
182
|
|
183 template <class T> int use_f() {
|
|
184 // FIXME: We should warn here!
|
|
185 return f(T());
|
|
186 }
|
|
187
|
|
188 int a = use_f<int>();
|
|
189 int b = use_f<char>();
|
|
190
|
|
191 template <class> int use_at_available() {
|
|
192 if (@available(macos 10.12, *))
|
|
193 return func_10_12();
|
|
194 else
|
|
195 return func_10_12(); // expected-warning {{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{enclose}}
|
|
196 }
|
|
197
|
|
198 int instantiate_template() {
|
|
199 if (@available(macos 10.12, *)) {
|
|
200 use_at_available<char>();
|
|
201 } else {
|
|
202 use_at_available<float>();
|
|
203 }
|
|
204 }
|
|
205
|
|
206 template <class>
|
|
207 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}}
|
|
208 return 0;
|
|
209 }
|
|
210
|
|
211 int instantiate_with_availability_attr() {
|
|
212 if (@available(macos 10.12, *))
|
|
213 with_availability_attr<char>();
|
|
214 else
|
|
215 with_availability_attr<int>(); // expected-warning {{'with_availability_attr<int>' is only available on macOS 10.11 or newer}} expected-note {{enclose}}
|
|
216 }
|
|
217
|
|
218 int instantiate_availability() {
|
|
219 if (@available(macOS 10.12, *))
|
|
220 with_availability_attr<int_10_12>();
|
|
221 else
|
|
222 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}}
|
|
223 }
|
|
224
|
|
225 auto topLevelLambda = [] () {
|
|
226 func_10_12(); // expected-warning{{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{@available}}
|
|
227 if (@available(macos 10.12, *))
|
|
228 func_10_12();
|
|
229 };
|
|
230
|
|
231 void functionInFunction() {
|
|
232 func_10_12(); // expected-warning{{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{@available}}
|
|
233 struct DontWarnTwice {
|
|
234 void f() {
|
|
235 func_10_12(); // expected-warning{{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{@available}}
|
|
236 }
|
|
237 };
|
|
238 void([] () {
|
|
239 func_10_12(); // expected-warning{{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{@available}}
|
|
240 });
|
|
241 (void)(^ {
|
|
242 func_10_12(); // expected-warning{{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{@available}}
|
|
243 });
|
207
|
244
|
|
245 if (@available(macos 10.12, *)) {
|
|
246 void([]() {
|
|
247 func_10_12();
|
|
248 void([] () {
|
|
249 func_10_12();
|
|
250 });
|
|
251 struct DontWarn {
|
|
252 void f() {
|
|
253 func_10_12();
|
|
254 }
|
|
255 };
|
|
256 });
|
|
257 }
|
|
258
|
|
259 if (@available(macos 10.12, *)) {
|
|
260 struct DontWarn {
|
|
261 void f() {
|
|
262 func_10_12();
|
|
263 void([] () {
|
|
264 func_10_12();
|
|
265 });
|
|
266 struct DontWarn2 {
|
|
267 void f() {
|
|
268 func_10_12();
|
|
269 }
|
|
270 };
|
|
271 }
|
|
272 };
|
|
273 }
|
150
|
274 }
|
|
275
|
|
276 #endif
|
|
277
|
|
278 struct InStruct { // expected-note{{annotate 'InStruct' with an availability attribute to silence}}
|
|
279 new_int mem; // expected-warning{{'new_int' is only available on macOS 10.12 or newer}}
|
|
280
|
|
281 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}}
|
|
282 };
|
|
283
|
|
284 #ifdef OBJCPP
|
|
285 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}}
|
|
286 typedef enum { // expected-note{{annotate anonymous enum with an availability attribute}}
|
|
287 SomeValue = SomeConstexprValue // expected-warning{{'SomeConstexprValue' is only available on macOS 10.12 or newer}}
|
|
288 } SomeEnum;
|
|
289 #endif
|
|
290
|
|
291 @interface InInterface
|
|
292 -(new_int)meth; // expected-warning{{'new_int' is only available on macOS 10.12 or newer}} expected-note{{annotate 'meth' with an availability attribute}}
|
|
293 @end
|
|
294
|
|
295 @interface Proper // expected-note{{annotate 'Proper' with an availability attribute}}
|
|
296 @property (class) new_int x; // expected-warning{{'new_int' is only available}}
|
|
297 @end
|
|
298
|
|
299 void with_local_struct() {
|
207
|
300 struct local {
|
|
301 new_int x; // expected-warning{{'new_int' is only available}} expected-note{{enclose 'new_int' in an @available check}}
|
150
|
302 };
|
207
|
303 if (@available(macos 10.12, *)) {
|
|
304 struct DontWarn {
|
|
305 new_int x;
|
|
306 };
|
|
307 }
|
150
|
308 }
|
|
309
|
|
310 // rdar://33156429:
|
|
311 // Avoid the warning on protocol requirements.
|
|
312
|
|
313 AVAILABLE_10_12
|
|
314 @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}}
|
|
315 @end
|
|
316
|
|
317 @protocol ProtocolWithNewProtocolRequirement <NewProtocol> // expected-note {{annotate 'ProtocolWithNewProtocolRequirement' with an availability attribute to silence}}
|
|
318
|
|
319 @property(copy) id<NewProtocol> prop; // expected-warning {{'NewProtocol' is only available on macOS 10.12 or newer}}
|
|
320
|
|
321 @end
|
|
322
|
|
323 @interface BaseClass
|
|
324 @end
|
|
325
|
|
326 @interface ClassWithNewProtocolRequirement : BaseClass <NewProtocol>
|
|
327
|
|
328 @end
|
|
329
|
|
330 @interface BaseClass (CategoryWithNewProtocolRequirement) <NewProtocol>
|
|
331
|
|
332 @end
|
|
333
|
|
334 typedef enum {
|
|
335 AK_Dodo __attribute__((availability(macos, deprecated=10.3))), // expected-note 3 {{marked deprecated here}}
|
|
336 AK_Cat __attribute__((availability(macos, introduced=10.4))),
|
|
337 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}}
|
|
338 } Animals;
|
|
339
|
|
340 void switchAnimals(Animals a) {
|
|
341 switch (a) {
|
|
342 case AK_Dodo: break; // expected-warning{{'AK_Dodo' is deprecated}}
|
|
343 case AK_Cat: break;
|
|
344 case AK_Cat|AK_CyborgCat: break; // expected-warning{{case value not in enum}}
|
|
345 case AK_CyborgCat: break; // no warn
|
|
346 }
|
|
347
|
|
348 switch (a) {
|
|
349 case AK_Dodo...AK_CyborgCat: // expected-warning {{'AK_Dodo' is depr}}
|
|
350 break;
|
|
351 }
|
|
352
|
|
353 (void)AK_Dodo; // expected-warning{{'AK_Dodo' is deprecated}}
|
|
354 (void)AK_Cat; // no warning
|
|
355 (void)AK_CyborgCat; // expected-warning{{'AK_CyborgCat' is only available on macOS 10.12 or newer}} expected-note {{@available}}
|
|
356 }
|
|
357
|
|
358
|
|
359 // test static initializers has the same availability as the deployment target and it cannot be overwritten.
|
|
360 @interface HasStaticInitializer : BaseClass
|
|
361 + (void)load AVAILABLE_10_11; // expected-warning{{ignoring availability attribute on '+load' method}}
|
|
362 @end
|
|
363
|
|
364 @implementation HasStaticInitializer
|
|
365 + (void)load {
|
|
366 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}}
|
|
367 }
|
|
368 @end
|
|
369
|
|
370 // test availability from interface is ignored when checking the unguarded availability in +load method.
|
|
371 AVAILABLE_10_11
|
|
372 @interface HasStaticInitializer1 : BaseClass
|
|
373 + (void)load;
|
|
374 + (void)load: (int)x; // no warning.
|
|
375 @end
|
|
376
|
|
377 @implementation HasStaticInitializer1
|
|
378 + (void)load {
|
|
379 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}}
|
|
380 }
|
|
381 + (void)load: (int)x {
|
|
382 func_10_11(); // no warning.
|
|
383 }
|
|
384 @end
|
|
385
|
|
386 __attribute__((constructor))
|
|
387 void is_constructor();
|
|
388
|
|
389 AVAILABLE_10_11 // expected-warning{{ignoring availability attribute with constructor attribute}}
|
|
390 void is_constructor() {
|
|
391 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}}
|
|
392 }
|
|
393
|
|
394 AVAILABLE_10_11 // expected-warning{{ignoring availability attribute with destructor attribute}}
|
|
395 __attribute__((destructor))
|
|
396 void is_destructor() {
|
|
397 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}}
|
|
398 }
|