Author: dexonsmith Date: Tue Mar 8 04:28:52 2016 New Revision: 262921 URL: http://llvm.org/viewvc/llvm-project?rev=262921&view=rev Log: 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 Modified: cfe/trunk/lib/Sema/SemaOverload.cpp cfe/trunk/test/SemaCXX/attr-unavailable.cpp Modified: cfe/trunk/lib/Sema/SemaOverload.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaOverload.cpp?rev=262921&r1=262920&r2=262921&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaOverload.cpp (original) +++ cfe/trunk/lib/Sema/SemaOverload.cpp Tue Mar 8 04:28:52 2016 @@ -1150,7 +1150,16 @@ bool Sema::IsOverload(FunctionDecl *New, /// \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. Modified: cfe/trunk/test/SemaCXX/attr-unavailable.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/attr-unavailable.cpp?rev=262921&r1=262920&r2=262921&view=diff ============================================================================== --- cfe/trunk/test/SemaCXX/attr-unavailable.cpp (original) +++ cfe/trunk/test/SemaCXX/attr-unavailable.cpp Tue Mar 8 04:28:52 2016 @@ -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(); } +}; _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits