diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index 671c3e92f451..ab1653d313be 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -4581,6 +4581,9 @@ def warn_deprecated_fwdclass_message : Warning< def warn_deprecated_def : Warning< "implementing deprecated %select{method|class|category}0">, InGroup, DefaultIgnore; +def warn_unavailable_def : Warning< + "implementing unavailable method">, + InGroup, DefaultIgnore; def err_unavailable : Error<"%0 is unavailable">; def err_property_method_unavailable : Error<"property access is using %0 method which is unavailable">; diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 2cf0ca94ac25..302f24880f6c 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -253,7 +253,17 @@ static void DiagnoseObjCImplementedDeprecations(Sema &S, const NamedDecl *ND, if (!ND) return; bool IsCategory = false; - if (!ND->isDeprecated()) { + AvailabilityResult Availability = ND->getAvailability(); + if (Availability != AR_Deprecated) { + if (const auto *MD = dyn_cast(ND)) { + if (Availability != AR_Unavailable) + return; + // Warn about implementing unavailable methods. + S.Diag(ImplLoc, diag::warn_unavailable_def); + S.Diag(ND->getLocation(), diag::note_method_declared_at) + << ND->getDeclName(); + return; + } if (const auto *CD = dyn_cast(ND)) { if (!CD->getClassInterface()->isDeprecated()) return; diff --git a/clang/test/SemaObjC/warn-deprecated-implementations.m b/clang/test/SemaObjC/warn-deprecated-implementations.m index ed2156d9abe6..440b2886f01d 100644 --- a/clang/test/SemaObjC/warn-deprecated-implementations.m +++ b/clang/test/SemaObjC/warn-deprecated-implementations.m @@ -1,9 +1,11 @@ -// RUN: %clang_cc1 -fsyntax-only -Wdeprecated-implementations -verify -Wno-objc-root-class %s +// RUN: %clang_cc1 -triple=x86_64-apple-macos10.10 -fsyntax-only -Wdeprecated-implementations -verify -Wno-objc-root-class %s // rdar://8973810 // rdar://12717705 @protocol P - (void) D __attribute__((deprecated)); // expected-note {{method 'D' declared here}} + +- (void) unavailable __attribute__((__unavailable__)); // expected-note {{method 'unavailable' declared here}} @end @interface A

@@ -18,6 +20,8 @@ + (void)F { } // No warning, implementing its own deprecated method - (void) D {} // expected-warning {{implementing deprecated method}} - (void) E {} // No warning, implementing deprecated method in its class extension. + +- (void) unavailable { } // expected-warning {{implementing unavailable metho}} @end @interface A(CAT) @@ -43,6 +47,8 @@ __attribute__((deprecated)) // expected-note {{'CL' has been explicitly marked d @interface BASE - (void) B __attribute__((deprecated)); // expected-note {{method 'B' declared here}} + ++ (void) unavailable __attribute__((availability(macos, unavailable))); // expected-note {{method 'unavailable' declared here}} @end @interface SUB : BASE @@ -50,6 +56,7 @@ __attribute__((deprecated)) // expected-note {{'CL' has been explicitly marked d @implementation SUB - (void) B {} // expected-warning {{implementing deprecated method}} ++ (void) unavailable { } // expected-warning {{implementing unavailable method}} @end @interface Test