Merge pull request #20005 from DougGregor/more-symbolic-references

[ABI] Introduce indirect symbolic references to context descriptors.
diff --git a/cmake/modules/SwiftSource.cmake b/cmake/modules/SwiftSource.cmake
index a988993..e20e628 100644
--- a/cmake/modules/SwiftSource.cmake
+++ b/cmake/modules/SwiftSource.cmake
@@ -454,13 +454,14 @@
   # Then we can compile both the object files and the swiftmodule files
   # in parallel in this target for the object file, and ...
 
-  # Windows doesn't support long command line paths, of 8191 chars or over.
-  # We need to work around this by avoiding long command line arguments. This can be
-  # achieved by writing the list of file paths to a file, then reading that list
-  # in the Python script.
+  # Windows doesn't support long command line paths, of 8191 chars or over. We
+  # need to work around this by avoiding long command line arguments. This can
+  # be achieved by writing the list of file paths to a file, then reading that
+  # list in the Python script.
   string(RANDOM file_name)
   set(file_path "${CMAKE_CURRENT_BINARY_DIR}/${file_name}.txt")
-  file(WRITE "${file_path}" "${source_files}")
+  string(REPLACE ";" "'\n'" source_files_quoted "${source_files}")
+  file(WRITE "${file_path}" "'${source_files_quoted}'")
   
   add_custom_command_target(
       dependency_target
diff --git a/include/swift/IDE/CodeCompletion.h b/include/swift/IDE/CodeCompletion.h
index fc8176a..293e2d4 100644
--- a/include/swift/IDE/CodeCompletion.h
+++ b/include/swift/IDE/CodeCompletion.h
@@ -899,26 +899,28 @@
 } // end namespace ide
 } // end namespace swift
 
