diff options
Diffstat (limited to 'clang/test/SemaCXX/attr-unavailable.cpp')
-rw-r--r-- | clang/test/SemaCXX/attr-unavailable.cpp | 62 |
1 files changed, 61 insertions, 1 deletions
diff --git a/clang/test/SemaCXX/attr-unavailable.cpp b/clang/test/SemaCXX/attr-unavailable.cpp index 51dc8fe3789..430cb5cdb8c 100644 --- a/clang/test/SemaCXX/attr-unavailable.cpp +++ b/clang/test/SemaCXX/attr-unavailable.cpp @@ -5,7 +5,8 @@ double &foo(double); // expected-note {{candidate}} void foo(...) __attribute__((__unavailable__)); // expected-note {{candidate function}} \ // expected-note{{'foo' has been explicitly marked unavailable here}} -void bar(...) __attribute__((__unavailable__)); // expected-note 2{{explicitly marked unavailable}} +void bar(...) __attribute__((__unavailable__)); // expected-note 2{{explicitly marked unavailable}} \ + // expected-note 2{{candidate function has been explicitly made unavailable}} void test_foo(short* sp) { int &ir = foo(1); @@ -56,3 +57,62 @@ typedef enum UnavailableEnum AnotherUnavailableEnum; // expected-error {{'Unavai __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 <class T> void unavail_class(UnavailableClass&); // expected-error {{'UnavailableClass' is unavailable}} +template <class T> void unavail_class_marked(UnavailableClass&) __attribute__((unavailable)); +template <class T> void templated(T&); +void untemplated(UnavailableClass &UC) { // expected-error {{'UnavailableClass' is unavailable}} + templated(UC); +} +void untemplated_marked(UnavailableClass &UC) __attribute__((unavailable)) { + templated(UC); +} + +template <class T> void templated_calls_bar() { bar(); } // \ + // expected-error{{call to unavailable function 'bar'}} +template <class T> void templated_calls_bar_arg(T v) { bar(v); } // \ + // expected-error{{call to unavailable function 'bar'}} +template <class T> void templated_calls_bar_arg_never_called(T v) { bar(v); } + +template <class T> +void unavail_templated_calls_bar() __attribute__((unavailable)) { // \ + expected-note{{candidate function [with T = int] has been explicitly made unavailable}} + bar(5); +} +template <class T> +void unavail_templated_calls_bar_arg(T v) __attribute__((unavailable)) { // \ + expected-note{{candidate function [with T = int] has been explicitly made unavailable}} + bar(v); +} + +void calls_templates_which_call_bar() { + templated_calls_bar<int>(); + + templated_calls_bar_arg(5); // \ + expected-note{{in instantiation of function template specialization 'templated_calls_bar_arg<int>' requested here}} + + unavail_templated_calls_bar<int>(); // \ + expected-error{{call to unavailable function 'unavail_templated_calls_bar'}} + + unavail_templated_calls_bar_arg(5); // \ + expected-error{{call to unavailable function 'unavail_templated_calls_bar_arg'}} +} + +template <class T> void unavail_templated(T) __attribute__((unavailable)); // \ + expected-note{{candidate function [with T = int] has been explicitly made unavailable}} +void calls_unavail_templated() { + unavail_templated(5); // expected-error{{call to unavailable function 'unavail_templated'}} +} +void unavail_calls_unavail_templated() __attribute__((unavailable)) { + unavail_templated(5); +} |