Merge pull request #12675 from rjmccall/labeled-setter-parameters-4.1

[4.1] Handle labeled singleton tuples in the setter value argument
diff --git a/lib/ClangImporter/ImportType.cpp b/lib/ClangImporter/ImportType.cpp
index 90eadf6..b7d318d 100644
--- a/lib/ClangImporter/ImportType.cpp
+++ b/lib/ClangImporter/ImportType.cpp
@@ -684,18 +684,13 @@
         auto typedefBridgeability = getTypedefBridgeability(underlyingType);
 
         // Figure out the typedef we should actually use.
-        auto underlyingBridgeability =
-          (Bridging == Bridgeability::Full
-             ? typedefBridgeability : Bridgeability::None);
-        SwiftTypeConverter innerConverter(Impl, AllowNSUIntegerAsInt,
-                                          underlyingBridgeability);
+        SwiftTypeConverter innerConverter(Impl, AllowNSUIntegerAsInt, Bridging);
         auto underlyingResult = innerConverter.Visit(underlyingType);
 
         // If we used different bridgeability than this typedef normally
-        // would because we're in a non-bridgeable context, and therefore
-        // the underlying type is different from the mapping of the typedef,
-        // use the underlying type.
-        if (underlyingBridgeability != typedefBridgeability &&
+        // would, and therefore the underlying type is different from the
+        // mapping of the typedef, use the underlying type.
+        if (Bridging != typedefBridgeability &&
             !underlyingResult.AbstractType->isEqual(mappedType)) {
           return underlyingResult;
         }
diff --git a/lib/SILOptimizer/IPO/DeadFunctionElimination.cpp b/lib/SILOptimizer/IPO/DeadFunctionElimination.cpp
index 8162028..18fee20 100644
--- a/lib/SILOptimizer/IPO/DeadFunctionElimination.cpp
+++ b/lib/SILOptimizer/IPO/DeadFunctionElimination.cpp
@@ -223,15 +223,22 @@
         auto id = component.getComputedPropertyId();
         switch (id.getKind()) {
         case KeyPathPatternComponent::ComputedPropertyId::DeclRef: {
-          auto decl = cast<AbstractFunctionDecl>(id.getDeclRef().getDecl());
-          if (auto clas = dyn_cast<ClassDecl>(decl->getDeclContext())) {
-            ensureAliveClassMethod(getMethodInfo(decl, /*witness*/ false),
-                                   dyn_cast<FuncDecl>(decl),
-                                   clas);
-          } else if (isa<ProtocolDecl>(decl->getDeclContext())) {
-            ensureAliveProtocolMethod(getMethodInfo(decl, /*witness*/ true));
+          auto declRef = id.getDeclRef();
+          if (declRef.isForeign) {
+            // Nothing to do here: foreign functions aren't ours to be deleting.
+            // (And even if they were, they're ObjC-dispatched and thus anchored
+            // already: see isAnchorFunction)
           } else {
-            llvm_unreachable("key path keyed by a non-class, non-protocol method");
+            auto decl = cast<AbstractFunctionDecl>(declRef.getDecl());
+            if (auto clas = dyn_cast<ClassDecl>(decl->getDeclContext())) {
+              ensureAliveClassMethod(getMethodInfo(decl, /*witness*/ false),
+                                     dyn_cast<FuncDecl>(decl),
+                                     clas);
+            } else if (isa<ProtocolDecl>(decl->getDeclContext())) {
+              ensureAliveProtocolMethod(getMethodInfo(decl, /*witness*/ true));
+            } else {
+              llvm_unreachable("key path keyed by a non-class, non-protocol method");
+            }
           }
           break;
         }
diff --git a/test/ClangImporter/Inputs/custom-modules/ObjCParseExtras.h b/test/ClangImporter/Inputs/custom-modules/ObjCParseExtras.h
index 4a86bae..27849b3 100644
--- a/test/ClangImporter/Inputs/custom-modules/ObjCParseExtras.h
+++ b/test/ClangImporter/Inputs/custom-modules/ObjCParseExtras.h
@@ -203,3 +203,9 @@
 @property (class, readonly) InstancetypeAccessor *prop;
 + (instancetype)prop;
 @end
+
+typedef NSArray<NSString *> *NSStringArray;
+
+@interface BridgedTypedefs : NSObject
+@property (readonly,nonnull) NSArray<NSStringArray> *arrayOfArrayOfStrings;
+@end
diff --git a/test/ClangImporter/objc_parse.swift b/test/ClangImporter/objc_parse.swift
index 9063d02..2f10fe7 100644
--- a/test/ClangImporter/objc_parse.swift
+++ b/test/ClangImporter/objc_parse.swift
@@ -638,3 +638,8 @@
   let _: () -> testStruct = testStruct.init
   let _: (CInt) -> testStruct = testStruct.init
 }
+
+// rdar://problem/34913507
+func testBridgedTypedef(bt: BridgedTypedefs) {
+  let _: Int = bt.arrayOfArrayOfStrings // expected-error{{'[[String]]'}}
+}
diff --git a/test/SILOptimizer/Inputs/keypaths_objc.h b/test/SILOptimizer/Inputs/keypaths_objc.h
new file mode 100644
index 0000000..f1a379b
--- /dev/null
+++ b/test/SILOptimizer/Inputs/keypaths_objc.h
@@ -0,0 +1,14 @@
+@import Foundation;
+
+@interface ObjCFoo
+
+@property(readonly) NSString *_Nonnull objcProp;
+
+@end
+
+
+@interface ObjCFoo (Extras)
+
+@property(readonly) NSString *_Nonnull objcExtraProp;
+
+@end
diff --git a/test/SILOptimizer/dead_func_objc_extension_keypath.swift b/test/SILOptimizer/dead_func_objc_extension_keypath.swift
new file mode 100644
index 0000000..ca04f4c
--- /dev/null
+++ b/test/SILOptimizer/dead_func_objc_extension_keypath.swift
@@ -0,0 +1,7 @@
+// RUN: %target-swift-frontend %s -O -emit-sil -import-objc-header %S/Inputs/keypaths_objc.h
+// REQUIRES: objc_interop
+
+import Foundation
+public func test_nocrash_rdar34913689() {
+  _ = \ObjCFoo.objcExtraProp
+}