-template <> struct llvm::DenseMapInfo<swift::ide::CodeCompletionKeywordKind> {
+namespace llvm {
+template <> struct DenseMapInfo<swift::ide::CodeCompletionKeywordKind> {
   using Kind = swift::ide::CodeCompletionKeywordKind;
   static Kind getEmptyKey() { return Kind(~0u); }
   static Kind getTombstoneKey() { return Kind(~1u); }
   static unsigned getHashValue(const Kind &Val) { return unsigned(Val); }
   static bool isEqual(const Kind &LHS, const Kind &RHS) { return LHS == RHS; }
 };
-template <> struct llvm::DenseMapInfo<swift::ide::CodeCompletionLiteralKind> {
+template <> struct DenseMapInfo<swift::ide::CodeCompletionLiteralKind> {
   using Kind = swift::ide::CodeCompletionLiteralKind;
   static Kind getEmptyKey() { return Kind(~0u); }
   static Kind getTombstoneKey() { return Kind(~1u); }
   static unsigned getHashValue(const Kind &Val) { return unsigned(Val); }
   static bool isEqual(const Kind &LHS, const Kind &RHS) { return LHS == RHS; }
 };
-template <> struct llvm::DenseMapInfo<swift::ide::CodeCompletionDeclKind> {
+template <> struct DenseMapInfo<swift::ide::CodeCompletionDeclKind> {
   using Kind = swift::ide::CodeCompletionDeclKind;
   static Kind getEmptyKey() { return Kind(~0u); }
   static Kind getTombstoneKey() { return Kind(~1u); }
   static unsigned getHashValue(const Kind &Val) { return unsigned(Val); }
   static bool isEqual(const Kind &LHS, const Kind &RHS) { return LHS == RHS; }
 };
+}
 
 #endif // SWIFT_IDE_CODECOMPLETION_H
diff --git a/include/swift/IRGen/Linking.h b/include/swift/IRGen/Linking.h
index 24983e2..d995632 100644
--- a/include/swift/IRGen/Linking.h
+++ b/include/swift/IRGen/Linking.h
@@ -1006,7 +1006,8 @@
 }
 
 /// Allow LinkEntity to be used as a key for a DenseMap.
-template <> struct llvm::DenseMapInfo<swift::irgen::LinkEntity> {
+namespace llvm {
+template <> struct DenseMapInfo<swift::irgen::LinkEntity> {
   using LinkEntity = swift::irgen::LinkEntity;
   static LinkEntity getEmptyKey() {
     LinkEntity entity;
@@ -1032,4 +1033,5 @@
            LHS.SecondaryPointer == RHS.SecondaryPointer && LHS.Data == RHS.Data;
   }
 };
+}
 #endif
diff --git a/include/swift/SILOptimizer/Analysis/AccessedStorageAnalysis.h b/include/swift/SILOptimizer/Analysis/AccessedStorageAnalysis.h
index e39d0d0..b41c70c 100644
--- a/include/swift/SILOptimizer/Analysis/AccessedStorageAnalysis.h
+++ b/include/swift/SILOptimizer/Analysis/AccessedStorageAnalysis.h
@@ -94,9 +94,10 @@
 };
 } // namespace swift
 
+namespace llvm {
 // Use the same DenseMapInfo for StorageAccessInfo as for AccessedStorage. None
 // of the subclass bitfields participate in the Key.
-template <> struct llvm::DenseMapInfo<swift::StorageAccessInfo> {
+template <> struct DenseMapInfo<swift::StorageAccessInfo> {
   static swift::StorageAccessInfo getEmptyKey() {
     auto key = DenseMapInfo<swift::AccessedStorage>::getEmptyKey();
     return static_cast<swift::StorageAccessInfo &>(key);
@@ -114,6 +115,7 @@
     return DenseMapInfo<swift::AccessedStorage>::isEqual(LHS, RHS);
   }
 };
+}
 
 namespace swift {
 /// The per-function result of AccessedStorageAnalysis.
diff --git a/include/swift/SILOptimizer/Analysis/AliasAnalysis.h b/include/swift/SILOptimizer/Analysis/AliasAnalysis.h
index 3885627..97d723d 100644
--- a/include/swift/SILOptimizer/Analysis/AliasAnalysis.h
+++ b/include/swift/SILOptimizer/Analysis/AliasAnalysis.h
@@ -306,7 +306,7 @@
 } // end namespace swift
 
 namespace llvm {
-  template <> struct llvm::DenseMapInfo<AliasKeyTy> {
+  template <> struct DenseMapInfo<AliasKeyTy> {
     static inline AliasKeyTy getEmptyKey() {
       auto Allone = std::numeric_limits<size_t>::max();
       return {0, Allone, nullptr, nullptr};
@@ -331,7 +331,7 @@
     }
   };
 
-  template <> struct llvm::DenseMapInfo<MemBehaviorKeyTy> {
+  template <> struct DenseMapInfo<MemBehaviorKeyTy> {
     static inline MemBehaviorKeyTy getEmptyKey() {
       auto Allone = std::numeric_limits<size_t>::max();
       return {0, Allone, RetainObserveKind::RetainObserveKindEnd};
diff --git a/include/swift/Syntax/SyntaxData.h b/include/swift/Syntax/SyntaxData.h
index 3452772..0f1d4f9 100644
--- a/include/swift/Syntax/SyntaxData.h
+++ b/include/swift/Syntax/SyntaxData.h
@@ -294,7 +294,7 @@
 namespace llvm {
   using SD = swift::syntax::SyntaxData;
   using RCSD = swift::RC<SD>;
-  template <> struct llvm::DenseMapInfo<RCSD> {
+  template <> struct DenseMapInfo<RCSD> {
     static inline RCSD getEmptyKey() {
       return SD::make(nullptr, nullptr, 0);
     }
diff --git a/lib/ClangImporter/ClangImporter.cpp b/lib/ClangImporter/ClangImporter.cpp
index 23589af..1707011 100644
--- a/lib/ClangImporter/ClangImporter.cpp
+++ b/lib/ClangImporter/ClangImporter.cpp
@@ -2011,72 +2011,89 @@
   return nullptr;
 }
 
+static const clang::Module *
+getClangTopLevelOwningModule(ClangNode Node,
+                             const clang::ASTContext &ClangCtx) {
+  const clang::Module *OwningModule = getClangOwningModule(Node, ClangCtx);
+  if (!OwningModule)
+    return nullptr;
+  return OwningModule->getTopLevelModule();
+}
+
 static bool isVisibleFromModule(const ClangModuleUnit *ModuleFilter,
                                 const ValueDecl *VD) {
-  // Include a value from module X if:
-  // * no particular module was requested, or
-  // * module X was specifically requested.
-  if (!ModuleFilter)
-    return true;
+  assert(ModuleFilter);
 
   auto ContainingUnit = VD->getDeclContext()->getModuleScopeContext();
   if (ModuleFilter == ContainingUnit)
     return true;
 
+  // The rest of this function is looking to see if the Clang entity that
+  // caused VD to be imported has redeclarations in the filter module.
   auto Wrapper = dyn_cast<ClangModuleUnit>(ContainingUnit);
   if (!Wrapper)
     return false;
 
   auto ClangNode = VD->getClangNode();
-  assert(ClangNode);
+  if (!ClangNode) {
+    // If we synthesized a ValueDecl, it won't have a Clang node. But so far
+    // all the situations where we synthesize top-level declarations are
+    // situations where we don't have to worry about C redeclarations.
+    // We should only consider the declaration visible from its owning module.
+    auto *SynthesizedTypeAttr =
+        VD->getAttrs().getAttribute<ClangImporterSynthesizedTypeAttr>();
+    assert(SynthesizedTypeAttr);
 
+    // When adding new ClangImporterSynthesizedTypeAttr::Kinds, make sure that
+    // the above statement still holds: "we don't want to allow these
+    // declarations to be treated as present in multiple modules".
+    switch (SynthesizedTypeAttr->getKind()) {
+    case ClangImporterSynthesizedTypeAttr::Kind::NSErrorWrapper:
+    case ClangImporterSynthesizedTypeAttr::Kind::NSErrorWrapperAnon:
+      break;
+    }
+
+    return false;
+  }
+
+  // Macros can be "redeclared" by putting an equivalent definition in two
+  // different modules. (We don't actually check the equivalence.)
+  // FIXME: We're also not checking if the redeclaration is in /this/ module.
+  if (ClangNode.getAsMacro())
+    return true;
+
+  const clang::Decl *D = ClangNode.castAsDecl();
   auto &ClangASTContext = ModuleFilter->getClangASTContext();
-  auto OwningClangModule = getClangOwningModule(ClangNode, ClangASTContext);
 
   // We don't handle Clang submodules; pop everything up to the top-level
   // module.
-  if (OwningClangModule)
-    OwningClangModule = OwningClangModule->getTopLevelModule();
-
+  auto OwningClangModule = getClangTopLevelOwningModule(ClangNode,
+                                                        ClangASTContext);
   if (OwningClangModule == ModuleFilter->getClangModule())
     return true;
 
-  if (auto D = ClangNode.getAsDecl()) {
-    // Handle redeclared decls.
-    if (isa<clang::FunctionDecl>(D) || isa<clang::VarDecl>(D) ||
-        isa<clang::TypedefNameDecl>(D)) {
-      for (auto Redeclaration : D->redecls()) {
-        if (Redeclaration == D)
-          continue;
-        auto OwningClangModule = getClangOwningModule(Redeclaration,
-                                                      ClangASTContext);
-        if (OwningClangModule)
-          OwningClangModule = OwningClangModule->getTopLevelModule();
-
-        if (OwningClangModule == ModuleFilter->getClangModule())
-          return true;
-      }
-    } else if (isa<clang::TagDecl>(D)) {
-      for (auto Redeclaration : D->redecls()) {
-        if (Redeclaration == D)
-          continue;
-        if (!cast<clang::TagDecl>(Redeclaration)->isCompleteDefinition())
-          continue;
-        auto OwningClangModule = getClangOwningModule(Redeclaration,
-                                                      ClangASTContext);
-        if (OwningClangModule)
-          OwningClangModule = OwningClangModule->getTopLevelModule();
-
-        if (OwningClangModule == ModuleFilter->getClangModule())
-          return true;
-      }
-    }
+  // Handle redeclarable Clang decls by checking each redeclaration.
+  bool IsTagDecl = isa<clang::TagDecl>(D);
+  if (!(IsTagDecl || isa<clang::FunctionDecl>(D) || isa<clang::VarDecl>(D) ||
+        isa<clang::TypedefNameDecl>(D))) {
+    return false;
   }
 
-  // Macros can be "redeclared" too, by putting an equivalent definition in two
-  // different modules.
-  if (ClangNode.getAsMacro())
-    return true;
+  for (auto Redeclaration : D->redecls()) {
+    if (Redeclaration == D)
+      continue;
+
+    // For enums, structs, and unions, only count definitions when looking to
+    // see what other modules they appear in.
+    if (IsTagDecl)
+      if (!cast<clang::TagDecl>(Redeclaration)->isCompleteDefinition())
+        continue;
+
+    auto OwningClangModule = getClangTopLevelOwningModule(Redeclaration,
+                                                          ClangASTContext);
+    if (OwningClangModule == ModuleFilter->getClangModule())
+      return true;
+  }
 
   return false;
 }
@@ -2106,12 +2123,14 @@
 
 class FilteringVisibleDeclConsumer : public swift::VisibleDeclConsumer {
   swift::VisibleDeclConsumer &NextConsumer;
-  const ClangModuleUnit *ModuleFilter = nullptr;
+  const ClangModuleUnit *ModuleFilter;
 
 public:
   FilteringVisibleDeclConsumer(swift::VisibleDeclConsumer &consumer,
                                const ClangModuleUnit *CMU)
-      : NextConsumer(consumer), ModuleFilter(CMU) {}
+      : NextConsumer(consumer), ModuleFilter(CMU) {
+    assert(CMU);
+  }
 
   void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason) override {
     if (isVisibleFromModule(ModuleFilter, VD))
@@ -2121,13 +2140,14 @@
 
 class FilteringDeclaredDeclConsumer : public swift::VisibleDeclConsumer {
   swift::VisibleDeclConsumer &NextConsumer;
-  const ClangModuleUnit *ModuleFilter = nullptr;
+  const ClangModuleUnit *ModuleFilter;
 
 public:
   FilteringDeclaredDeclConsumer(swift::VisibleDeclConsumer &consumer,
                                 const ClangModuleUnit *CMU)
-      : NextConsumer(consumer),
-        ModuleFilter(CMU) {}
+      : NextConsumer(consumer), ModuleFilter(CMU) {
+    assert(CMU);
+  }
 
   void foundDecl(ValueDecl *VD, DeclVisibilityKind Reason) override {
     if (isDeclaredInModule(ModuleFilter, VD))
@@ -2868,10 +2888,7 @@
   auto &clangCtx = clangSema.getASTContext();
   for (auto objcMethod : objcMethods) {
     // Verify that this method came from this module.
-    auto owningClangModule = getClangOwningModule(objcMethod, clangCtx);
-    if (owningClangModule)
-      owningClangModule = owningClangModule->getTopLevelModule();
-
+    auto owningClangModule = getClangTopLevelOwningModule(objcMethod, clangCtx);
     if (owningClangModule != clangModule) continue;
 
     // If we found a property accessor, import the property.
diff --git a/lib/Driver/UnixToolChains.cpp b/lib/Driver/UnixToolChains.cpp
index 5d7711e..bcb75fa7 100644
--- a/lib/Driver/UnixToolChains.cpp
+++ b/lib/Driver/UnixToolChains.cpp
@@ -111,6 +111,7 @@
     // final executables, as such, unless specified, we default to gold
     // linker.
     return "gold";
+  case llvm::Triple::x86:
   case llvm::Triple::x86_64:
   case llvm::Triple::ppc64:
   case llvm::Triple::ppc64le:
diff --git a/lib/IRGen/LocalTypeDataKind.h b/lib/IRGen/LocalTypeDataKind.h
index 58bd817..0b32e1a 100644
--- a/lib/IRGen/LocalTypeDataKind.h
+++ b/lib/IRGen/LocalTypeDataKind.h
@@ -190,7 +190,8 @@
 }
 }
 
-template <> struct llvm::DenseMapInfo<swift::irgen::LocalTypeDataKey> {
+namespace llvm {
+template <> struct DenseMapInfo<swift::irgen::LocalTypeDataKey> {
   using LocalTypeDataKey = swift::irgen::LocalTypeDataKey;
   using CanTypeInfo = DenseMapInfo<swift::CanType>;
   static inline LocalTypeDataKey getEmptyKey() {
@@ -209,5 +210,6 @@
     return a == b;
   }
 };
+}
 
 #endif
diff --git a/lib/SILGen/SILGenExpr.cpp b/lib/SILGen/SILGenExpr.cpp
index f53f386..409d551 100644
--- a/lib/SILGen/SILGenExpr.cpp
+++ b/lib/SILGen/SILGenExpr.cpp
@@ -2046,9 +2046,8 @@
     if (value.getOwnershipKind() == ValueOwnershipKind::Trivial)
       return ManagedValue::forUnmanaged(value.getValue());
 
-    // Otherwise, retain and enter a release cleanup.
-    valueTL.emitCopyValue(B, loc, value.getValue());
-    return emitManagedRValueWithCleanup(value.getValue(), valueTL);
+    // Otherwise, copy the value and return.
+    return value.getFinalManagedValue().copy(*this, loc);
   }
 
   // Otherwise, produce a temporary and copy into that.
diff --git a/lib/SILGen/SILGenPattern.cpp b/lib/SILGen/SILGenPattern.cpp
index 8944c45..9f5987a 100644
--- a/lib/SILGen/SILGenPattern.cpp
+++ b/lib/SILGen/SILGenPattern.cpp
@@ -741,22 +741,28 @@
 
   auto consumptionKind = outerCMV.getFinalConsumption();
   (void)consumptionKind;
+
+  // If we have an object and it is take always, we need to borrow the value
+  // since we do not own the value at this point.
+  if (outerMV.getType().isObject()) {
+    assert(consumptionKind == CastConsumptionKind::TakeAlways &&
+           "Object without cleanup that is not take_always?!");
+    return {outerMV.borrow(SGF, loc), CastConsumptionKind::BorrowAlways};
+  }
+
+  // Only address only values use TakeOnSuccess.
+  assert(outerMV.getType().isAddressOnly(SGF.getModule()) &&
+         "TakeOnSuccess can only be used with address only values");
+
   assert((consumptionKind == CastConsumptionKind::TakeAlways ||
           consumptionKind == CastConsumptionKind::TakeOnSuccess) &&
          "non-+1 consumption with a cleanup?");
   scope.pushCleanupState(outerMV.getCleanup(),
                          CleanupState::PersistentlyActive);
 
-  // If SILOwnership is enabled and we have an object, borrow instead of take on
-  // success.
-  if (SGF.F.getModule().getOptions().EnableSILOwnership &&
-      outerMV.getType().isObject()) {
-    return {outerMV.borrow(SGF, loc), CastConsumptionKind::BorrowAlways};
-  }
-
   // Success means that we won't end up in the other branch,
   // but failure doesn't.
-  return { outerMV, CastConsumptionKind::TakeOnSuccess };
+  return {outerMV, CastConsumptionKind::TakeOnSuccess};
 }
 
 /// Forward a value down into an irrefutable branch of the decision tree.
@@ -2728,9 +2734,39 @@
   PatternMatchContext switchContext = { emission };
   SwitchStack.push_back(&switchContext);
 
-  // Emit the subject value. Dispatching will consume it.
-  ManagedValue subjectMV = emitRValueAsSingleValue(S->getSubjectExpr());
-  auto subject = ConsumableManagedValue::forOwned(subjectMV);
+  // Emit the subject value. If at +1, dispatching will consume it. If it is at
+  // +0, we just forward down borrows.
+  ManagedValue subjectMV = emitRValueAsSingleValue(
+      S->getSubjectExpr(), SGFContext::AllowGuaranteedPlusZero);
+
+  // Inline constructor for subject.
+  auto subject = ([&]() -> ConsumableManagedValue {
+    // If we have a plus one value...
+    if (subjectMV.isPlusOne(*this)) {
+      // And we have an address that is loadable, perform a load [take].
+      if (subjectMV.getType().isAddress() &&
+          subjectMV.getType().isLoadable(getModule())) {
+        subjectMV = B.createLoadTake(S, subjectMV);
+      }
+      return {subjectMV, CastConsumptionKind::TakeAlways};
+    }
+
+    // If we have a loadable address and +0, perform a load borrow.
+    if (subjectMV.getType().isAddress() &&
+        subjectMV.getType().isLoadable(getModule())) {
+      subjectMV = B.createLoadBorrow(S, subjectMV);
+    }
+
+    // If then we have an object, return it at +0.
+    if (subjectMV.getType().isObject()) {
+      return {subjectMV, CastConsumptionKind::BorrowAlways};
+    }
+
+    // If we have an address only type returned without a cleanup, we
+    // need to do a copy just to be safe. So for efficiency we pass it
+    // down take_always.
+    return {subjectMV.copy(*this, S), CastConsumptionKind::TakeAlways};
+  }());
 
   auto failure = [&](SILLocation location) {
     // If we fail to match anything, we trap. This can happen with a switch
@@ -2855,13 +2891,14 @@
 
   // Set up an initial clause matrix.
   ClauseMatrix clauseMatrix(clauseRows);
-  ConsumableManagedValue subject;
-  if (F.getModule().getOptions().EnableSILOwnership &&
-      exn.getType().isObject()) {
-    subject = {exn.borrow(*this, S), CastConsumptionKind::BorrowAlways};
-  } else {
-    subject = {exn, CastConsumptionKind::TakeOnSuccess};
-  }
+
+  assert(exn.getType().isObject() &&
+         "Error is special and should always be an object");
+  // Our model is that sub-cases get the exception at +0 and the throw (if we
+  // need to rethrow the exception) gets the exception at +1 since we need to
+  // trampoline it's ownership to our caller.
+  ConsumableManagedValue subject = {exn.borrow(*this, S),
+                                    CastConsumptionKind::BorrowAlways};
 
   auto failure = [&](SILLocation location) {
     // If we fail to match anything, just rethrow the exception.
@@ -2874,7 +2911,10 @@
       return;
     }
 
-    // Don't actually kill the exception's cleanup.
+    // Since we borrowed exn before sending it to our subcases, we know that it
+    // must be at +1 at this point. That being said, SILGenPattern will
+    // potentially invoke this for each of the catch statements, so we need to
+    // copy before we pass it into the throw.
     CleanupStateRestorationScope scope(Cleanups);
     if (exn.hasCleanup()) {
       scope.pushCleanupState(exn.getCleanup(),
diff --git a/lib/SILGen/SILGenStmt.cpp b/lib/SILGen/SILGenStmt.cpp
index df9f587..5eb7e95 100644
--- a/lib/SILGen/SILGenStmt.cpp
+++ b/lib/SILGen/SILGenStmt.cpp
@@ -800,6 +800,12 @@
     // Emit all the catch clauses, branching to the end destination if
     // we fall out of one.
     SGF.emitCatchDispatch(S, exn, S->getCatches(), endDest);
+
+    // We assume that exn's cleanup is still valid at this point. To ensure that
+    // we do not re-emit it and do a double consume, we rely on us having
+    // finished emitting code and thus unsetting the insertion point here. This
+    // assert is to make sure this invariant is clear in the code and validated.
+    assert(!SGF.B.hasValidInsertionPoint());
   }
 
   if (hasLabel) {
diff --git a/lib/Sema/CSDiagnostics.cpp b/lib/Sema/CSDiagnostics.cpp
index dd8ff58..d6ea4e7 100644
--- a/lib/Sema/CSDiagnostics.cpp
+++ b/lib/Sema/CSDiagnostics.cpp
@@ -103,10 +103,16 @@
     locator = cs.getConstraintLocator(
         ctor.withPathElement(PathEltKind::ApplyFunction)
             .withPathElement(PathEltKind::ConstructorMember));
-  } else if (isa<UnresolvedDotExpr>(anchor)) {
+  } else if (auto *UDE = dyn_cast<UnresolvedDotExpr>(anchor)) {
     ConstraintLocatorBuilder member(locator);
-    locator =
-        cs.getConstraintLocator(member.withPathElement(PathEltKind::Member));
+
+    if (UDE->getName().isSimpleName(DeclBaseName::createConstructor())) {
+      member = member.withPathElement(PathEltKind::ConstructorMember);
+    } else {
+      member = member.withPathElement(PathEltKind::Member);
+    }
+
+    locator = cs.getConstraintLocator(member);
   } else if (isa<SubscriptExpr>(anchor)) {
     ConstraintLocatorBuilder subscript(locator);
     locator = cs.getConstraintLocator(
diff --git a/lib/Sema/CSDiagnostics.h b/lib/Sema/CSDiagnostics.h
index b3ea2d2..b871548 100644
--- a/lib/Sema/CSDiagnostics.h
+++ b/lib/Sema/CSDiagnostics.h
@@ -163,6 +163,7 @@
   RequirementFailure(Expr *expr, ConstraintSystem &cs,
                      ConstraintLocator *locator)
       : FailureDiagnostic(expr, cs, locator), AffectedDecl(getDeclRef()) {
+    assert(AffectedDecl);
     auto *anchor = getAnchor();
     expr->forEachChildExpr([&](Expr *subExpr) -> Expr * {
       auto *AE = dyn_cast<ApplyExpr>(subExpr);
diff --git a/stdlib/public/SDK/Foundation/AffineTransform.swift b/stdlib/public/SDK/Foundation/AffineTransform.swift
index 80caad0..7978bd9 100644
--- a/stdlib/public/SDK/Foundation/AffineTransform.swift
+++ b/stdlib/public/SDK/Foundation/AffineTransform.swift
@@ -239,7 +239,7 @@
     
     public func inverted() -> AffineTransform? {
         let determinant = (m11 * m22) - (m12 * m21)
-        if fabs(determinant) <= ε {
+        if abs(determinant) <= ε {
             return nil
         }
         var inverse = AffineTransform()
diff --git a/stdlib/public/SDK/Foundation/CMakeLists.txt b/stdlib/public/SDK/Foundation/CMakeLists.txt
index a42c512..8d07ab8 100644
--- a/stdlib/public/SDK/Foundation/CMakeLists.txt
+++ b/stdlib/public/SDK/Foundation/CMakeLists.txt
@@ -59,7 +59,7 @@
   UUID.swift
   CheckClass.mm
 
-  SWIFT_COMPILE_FLAGS "${SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS}" "-Xllvm" "-sil-inline-generics" "-Xllvm" "-sil-partial-specialization" "-swift-version" "3"
+  SWIFT_COMPILE_FLAGS "${SWIFT_RUNTIME_SWIFT_COMPILE_FLAGS}" "-Xllvm" "-sil-inline-generics" "-Xllvm" "-sil-partial-specialization" "-swift-version" "5"
   LINK_FLAGS "${SWIFT_RUNTIME_SWIFT_LINK_FLAGS}"
 
   SWIFT_MODULE_DEPENDS_OSX Darwin CoreFoundation CoreGraphics Dispatch IOKit ObjectiveC # auto-updated
diff --git a/stdlib/public/SDK/Foundation/Calendar.swift b/stdlib/public/SDK/Foundation/Calendar.swift
index 4e87045..2d343e3 100644
--- a/stdlib/public/SDK/Foundation/Calendar.swift
+++ b/stdlib/public/SDK/Foundation/Calendar.swift
@@ -357,7 +357,7 @@
     /// - parameter component: A component to calculate a range for.
     /// - returns: The range, or nil if it could not be calculated.
     public func minimumRange(of component: Component) -> Range<Int>? {
-        return _handle.map { $0.minimumRange(of: Calendar._toCalendarUnit([component])).toRange() }
+        return _handle.map { Range($0.minimumRange(of: Calendar._toCalendarUnit([component]))) }
     }
     
     /// The maximum range limits of the values that a given component can take on in the receive
@@ -366,7 +366,7 @@
     /// - parameter component: A component to calculate a range for.
     /// - returns: The range, or nil if it could not be calculated.
     public func maximumRange(of component: Component) -> Range<Int>? {
-        return _handle.map { $0.maximumRange(of: Calendar._toCalendarUnit([component])).toRange() }
+        return _handle.map { Range($0.maximumRange(of: Calendar._toCalendarUnit([component]))) }
     }
     
     
@@ -383,7 +383,7 @@
     /// - parameter date: The absolute time for which the calculation is performed.
     /// - returns: The range of absolute time values smaller can take on in larger at the time specified by date. Returns `nil` if larger is not logically bigger than smaller in the calendar, or the given combination of components does not make sense (or is a computation which is undefined).
     public func range(of smaller: Component, in larger: Component, for date: Date) -> Range<Int>? {
-        return _handle.map { $0.range(of: Calendar._toCalendarUnit([smaller]), in: Calendar._toCalendarUnit([larger]), for: date).toRange() }
+        return _handle.map { Range($0.range(of: Calendar._toCalendarUnit([smaller]), in: Calendar._toCalendarUnit([larger]), for: date)) }
     }
     
     @available(*, unavailable, message: "use range(of:in:for:) instead")
diff --git a/stdlib/public/SDK/Foundation/Data.swift b/stdlib/public/SDK/Foundation/Data.swift
index 57e14cb..f666f0f 100644
--- a/stdlib/public/SDK/Foundation/Data.swift
+++ b/stdlib/public/SDK/Foundation/Data.swift
@@ -141,6 +141,8 @@
                 return d.bytes.advanced(by: -_offset)
             case .customMutableReference(let d):
                 return d.bytes.advanced(by: -_offset)
+            @unknown default:
+                fatalError("Unknown Data backing type")
             }
         }
     }
@@ -267,6 +269,8 @@
                 return data.mutableBytes.advanced(by: -_offset)
             case .customMutableReference(let d):
                 return d.mutableBytes.advanced(by: -_offset)
+            @unknown default:
+                fatalError("Unknown Data backing type")
             }
         }
     }
@@ -287,6 +291,8 @@
                 return d.length
             case .customMutableReference(let d):
                 return d.length
+            @unknown default:
+                fatalError("Unknown Data backing type")
             }
         }
         @inlinable
@@ -447,6 +453,8 @@
             _backing = .customMutableReference(data)
         case .customMutableReference(let d):
             d.length = length
+        @unknown default:
+            fatalError("Unknown Data backing type")
         }
     }
     
@@ -478,6 +486,8 @@
             _backing = .customMutableReference(data)
         case .customMutableReference(let d):
             d.append(bytes, length: length)
+        @unknown default:
+            fatalError("Unknown Data backing type")
         }
         
     }
@@ -528,6 +538,8 @@
             _backing = .customReference(data)
         case .customMutableReference(let d):
             d.increaseLength(by: extraLength)
+        @unknown default:
+            fatalError("Unknown Data backing type")
         }
         
     }
@@ -614,6 +626,8 @@
             _backing = .customMutableReference(data)
         case .customMutableReference(let d):
             d.replaceBytes(in: NSRange(location: range.location - _offset, length: range.length), withBytes: bytes!)
+        @unknown default:
+            fatalError("Unknown Data backing type")
         }
     }
     
@@ -664,6 +678,8 @@
             _backing = .customMutableReference(data)
         case .customMutableReference(let d):
             d.replaceBytes(in: range, withBytes: replacementBytes, length: replacementLength)
+        @unknown default:
+            fatalError("Unknown Data backing type")
         }
     }
     
@@ -697,6 +713,8 @@
             _backing = .customMutableReference(data)
         case .customMutableReference(let d):
             d.resetBytes(in: range)
+        @unknown default:
+            fatalError("Unknown Data backing type")
         }
         
     }
@@ -887,6 +905,8 @@
             } else {
                 return _DataStorage(mutableReference: d.subdata(with: NSRange(location: range.lowerBound, length: range.count))._bridgeToObjectiveC().mutableCopy() as! NSMutableData, offset: range.lowerBound)
             }
+        @unknown default:
+            fatalError("Unknown Data backing type")
         }
     }
     
diff --git a/stdlib/public/SDK/Foundation/ExtraStringAPIs.swift b/stdlib/public/SDK/Foundation/ExtraStringAPIs.swift
index e6e5a84..6865dcd 100644
--- a/stdlib/public/SDK/Foundation/ExtraStringAPIs.swift
+++ b/stdlib/public/SDK/Foundation/ExtraStringAPIs.swift
@@ -15,19 +15,18 @@
   @available(swift, deprecated: 3.2)
   @available(swift, obsoleted: 4.0)
   public init(_ offset: Int) {
-    assert(offset >= 0, "Negative UTF16 index offset not allowed")
-    self.init(encodedOffset: offset)
+    fatalError()
   }
 
   @available(swift, deprecated: 3.2)
   @available(swift, obsoleted: 4.0)
   public func distance(to other: String.UTF16View.Index?) -> Int {
-    return _offset.distance(to: other!._offset)
+    fatalError()
   }
 
   @available(swift, deprecated: 3.2)
   @available(swift, obsoleted: 4.0)
   public func advanced(by n: Int) -> String.UTF16View.Index {
-    return String.UTF16View.Index(_offset.advanced(by: n))
+    fatalError()
   }
 }
