diff options
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/Sema/SemaOverload.cpp | 11 | ||||
-rw-r--r-- | clang/test/SemaCXX/attr-unavailable.cpp | 23 |
2 files changed, 33 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 1765db6734e..a28ded474a7 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1150,7 +1150,16 @@ bool Sema::IsOverload(FunctionDecl *New, FunctionDecl *Old, /// \returns true if \arg FD is unavailable and current context is inside /// an available function, false otherwise. bool Sema::isFunctionConsideredUnavailable(FunctionDecl *FD) { - return FD->isUnavailable() && !cast<Decl>(CurContext)->isUnavailable(); + if (!FD->isUnavailable()) + return false; + + // Walk up the context of the caller. + Decl *C = cast<Decl>(CurContext); + do { + if (C->isUnavailable()) + return false; + } while ((C = cast_or_null<Decl>(C->getDeclContext()))); + return true; } /// \brief Tries a user-defined conversion from From to ToType. diff --git a/clang/test/SemaCXX/attr-unavailable.cpp b/clang/test/SemaCXX/attr-unavailable.cpp index 430cb5cdb8c..bafae2ab43a 100644 --- a/clang/test/SemaCXX/attr-unavailable.cpp +++ b/clang/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(); } +}; |