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