diff --git a/stdlib/public/SDK/Foundation/JSONEncoder.swift b/stdlib/public/SDK/Foundation/JSONEncoder.swift
index 4d1bfc4..8f90826 100644
--- a/stdlib/public/SDK/Foundation/JSONEncoder.swift
+++ b/stdlib/public/SDK/Foundation/JSONEncoder.swift
@@ -1077,7 +1077,7 @@
             guard !stringKey.isEmpty else { return stringKey }
         
             // Find the first non-underscore character
-            guard let firstNonUnderscore = stringKey.index(where: { $0 != "_" }) else {
+            guard let firstNonUnderscore = stringKey.firstIndex(where: { $0 != "_" }) else {
                 // Reached the end without finding an _
                 return stringKey
             }
diff --git a/stdlib/public/SDK/Foundation/NSError.swift b/stdlib/public/SDK/Foundation/NSError.swift
index 29aa4a2..598f54d 100644
--- a/stdlib/public/SDK/Foundation/NSError.swift
+++ b/stdlib/public/SDK/Foundation/NSError.swift
@@ -428,16 +428,6 @@
   init(_nsError error: NSError)
 }
 
-/// TODO: Better way to do this?
-internal func _stringDictToAnyHashableDict(_ input: [String : Any])
-    -> [AnyHashable : Any] {
-  var result = [AnyHashable : Any](minimumCapacity: input.count)
-  for (k, v) in input {
-    result[k] = v
-  }
-  return result
-}
-
 /// Various helper implementations for _BridgedStoredNSError
 extension _BridgedStoredNSError {
   public var code: Code {
@@ -449,7 +439,7 @@
   public init(_ code: Code, userInfo: [String : Any] = [:]) {
     self.init(_nsError: NSError(domain: Self.errorDomain,
                                 code: unsafeBinaryIntegerToInt(code.rawValue),
-                                userInfo: _stringDictToAnyHashableDict(userInfo)))
+                                userInfo: userInfo))
   }
 
   /// The user-info dictionary for an error that was bridged from
@@ -483,8 +473,7 @@
   var errorUserInfo: [String : Any] {
     var result: [String : Any] = [:]
     for (key, value) in _nsError.userInfo {
-      guard let stringKey = key.base as? String else { continue }
-      result[stringKey] = value
+      result[key] = value
     }
     return result
   }
