summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Sema/SemaOverload.cpp11
-rw-r--r--clang/test/SemaCXX/attr-unavailable.cpp23
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(); }
+};
OpenPOWER on IntegriCloud