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
8typedef 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}}
9
10int func_10_11(void) 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}}
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}}
14#endif
15int func_10_12(void) 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}}
16
17int func_10_0(void) AVAILABLE_10_0;
18
19void use_func(void) {
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
28void defn_10_11(void) AVAILABLE_10_11;
29
30void defn_10_11(void) {
31  func_10_11();
32}
33
34void nested_ifs(void) {
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
46void star_case(void) {
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
64typedef 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}}
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}}
67#endif
68typedef 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}}
69
70void use_typedef(void) {
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))
75AVAILABLE_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
95int protected_scope(void) {
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
107struct 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}}
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}}
113  } n;
114};
115
116int test_members(void) {
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
124void test_blocks(void) {
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  if (@available(macos 10.12, *))
130    (void) ^{
131      func_10_12();
132      (void) ^{
133        func_10_12();
134      };
135    };
136}
137
138void 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
140void test_params2(int_10_12 x) AVAILABLE_10_12; // no warn
141
142void (^topLevelBlockDecl)(void) = ^ {
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
148AVAILABLE_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}}
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}}
153@end
154void 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}}
162@end
163
164void 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
168void uncheckAtAvailable(void) {
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
174void justAtAvailable(void) {
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
180int f(char) AVAILABLE_10_12;
181int f(int);
182
183template <class T> int use_f() {
184  // FIXME: We should warn here!
185  return f(T());
186}
187
188int a = use_f<int>();
189int b = use_f<char>();
190
191template <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
198int instantiate_template() {
199  if (@available(macos 10.12, *)) {
200    use_at_available<char>();
201  } else {
202    use_at_available<float>();
203  }
204}
205
206template <class>
207int 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}}
208  return 0;
209}
210
211int 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
218int 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
225auto 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
231void 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  });
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  }
274}
275
276#endif
277
278struct 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
285static 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}}
286typedef 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
299void with_local_struct(void) {
300  struct local {
301    new_int x; // expected-warning{{'new_int' is only available}} expected-note{{enclose 'new_int' in an @available check}}
302  };
303  if (@available(macos 10.12, *)) {
304    struct DontWarn {
305      new_int x;
306    };
307  }
308}
309
310// rdar://33156429:
311// Avoid the warning on protocol requirements.
312
313AVAILABLE_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}}
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
334typedef 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}}
338} Animals;
339
340void 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.
371AVAILABLE_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))
387void is_constructor(void);
388
389AVAILABLE_10_11 // expected-warning{{ignoring availability attribute with constructor attribute}}
390void is_constructor(void) {
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
394AVAILABLE_10_11 // expected-warning{{ignoring availability attribute with destructor attribute}}
395__attribute__((destructor))
396void is_destructor(void) {
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}
399