summaryrefslogtreecommitdiffstats
path: root/test/SemaCXX/attr-unavailable.cpp
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2016-03-08 10:28:52 +0000
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2016-03-08 10:28:52 +0000
commit2b2f843fd0eed77baa55dd4371f14c1d68231572 (patch)
treeef93c3cf0635754ad72a12e9109ed60cd38e9b29 /test/SemaCXX/attr-unavailable.cpp
parenta1d201fccaf0e072dc2c70c2ecbc6c129087e3bd (diff)
Sema: Methods in unavailable classes are unavailable
Similar to the template cases in r262050, when a C++ method in an unavailable struct/class calls unavailable API, don't diagnose an error. I.e., this case was failing: void foo() __attribute__((unavailable)); struct __attribute__((unavailable)) A { void bar() { foo(); } }; Since A is unavailable, A::bar is allowed to call foo. However, we were emitting a diagnostic here. This commit checks up the context chain from A::bar, in a manner inspired by SemaDeclAttr.cpp:isDeclUnavailable. I expected to find other related issues but failed to trigger them: - I wondered if DeclBase::getAvailability should check for `TemplateDecl` instead of `FunctionTemplateDecl`, but I couldn't find a way to trigger this. I left behind a few extra tests to make sure we don't regress. - I wondered if Sema::isFunctionConsideredUnavailable should be symmetric, checking up the context chain of the callee (this commit only checks up the context chain of the caller). However, I couldn't think of a testcase that didn't require first referencing the unavailable type; this, we already diagnose. rdar://problem/25030656 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@262921 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/SemaCXX/attr-unavailable.cpp')
-rw-r--r--test/SemaCXX/attr-unavailable.cpp23
1 files changed, 23 insertions, 0 deletions
diff --git a/test/SemaCXX/attr-unavailable.cpp b/test/SemaCXX/attr-unavailable.cpp
index 430cb5cdb8..bafae2ab43 100644
--- a/test/SemaCXX/attr-unavailable.cpp
+++ b/test/SemaCXX/attr-unavailable.cpp
@@ -116,3 +116,26 @@ void calls_unavail_templated() {
void unavail_calls_unavail_templated() __attribute__((unavailable)) {
unavail_templated(5);
}
+
+void unavailable() __attribute((unavailable)); // \
+ expected-note 4{{candidate function has been explicitly made unavailable}}
+struct AvailableStruct {
+ void calls_unavailable() { unavailable(); } // \
+ expected-error{{call to unavailable function 'unavailable'}}
+ template <class U> void calls_unavailable() { unavailable(); } // \
+ expected-error{{call to unavailable function 'unavailable'}}
+};
+template <class T> struct AvailableStructTemplated {
+ void calls_unavailable() { unavailable(); } // \
+ expected-error{{call to unavailable function 'unavailable'}}
+ template <class U> void calls_unavailable() { unavailable(); } // \
+ expected-error{{call to unavailable function 'unavailable'}}
+};
+struct __attribute__((unavailable)) UnavailableStruct {
+ void calls_unavailable() { unavailable(); }
+ template <class U> void calls_unavailable() { unavailable(); }
+};
+template <class T> struct __attribute__((unavailable)) UnavailableStructTemplated {
+ void calls_unavailable() { unavailable(); }
+ template <class U> void calls_unavailable() { unavailable(); }
+};