@@ -615,7 +604,7 @@
 
 extension CocoaError {
     public static func error(_ code: CocoaError.Code, userInfo: [AnyHashable : Any]? = nil, url: URL? = nil) -> Error {
-        var info: [AnyHashable : Any] = userInfo ?? [:]
+        var info: [String : Any] = userInfo as? [String : Any] ?? [:]
         if let url = url {
             info[NSURLErrorKey] = url
         }
diff --git a/stdlib/public/SDK/Foundation/NSObject.swift b/stdlib/public/SDK/Foundation/NSObject.swift
index 04e4cd3..e6cde6f 100644
--- a/stdlib/public/SDK/Foundation/NSObject.swift
+++ b/stdlib/public/SDK/Foundation/NSObject.swift
@@ -149,8 +149,8 @@
         let bridgeClass: AnyClass = NSKeyValueObservation.self
         let observeSel = #selector(NSObject.observeValue(forKeyPath:of:change:context:))
         let swapSel = #selector(NSKeyValueObservation._swizzle_me_observeValue(forKeyPath:of:change:context:))
-        let rootObserveImpl = class_getInstanceMethod(bridgeClass, observeSel)
-        let swapObserveImpl = class_getInstanceMethod(bridgeClass, swapSel)
+        let rootObserveImpl = class_getInstanceMethod(bridgeClass, observeSel)!
+        let swapObserveImpl = class_getInstanceMethod(bridgeClass, swapSel)!
         method_exchangeImplementations(rootObserveImpl, swapObserveImpl)
         return nil
     }()
diff --git a/stdlib/public/SDK/Foundation/NSStringAPI.swift b/stdlib/public/SDK/Foundation/NSStringAPI.swift
index ba2cdff..0e9ebbe 100644
--- a/stdlib/public/SDK/Foundation/NSStringAPI.swift
+++ b/stdlib/public/SDK/Foundation/NSStringAPI.swift
@@ -1217,12 +1217,12 @@
     let range = range.relative(to: self)
     _ns.enumerateLinguisticTags(
       in: _toRelativeNSRange(range),
-      scheme: tagScheme._ephemeralString,
+      scheme: NSLinguisticTagScheme(rawValue: tagScheme._ephemeralString),
       options: opts,
       orthography: orthography != nil ? orthography! : nil
     ) {
       var stop_ = false
-      body($0, self._range($1), self._range($2), &stop_)
+      body($0!.rawValue, self._range($1), self._range($2), &stop_)
       if stop_ {
         $3.pointee = true
       }
@@ -1463,7 +1463,7 @@
     let result = tokenRanges._withNilOrAddress(of: &nsTokenRanges) {
       self._ns.linguisticTags(
         in: _toRelativeNSRange(range.relative(to: self)),
-        scheme: tagScheme._ephemeralString,
+        scheme: NSLinguisticTagScheme(rawValue: tagScheme._ephemeralString),
         options: opts,
         orthography: orthography,
         tokenRanges: $0) as NSArray
diff --git a/stdlib/public/SwiftShims/DispatchOverlayShims.h b/stdlib/public/SwiftShims/DispatchOverlayShims.h
index fc51383..f677747 100644
--- a/stdlib/public/SwiftShims/DispatchOverlayShims.h
+++ b/stdlib/public/SwiftShims/DispatchOverlayShims.h
@@ -193,9 +193,9 @@
 
 static inline void _swift_dispatch_apply_current(
     size_t iterations,
-    void SWIFT_DISPATCH_NOESCAPE (^block)(long)) {
+    void SWIFT_DISPATCH_NOESCAPE (^block)(intptr_t)) {
   dispatch_apply(iterations, (dispatch_queue_t _Nonnull)0, ^(size_t i){
-    block((long)i);
+    block((intptr_t)i);
   });
 }
 
diff --git a/test/ClangImporter/Inputs/custom-modules/RedeclaredErrorEnum/Base.h b/test/ClangImporter/Inputs/custom-modules/RedeclaredErrorEnum/Base.h
new file mode 100644
index 0000000..c708209
--- /dev/null
+++ b/test/ClangImporter/Inputs/custom-modules/RedeclaredErrorEnum/Base.h
@@ -0,0 +1,9 @@
+@import Foundation;
+
+extern NSString * const SomeErrorDomain;
+// typedef NS_ERROR_ENUM(SomeErrorDomain, SomeErrorCode) { ... }
+typedef enum SomeErrorCode : long SomeErrorCode;
+enum __attribute__((ns_error_domain(SomeErrorDomain))) SomeErrorCode : long {
+  SomeErrorX,
+  SomeErrorY
+};
diff --git a/test/ClangImporter/Inputs/custom-modules/RedeclaredErrorEnum/Redeclared.h b/test/ClangImporter/Inputs/custom-modules/RedeclaredErrorEnum/Redeclared.h
new file mode 100644
index 0000000..94f733a
--- /dev/null
+++ b/test/ClangImporter/Inputs/custom-modules/RedeclaredErrorEnum/Redeclared.h
@@ -0,0 +1,7 @@
+@import Foundation;
+@import Base;
+
+extern NSString * const SomeErrorDomain;
+// typedef NS_ERROR_ENUM(SomeErrorDomain, SomeErrorCode);
+typedef enum SomeErrorCode : long SomeErrorCode;
+enum __attribute__((ns_error_domain(SomeErrorDomain))) SomeErrorCode : long;
\ No newline at end of file
diff --git a/test/ClangImporter/Inputs/custom-modules/RedeclaredErrorEnum/module.modulemap b/test/ClangImporter/Inputs/custom-modules/RedeclaredErrorEnum/module.modulemap
new file mode 100644
index 0000000..24ea6de
--- /dev/null
+++ b/test/ClangImporter/Inputs/custom-modules/RedeclaredErrorEnum/module.modulemap
@@ -0,0 +1,8 @@
+module Base {
+  header "Base.h"
+}
+
+module Redeclared {
+  header "Redeclared.h"
+  export *
+}
\ No newline at end of file
diff --git a/test/ClangImporter/enum-error-redeclared.swift b/test/ClangImporter/enum-error-redeclared.swift
new file mode 100644
index 0000000..6833908
--- /dev/null
+++ b/test/ClangImporter/enum-error-redeclared.swift
@@ -0,0 +1,11 @@
+// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck %s -verify -enable-objc-interop -I %S/Inputs/custom-modules/RedeclaredErrorEnum
+
+import Redeclared
+
+// Referencing this error type (defined in Base, redeclared in Redeclared)
+// used to cause a compiler crash (rdar://problem/45414271).
+_ = SomeError.self
+_ = SomeError.Code.self
+
+_ = Redeclared.SomeError.self
+_ = Base.SomeError.self
diff --git a/test/SIL/ownership-verifier/over_consume.sil b/test/SIL/ownership-verifier/over_consume.sil
index f87f5fa..be04631 100644
--- a/test/SIL/ownership-verifier/over_consume.sil
+++ b/test/SIL/ownership-verifier/over_consume.sil
@@ -22,7 +22,12 @@
 case none
 }
 
-class SuperKlass {}
+class SuperKlass {
+  func doSomething()
+}
+
+class Klass : SuperKlass {
+}
 
 ///////////
 // Tests //
@@ -434,3 +439,21 @@
   %9999 = tuple()
   return %9999 : $()
 }
+
+// CHECK-LABEL: Function: 'consume_with_classmethod'
+// CHECK: Found use after free?!
+// CHECK: Value:   %2 = upcast %0 : $Klass to $SuperKlass
+// CHECK: Consuming User:   store %2 to [init] %1 : $*SuperKlass
+// CHECK: Non Consuming User:   %4 = class_method %2 : $SuperKlass, #SuperKlass.doSomething!1 : (SuperKlass) -> () -> (), $@convention(method) (@guaranteed SuperKlass) -> ()
+// CHECK: Block: bb0
+sil @consume_with_classmethod : $@convention(thin) (@owned Klass) -> () {
+bb0(%0 : @owned $Klass):
+  %1 = alloc_stack $SuperKlass
+  %2 = upcast %0 : $Klass to $SuperKlass
+  store %2 to [init] %1 : $*SuperKlass
+  %3 = class_method %2 : $SuperKlass, #SuperKlass.doSomething!1 : (SuperKlass) -> () -> (), $@convention(method) (@guaranteed SuperKlass) -> ()
+  destroy_addr %1 : $*SuperKlass
+  dealloc_stack %1 : $*SuperKlass
+  %9999 = tuple()
+  return %9999 : $()
+}
\ No newline at end of file
diff --git a/test/SILGen/class_bound_protocols.swift b/test/SILGen/class_bound_protocols.swift
index 7de76f1..acbddd8 100644
--- a/test/SILGen/class_bound_protocols.swift
+++ b/test/SILGen/class_bound_protocols.swift
@@ -1,5 +1,5 @@
 
-// RUN: %target-swift-emit-silgen -parse-stdlib -parse-as-library -module-name Swift %s | %FileCheck %s
+// RUN: %target-swift-emit-silgen -enable-sil-ownership -parse-stdlib -parse-as-library -module-name Swift %s | %FileCheck %s
 
 enum Optional<T> {
   case some(T)
@@ -132,8 +132,9 @@
   // CHECK: [[READ:%.*]] = begin_access [read] [unknown] [[XBOX_PB]] : $*ClassBound
   // CHECK: [[X:%.*]] = load [copy] [[READ]] : $*ClassBound
   // CHECK: [[PROJ:%.*]] = open_existential_ref [[X]] : $ClassBound to $[[OPENED:@opened(.*) ClassBound]]
+  // CHECK: [[BORROWED_PROJ:%.*]] = begin_borrow [[PROJ]]
   // CHECK: [[METHOD:%.*]] = witness_method $[[OPENED]], #ClassBound.classBoundMethod!1
-  // CHECK: apply [[METHOD]]<[[OPENED]]>([[PROJ]])
+  // CHECK: apply [[METHOD]]<[[OPENED]]>([[BORROWED_PROJ]])
   // CHECK: destroy_value [[PROJ]]
   // CHECK: destroy_value [[XBOX]]
 }
diff --git a/test/SILGen/errors.swift b/test/SILGen/errors.swift
index 548b19e..4813da3 100644
--- a/test/SILGen/errors.swift
+++ b/test/SILGen/errors.swift
@@ -1,17 +1,5 @@
 // RUN: %target-swift-emit-silgen -parse-stdlib -enable-sil-ownership -Xllvm -sil-print-debuginfo -verify -primary-file %s %S/Inputs/errors_other.swift | %FileCheck %s
 
-// TODO: Turn back on ownership verification. I turned off the verification on
-// this file since it shows an ownership error that does not affect
-// codegen. Specifically when we destroy the temporary array we use for the
-// variadic tuple, we try to borrow the temporary array when we pass it to the
-// destroy function. This makes the ownership verifier think that the owned
-// value we are trying to destroy is not cleaned up. But once ownership is
-// stripped out, the destroy array function still does what it needs to do. The
-// actual fix for this would require a bunch of surgery in SILGenApply around
-// how function types are computed and preserving non-canonical function types
-// through SILGenApply. This is something that can be done after +0 is turned
-// on.
-
 import Swift
 
 class Cat {}
@@ -176,6 +164,83 @@
   }
 }
 
+// Make sure that if we catch an error in a throwing function we borrow the
+// error and only consume the error in the rethrow block.
+//
+// CHECK-LABEL: sil hidden @$s6errors20all_together_now_twoyAA3CatCSgSbKF : $@convention(thin) (Bool) -> (@owned Optional<Cat>, @error Error) {
+// CHECK: bb0(
+// CHECK-NOT: bb1
+// CHECK:   try_apply {{.*}}, normal [[NORMAL_BB:bb[0-9]+]], error [[ERROR_BB:bb[0-9]+]]
+//
+// CHECK: [[ERROR_BB]]([[ERROR:%.*]] : @owned $Error):
+// CHECK:   [[BORROWED_ERROR:%.*]] = begin_borrow [[ERROR]]
+// CHECK:   [[COPIED_ERROR:%.*]] = copy_value [[BORROWED_ERROR]]
+// CHECK:   store [[COPIED_ERROR]] to [init] [[CAST_INPUT_MEM:%.*]] : $*Error
+// CHECK:   checked_cast_addr_br copy_on_success Error in [[CAST_INPUT_MEM]] : $*Error to HomeworkError in [[CAST_OUTPUT_MEM:%.*]] : $*HomeworkError, [[CAST_YES_BB:bb[0-9]+]], [[CAST_NO_BB:bb[0-9]+]],
+//
+// CHECK: [[CAST_YES_BB]]:
+// CHECK:   [[SUBERROR:%.*]] = load [take] [[CAST_OUTPUT_MEM]]
+// CHECK:   switch_enum [[SUBERROR]] : $HomeworkError, case #HomeworkError.TooHard!enumelt: {{bb[0-9]+}}, default [[SWITCH_MATCH_FAIL_BB:bb[0-9]+]],
+//
+// CHECK: [[SWITCH_MATCH_FAIL_BB]]([[SUBERROR:%.*]] : @owned $HomeworkError):
+// CHECK:   destroy_value [[SUBERROR]]
+// CHECK:   end_borrow [[BORROWED_ERROR]]
+// CHECK:   br [[RETHROW_BB:bb[0-9]+]]([[ERROR]] : $Error)
+//
+// CHECK: [[CAST_NO_BB]]:
+// CHECK:   end_borrow [[BORROWED_ERROR]]
+// CHECK:   br [[RETHROW_BB]]([[ERROR]] : $Error)
+//
+// CHECK: [[RETHROW_BB]]([[ERROR_FOR_RETHROW:%.*]] : @owned $Error):
+// CHECK:   throw [[ERROR_FOR_RETHROW]]
+// CHECK: } // end sil function '$s6errors20all_together_now_twoyAA3CatCSgSbKF'
+func all_together_now_two(_ flag: Bool) throws -> Cat? {
+  do {
+    return try dont_return(Cat())
+  } catch HomeworkError.TooHard {
+    return nil
+  }
+}
+
+// Same as the previous test, but with multiple cases instead of just one.
+//
+// CHECK-LABEL: sil hidden @$s6errors22all_together_now_threeyAA3CatCSgSbKF : $@convention(thin) (Bool) -> (@owned Optional<Cat>, @error Error) {
+// CHECK: bb0(
+// CHECK-NOT: bb1
+// CHECK:   try_apply {{.*}}, normal [[NORMAL_BB:bb[0-9]+]], error [[ERROR_BB:bb[0-9]+]]
+//
+// CHECK: [[ERROR_BB]]([[ERROR:%.*]] : @owned $Error):
+// CHECK:   [[BORROWED_ERROR:%.*]] = begin_borrow [[ERROR]]
+// CHECK:   [[COPIED_ERROR:%.*]] = copy_value [[BORROWED_ERROR]]
+// CHECK:   store [[COPIED_ERROR]] to [init] [[CAST_INPUT_MEM:%.*]] : $*Error
+// CHECK:   checked_cast_addr_br copy_on_success Error in [[CAST_INPUT_MEM]] : $*Error to HomeworkError in [[CAST_OUTPUT_MEM:%.*]] : $*HomeworkError, [[CAST_YES_BB:bb[0-9]+]], [[CAST_NO_BB:bb[0-9]+]],
+//
+// CHECK: [[CAST_YES_BB]]:
+// CHECK:   [[SUBERROR:%.*]] = load [take] [[CAST_OUTPUT_MEM]]
+// CHECK:   switch_enum [[SUBERROR]] : $HomeworkError, case #HomeworkError.TooHard!enumelt: {{bb[0-9]+}}, case #HomeworkError.TooMuch!enumelt: {{bb[0-9]+}}, default [[SWITCH_MATCH_FAIL_BB:bb[0-9]+]],
+//
+// CHECK: [[SWITCH_MATCH_FAIL_BB]]([[SUBERROR:%.*]] : @owned $HomeworkError):
+// CHECK:   destroy_value [[SUBERROR]]
+// CHECK:   end_borrow [[BORROWED_ERROR]]
+// CHECK:   br [[RETHROW_BB:bb[0-9]+]]([[ERROR]] : $Error)
+//
+// CHECK: [[CAST_NO_BB]]:
+// CHECK:   end_borrow [[BORROWED_ERROR]]
+// CHECK:   br [[RETHROW_BB]]([[ERROR]] : $Error)
+//
+// CHECK: [[RETHROW_BB]]([[ERROR_FOR_RETHROW:%.*]] : @owned $Error):
+// CHECK:   throw [[ERROR_FOR_RETHROW]]
+// CHECK: } // end sil function '$s6errors22all_together_now_threeyAA3CatCSgSbKF'
+func all_together_now_three(_ flag: Bool) throws -> Cat? {
+  do {
+    return try dont_return(Cat())
+  } catch HomeworkError.TooHard {
+    return nil
+  } catch HomeworkError.TooMuch {
+    return nil
+  }
+}
+
 //   Catch in non-throwing context.
 // CHECK-LABEL: sil hidden @$s6errors11catch_a_catAA3CatCyF : $@convention(thin) () -> @owned Cat
 // CHECK-NEXT: bb0:
