Merge pull request #15275 from DougGregor/sr-7182-4.1

[4.1] [SR-7182] Allow ownership keywords on properties in @objc protocols.
diff --git a/lib/Sema/TypeCheckAttr.cpp b/lib/Sema/TypeCheckAttr.cpp
index eeebf92..c874a5b 100644
--- a/lib/Sema/TypeCheckAttr.cpp
+++ b/lib/Sema/TypeCheckAttr.cpp
@@ -2091,8 +2091,10 @@
 
     diagnose(var->getStartLoc(), D, (unsigned) ownershipKind, underlyingType);
     attr->setInvalid();
-  } else if (dyn_cast<ProtocolDecl>(var->getDeclContext())) {
-    // Ownership does not make sense in protocols.
+  } else if (isa<ProtocolDecl>(var->getDeclContext()) &&
+             !cast<ProtocolDecl>(var->getDeclContext())->isObjC()) {
+    // Ownership does not make sense in protocols, except for "weak" on
+    // properties of Objective-C protocols.
     if (Context.isSwiftVersionAtLeast(5))
       diagnose(attr->getLocation(),
         diag::ownership_invalid_in_protocols,
diff --git a/test/PrintAsObjC/protocols.swift b/test/PrintAsObjC/protocols.swift
index 0542287..396c5f4 100644
--- a/test/PrintAsObjC/protocols.swift
+++ b/test/PrintAsObjC/protocols.swift
@@ -190,5 +190,17 @@
 // CHECK-LABEL: @interface Subclass : RootClass1 <ZZZ>{{$}}
 @objc class Subclass : RootClass1, ZZZ {}
 
+// CHECK-LABEL: @protocol UnownedProperty
+// CHECK-NEXT: @property (nonatomic, assign) id _Nonnull unownedProp;
+@objc protocol UnownedProperty {
+  unowned var unownedProp: AnyObject { get set }
+}
+
+// CHECK-LABEL: @protocol WeakProperty
+// CHECK-NEXT: @property (nonatomic, weak) id _Nullable weakProp;
+@objc protocol WeakProperty {
+  weak var weakProp: AnyObject? { get set }
+}
+
 // Deliberately at the end of the file.
 @objc protocol ZZZ {}
diff --git a/test/attr/attr_objc.swift b/test/attr/attr_objc.swift
index bc96ac2..3d3e69f 100644
--- a/test/attr/attr_objc.swift
+++ b/test/attr/attr_objc.swift
@@ -2294,3 +2294,13 @@
   @_versioned @objc dynamic func badMethod2() {}
   // expected-error@-1 {{'@_versioned' attribute cannot be applied to 'dynamic' declarations}}
 }
+
+@objc
+protocol ObjCProtocolWithWeakProperty {
+   weak var weakProp: AnyObject? { get set } // okay
+}
+
+@objc
+protocol ObjCProtocolWithUnownedProperty {
+   unowned var unownedProp: AnyObject { get set } // okay
+}