xref: /aosp_15_r20/external/clang/test/SemaCXX/attr-unavailable.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li // RUN: %clang_cc1 -fsyntax-only -verify %s
2*67e74705SXin Li 
3*67e74705SXin Li int &foo(int); // expected-note {{candidate}}
4*67e74705SXin Li double &foo(double); // expected-note {{candidate}}
5*67e74705SXin Li void foo(...) __attribute__((__unavailable__)); // expected-note {{candidate function}} \
6*67e74705SXin Li // expected-note{{'foo' has been explicitly marked unavailable here}}
7*67e74705SXin Li 
8*67e74705SXin Li void bar(...) __attribute__((__unavailable__)); // expected-note 2{{explicitly marked unavailable}} \
9*67e74705SXin Li        // expected-note 2{{candidate function has been explicitly made unavailable}}
10*67e74705SXin Li 
test_foo(short * sp)11*67e74705SXin Li void test_foo(short* sp) {
12*67e74705SXin Li   int &ir = foo(1);
13*67e74705SXin Li   double &dr = foo(1.0);
14*67e74705SXin Li   foo(sp); // expected-error{{call to unavailable function 'foo'}}
15*67e74705SXin Li 
16*67e74705SXin Li   void (*fp)(...) = &bar; // expected-error{{'bar' is unavailable}}
17*67e74705SXin Li   void (*fp2)(...) = bar; // expected-error{{'bar' is unavailable}}
18*67e74705SXin Li 
19*67e74705SXin Li   int &(*fp3)(int) = foo;
20*67e74705SXin Li   void (*fp4)(...) = foo; // expected-error{{'foo' is unavailable}}
21*67e74705SXin Li }
22*67e74705SXin Li 
23*67e74705SXin Li namespace radar9046492 {
24*67e74705SXin Li // rdar://9046492
25*67e74705SXin Li #define FOO __attribute__((unavailable("not available - replaced")))
26*67e74705SXin Li 
27*67e74705SXin Li void foo() FOO; // expected-note {{candidate function has been explicitly made unavailable}}
bar()28*67e74705SXin Li void bar() {
29*67e74705SXin Li   foo(); // expected-error {{call to unavailable function 'foo': not available - replaced}}
30*67e74705SXin Li }
31*67e74705SXin Li }
32*67e74705SXin Li 
33*67e74705SXin Li void unavail(short* sp)  __attribute__((__unavailable__));
unavail(short * sp)34*67e74705SXin Li void unavail(short* sp) {
35*67e74705SXin Li   // No complains inside an unavailable function.
36*67e74705SXin Li   int &ir = foo(1);
37*67e74705SXin Li   double &dr = foo(1.0);
38*67e74705SXin Li   foo(sp);
39*67e74705SXin Li   foo();
40*67e74705SXin Li }
41*67e74705SXin Li 
42*67e74705SXin Li // Show that delayed processing of 'unavailable' is the same
43*67e74705SXin Li // delayed process for 'deprecated'.
44*67e74705SXin Li // <rdar://problem/12241361> and <rdar://problem/15584219>
45*67e74705SXin Li enum DeprecatedEnum { DE_A, DE_B } __attribute__((deprecated)); // expected-note {{'DeprecatedEnum' has been explicitly marked deprecated here}}
46*67e74705SXin Li __attribute__((deprecated)) typedef enum DeprecatedEnum DeprecatedEnum;
47*67e74705SXin Li typedef enum DeprecatedEnum AnotherDeprecatedEnum; // expected-warning {{'DeprecatedEnum' is deprecated}}
48*67e74705SXin Li 
49*67e74705SXin Li __attribute__((deprecated))
testDeprecated(DeprecatedEnum X)50*67e74705SXin Li DeprecatedEnum testDeprecated(DeprecatedEnum X) { return X; }
51*67e74705SXin Li 
52*67e74705SXin Li 
53*67e74705SXin Li enum UnavailableEnum { UE_A, UE_B } __attribute__((unavailable)); // expected-note {{'UnavailableEnum' has been explicitly marked unavailable here}}
54*67e74705SXin Li __attribute__((unavailable)) typedef enum UnavailableEnum UnavailableEnum;
55*67e74705SXin Li typedef enum UnavailableEnum AnotherUnavailableEnum; // expected-error {{'UnavailableEnum' is unavailable}}
56*67e74705SXin Li 
57*67e74705SXin Li 
58*67e74705SXin Li __attribute__((unavailable))
testUnavailable(UnavailableEnum X)59*67e74705SXin Li UnavailableEnum testUnavailable(UnavailableEnum X) { return X; }
60*67e74705SXin Li 
61*67e74705SXin Li 
62*67e74705SXin Li // Check that unavailable classes can be used as arguments to unavailable
63*67e74705SXin Li // function, particularly in template functions.
64*67e74705SXin Li #if !__has_feature(attribute_availability_in_templates)
65*67e74705SXin Li #error "Missing __has_feature"
66*67e74705SXin Li #endif
67*67e74705SXin Li class __attribute((unavailable)) UnavailableClass; // \
68*67e74705SXin Li         expected-note 3{{'UnavailableClass' has been explicitly marked unavailable here}}
69*67e74705SXin Li void unavail_class(UnavailableClass&); // expected-error {{'UnavailableClass' is unavailable}}
70*67e74705SXin Li void unavail_class_marked(UnavailableClass&) __attribute__((unavailable));
71*67e74705SXin Li template <class T> void unavail_class(UnavailableClass&); // expected-error {{'UnavailableClass' is unavailable}}
72*67e74705SXin Li template <class T> void unavail_class_marked(UnavailableClass&) __attribute__((unavailable));
73*67e74705SXin Li template <class T> void templated(T&);
untemplated(UnavailableClass & UC)74*67e74705SXin Li void untemplated(UnavailableClass &UC) {  // expected-error {{'UnavailableClass' is unavailable}}
75*67e74705SXin Li   templated(UC);
76*67e74705SXin Li }
untemplated_marked(UnavailableClass & UC)77*67e74705SXin Li void untemplated_marked(UnavailableClass &UC) __attribute__((unavailable)) {
78*67e74705SXin Li   templated(UC);
79*67e74705SXin Li }
80*67e74705SXin Li 
templated_calls_bar()81*67e74705SXin Li template <class T> void templated_calls_bar() { bar(); } // \
82*67e74705SXin Li            // expected-error{{call to unavailable function 'bar'}}
templated_calls_bar_arg(T v)83*67e74705SXin Li template <class T> void templated_calls_bar_arg(T v) { bar(v); } // \
84*67e74705SXin Li            // expected-error{{call to unavailable function 'bar'}}
templated_calls_bar_arg_never_called(T v)85*67e74705SXin Li template <class T> void templated_calls_bar_arg_never_called(T v) { bar(v); }
86*67e74705SXin Li 
87*67e74705SXin Li template <class T>
unavail_templated_calls_bar()88*67e74705SXin Li void unavail_templated_calls_bar() __attribute__((unavailable)) { // \
89*67e74705SXin Li   expected-note{{candidate function [with T = int] has been explicitly made unavailable}}
90*67e74705SXin Li   bar(5);
91*67e74705SXin Li }
92*67e74705SXin Li template <class T>
unavail_templated_calls_bar_arg(T v)93*67e74705SXin Li void unavail_templated_calls_bar_arg(T v) __attribute__((unavailable)) { // \
94*67e74705SXin Li   expected-note{{candidate function [with T = int] has been explicitly made unavailable}}
95*67e74705SXin Li   bar(v);
96*67e74705SXin Li }
97*67e74705SXin Li 
calls_templates_which_call_bar()98*67e74705SXin Li void calls_templates_which_call_bar() {
99*67e74705SXin Li   templated_calls_bar<int>();
100*67e74705SXin Li 
101*67e74705SXin Li   templated_calls_bar_arg(5); // \
102*67e74705SXin Li   expected-note{{in instantiation of function template specialization 'templated_calls_bar_arg<int>' requested here}}
103*67e74705SXin Li 
104*67e74705SXin Li   unavail_templated_calls_bar<int>(); // \
105*67e74705SXin Li   expected-error{{call to unavailable function 'unavail_templated_calls_bar'}}
106*67e74705SXin Li 
107*67e74705SXin Li   unavail_templated_calls_bar_arg(5); // \
108*67e74705SXin Li   expected-error{{call to unavailable function 'unavail_templated_calls_bar_arg'}}
109*67e74705SXin Li }
110*67e74705SXin Li 
111*67e74705SXin Li template <class T> void unavail_templated(T) __attribute__((unavailable)); // \
112*67e74705SXin Li            expected-note{{candidate function [with T = int] has been explicitly made unavailable}}
calls_unavail_templated()113*67e74705SXin Li void calls_unavail_templated() {
114*67e74705SXin Li   unavail_templated(5); // expected-error{{call to unavailable function 'unavail_templated'}}
115*67e74705SXin Li }
unavail_calls_unavail_templated()116*67e74705SXin Li void unavail_calls_unavail_templated() __attribute__((unavailable)) {
117*67e74705SXin Li   unavail_templated(5);
118*67e74705SXin Li }
119*67e74705SXin Li 
120*67e74705SXin Li void unavailable() __attribute((unavailable)); // \
121*67e74705SXin Li        expected-note 4{{candidate function has been explicitly made unavailable}}
122*67e74705SXin Li struct AvailableStruct {
calls_unavailableAvailableStruct123*67e74705SXin Li   void calls_unavailable() { unavailable(); } // \
124*67e74705SXin Li   expected-error{{call to unavailable function 'unavailable'}}
calls_unavailableAvailableStruct125*67e74705SXin Li   template <class U> void calls_unavailable() { unavailable(); } // \
126*67e74705SXin Li   expected-error{{call to unavailable function 'unavailable'}}
127*67e74705SXin Li };
128*67e74705SXin Li template <class T> struct AvailableStructTemplated {
calls_unavailableAvailableStructTemplated129*67e74705SXin Li   void calls_unavailable() { unavailable(); } // \
130*67e74705SXin Li   expected-error{{call to unavailable function 'unavailable'}}
calls_unavailableAvailableStructTemplated131*67e74705SXin Li   template <class U> void calls_unavailable() { unavailable(); } // \
132*67e74705SXin Li   expected-error{{call to unavailable function 'unavailable'}}
133*67e74705SXin Li };
134*67e74705SXin Li struct __attribute__((unavailable)) UnavailableStruct {
calls_unavailableUnavailableStruct135*67e74705SXin Li   void calls_unavailable() { unavailable(); }
calls_unavailableUnavailableStruct136*67e74705SXin Li   template <class U> void calls_unavailable() { unavailable(); }
137*67e74705SXin Li };
138*67e74705SXin Li template <class T> struct __attribute__((unavailable)) UnavailableStructTemplated {
calls_unavailableUnavailableStructTemplated139*67e74705SXin Li   void calls_unavailable() { unavailable(); }
calls_unavailableUnavailableStructTemplated140*67e74705SXin Li   template <class U> void calls_unavailable() { unavailable(); }
141*67e74705SXin Li };
142