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 | } |
356 | |