This revision was automatically updated to reflect the committed changes.
Closed by commit rG50be48b0f3c8: [clang][ObjC] Allow different availability 
annotation on a method (authored by arphaman).
Herald added a project: clang.

Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D102459/new/

https://reviews.llvm.org/D102459

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaDecl.cpp
  clang/lib/Sema/SemaDeclAttr.cpp
  clang/test/SemaObjC/attr-availability.m
  clang/test/SemaObjC/override-opt-prop-availability.m

Index: clang/test/SemaObjC/override-opt-prop-availability.m
===================================================================
--- /dev/null
+++ clang/test/SemaObjC/override-opt-prop-availability.m
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -triple arm64-apple-ios11 -fsyntax-only -verify %s
+
+@protocol P
+
+@property (nonatomic) int reqProp __attribute__((availability(ios, introduced=12.0))); // expected-note 2 {{is here}}
+
+
+
+@optional
+@property (nonatomic) int myProp __attribute__((availability(ios, introduced=12.0))); // expected-note {{has been marked as being introduced in}}
+
+@optional
+@property (nonatomic, readonly) int depProp __attribute__((availability(ios, introduced=8.0, deprecated=12.0))); // expected-note {{protocol method is here}}
+
+@optional
+@property (nonatomic) int obsProp __attribute__((availability(ios, introduced=8.0, obsoleted=12.0)));
+
+@optional
+- (void) unavaibleInClass __attribute__((availability(ios, introduced=12.0))); // expected-note {{method is here}}
+
+@end
+
+@interface X <P>
+
+@property (nonatomic) int myProp __attribute__((availability(ios, introduced=13.0))); // expected-note 2 {{has been marked as being introduced in}}
+
+@property (nonatomic) int reqProp __attribute__((availability(ios, introduced=13.0))); // expected-warning 2 {{method introduced after the protocol method it implements on iOS}}
+
+@property (nonatomic, readonly) int depProp __attribute__((availability(ios, introduced=8.0, deprecated=10.0))); // expected-warning {{method deprecated before the protocol method it implements on iOS (12.0 vs. 10.0)}} expected-note {{been explicitly marked deprecated here}}
+
+@property (nonatomic) int obsProp __attribute__((availability(ios, introduced=8.0, obsoleted=10.0))); // expected-note {{been explicitly marked unavailable here}}
+
+- (void) unavaibleInClass __attribute__((availability(ios, unavailable))); // expected-warning {{method cannot be unavailable on iOS when the protocol method it implements is available}}
+
+@end
+
+
+void test(X *x) {
+  int i =  x.myProp;  // expected-warning {{'myProp' is only available on iOS 13.0 or newer}} expected-note {{enclose}}
+  x.myProp = i;       // expected-warning {{'setMyProp:' is only available on iOS 13.0 or newer}} expected-note {{enclose}}
+  int i2 = x.depProp; // expected-warning {{'depProp' is deprecated: first deprecated in iOS 10.0}}
+  int i3 = x.obsProp; // expected-error {{'obsProp' is unavailable: obsoleted in iOS 10.0}}
+}
+
+void testProto(id<P> x) {
+  int i = x.myProp; // expected-warning {{'myProp' is only available on iOS 12.0 or newer}} expected-note {{enclose}}
+}
Index: clang/test/SemaObjC/attr-availability.m
===================================================================
--- clang/test/SemaObjC/attr-availability.m
+++ clang/test/SemaObjC/attr-availability.m
@@ -229,8 +229,7 @@
 // inherited be implementations of those protocol methods.
 @protocol AvailabilityP2
 @optional
--(void)methodA __attribute__((availability(macosx,introduced=10.1,deprecated=10.2))); // expected-note 4{{'methodA' has been explicitly marked deprecated here}} \
-// expected-note 2{{protocol method is here}}
+-(void)methodA __attribute__((availability(macosx,introduced=10.1,deprecated=10.2))); // expected-note 4{{'methodA' has been explicitly marked deprecated here}}
 -(void)methodB __attribute__((unavailable)); // expected-note 4{{'methodB' has been explicitly marked unavailable here}}
 -(void)methodC;
 @end
@@ -279,7 +278,7 @@
 
 __attribute__((objc_root_class))
 @interface ImplementsAvailabilityP2c <AvailabilityP2>
