summaryrefslogtreecommitdiffstats
path: root/clang/test/SemaCXX/attr-unavailable.cpp
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2016-02-26 19:27:00 +0000
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2016-02-26 19:27:00 +0000
commitec599a906b7388f6ebdd3d00d6904473b69ec288 (patch)
tree6eac50103586441591f2527e034c4f4fd958ed53 /clang/test/SemaCXX/attr-unavailable.cpp
parent2993854bb464c08f060e1f704f4c0b6dbc9ccda8 (diff)
downloadbcm5719-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.cpp62
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);
+}
OpenPOWER on IntegriCloud