diff --git a/test/SILGen/indirect_enum.swift b/test/SILGen/indirect_enum.swift
index e7615f1..d0d91ed 100644
--- a/test/SILGen/indirect_enum.swift
+++ b/test/SILGen/indirect_enum.swift
@@ -149,10 +149,8 @@
 // CHECK-LABEL: sil hidden @$s13indirect_enum11switchTreeAyyAA0D1AOyxGlF : $@convention(thin) <T> (@guaranteed TreeA<T>) -> () {
 func switchTreeA<T>(_ x: TreeA<T>) {
   // CHECK: bb0([[ARG:%.*]] : @guaranteed $TreeA<T>):
-  // --           x +2
-  // CHECK:       [[ARG_COPY:%.*]] = copy_value [[ARG]]
-  // CHECK:       [[BORROWED_ARG_COPY:%.*]] = begin_borrow [[ARG_COPY]]
-  // CHECK:       switch_enum [[BORROWED_ARG_COPY]] : $TreeA<T>,
+  // --           x +0
+  // CHECK:       switch_enum [[ARG]] : $TreeA<T>,
   // CHECK:          case #TreeA.Nil!enumelt: [[NIL_CASE:bb1]],
   // CHECK:          case #TreeA.Leaf!enumelt.1: [[LEAF_CASE:bb2]],
   // CHECK:          case #TreeA.Branch!enumelt.1: [[BRANCH_CASE:bb3]],
@@ -168,7 +166,7 @@
   // CHECK:       function_ref @$s13indirect_enum1b{{[_0-9a-zA-Z]*}}F
   // CHECK:       destroy_addr [[X]]
   // CHECK:       dealloc_stack [[X]]
-  // --           x +1
+  // --           x +0
   // CHECK:       br [[OUTER_CONT]]
   case .Leaf(let x):
     b(x)
@@ -204,8 +202,7 @@
     c(x, y)
 
   // CHECK:     [[DEFAULT]]:
-  // --           x +1
-  // CHECK:       destroy_value [[ARG_COPY]]
+  // --           x +0
   default:
     d()
   }