--(void)methodA __attribute__((availability(macosx,introduced=10.2))); // expected-warning{{method introduced after the protocol method it implements on macOS (10.2 vs. 10.1)}}
+-(void)methodA __attribute__((availability(macosx,introduced=10.2)));
 -(void)methodB __attribute__((unavailable));
 @end
 
@@ -288,7 +287,7 @@
 @end
 
 @implementation ImplementsAvailabilityP2d
--(void)methodA __attribute__((availability(macosx,introduced=10.2))) // expected-warning{{method introduced after the protocol method it implements on macOS (10.2 vs. 10.1)}}
+-(void)methodA __attribute__((availability(macosx,introduced=10.2)))
 {
 }
 -(void)methodB __attribute__((unavailable)) {
Index: clang/lib/Sema/SemaDeclAttr.cpp
===================================================================
--- clang/lib/Sema/SemaDeclAttr.cpp
+++ clang/lib/Sema/SemaDeclAttr.cpp
@@ -2300,6 +2300,7 @@
 
   case AMK_Override:
   case AMK_ProtocolImplementation:
+  case AMK_OptionalProtocolImplementation:
     OverrideOrImpl = true;
     break;
   }
@@ -2368,6 +2369,14 @@
                  diag::warn_mismatched_availability_override_unavail)
               << AvailabilityAttr::getPrettyPlatformName(Platform->getName())
               << (AMK == AMK_Override);
+          } else if (Which != 1 && AMK == AMK_OptionalProtocolImplementation) {
+            // Allow different 'introduced' / 'obsoleted' availability versions
+            // on a method that implements an optional protocol requirement. It
+            // makes less sense to allow this for 'deprecated' as the user can't
+            // see if the method is 'deprecated' as 'respondsToSelector' will
+            // still return true when the method is deprecated.
+            ++i;
+            continue;
           } else {
             Diag(OldAA->getLocation(),
                  diag::warn_mismatched_availability_override)
Index: clang/lib/Sema/SemaDecl.cpp
===================================================================
--- clang/lib/Sema/SemaDecl.cpp
+++ clang/lib/Sema/SemaDecl.cpp
@@ -2608,7 +2608,8 @@
     NewAttr = nullptr;
   else if ((isa<DeprecatedAttr>(Attr) || isa<UnavailableAttr>(Attr)) &&
            (AMK == Sema::AMK_Override ||
-            AMK == Sema::AMK_ProtocolImplementation))
+            AMK == Sema::AMK_ProtocolImplementation ||
+            AMK == Sema::AMK_OptionalProtocolImplementation))
     NewAttr = nullptr;
   else if (const auto *UA = dyn_cast<UuidAttr>(Attr))
     NewAttr = S.mergeUuidAttr(D, *UA, UA->getGuid(), UA->getGuidDecl());
@@ -2956,6 +2957,7 @@
       case AMK_Redeclaration:
       case AMK_Override:
       case AMK_ProtocolImplementation:
+      case AMK_OptionalProtocolImplementation:
         LocalAMK = AMK;
         break;
       }
@@ -3861,10 +3863,11 @@
                                 ObjCMethodDecl *oldMethod) {
   // Merge the attributes, including deprecated/unavailable
   AvailabilityMergeKind MergeKind =
-    isa<ObjCProtocolDecl>(oldMethod->getDeclContext())
-      ? AMK_ProtocolImplementation
-      : isa<ObjCImplDecl>(newMethod->getDeclContext()) ? AMK_Redeclaration
-                                                       : AMK_Override;
+      isa<ObjCProtocolDecl>(oldMethod->getDeclContext())
+          ? (oldMethod->isOptional() ? AMK_OptionalProtocolImplementation
+                                     : AMK_ProtocolImplementation)
+          : isa<ObjCImplDecl>(newMethod->getDeclContext()) ? AMK_Redeclaration
+                                                           : AMK_Override;
 
   mergeDeclAttributes(newMethod, oldMethod, MergeKind);
 
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -3255,6 +3255,9 @@
     /// Merge availability attributes for an implementation of
     /// a protocol requirement.
     AMK_ProtocolImplementation,
+    /// Merge availability attributes for an implementation of
+    /// an optional protocol requirement.
+    AMK_OptionalProtocolImplementation
   };
 
   /// Describes the kind of priority given to an availability attribute.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to