Update aosp/master clang for rebase to r235153

Change-Id: Ia94bbcb6da7c75b6e7c2afedd1001094d62a7324
diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp
index 223b8f7..ff12a9a 100644
--- a/lib/CodeGen/CGException.cpp
+++ b/lib/CodeGen/CGException.cpp
@@ -19,8 +19,11 @@
 #include "clang/AST/Mangle.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/StmtObjC.h"
+#include "clang/AST/StmtVisitor.h"
 #include "llvm/IR/CallSite.h"
 #include "llvm/IR/Intrinsics.h"
+#include "llvm/IR/IntrinsicInst.h"
+#include "llvm/Support/SaveAndRestore.h"
 
 using namespace clang;
 using namespace CodeGen;
@@ -406,13 +409,6 @@
   return Builder.CreateLoad(getEHSelectorSlot(), "sel");
 }
 
-llvm::Value *CodeGenFunction::getAbnormalTerminationSlot() {
-  if (!AbnormalTerminationSlot)
-    AbnormalTerminationSlot =
-        CreateTempAlloca(Int8Ty, "abnormal.termination.slot");
-  return AbnormalTerminationSlot;
-}
-
 void CodeGenFunction::EmitCXXThrowExpr(const CXXThrowExpr *E,
                                        bool KeepInsertionPoint) {
   if (const Expr *SubExpr = E->getSubExpr()) {
@@ -458,6 +454,10 @@
       EHStack.pushTerminate();
     }
   } else if (EST == EST_Dynamic || EST == EST_DynamicNone) {
+    // TODO: Revisit exception specifications for the MS ABI.  There is a way to
+    // encode these in an object file but MSVC doesn't do anything with it.
+    if (getTarget().getCXXABI().isMicrosoft())
+      return;
     unsigned NumExceptions = Proto->getNumExceptions();
     EHFilterScope *Filter = EHStack.pushFilter(NumExceptions);
 
@@ -532,6 +532,10 @@
       EHStack.popTerminate();
     }
   } else if (EST == EST_Dynamic || EST == EST_DynamicNone) {
+    // TODO: Revisit exception specifications for the MS ABI.  There is a way to
+    // encode these in an object file but MSVC doesn't do anything with it.
+    if (getTarget().getCXXABI().isMicrosoft())
+      return;
     EHFilterScope &filterScope = cast<EHFilterScope>(*EHStack.begin());
     emitFilterDispatchBlock(*this, filterScope);
     EHStack.popFilter();
@@ -568,7 +572,7 @@
         TypeInfo = CGM.getObjCRuntime().GetEHType(CaughtType);
       else
         TypeInfo =
-            CGM.getAddrOfCXXHandlerMapEntry(CaughtType, C->getCaughtType());
+            CGM.getAddrOfCXXCatchHandlerType(CaughtType, C->getCaughtType());
       CatchScope->setHandler(I, TypeInfo, Handler);
     } else {
       // No exception decl indicates '...', a catch-all.
@@ -1277,8 +1281,7 @@
     return;
   }
 
-  SEHFinallyInfo FI;
-  EnterSEHTryStmt(S, FI);
+  EnterSEHTryStmt(S);
   {
     JumpDest TryExit = getJumpDestInCurrentScope("__try.__leave");
 
@@ -1291,109 +1294,224 @@
     else
       delete TryExit.getBlock();
   }
