// RUN: %clang_cc1 -fsyntax-only -verify %s int &foo(int); double &foo(double); void foo(...) __attribute__((__unavailable__)); // \ // expected-note 2 {{'foo' has been explicitly marked unavailable here}} void bar(...) __attribute__((__unavailable__)); // expected-note 4 {{explicitly marked unavailable}} void test_foo(short* sp) { int &ir = foo(1); double &dr = foo(1.0); foo(sp); // expected-error{{'foo' is unavailable}} void (*fp)(...) = &bar; // expected-error{{'bar' is unavailable}} void (*fp2)(...) = bar; // expected-error{{'bar' is unavailable}} int &(*fp3)(int) = foo; void (*fp4)(...) = foo; // expected-error{{'foo' is unavailable}} } namespace radar9046492 { // rdar://9046492 #define FOO __attribute__((unavailable("not available - replaced"))) void foo() FOO; // expected-note{{'foo' has been explicitly marked unavailable here}} void bar() { foo(); // expected-error {{'foo' is unavailable: not available - replaced}} } } void unavail(short* sp) __attribute__((__unavailable__)); void unavail(short* sp) { // No complains inside an unavailable function. int &ir = foo(1); double &dr = foo(1.0); foo(sp); foo(); } // Show that delayed processing of 'unavailable' is the same // delayed process for 'deprecated'. // and enum DeprecatedEnum { DE_A, DE_B } __attribute__((deprecated)); // expected-note {{'DeprecatedEnum' has been explicitly marked deprecated here}} __attribute__((deprecated)) typedef enum DeprecatedEnum DeprecatedEnum; typedef enum DeprecatedEnum AnotherDeprecatedEnum; // expected-warning {{'DeprecatedEnum' is deprecated}} __attribute__((deprecated)) DeprecatedEnum testDeprecated(DeprecatedEnum X) { return X; } enum UnavailableEnum { UE_A, UE_B } __attribute__((unavailable)); // expected-note {{'UnavailableEnum' has been explicitly marked unavailable here}} __attribute__((unavailable)) typedef enum UnavailableEnum UnavailableEnum; typedef enum UnavailableEnum AnotherUnavailableEnum; // expected-error {{'UnavailableEnum' is unavailable}} __attribute__((unavailable)) UnavailableEnum testUnavailable(UnavailableEnum X) { return X; } // Check that unavailable classes can be used as arguments to unavailable // function, particularly in template functions. #if !__has_feature(attribute_availability_in_templates) #error "Missing __has_feature" #endif class __attribute((unavailable)) UnavailableClass; // \ expected-note 3{{'UnavailableClass' has been explicitly marked unavailable here}} void unavail_class(UnavailableClass&); // expected-error {{'UnavailableClass' is unavailable}} void unavail_class_marked(UnavailableClass&) __attribute__((unavailable)); template void unavail_class(UnavailableClass&); // expected-error {{'UnavailableClass' is unavailable}} template void unavail_class_marked(UnavailableClass&) __attribute__((unavailable)); template void templated(T&); void untemplated(UnavailableClass &UC) { // expected-error {{'UnavailableClass' is unavailable}} templated(UC); } void untemplated_marked(UnavailableClass &UC) __attribute__((unavailable)) { templated(UC); } template void templated_calls_bar() { bar(); } // \ // expected-error{{'bar' is unavailable}} template void templated_calls_bar_arg(T v) { bar(v); } // \ // expected-error{{'bar' is unavailable}} template void templated_calls_bar_arg_never_called(T v) { bar(v); } template void unavail_templated_calls_bar() __attribute__((unavailable)) { // \ // expected-note {{'unavail_templated_calls_bar' has been explicitly marked unavailable here}} bar(5); } template void unavail_templated_calls_bar_arg(T v) __attribute__((unavailable)) { // expected-note@-1 {{'unavail_templated_calls_bar_arg' has been explicitly marked unavailable here}} bar(v); } void calls_templates_which_call_bar() { templated_calls_bar(); templated_calls_bar_arg(5); // \ expected-note{{in instantiation of function template specialization 'templated_calls_bar_arg' requested here}} unavail_templated_calls_bar(); // \ expected-error{{'unavail_templated_calls_bar' is unavailable}} unavail_templated_calls_bar_arg(5); // \ expected-error{{'unavail_templated_calls_bar_arg' is unavailable}} } template void unavail_templated(T) __attribute__((unavailable)); // expected-note@-1 {{'unavail_templated' has been explicitly marked unavailable here}} void calls_unavail_templated() { unavail_templated(5); // expected-error{{'unavail_templated' is unavailable}} } void unavail_calls_unavail_templated() __attribute__((unavailable)) { unavail_templated(5); } void unavailable() __attribute((unavailable)); // expected-note@-1 4 {{'unavailable' has been explicitly marked unavailable here}} struct AvailableStruct { void calls_unavailable() { unavailable(); } // \ expected-error{{'unavailable' is unavailable}} template void calls_unavailable() { unavailable(); } // \ expected-error{{'unavailable' is unavailable}} }; template struct AvailableStructTemplated { void calls_unavailable() { unavailable(); } // \ expected-error{{'unavailable' is unavailable}} template void calls_unavailable() { unavailable(); } // \ expected-error{{'unavailable' is unavailable}} }; struct __attribute__((unavailable)) UnavailableStruct { void calls_unavailable() { unavailable(); } template void calls_unavailable() { unavailable(); } }; template struct __attribute__((unavailable)) UnavailableStructTemplated { void calls_unavailable() { unavailable(); } template void calls_unavailable() { unavailable(); } }; int unavailable_int() __attribute__((unavailable)); // expected-note 2 {{'unavailable_int' has been explicitly marked unavailable here}} int has_default_arg(int x = unavailable_int()) { // expected-error{{'unavailable_int' is unavailable}} return x; } int has_default_arg2(int x = unavailable_int()) __attribute__((unavailable)) { return x; } template T unavailable_template() __attribute__((unavailable)); // expected-note@-1 {{'unavailable_template' has been explicitly marked unavailable here}} template int has_default_arg_template(T x = unavailable_template()) {} // expected-error@-1 {{'unavailable_template' is unavailable}} int instantiate_it = has_default_arg_template(); // expected-note@-1 {{in instantiation of default function argument expression for 'has_default_arg_template' required here}} template int has_default_arg_template2(T x = unavailable_template()) __attribute__((unavailable)) {} __attribute__((unavailable)) int instantiate_it2 = has_default_arg_template2(); template int phase_one_unavailable(int x = unavailable_int()) {} // expected-error@-1 {{'unavailable_int' is unavailable}} template int phase_one_unavailable2(int x = unavailable_int()) __attribute__((unavailable)) {}