diff --git a/test/SILGen/switch.swift b/test/SILGen/switch.swift
index a6f8a93..18aaace 100644
--- a/test/SILGen/switch.swift
+++ b/test/SILGen/switch.swift
@@ -413,9 +413,7 @@
 // CHECK-LABEL: sil hidden @$s6switch16test_isa_class_11xyAA1BC_tF : $@convention(thin) (@guaranteed B) -> () {
 func test_isa_class_1(x: B) {
   // CHECK: bb0([[X:%.*]] : @guaranteed $B):
-  // CHECK:   [[X_COPY:%.*]] = copy_value [[X]]
-  // CHECK:   [[BORROWED_X_COPY:%.*]] = begin_borrow [[X_COPY]]
-  // CHECK:   checked_cast_br [[BORROWED_X_COPY]] : $B to $D1, [[IS_D1:bb[0-9]+]], [[IS_NOT_D1:bb[0-9]+]]
+  // CHECK:   checked_cast_br [[X]] : $B to $D1, [[IS_D1:bb[0-9]+]], [[IS_NOT_D1:bb[0-9]+]]
   switch x {
 
   // CHECK: [[IS_D1]]([[CAST_D1:%.*]] : @guaranteed $D1):
@@ -427,8 +425,6 @@
   case is D1 where runced():
   // CHECK:   destroy_value [[CAST_D1_COPY]]
   // CHECK:   end_borrow [[CAST_D1]]
-  // CHECK:   end_borrow [[BORROWED_X_COPY]]
-  // CHECK:   destroy_value [[X_COPY]]
   // CHECK:   function_ref @$s6switch1ayyF
   // CHECK:   br [[CONT:bb[0-9]+]]
     a()
@@ -436,31 +432,25 @@
   // CHECK: [[NO_CASE1]]:
   // CHECK-NEXT:   destroy_value [[CAST_D1_COPY]]
   // CHECK-NEXT:   end_borrow [[CAST_D1]]
-  // CHECK-NEXT:   end_borrow [[BORROWED_X_COPY]]
   // CHECK:   br [[NEXT_CASE:bb[0-9]+]]
 
   // CHECK: [[IS_NOT_D1]]([[CASTFAIL_D1:%.*]] : @guaranteed $B):
   // CHECK-NEXT:   end_borrow [[CASTFAIL_D1]]
-  // CHECK-NEXT:   end_borrow [[BORROWED_X_COPY]]
   // CHECK-NEXT:   br [[NEXT_CASE]]
 
   // CHECK: [[NEXT_CASE]]:
-  // CHECK:   [[BORROWED_X_COPY:%.*]] = begin_borrow [[X_COPY]]
-  // CHECK:   checked_cast_br [[BORROWED_X_COPY]] : $B to $D2, [[IS_D2:bb[0-9]+]], [[IS_NOT_D2:bb[0-9]+]]
+  // CHECK:   checked_cast_br [[X]] : $B to $D2, [[IS_D2:bb[0-9]+]], [[IS_NOT_D2:bb[0-9]+]]
   case is D2:
   // CHECK: [[IS_D2]]([[CAST_D2:%.*]] : @guaranteed $D2):
   // CHECK:   [[CAST_D2_COPY:%.*]] = copy_value [[CAST_D2]]
   // CHECK:   destroy_value [[CAST_D2_COPY]]
-  // CHECK:   end_borrow [[BORROWED_X_COPY]]
-  // CHECK:   destroy_value [[X_COPY]]
   // CHECK:   function_ref @$s6switch1byyF
   // CHECK:   br [[CONT]]
     b()
 
   // CHECK: [[IS_NOT_D2]]([[CASTFAIL_D2:%.*]] : @guaranteed $B):
   // CHECK:   end_borrow [[CASTFAIL_D2]]
-  // CHECK:   [[BORROWED_X_COPY:%.*]] = begin_borrow [[X_COPY]]
-  // CHECK:   checked_cast_br [[BORROWED_X_COPY]] : $B to $E, [[IS_E:bb[0-9]+]], [[IS_NOT_E:bb[0-9]+]]
+  // CHECK:   checked_cast_br [[X]] : $B to $E, [[IS_E:bb[0-9]+]], [[IS_NOT_E:bb[0-9]+]]
   case is E where funged():
   // CHECK: [[IS_E]]([[CAST_E:%.*]] : @guaranteed $E):
   // CHECK:   [[CAST_E_COPY:%.*]] = copy_value [[CAST_E]]
@@ -469,8 +459,6 @@
 
   // CHECK: [[CASE3]]:
   // CHECK:   destroy_value [[CAST_E_COPY]]
-  // CHECK:   end_borrow [[BORROWED_X_COPY]]
-  // CHECK:   destroy_value [[X_COPY]]
   // CHECK:   function_ref @$s6switch1cyyF
   // CHECK:   br [[CONT]]
     c()
@@ -478,7 +466,6 @@
   // CHECK: [[NO_CASE3]]:
   // CHECK-NEXT:   destroy_value [[CAST_E_COPY]]
   // CHECK-NEXT:   end_borrow
-  // CHECK-NEXT:   end_borrow [[BORROWED_X_COPY]]
   // CHECK:   br [[NEXT_CASE:bb[0-9]+]]
 
   // CHECK: [[IS_NOT_E]]([[NOTCAST_E:%.*]] : @guaranteed $B):
@@ -486,15 +473,13 @@
   // CHECK:   br [[NEXT_CASE]]
 
   // CHECK: [[NEXT_CASE]]:
-  // CHECK: [[BORROWED_X_COPY:%.*]] = begin_borrow [[X_COPY]]
-  // CHECK:   checked_cast_br [[BORROWED_X_COPY]] : $B to $C, [[IS_C:bb[0-9]+]], [[IS_NOT_C:bb[0-9]+]]
+  // CHECK:   checked_cast_br [[X]] : $B to $C, [[IS_C:bb[0-9]+]], [[IS_NOT_C:bb[0-9]+]]
 
   case is C:
   // CHECK: [[IS_C]]([[CAST_C:%.*]] : @guaranteed $C):
   // CHECK:   [[CAST_C_COPY:%.*]] = copy_value [[CAST_C]]
   // CHECK:   destroy_value [[CAST_C_COPY]]
   // CHECK:   end_borrow [[CAST_C]]
-  // CHECK:   destroy_value [[X_COPY]]
   // CHECK:   function_ref @$s6switch1dyyF
   // CHECK:   br [[CONT]]
     d()
@@ -502,7 +487,6 @@
   // CHECK: [[IS_NOT_C]]([[NOCAST_C:%.*]] : @guaranteed $B):
   // CHECK:   end_borrow [[NOCAST_C]]
   default:
-  // CHECK:    destroy_value [[X_COPY]]
   // CHECK:    function_ref @$s6switch1eyyF
   // CHECK:    br [[CONT]]
     e()
@@ -517,11 +501,9 @@
 // CHECK-LABEL: sil hidden @$s6switch16test_isa_class_21xyXlAA1BC_tF : $@convention(thin)
 func test_isa_class_2(x: B) -> AnyObject {
   // CHECK: bb0([[X:%.*]] : @guaranteed $B):
-  // CHECK:   [[X_COPY:%.*]] = copy_value [[X]]
-  // CHECK:   [[BORROWED_X_COPY:%.*]] = begin_borrow [[X_COPY]]
   switch x {
 
-  // CHECK:   checked_cast_br [[BORROWED_X_COPY]] : $B to $D1, [[IS_D1:bb[0-9]+]], [[IS_NOT_D1:bb[0-9]+]]
+  // CHECK:   checked_cast_br [[X]] : $B to $D1, [[IS_D1:bb[0-9]+]], [[IS_NOT_D1:bb[0-9]+]]
   case let y as D1 where runced():
   // CHECK: [[IS_D1]]([[CAST_D1:%.*]] : @guaranteed $D1):
   // CHECK:   [[CAST_D1_COPY:%.*]] = copy_value [[CAST_D1]]
@@ -535,8 +517,6 @@
   // CHECK:   [[RET:%.*]] = init_existential_ref [[CAST_D1_COPY_COPY]]
   // CHECK:   end_borrow [[BORROWED_CAST_D1_COPY]]
   // CHECK:   destroy_value [[CAST_D1_COPY]]
-  // CHECK:   end_borrow [[BORROWED_X_COPY]]
-  // CHECK:   destroy_value [[X_COPY]] : $B
   // CHECK:   br [[CONT:bb[0-9]+]]([[RET]] : $AnyObject)
     a()
     return y
@@ -550,8 +530,7 @@
   // CHECK:   br [[NEXT_CASE]]
 
   // CHECK: [[NEXT_CASE]]:
-  // CHECK:   [[BORROWED_X_COPY:%.*]] = begin_borrow [[X_COPY]]
-  // CHECK:   checked_cast_br [[BORROWED_X_COPY]] : $B to $D2, [[CASE2:bb[0-9]+]], [[IS_NOT_D2:bb[0-9]+]]
+  // CHECK:   checked_cast_br [[X]] : $B to $D2, [[CASE2:bb[0-9]+]], [[IS_NOT_D2:bb[0-9]+]]
   case let y as D2:
   // CHECK: [[CASE2]]([[CAST_D2:%.*]] : @guaranteed $D2):
   // CHECK:   [[CAST_D2_COPY:%.*]] = copy_value [[CAST_D2]]
@@ -561,16 +540,13 @@
   // CHECK:   [[RET:%.*]] = init_existential_ref [[CAST_D2_COPY_COPY]]
   // CHECK:   end_borrow [[BORROWED_CAST_D2_COPY]]
   // CHECK:   destroy_value [[CAST_D2_COPY]]
-  // CHECK:   end_borrow [[BORROWED_X_COPY]]
-  // CHECK:   destroy_value [[X_COPY]]
   // CHECK:   br [[CONT]]([[RET]] : $AnyObject)
     b()
     return y
 
   // CHECK: [[IS_NOT_D2]]([[NOCAST_D2:%.*]] : @guaranteed $B):
   // CHECK:   end_borrow [[NOCAST_D2]]
-  // CHECK:   [[BORROWED_X_COPY:%.*]] = begin_borrow [[X_COPY]]
-  // CHECK:   checked_cast_br [[BORROWED_X_COPY]] : $B to $E, [[IS_E:bb[0-9]+]], [[IS_NOT_E:bb[0-9]+]]
+  // CHECK:   checked_cast_br [[X]] : $B to $E, [[IS_E:bb[0-9]+]], [[IS_NOT_E:bb[0-9]+]]
   case let y as E where funged():
   // CHECK: [[IS_E]]([[CAST_E:%.*]] : @guaranteed $E):
   // CHECK:   [[CAST_E_COPY:%.*]] = copy_value [[CAST_E]]
@@ -585,7 +561,6 @@
   // CHECK:   end_borrow [[BORROWED_CAST_E_COPY]]
   // CHECK:   destroy_value [[CAST_E_COPY]]
   // CHECK:   end_borrow [[CAST_E]]
-  // CHECK:   destroy_value [[X_COPY]] : $B
   // CHECK:   br [[CONT]]([[RET]] : $AnyObject)
     c()
     return y
@@ -599,8 +574,7 @@
   // CHECK:   br [[NEXT_CASE]]
 
   // CHECK: [[NEXT_CASE]]
-  // CHECK:   [[BORROWED_X_COPY:%.*]] = begin_borrow [[X_COPY]]
-  // CHECK:   checked_cast_br [[BORROWED_X_COPY]] : $B to $C, [[CASE4:bb[0-9]+]], [[IS_NOT_C:bb[0-9]+]]
+  // CHECK:   checked_cast_br [[X]] : $B to $C, [[CASE4:bb[0-9]+]], [[IS_NOT_C:bb[0-9]+]]
   case let y as C:
   // CHECK: [[CASE4]]([[CAST_C:%.*]] : @guaranteed $C):
   // CHECK:   [[CAST_C_COPY:%.*]] = copy_value [[CAST_C]]
@@ -610,8 +584,6 @@
   // CHECK:   [[RET:%.*]] = init_existential_ref [[CAST_C_COPY_COPY]]
   // CHECK:   end_borrow [[BORROWED_CAST_C_COPY]]
   // CHECK:   destroy_value [[CAST_C_COPY]]
-  // CHECK:   end_borrow [[BORROWED_X_COPY]]
-  // CHECK:   destroy_value [[X_COPY]]
   // CHECK:   br [[CONT]]([[RET]] : $AnyObject)
     d()
     return y
@@ -619,7 +591,6 @@
   // CHECK: [[IS_NOT_C]]([[NOCAST_C:%.*]] : @guaranteed $B):
   // CHECK:   end_borrow [[NOCAST_C]]
   default:
-  // CHECK:   destroy_value [[X_COPY]]
   // CHECK:   function_ref @$s6switch1eyyF
   // CHECK:   [[X_COPY_2:%.*]] = copy_value [[X]]
   // CHECK:   [[RET:%.*]] = init_existential_ref [[X_COPY_2]]
@@ -663,17 +634,15 @@
   // CHECK:   br [[CONT]]
     b()
 
-  // CHECK: [[IS_RIGHT]]([[STR:%.*]] : @owned $String):
+  // CHECK: [[IS_RIGHT]]([[STR:%.*]] : @guaranteed $String):
   case var .Right:
-  // CHECK:   destroy_value [[STR]] : $String
   // CHECK:   function_ref @$s6switch1cyyF
   // CHECK:   br [[CONT]]
     c()
 
-  // CHECK: [[IS_BOTH]]([[TUP:%.*]] : @owned $(Int, String)):
+  // CHECK: [[IS_BOTH]]([[TUP:%.*]] : @guaranteed $(Int, String)):
   case .Both:
   // CHECK:   ({{%.*}}, [[TUP_STR:%.*]]) = destructure_tuple [[TUP]]
-  // CHECK:   destroy_value [[TUP_STR]] : $String
   // CHECK:   function_ref @$s6switch1dyyF
   // CHECK:   br [[CONT]]
     d()
@@ -688,9 +657,7 @@
 // CHECK-LABEL: sil hidden @$s6switch12test_union_31uyAA9MaybePairO_tF : $@convention(thin) (@guaranteed MaybePair) -> () {
 func test_union_3(u: MaybePair) {
   // CHECK: bb0([[ARG:%.*]] : @guaranteed $MaybePair):
-  // CHECK:   [[ARG_COPY:%.*]] = copy_value [[ARG]]
-  // CHECK:   [[SUBJECT:%.*]] = begin_borrow [[ARG_COPY]]
-  // CHECK:   switch_enum [[SUBJECT]] : $MaybePair,
+  // CHECK:   switch_enum [[ARG]] : $MaybePair,
   // CHECK:     case #MaybePair.Neither!enumelt: [[IS_NEITHER:bb[0-9]+]],
   // CHECK:     case #MaybePair.Left!enumelt.1: [[IS_LEFT:bb[0-9]+]],
   // CHECK:     case #MaybePair.Right!enumelt.1: [[IS_RIGHT:bb[0-9]+]],
@@ -716,7 +683,6 @@
 
   // CHECK: [[DEFAULT]](
   // -- Ensure the fully-opaque value is destroyed in the default case.
-  // CHECK:   destroy_value [[ARG_COPY]] :
   // CHECK:   function_ref @$s6switch1dyyF
   // CHECK:   br [[CONT]]
 
diff --git a/test/SILGen/switch_abstraction.swift b/test/SILGen/switch_abstraction.swift
index 5dfdbd4..4e63cc8 100644
--- a/test/SILGen/switch_abstraction.swift
+++ b/test/SILGen/switch_abstraction.swift
@@ -9,8 +9,11 @@
 }
 
 // CHECK-LABEL: sil hidden @$s18switch_abstraction18enum_reabstraction1x1ayAA10OptionableOyAA1AVAHcG_AHtF : $@convention(thin) (@guaranteed Optionable<(A) -> A>, A) -> ()
-// CHECK: switch_enum {{%.*}} : $Optionable<(A) -> A>, case #Optionable.Summn!enumelt.1: [[DEST:bb[0-9]+]]
-// CHECK: [[DEST]]([[ORIG:%.*]] : @owned $@callee_guaranteed (@in_guaranteed A) -> @out A):
+// CHECK: bb0([[ARG:%.*]] : @guaranteed $Optionable<(A) -> A>,
+// CHECK: switch_enum [[ARG]] : $Optionable<(A) -> A>, case #Optionable.Summn!enumelt.1: [[DEST:bb[0-9]+]]
+//
+// CHECK: [[DEST]]([[ARG:%.*]] : @guaranteed $@callee_guaranteed (@in_guaranteed A) -> @out A):
+// CHECK:   [[ORIG:%.*]] = copy_value [[ARG]]
 // CHECK:   [[REABSTRACT:%.*]] = function_ref @$s{{.*}}TR :
 // CHECK:   [[SUBST:%.*]] = partial_apply [callee_guaranteed] [[REABSTRACT]]([[ORIG]])
 func enum_reabstraction(x x: Optionable<(A) -> A>, a: A) {
diff --git a/test/SILGen/types.swift b/test/SILGen/types.swift
index f4f5f14..ec258e5 100644
--- a/test/SILGen/types.swift
+++ b/test/SILGen/types.swift
@@ -85,8 +85,8 @@
 }
 
 // CHECK-LABEL: sil hidden @$s5types32referencedFromFunctionEnumFieldsyyAA010ReferencedcdE0OcSg_yAA0gcD6StructVcSgtADF
-// CHECK:       bb{{[0-9]+}}([[F:%.*]] : @owned $@callee_guaranteed (@guaranteed ReferencedFromFunctionEnum) -> ()):
-// CHECK:       bb{{[0-9]+}}([[G:%.*]] : @owned $@callee_guaranteed (@guaranteed ReferencedFromFunctionStruct) -> ()):
+// CHECK:       bb{{[0-9]+}}([[F:%.*]] : @guaranteed $@callee_guaranteed (@guaranteed ReferencedFromFunctionEnum) -> ()):
+// CHECK:       bb{{[0-9]+}}([[G:%.*]] : @guaranteed $@callee_guaranteed (@guaranteed ReferencedFromFunctionStruct) -> ()):
 func referencedFromFunctionEnumFields(_ x: ReferencedFromFunctionEnum)
     -> (
       ((ReferencedFromFunctionEnum) -> ())?,
diff --git a/test/SILOptimizer/access_marker_verify.swift b/test/SILOptimizer/access_marker_verify.swift
index eeb8218..8d5fb8f 100644
--- a/test/SILOptimizer/access_marker_verify.swift
+++ b/test/SILOptimizer/access_marker_verify.swift
@@ -379,7 +379,7 @@
 // CHECK-LABEL: sil hidden @$s20access_marker_verify7IntEnumO8getValueSivg : $@convention(method) (@guaranteed IntEnum) -> Int {
 // CHECK: bb0(%0 : @guaranteed $IntEnum):
 // CHECK:   switch_enum %{{.*}} : $IntEnum, case #IntEnum.int!enumelt.1: bb1
-// CHECK: bb1(%{{.*}} : @owned ${ var Int }):
+// CHECK: bb1(%{{.*}} : @guaranteed ${ var Int }):
 // CHECK:   [[PROJ:%.*]] = project_box
 // CHECK-NOT: begin_access
 // CHECK:   load [trivial] [[PROJ]] : $*Int
@@ -398,7 +398,7 @@
 // CHECK-LABEL: sil hidden @$s20access_marker_verify7RefEnumO8getValueAA9BaseClassCvg : $@convention(method) (@guaranteed RefEnum) -> @owned BaseClass {
 // CHECK: bb0(%0 : @guaranteed $RefEnum):
 // CHECK:   switch_enum %{{.*}} : $RefEnum, case #RefEnum.ref!enumelt.1: bb1
-// CHECK: bb1(%{{.*}} : @owned ${ var BaseClass }):
+// CHECK: bb1(%{{.*}} : @guaranteed ${ var BaseClass }):
 // CHECK:   [[PROJ:%.*]] = project_box %{{.*}} : ${ var BaseClass }, 0
 // CHECK-NOT: begin_access
 // CHECK:   load_borrow [[PROJ]] : $*BaseClass
diff --git a/test/Serialization/transparent.swift b/test/Serialization/transparent.swift
index 99db1e6..1b82fa0 100644
--- a/test/Serialization/transparent.swift
+++ b/test/Serialization/transparent.swift
@@ -42,7 +42,6 @@
 
 // SIL-LABEL: sil public_external [transparent] [serialized] @$s15def_transparent9do_switch1uyAA9MaybePairO_tF : $@convention(thin) (@guaranteed MaybePair) -> () {
 // SIL: bb0(%0 : $MaybePair):
-// SIL: retain_value %0 : $MaybePair
 // SIL: switch_enum %0 : $MaybePair, case #MaybePair.Neither!enumelt: bb[[CASE1:[0-9]+]], case #MaybePair.Left!enumelt.1: bb[[CASE2:[0-9]+]], case #MaybePair.Right!enumelt.1: bb[[CASE3:[0-9]+]], case #MaybePair.Both!enumelt.1: bb[[CASE4:[0-9]+]]
 // SIL: bb[[CASE4]](%{{.*}} : $(Int32, String)):
 // SIL: bb[[CASE3]](%{{.*}} : $String):
diff --git a/test/lit.cfg b/test/lit.cfg
index 8937f12..39aa0b5 100644
--- a/test/lit.cfg
+++ b/test/lit.cfg
@@ -932,7 +932,8 @@
 ENV_VAR_PREFIXES = {
     'iphonesimulator': SIMULATOR_ENV_PREFIX,
     'watchsimulator': SIMULATOR_ENV_PREFIX,
-    'appletvsimulator': SIMULATOR_ENV_PREFIX
+    'appletvsimulator': SIMULATOR_ENV_PREFIX,
+    'android': 'ANDROID_CHILD_'
 }
 TARGET_ENV_PREFIX = ENV_VAR_PREFIXES.get(config.target_sdk_name, "")
 
diff --git a/utils/android/adb/commands.py b/utils/android/adb/commands.py
index d9595a5..3823d33 100644
--- a/utils/android/adb/commands.py
+++ b/utils/android/adb/commands.py
@@ -17,6 +17,7 @@
 
 from __future__ import print_function
 
+import os
 import subprocess
 import tempfile
 import uuid
@@ -24,6 +25,7 @@
 
 # A temporary directory on the Android device.
 DEVICE_TEMP_DIR = '/data/local/tmp'
+ENV_PREFIX = 'ANDROID_CHILD_'
 
 
 def shell(args):
@@ -93,6 +95,10 @@
     executable = '{}/__executable'.format(uuid_dir)
     push(executable_path, executable)
 
+    child_environment = ['{}="{}"'.format(k.replace(ENV_PREFIX, '', 1), v)
+                         for (k, v) in os.environ.items()
+                         if k.startswith(ENV_PREFIX)]
+
     # When running the executable on the device, we need to pass it the same
     # arguments, as well as specify the correct LD_LIBRARY_PATH. Save these
     # to a file we can easily call multiple times.
@@ -100,9 +106,10 @@
     _create_executable_on_device(
         executable_with_args,
         'LD_LIBRARY_PATH={uuid_dir}:{tmp_dir} '
-        '{executable} {executable_arguments}'.format(
+        '{child_environment} {executable} {executable_arguments}'.format(
             uuid_dir=uuid_dir,
             tmp_dir=DEVICE_TEMP_DIR,
+            child_environment=' '.join(child_environment),
             executable=executable,
             executable_arguments=' '.join(executable_arguments)))
 
@@ -146,7 +153,7 @@
         # the executable on the device.
         return 1
 
-    print(stdout)
+    print(stdout, end='')
 
     shell(['rm', '-rf', uuid_dir])
     return 0
diff --git a/utils/build-script-impl b/utils/build-script-impl
index e390c50..20e3e33 100755
--- a/utils/build-script-impl
+++ b/utils/build-script-impl
@@ -3081,7 +3081,7 @@
                 fi
                 # If libdispatch is being built, TestFoundation will need access to it
                 if [[ ! "${SKIP_BUILD_LIBDISPATCH}" ]] ; then
-                    LIBDISPATCH_LIB_DIR=":$(build_directory ${host} libdispatch)/src/.libs"
+                    LIBDISPATCH_LIB_DIR=":$(build_directory ${host} libdispatch):$(build_directory ${host} libdispatch)/src"
                 else
                     LIBDISPATCH_LIB_DIR=""
                 fi
diff --git a/utils/line-directive b/utils/line-directive
index 238073c..87d0ef8 100755
--- a/utils/line-directive
+++ b/utils/line-directive
@@ -21,6 +21,7 @@
 import bisect
 import os
 import re
+import shlex
 import subprocess
 import sys
 
@@ -178,7 +179,11 @@
 
 def read_response_file(file_path):
     with open(file_path, 'r') as files:
-        return filter(None, files.read().split(';'))
+        # "Make an iterator out of shlex.shlex.get_token, then consume items
+        # until it returns None." (Then eagerly convert the result to a list so
+        # that we can close the file.)
+        return list(iter(shlex.shlex(files, file_path, posix=True).get_token,
+                         None))
 
 
 def expand_response_files(files):
diff --git a/validation-test/Sema/type_checker_crashers_fixed/rdar45470505.swift b/validation-test/Sema/type_checker_crashers_fixed/rdar45470505.swift
new file mode 100644
index 0000000..9a760e5
--- /dev/null
+++ b/validation-test/Sema/type_checker_crashers_fixed/rdar45470505.swift
@@ -0,0 +1,16 @@
+// RUN: %target-typecheck-verify-swift
+
+extension BinaryInteger {
+  init(bytes: [UInt8]) { fatalError() }
+
+  init<S: Sequence>(bytes: S) where S.Iterator.Element == UInt8 {
+    self.init(bytes // expected-error {{ambiguous reference to initializer 'init(_:)'}}
+// expected-note@-1 {{}}
+
+extension
+// expected-error@-1 {{declaration is only valid at file scope}}
+// expected-error@-2 {{expected ')' in expression list}}
+// expected-error@-3 {{expected '{' in extension}}
+  }
+// expected-error@-1 {{expected type name in extension declaration}}
+}