-  ExitSEHTryStmt(S, FI);
+  ExitSEHTryStmt(S);
 }
 
 namespace {
-struct PerformSEHFinally : EHScopeStack::Cleanup  {
-  CodeGenFunction::SEHFinallyInfo *FI;
-  PerformSEHFinally(CodeGenFunction::SEHFinallyInfo *FI) : FI(FI) {}
+struct PerformSEHFinally : EHScopeStack::Cleanup {
+  llvm::Function *OutlinedFinally;
+  PerformSEHFinally(llvm::Function *OutlinedFinally)
+      : OutlinedFinally(OutlinedFinally) {}
 
   void Emit(CodeGenFunction &CGF, Flags F) override {
-    // Cleanups are emitted at most twice: once for normal control flow and once
-    // for exception control flow. Branch into the finally block, and remember
-    // the continuation block so we can branch out later.
-    if (!FI->FinallyBB) {
-      FI->FinallyBB = CGF.createBasicBlock("__finally");
-      FI->FinallyBB->insertInto(CGF.CurFn);
-      FI->FinallyBB->moveAfter(CGF.Builder.GetInsertBlock());
-    }
+    ASTContext &Context = CGF.getContext();
+    QualType ArgTys[2] = {Context.BoolTy, Context.VoidPtrTy};
+    FunctionProtoType::ExtProtoInfo EPI;
+    const auto *FTP = cast<FunctionType>(
+        Context.getFunctionType(Context.VoidTy, ArgTys, EPI));
 
-    // Set the termination status and branch in.
-    CGF.Builder.CreateStore(
-        llvm::ConstantInt::get(CGF.Int8Ty, F.isForEHCleanup()),
-        CGF.getAbnormalTerminationSlot());
-    CGF.Builder.CreateBr(FI->FinallyBB);
+    CallArgList Args;
+    llvm::Value *IsForEH =
+        llvm::ConstantInt::get(CGF.ConvertType(ArgTys[0]), F.isForEHCleanup());
+    Args.add(RValue::get(IsForEH), ArgTys[0]);
 
-    // Create a continuation block for normal or exceptional control.
-    if (F.isForEHCleanup()) {
-      assert(!FI->ResumeBB && "double emission for EH");
-      FI->ResumeBB = CGF.createBasicBlock("__finally.resume");
-      CGF.EmitBlock(FI->ResumeBB);
-    } else {
-      assert(F.isForNormalCleanup() && !FI->ContBB && "double normal emission");
-      FI->ContBB = CGF.createBasicBlock("__finally.cont");
-      CGF.EmitBlock(FI->ContBB);
-      // Try to keep source order.
-      FI->ContBB->moveAfter(FI->FinallyBB);
-    }
+    CodeGenModule &CGM = CGF.CGM;
+    llvm::Value *Zero = llvm::ConstantInt::get(CGM.Int32Ty, 0);
+    llvm::Value *FrameAddr = CGM.getIntrinsic(llvm::Intrinsic::frameaddress);
+    llvm::Value *FP = CGF.Builder.CreateCall(FrameAddr, Zero);
+    Args.add(RValue::get(FP), ArgTys[1]);
+
+    const CGFunctionInfo &FnInfo =
+        CGM.getTypes().arrangeFreeFunctionCall(Args, FTP, /*chainCall=*/false);
+    CGF.EmitCall(FnInfo, OutlinedFinally, ReturnValueSlot(), Args);
   }
 };
 }
 
+namespace {
+/// Find all local variable captures in the statement.
+struct CaptureFinder : ConstStmtVisitor<CaptureFinder> {
+  CodeGenFunction &ParentCGF;
+  const VarDecl *ParentThis;
+  SmallVector<const VarDecl *, 4> Captures;
+  CaptureFinder(CodeGenFunction &ParentCGF, const VarDecl *ParentThis)
+      : ParentCGF(ParentCGF), ParentThis(ParentThis) {}
+
+  void Visit(const Stmt *S) {
+    // See if this is a capture, then recurse.
+    ConstStmtVisitor<CaptureFinder>::Visit(S);
+    for (const Stmt *Child : S->children())
+      if (Child)
+        Visit(Child);
+  }
+
+  void VisitDeclRefExpr(const DeclRefExpr *E) {
+    // If this is already a capture, just make sure we capture 'this'.
+    if (E->refersToEnclosingVariableOrCapture()) {
+      Captures.push_back(ParentThis);
+      return;
+    }
+
+    const auto *D = dyn_cast<VarDecl>(E->getDecl());
+    if (D && D->isLocalVarDeclOrParm() && D->hasLocalStorage())
+      Captures.push_back(D);
+  }
+
+  void VisitCXXThisExpr(const CXXThisExpr *E) {
+    Captures.push_back(ParentThis);
+  }
+};
+}
+
+void CodeGenFunction::EmitCapturedLocals(CodeGenFunction &ParentCGF,
+                                         const Stmt *OutlinedStmt,
+                                         llvm::Value *ParentFP) {
+  // Find all captures in the Stmt.
+  CaptureFinder Finder(ParentCGF, ParentCGF.CXXABIThisDecl);
+  Finder.Visit(OutlinedStmt);
+
+  // Typically there are no captures and we can exit early.
+  if (Finder.Captures.empty())
+    return;
+
+  // Prepare the first two arguments to llvm.framerecover.
+  llvm::Function *FrameRecoverFn = llvm::Intrinsic::getDeclaration(
+      &CGM.getModule(), llvm::Intrinsic::framerecover);
+  llvm::Constant *ParentI8Fn =
+      llvm::ConstantExpr::getBitCast(ParentCGF.CurFn, Int8PtrTy);
+
+  // Create llvm.framerecover calls for all captures.
+  for (const VarDecl *VD : Finder.Captures) {
+    if (isa<ImplicitParamDecl>(VD)) {
+      CGM.ErrorUnsupported(VD, "'this' captured by SEH");
+      CXXThisValue = llvm::UndefValue::get(ConvertTypeForMem(VD->getType()));
+      continue;
+    }
+    if (VD->getType()->isVariablyModifiedType()) {
+      CGM.ErrorUnsupported(VD, "VLA captured by SEH");
+      continue;
+    }
+    assert((isa<ImplicitParamDecl>(VD) || VD->isLocalVarDeclOrParm()) &&
+           "captured non-local variable");
+
+    // If this decl hasn't been declared yet, it will be declared in the
+    // OutlinedStmt.
+    auto I = ParentCGF.LocalDeclMap.find(VD);
+    if (I == ParentCGF.LocalDeclMap.end())
+      continue;
+    llvm::Value *ParentVar = I->second;
+
+    llvm::CallInst *RecoverCall = nullptr;
+    CGBuilderTy Builder(AllocaInsertPt);
+    if (auto *ParentAlloca = dyn_cast<llvm::AllocaInst>(ParentVar)) {
+      // Mark the variable escaped if nobody else referenced it and compute the
+      // frameescape index.
+      auto InsertPair =
+          ParentCGF.EscapedLocals.insert(std::make_pair(ParentAlloca, -1));
+      if (InsertPair.second)
+        InsertPair.first->second = ParentCGF.EscapedLocals.size() - 1;
+      int FrameEscapeIdx = InsertPair.first->second;
+      // call i8* @llvm.framerecover(i8* bitcast(@parentFn), i8* %fp, i32 N)
+      RecoverCall =
+          Builder.CreateCall3(FrameRecoverFn, ParentI8Fn, ParentFP,
+                              llvm::ConstantInt::get(Int32Ty, FrameEscapeIdx));
+
+    } else {
+      // If the parent didn't have an alloca, we're doing some nested outlining.
+      // Just clone the existing framerecover call, but tweak the FP argument to
+      // use our FP value. All other arguments are constants.
+      auto *ParentRecover =
+          cast<llvm::IntrinsicInst>(ParentVar->stripPointerCasts());
+      assert(ParentRecover->getIntrinsicID() == llvm::Intrinsic::framerecover &&
+             "expected alloca or framerecover in parent LocalDeclMap");
+      RecoverCall = cast<llvm::CallInst>(ParentRecover->clone());
+      RecoverCall->setArgOperand(1, ParentFP);
+      RecoverCall->insertBefore(AllocaInsertPt);
+    }
+
+    // Bitcast the variable, rename it, and insert it in the local decl map.
+    llvm::Value *ChildVar =
+        Builder.CreateBitCast(RecoverCall, ParentVar->getType());
+    ChildVar->setName(ParentVar->getName());
+    LocalDeclMap[VD] = ChildVar;
+  }
+}
+
+/// Arrange a function prototype that can be called by Windows exception
+/// handling personalities. On Win64, the prototype looks like:
+/// RetTy func(void *EHPtrs, void *ParentFP);
+void CodeGenFunction::startOutlinedSEHHelper(CodeGenFunction &ParentCGF,
+                                             StringRef Name, QualType RetTy,
+                                             FunctionArgList &Args,
+                                             const Stmt *OutlinedStmt) {
+  llvm::Function *ParentFn = ParentCGF.CurFn;
+  const CGFunctionInfo &FnInfo = CGM.getTypes().arrangeFreeFunctionDeclaration(
+      RetTy, Args, FunctionType::ExtInfo(), /*isVariadic=*/false);
+
+  llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FnInfo);
+  llvm::Function *Fn = llvm::Function::Create(
+      FnTy, llvm::GlobalValue::InternalLinkage, Name.str(), &CGM.getModule());
+  // The filter is either in the same comdat as the function, or it's internal.
+  if (llvm::Comdat *C = ParentFn->getComdat()) {
+    Fn->setComdat(C);
+  } else if (ParentFn->hasWeakLinkage() || ParentFn->hasLinkOnceLinkage()) {
+    llvm::Comdat *C = CGM.getModule().getOrInsertComdat(ParentFn->getName());
+    ParentFn->setComdat(C);
+    Fn->setComdat(C);
+  } else {
+    Fn->setLinkage(llvm::GlobalValue::InternalLinkage);
+  }
+
+  IsOutlinedSEHHelper = true;
+
+  StartFunction(GlobalDecl(), RetTy, Fn, FnInfo, Args,
+                OutlinedStmt->getLocStart(), OutlinedStmt->getLocStart());
+
+  CGM.SetLLVMFunctionAttributes(nullptr, FnInfo, CurFn);
+
+  auto AI = Fn->arg_begin();
+  ++AI;
+  EmitCapturedLocals(ParentCGF, OutlinedStmt, &*AI);
+}
+
 /// Create a stub filter function that will ultimately hold the code of the
 /// filter expression. The EH preparation passes in LLVM will outline the code
 /// from the main function body into this stub.
 llvm::Function *
 CodeGenFunction::GenerateSEHFilterFunction(CodeGenFunction &ParentCGF,
                                            const SEHExceptStmt &Except) {
-  const Decl *ParentCodeDecl = ParentCGF.CurCodeDecl;
-  llvm::Function *ParentFn = ParentCGF.CurFn;
+  const Expr *FilterExpr = Except.getFilterExpr();
+  SourceLocation StartLoc = FilterExpr->getLocStart();
 
-  Expr *FilterExpr = Except.getFilterExpr();
+  SEHPointersDecl = ImplicitParamDecl::Create(
+      getContext(), nullptr, StartLoc,
+      &getContext().Idents.get("exception_pointers"), getContext().VoidPtrTy);
+  FunctionArgList Args;
+  Args.push_back(SEHPointersDecl);
+  Args.push_back(ImplicitParamDecl::Create(
+      getContext(), nullptr, StartLoc,
+      &getContext().Idents.get("frame_pointer"), getContext().VoidPtrTy));
 
   // Get the mangled function name.
   SmallString<128> Name;
   {
     llvm::raw_svector_ostream OS(Name);
+    const Decl *ParentCodeDecl = ParentCGF.CurCodeDecl;
     const NamedDecl *Parent = dyn_cast_or_null<NamedDecl>(ParentCodeDecl);
     assert(Parent && "FIXME: handle unnamed decls (lambdas, blocks) with SEH");
     CGM.getCXXABI().getMangleContext().mangleSEHFilterExpression(Parent, OS);
   }
 
-  // Arrange a function with the declaration:
-  // int filt(EXCEPTION_POINTERS *exception_pointers, void *frame_pointer)
-  QualType RetTy = getContext().IntTy;
-  FunctionArgList Args;
-  SEHPointersDecl = ImplicitParamDecl::Create(
-      getContext(), nullptr, FilterExpr->getLocStart(),
-      &getContext().Idents.get("exception_pointers"), getContext().VoidPtrTy);
-  Args.push_back(SEHPointersDecl);
-  Args.push_back(ImplicitParamDecl::Create(
-      getContext(), nullptr, FilterExpr->getLocStart(),
-      &getContext().Idents.get("frame_pointer"), getContext().VoidPtrTy));
-  const CGFunctionInfo &FnInfo = CGM.getTypes().arrangeFreeFunctionDeclaration(
-      RetTy, Args, FunctionType::ExtInfo(), /*isVariadic=*/false);
-  llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FnInfo);
-  llvm::Function *Fn = llvm::Function::Create(FnTy, ParentFn->getLinkage(),
-                                              Name.str(), &CGM.getModule());
-  // The filter is either in the same comdat as the function, or it's internal.
-  if (llvm::Comdat *C = ParentFn->getComdat()) {
-    Fn->setComdat(C);
-  } else if (ParentFn->hasWeakLinkage() || ParentFn->hasLinkOnceLinkage()) {
-    // FIXME: Unreachable with Rafael's changes?
-    llvm::Comdat *C = CGM.getModule().getOrInsertComdat(ParentFn->getName());
-    ParentFn->setComdat(C);
-    Fn->setComdat(C);
-  } else {
-    Fn->setLinkage(llvm::GlobalValue::InternalLinkage);
-  }
+  startOutlinedSEHHelper(ParentCGF, Name, getContext().IntTy, Args, FilterExpr);
 
