diff options
author | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2016-02-26 19:27:00 +0000 |
---|---|---|
committer | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2016-02-26 19:27:00 +0000 |
commit | ec599a906b7388f6ebdd3d00d6904473b69ec288 (patch) | |
tree | 6eac50103586441591f2527e034c4f4fd958ed53 /clang/test/SemaCXX/attr-unavailable.cpp | |
parent | 2993854bb464c08f060e1f704f4c0b6dbc9ccda8 (diff) | |
download | bcm5719-llvm-ec599a906b7388f6ebdd3d00d6904473b69ec288.tar.gz bcm5719-llvm-ec599a906b7388f6ebdd3d00d6904473b69ec288.zip |
SemaCXX: Support templates in availability attributes
If the availability context is `FunctionTemplateDecl`, we should look
through it to the `FunctionDecl`. This prevents a diagnostic in the
following case:
class C __attribute__((unavailable));
template <class T> void foo(C&) __attribute__((unavailable));
This adds tests for availability in templates in many other cases, but
that was the only case that failed before this patch.
I added a feature `__has_feature(attribute_availability_in_templates)`
so users can test for this.
rdar://problem/24561029
llvm-svn: 262050
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); +} |