From: Alex Lorenz Date: Thu, 3 May 2018 01:12:06 +0000 (+0000) Subject: [ObjC] Supress the 'implementing unavailable method' warning when X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=094219deccc9dd36708632c3982a4142fedab446;p=clang [ObjC] Supress the 'implementing unavailable method' warning when the method declaration is unavailable for an app extension platform Rationale: Classes are often shared between an app extension code and non-app extension code. There's no way to remove the implementation using preprocessor when building the app extension, so we should not warn here. rdar://38150617 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@331421 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index 1243a67397..88f82161f9 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -644,9 +644,14 @@ public: /// /// \param EnclosingVersion The version to compare with. If empty, assume the /// deployment target version. + /// + /// \param RealizedPlatform If non-NULL and the availability result is found + /// in an available attribute it will set to the platform which is written in + /// the available attribute. AvailabilityResult getAvailability(std::string *Message = nullptr, - VersionTuple EnclosingVersion = VersionTuple()) const; + VersionTuple EnclosingVersion = VersionTuple(), + StringRef *RealizedPlatform = nullptr) const; /// \brief Retrieve the version of the target platform in which this /// declaration was introduced. diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index baf83a393c..8d7291ee3e 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -590,9 +590,11 @@ static AvailabilityResult CheckAvailability(ASTContext &Context, } AvailabilityResult Decl::getAvailability(std::string *Message, - VersionTuple EnclosingVersion) const { + VersionTuple EnclosingVersion, + StringRef *RealizedPlatform) const { if (auto *FTD = dyn_cast(this)) - return FTD->getTemplatedDecl()->getAvailability(Message, EnclosingVersion); + return FTD->getTemplatedDecl()->getAvailability(Message, EnclosingVersion, + RealizedPlatform); AvailabilityResult Result = AR_Available; std::string ResultMessage; @@ -619,8 +621,11 @@ AvailabilityResult Decl::getAvailability(std::string *Message, AvailabilityResult AR = CheckAvailability(getASTContext(), Availability, Message, EnclosingVersion); - if (AR == AR_Unavailable) + if (AR == AR_Unavailable) { + if (RealizedPlatform) + *RealizedPlatform = Availability->getPlatform()->getName(); return AR_Unavailable; + } if (AR > Result) { Result = AR; diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index 5b8a9f3917..e1eed82716 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -266,12 +266,20 @@ static void DiagnoseObjCImplementedDeprecations(Sema &S, const NamedDecl *ND, if (!ND) return; bool IsCategory = false; - AvailabilityResult Availability = ND->getAvailability(); + StringRef RealizedPlatform; + AvailabilityResult Availability = ND->getAvailability( + /*Message=*/nullptr, /*EnclosingVersion=*/VersionTuple(), + &RealizedPlatform); if (Availability != AR_Deprecated) { if (isa(ND)) { if (Availability != AR_Unavailable) return; - // Warn about implementing unavailable methods. + if (RealizedPlatform.empty()) + RealizedPlatform = S.Context.getTargetInfo().getPlatformName(); + // Warn about implementing unavailable methods, unless the unavailable + // is for an app extension. + if (RealizedPlatform.endswith("_app_extension")) + return; S.Diag(ImplLoc, diag::warn_unavailable_def); S.Diag(ND->getLocation(), diag::note_method_declared_at) << ND->getDeclName(); diff --git a/test/SemaObjC/avoid-unavailable-implementation-warning-in-app-extension.m b/test/SemaObjC/avoid-unavailable-implementation-warning-in-app-extension.m new file mode 100644 index 0000000000..06872a9cab --- /dev/null +++ b/test/SemaObjC/avoid-unavailable-implementation-warning-in-app-extension.m @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -triple arm64-apple-ios11 -fapplication-extension -Wdeprecated-implementations -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -triple arm64-apple-tvos11 -fapplication-extension -Wdeprecated-implementations -verify -Wno-objc-root-class %s +// Declarations marked as 'unavailable' in an app extension should not generate a +// warning on implementation. + +@interface Parent +- (void)ok __attribute__((availability(ios_app_extension,unavailable,message="not available"))); +- (void)reallyUnavail __attribute__((availability(ios,unavailable))); // expected-note {{method 'reallyUnavail' declared here}} +- (void)reallyUnavail2 __attribute__((unavailable)); // expected-note {{method 'reallyUnavail2' declared here}} +@end + +@interface Child : Parent +@end + +@implementation Child + +- (void)ok { // no warning. +} +- (void)reallyUnavail { // expected-warning {{implementing unavailable method}} +} +- (void)reallyUnavail2 { // expected-warning {{implementing unavailable method}} +} + +@end