-  StartFunction(GlobalDecl(), RetTy, Fn, FnInfo, Args,
-                FilterExpr->getLocStart(), FilterExpr->getLocStart());
+  // Mark finally block calls as nounwind and noinline to make LLVM's job a
+  // little easier.
+  // FIXME: Remove these restrictions in the future.
+  CurFn->addFnAttr(llvm::Attribute::NoUnwind);
+  CurFn->addFnAttr(llvm::Attribute::NoInline);
 
   EmitSEHExceptionCodeSave();
 
-  // Insert dummy allocas for every local variable in scope. We'll initialize
-  // them and prune the unused ones after we find out which ones were
-  // referenced.
-  for (const auto &DeclPtrs : ParentCGF.LocalDeclMap) {
-    const Decl *VD = DeclPtrs.first;
-    llvm::Value *Ptr = DeclPtrs.second;
-    auto *ValTy = cast<llvm::PointerType>(Ptr->getType())->getElementType();
-    LocalDeclMap[VD] = CreateTempAlloca(ValTy, Ptr->getName() + ".filt");
-  }
-
   // Emit the original filter expression, convert to i32, and return.
   llvm::Value *R = EmitScalarExpr(FilterExpr);
   R = Builder.CreateIntCast(R, CGM.IntTy,
@@ -1402,18 +1520,42 @@
 
   FinishFunction(FilterExpr->getLocEnd());
 
-  for (const auto &DeclPtrs : ParentCGF.LocalDeclMap) {
-    const Decl *VD = DeclPtrs.first;
-    auto *Alloca = cast<llvm::AllocaInst>(LocalDeclMap[VD]);
-    if (Alloca->hasNUses(0)) {
-      Alloca->eraseFromParent();
-      continue;
-    }
-    ErrorUnsupported(FilterExpr,
-                     "SEH filter expression local variable capture");
+  return CurFn;
+}
+
+llvm::Function *
+CodeGenFunction::GenerateSEHFinallyFunction(CodeGenFunction &ParentCGF,
+                                            const SEHFinallyStmt &Finally) {
+  const Stmt *FinallyBlock = Finally.getBlock();
+  SourceLocation StartLoc = FinallyBlock->getLocStart();
+
+  FunctionArgList Args;
+  Args.push_back(ImplicitParamDecl::Create(
+      getContext(), nullptr, StartLoc,
+      &getContext().Idents.get("abnormal_termination"), getContext().BoolTy));
+  Args.push_back(ImplicitParamDecl::Create(
+      getContext(), nullptr, StartLoc,
+      &getContext().Idents.get("frame_pointer"), getContext().VoidPtrTy));
+
+  // Get the mangled function name.
+  SmallString<128> Name;
+  {
+    llvm::raw_svector_ostream OS(Name);
+    const Decl *ParentCodeDecl = ParentCGF.CurCodeDecl;
+    const NamedDecl *Parent = dyn_cast_or_null<NamedDecl>(ParentCodeDecl);
+    assert(Parent && "FIXME: handle unnamed decls (lambdas, blocks) with SEH");
+    CGM.getCXXABI().getMangleContext().mangleSEHFinallyBlock(Parent, OS);
   }
 
-  return Fn;
+  startOutlinedSEHHelper(ParentCGF, Name, getContext().VoidTy, Args,
+                         FinallyBlock);
+
+  // Emit the original filter expression, convert to i32, and return.
+  EmitStmt(FinallyBlock);
+
+  FinishFunction(FinallyBlock->getLocEnd());
+
+  return CurFn;
 }
 
 void CodeGenFunction::EmitSEHExceptionCodeSave() {
@@ -1429,7 +1571,7 @@
   llvm::Type *RecordTy = CGM.Int32Ty->getPointerTo();
   llvm::Type *PtrsTy = llvm::StructType::get(RecordTy, CGM.VoidPtrTy, nullptr);
   Ptrs = Builder.CreateBitCast(Ptrs, PtrsTy->getPointerTo());
-  llvm::Value *Rec = Builder.CreateStructGEP(Ptrs, 0);
+  llvm::Value *Rec = Builder.CreateStructGEP(PtrsTy, Ptrs, 0);
   Rec = Builder.CreateLoad(Rec);
   llvm::Value *Code = Builder.CreateLoad(Rec);
   Code = Builder.CreateZExt(Code, CGM.IntPtrTy);
@@ -1457,21 +1599,24 @@
 }
 
 llvm::Value *CodeGenFunction::EmitSEHAbnormalTermination() {
-  // Load from the abnormal termination slot. It will be uninitialized outside
-  // of __finally blocks, which we should warn or error on.
-  llvm::Value *IsEH = Builder.CreateLoad(getAbnormalTerminationSlot());
-  return Builder.CreateZExt(IsEH, Int32Ty);
+  // Abnormal termination is just the first parameter to the outlined finally
+  // helper.
+  auto AI = CurFn->arg_begin();
+  return Builder.CreateZExt(&*AI, Int32Ty);
 }
 
-void CodeGenFunction::EnterSEHTryStmt(const SEHTryStmt &S, SEHFinallyInfo &FI) {
-  if (S.getFinallyHandler()) {
+void CodeGenFunction::EnterSEHTryStmt(const SEHTryStmt &S) {
+  CodeGenFunction HelperCGF(CGM, /*suppressNewContext=*/true);
+  if (const SEHFinallyStmt *Finally = S.getFinallyHandler()) {
     // Push a cleanup for __finally blocks.
-    EHStack.pushCleanup<PerformSEHFinally>(NormalAndEHCleanup, &FI);
+    llvm::Function *FinallyFunc =
+        HelperCGF.GenerateSEHFinallyFunction(*this, *Finally);
+    EHStack.pushCleanup<PerformSEHFinally>(NormalAndEHCleanup, FinallyFunc);
     return;
   }
 
   // Otherwise, we must have an __except block.
-  SEHExceptStmt *Except = S.getExceptHandler();
+  const SEHExceptStmt *Except = S.getExceptHandler();
   assert(Except);
   EHCatchScope *CatchScope = EHStack.pushCatch(1);
 
@@ -1486,40 +1631,17 @@
 
   // In general, we have to emit an outlined filter function. Use the function
   // in place of the RTTI typeinfo global that C++ EH uses.
-  CodeGenFunction FilterCGF(CGM, /*suppressNewContext=*/true);
   llvm::Function *FilterFunc =
-      FilterCGF.GenerateSEHFilterFunction(*this, *Except);
+      HelperCGF.GenerateSEHFilterFunction(*this, *Except);
   llvm::Constant *OpaqueFunc =
       llvm::ConstantExpr::getBitCast(FilterFunc, Int8PtrTy);
   CatchScope->setHandler(0, OpaqueFunc, createBasicBlock("__except"));
 }
 
-void CodeGenFunction::ExitSEHTryStmt(const SEHTryStmt &S, SEHFinallyInfo &FI) {
+void CodeGenFunction::ExitSEHTryStmt(const SEHTryStmt &S) {
   // Just pop the cleanup if it's a __finally block.
-  if (const SEHFinallyStmt *Finally = S.getFinallyHandler()) {
+  if (S.getFinallyHandler()) {
     PopCleanupBlock();
-    assert(FI.ContBB && "did not emit normal cleanup");
-
-    // Emit the code into FinallyBB.
-    CGBuilderTy::InsertPoint SavedIP = Builder.saveIP();
-    Builder.SetInsertPoint(FI.FinallyBB);
-    EmitStmt(Finally->getBlock());
-
-    if (HaveInsertPoint()) {
-      if (FI.ResumeBB) {
-        llvm::Value *IsEH = Builder.CreateLoad(getAbnormalTerminationSlot(),
-                                               "abnormal.termination");
-        IsEH = Builder.CreateICmpEQ(IsEH, llvm::ConstantInt::get(Int8Ty, 0));
-        Builder.CreateCondBr(IsEH, FI.ContBB, FI.ResumeBB);
-      } else {
-        // There was nothing exceptional in the try body, so we only have normal
-        // control flow.
-        Builder.CreateBr(FI.ContBB);
-      }
-    }
-
-    Builder.restoreIP(SavedIP);
-
     return;
   }
 
@@ -1569,7 +1691,13 @@
   if (HaveInsertPoint())
     EmitStopPoint(&S);
 
-  assert(!SEHTryEpilogueStack.empty() &&
-         "sema should have rejected this __leave");
+  // This must be a __leave from a __finally block, which we warn on and is UB.
+  // Just emit unreachable.
+  if (!isSEHTryScope()) {
+    Builder.CreateUnreachable();
+    Builder.ClearInsertionPoint();
+    return;
+  }
+
   EmitBranchThroughCleanup(*SEHTryEpilogueStack.back());
 }