diff options
author | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2016-03-08 10:28:52 +0000 |
---|---|---|
committer | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2016-03-08 10:28:52 +0000 |
commit | 2b2f843fd0eed77baa55dd4371f14c1d68231572 (patch) | |
tree | ef93c3cf0635754ad72a12e9109ed60cd38e9b29 /test/SemaCXX/attr-unavailable.cpp | |
parent | a1d201fccaf0e072dc2c70c2ecbc6c129087e3bd (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.cpp | 23 |
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(); } +}; |