brintos

brintos / llvm-project-archived public Read only

0
0
Text · 85.5 KiB · e9d2067 Raw
2301 lines · cpp
1//===--- CGException.cpp - Emit LLVM Code for C++ exceptions ----*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This contains code dealing with C++ exception related code generation.10//11//===----------------------------------------------------------------------===//12 13#include "CGCXXABI.h"14#include "CGCleanup.h"15#include "CGDebugInfo.h"16#include "CGObjCRuntime.h"17#include "CodeGenFunction.h"18#include "ConstantEmitter.h"19#include "TargetInfo.h"20#include "clang/AST/Mangle.h"21#include "clang/AST/StmtCXX.h"22#include "clang/AST/StmtObjC.h"23#include "clang/AST/StmtVisitor.h"24#include "clang/Basic/DiagnosticSema.h"25#include "llvm/IR/IntrinsicInst.h"26#include "llvm/IR/Intrinsics.h"27#include "llvm/IR/IntrinsicsWebAssembly.h"28#include "llvm/Support/SaveAndRestore.h"29 30using namespace clang;31using namespace CodeGen;32 33static llvm::FunctionCallee getFreeExceptionFn(CodeGenModule &CGM) {34  // void __cxa_free_exception(void *thrown_exception);35 36  llvm::FunctionType *FTy =37    llvm::FunctionType::get(CGM.VoidTy, CGM.Int8PtrTy, /*isVarArg=*/false);38 39  return CGM.CreateRuntimeFunction(FTy, "__cxa_free_exception");40}41 42static llvm::FunctionCallee getSehTryBeginFn(CodeGenModule &CGM) {43  llvm::FunctionType *FTy =44      llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);45  return CGM.CreateRuntimeFunction(FTy, "llvm.seh.try.begin");46}47 48static llvm::FunctionCallee getSehTryEndFn(CodeGenModule &CGM) {49  llvm::FunctionType *FTy =50      llvm::FunctionType::get(CGM.VoidTy, /*isVarArg=*/false);51  return CGM.CreateRuntimeFunction(FTy, "llvm.seh.try.end");52}53 54static llvm::FunctionCallee getUnexpectedFn(CodeGenModule &CGM) {55  // void __cxa_call_unexpected(void *thrown_exception);56 57  llvm::FunctionType *FTy =58    llvm::FunctionType::get(CGM.VoidTy, CGM.Int8PtrTy, /*isVarArg=*/false);59 60  return CGM.CreateRuntimeFunction(FTy, "__cxa_call_unexpected");61}62 63llvm::FunctionCallee CodeGenModule::getTerminateFn() {64  // void __terminate();65 66  llvm::FunctionType *FTy =67    llvm::FunctionType::get(VoidTy, /*isVarArg=*/false);68 69  StringRef name;70 71  // In C++, use std::terminate().72  if (getLangOpts().CPlusPlus &&73      getTarget().getCXXABI().isItaniumFamily()) {74    name = "_ZSt9terminatev";75  } else if (getLangOpts().CPlusPlus &&76             getTarget().getCXXABI().isMicrosoft()) {77    if (getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015))78      name = "__std_terminate";79    else80      name = "?terminate@@YAXXZ";81  } else if (getLangOpts().ObjC &&82             getLangOpts().ObjCRuntime.hasTerminate())83    name = "objc_terminate";84  else85    name = "abort";86  return CreateRuntimeFunction(FTy, name);87}88 89static llvm::FunctionCallee getCatchallRethrowFn(CodeGenModule &CGM,90                                                 StringRef Name) {91  llvm::FunctionType *FTy =92    llvm::FunctionType::get(CGM.VoidTy, CGM.Int8PtrTy, /*isVarArg=*/false);93 94  return CGM.CreateRuntimeFunction(FTy, Name);95}96 97const EHPersonality EHPersonality::GNU_C = { "__gcc_personality_v0", nullptr };98const EHPersonality99EHPersonality::GNU_C_SJLJ = { "__gcc_personality_sj0", nullptr };100const EHPersonality101EHPersonality::GNU_C_SEH = { "__gcc_personality_seh0", nullptr };102const EHPersonality103EHPersonality::NeXT_ObjC = { "__objc_personality_v0", nullptr };104const EHPersonality105EHPersonality::GNU_CPlusPlus = { "__gxx_personality_v0", nullptr };106const EHPersonality107EHPersonality::GNU_CPlusPlus_SJLJ = { "__gxx_personality_sj0", nullptr };108const EHPersonality109EHPersonality::GNU_CPlusPlus_SEH = { "__gxx_personality_seh0", nullptr };110const EHPersonality111EHPersonality::GNU_ObjC = {"__gnu_objc_personality_v0", "objc_exception_throw"};112const EHPersonality113EHPersonality::GNU_ObjC_SJLJ = {"__gnu_objc_personality_sj0", "objc_exception_throw"};114const EHPersonality115EHPersonality::GNU_ObjC_SEH = {"__gnu_objc_personality_seh0", "objc_exception_throw"};116const EHPersonality117EHPersonality::GNU_ObjCXX = { "__gnustep_objcxx_personality_v0", nullptr };118const EHPersonality119EHPersonality::GNUstep_ObjC = { "__gnustep_objc_personality_v0", nullptr };120const EHPersonality121EHPersonality::MSVC_except_handler = { "_except_handler3", nullptr };122const EHPersonality123EHPersonality::MSVC_C_specific_handler = { "__C_specific_handler", nullptr };124const EHPersonality125EHPersonality::MSVC_CxxFrameHandler3 = { "__CxxFrameHandler3", nullptr };126const EHPersonality127EHPersonality::GNU_Wasm_CPlusPlus = { "__gxx_wasm_personality_v0", nullptr };128const EHPersonality EHPersonality::XL_CPlusPlus = {"__xlcxx_personality_v1",129                                                   nullptr};130const EHPersonality EHPersonality::ZOS_CPlusPlus = {"__zos_cxx_personality_v2",131                                                    nullptr};132 133static const EHPersonality &getCPersonality(const TargetInfo &Target,134                                            const CodeGenOptions &CGOpts) {135  const llvm::Triple &T = Target.getTriple();136  if (T.isWindowsMSVCEnvironment())137    return EHPersonality::MSVC_CxxFrameHandler3;138  if (CGOpts.hasSjLjExceptions())139    return EHPersonality::GNU_C_SJLJ;140  if (CGOpts.hasDWARFExceptions())141    return EHPersonality::GNU_C;142  if (CGOpts.hasSEHExceptions())143    return EHPersonality::GNU_C_SEH;144  return EHPersonality::GNU_C;145}146 147static const EHPersonality &getObjCPersonality(const TargetInfo &Target,148                                               const CodeGenOptions &CGOpts,149                                               const LangOptions &L) {150  const llvm::Triple &T = Target.getTriple();151  if (T.isWindowsMSVCEnvironment())152    return EHPersonality::MSVC_CxxFrameHandler3;153 154  switch (L.ObjCRuntime.getKind()) {155  case ObjCRuntime::FragileMacOSX:156    return getCPersonality(Target, CGOpts);157  case ObjCRuntime::MacOSX:158  case ObjCRuntime::iOS:159  case ObjCRuntime::WatchOS:160    return EHPersonality::NeXT_ObjC;161  case ObjCRuntime::GNUstep:162    if (T.isOSCygMing())163      return EHPersonality::GNU_CPlusPlus_SEH;164    else if (L.ObjCRuntime.getVersion() >= VersionTuple(1, 7))165      return EHPersonality::GNUstep_ObjC;166    [[fallthrough]];167  case ObjCRuntime::GCC:168  case ObjCRuntime::ObjFW:169    if (CGOpts.hasSjLjExceptions())170      return EHPersonality::GNU_ObjC_SJLJ;171    if (CGOpts.hasSEHExceptions())172      return EHPersonality::GNU_ObjC_SEH;173    return EHPersonality::GNU_ObjC;174  }175  llvm_unreachable("bad runtime kind");176}177 178static const EHPersonality &getCXXPersonality(const TargetInfo &Target,179                                              const CodeGenOptions &CGOpts) {180  const llvm::Triple &T = Target.getTriple();181  if (T.isWindowsMSVCEnvironment())182    return EHPersonality::MSVC_CxxFrameHandler3;183  if (T.isOSAIX())184    return EHPersonality::XL_CPlusPlus;185  if (CGOpts.hasSjLjExceptions())186    return EHPersonality::GNU_CPlusPlus_SJLJ;187  if (CGOpts.hasDWARFExceptions())188    return EHPersonality::GNU_CPlusPlus;189  if (CGOpts.hasSEHExceptions())190    return EHPersonality::GNU_CPlusPlus_SEH;191  if (CGOpts.hasWasmExceptions())192    return EHPersonality::GNU_Wasm_CPlusPlus;193  if (T.isOSzOS())194    return EHPersonality::ZOS_CPlusPlus;195  return EHPersonality::GNU_CPlusPlus;196}197 198/// Determines the personality function to use when both C++199/// and Objective-C exceptions are being caught.200static const EHPersonality &getObjCXXPersonality(const TargetInfo &Target,201                                                 const CodeGenOptions &CGOpts,202                                                 const LangOptions &L) {203  if (Target.getTriple().isWindowsMSVCEnvironment())204    return EHPersonality::MSVC_CxxFrameHandler3;205 206  switch (L.ObjCRuntime.getKind()) {207  // In the fragile ABI, just use C++ exception handling and hope208  // they're not doing crazy exception mixing.209  case ObjCRuntime::FragileMacOSX:210    return getCXXPersonality(Target, CGOpts);211 212  // The ObjC personality defers to the C++ personality for non-ObjC213  // handlers.  Unlike the C++ case, we use the same personality214  // function on targets using (backend-driven) SJLJ EH.215  case ObjCRuntime::MacOSX:216  case ObjCRuntime::iOS:217  case ObjCRuntime::WatchOS:218    return getObjCPersonality(Target, CGOpts, L);219 220  case ObjCRuntime::GNUstep:221    return Target.getTriple().isOSCygMing() ? EHPersonality::GNU_CPlusPlus_SEH222                                            : EHPersonality::GNU_ObjCXX;223 224  // The GCC runtime's personality function inherently doesn't support225  // mixed EH.  Use the ObjC personality just to avoid returning null.226  case ObjCRuntime::GCC:227  case ObjCRuntime::ObjFW:228    return getObjCPersonality(Target, CGOpts, L);229  }230  llvm_unreachable("bad runtime kind");231}232 233static const EHPersonality &getSEHPersonalityMSVC(const llvm::Triple &T) {234  if (T.getArch() == llvm::Triple::x86)235    return EHPersonality::MSVC_except_handler;236  return EHPersonality::MSVC_C_specific_handler;237}238 239const EHPersonality &EHPersonality::get(CodeGenModule &CGM,240                                        const FunctionDecl *FD) {241  const llvm::Triple &T = CGM.getTarget().getTriple();242  const CodeGenOptions &CGOpts = CGM.getCodeGenOpts();243  const LangOptions &L = CGM.getLangOpts();244  const TargetInfo &Target = CGM.getTarget();245 246  // Functions using SEH get an SEH personality.247  if (FD && FD->usesSEHTry())248    return getSEHPersonalityMSVC(T);249 250  if (L.ObjC)251    return L.CPlusPlus ? getObjCXXPersonality(Target, CGOpts, L)252                       : getObjCPersonality(Target, CGOpts, L);253  return L.CPlusPlus ? getCXXPersonality(Target, CGOpts)254                     : getCPersonality(Target, CGOpts);255}256 257const EHPersonality &EHPersonality::get(CodeGenFunction &CGF) {258  const auto *FD = CGF.CurCodeDecl;259  // For outlined finallys and filters, use the SEH personality in case they260  // contain more SEH. This mostly only affects finallys. Filters could261  // hypothetically use gnu statement expressions to sneak in nested SEH.262  FD = FD ? FD : CGF.CurSEHParent.getDecl();263  return get(CGF.CGM, dyn_cast_or_null<FunctionDecl>(FD));264}265 266static llvm::FunctionCallee getPersonalityFn(CodeGenModule &CGM,267                                             const EHPersonality &Personality) {268  return CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.Int32Ty, true),269                                   Personality.PersonalityFn,270                                   llvm::AttributeList(), /*Local=*/true);271}272 273static llvm::Constant *getOpaquePersonalityFn(CodeGenModule &CGM,274                                        const EHPersonality &Personality) {275  llvm::FunctionCallee Fn = getPersonalityFn(CGM, Personality);276  return cast<llvm::Constant>(Fn.getCallee());277}278 279/// Check whether a landingpad instruction only uses C++ features.280static bool LandingPadHasOnlyCXXUses(llvm::LandingPadInst *LPI) {281  for (unsigned I = 0, E = LPI->getNumClauses(); I != E; ++I) {282    // Look for something that would've been returned by the ObjC283    // runtime's GetEHType() method.284    llvm::Value *Val = LPI->getClause(I)->stripPointerCasts();285    if (LPI->isCatch(I)) {286      // Check if the catch value has the ObjC prefix.287      if (llvm::GlobalVariable *GV = dyn_cast<llvm::GlobalVariable>(Val))288        // ObjC EH selector entries are always global variables with289        // names starting like this.290        if (GV->getName().starts_with("OBJC_EHTYPE"))291          return false;292    } else {293      // Check if any of the filter values have the ObjC prefix.294      llvm::Constant *CVal = cast<llvm::Constant>(Val);295      for (llvm::User::op_iterator296              II = CVal->op_begin(), IE = CVal->op_end(); II != IE; ++II) {297        if (llvm::GlobalVariable *GV =298            cast<llvm::GlobalVariable>((*II)->stripPointerCasts()))299          // ObjC EH selector entries are always global variables with300          // names starting like this.301          if (GV->getName().starts_with("OBJC_EHTYPE"))302            return false;303      }304    }305  }306  return true;307}308 309/// Check whether a personality function could reasonably be swapped310/// for a C++ personality function.311static bool PersonalityHasOnlyCXXUses(llvm::Constant *Fn) {312  for (llvm::User *U : Fn->users()) {313    // Conditionally white-list bitcasts.314    if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(U)) {315      if (CE->getOpcode() != llvm::Instruction::BitCast) return false;316      if (!PersonalityHasOnlyCXXUses(CE))317        return false;318      continue;319    }320 321    // Otherwise it must be a function.322    llvm::Function *F = dyn_cast<llvm::Function>(U);323    if (!F) return false;324 325    for (llvm::BasicBlock &BB : *F) {326      if (BB.isLandingPad())327        if (!LandingPadHasOnlyCXXUses(BB.getLandingPadInst()))328          return false;329    }330  }331 332  return true;333}334 335/// Try to use the C++ personality function in ObjC++.  Not doing this336/// can cause some incompatibilities with gcc, which is more337/// aggressive about only using the ObjC++ personality in a function338/// when it really needs it.339void CodeGenModule::SimplifyPersonality() {340  // If we're not in ObjC++ -fexceptions, there's nothing to do.341  if (!LangOpts.CPlusPlus || !LangOpts.ObjC || !LangOpts.Exceptions)342    return;343 344  // Both the problem this endeavors to fix and the way the logic345  // above works is specific to the NeXT runtime.346  if (!LangOpts.ObjCRuntime.isNeXTFamily())347    return;348 349  const EHPersonality &ObjCXX = EHPersonality::get(*this, /*FD=*/nullptr);350  const EHPersonality &CXX = getCXXPersonality(getTarget(), CodeGenOpts);351  if (&ObjCXX == &CXX)352    return;353 354  assert(std::strcmp(ObjCXX.PersonalityFn, CXX.PersonalityFn) != 0 &&355         "Different EHPersonalities using the same personality function.");356 357  llvm::Function *Fn = getModule().getFunction(ObjCXX.PersonalityFn);358 359  // Nothing to do if it's unused.360  if (!Fn || Fn->use_empty()) return;361 362  // Can't do the optimization if it has non-C++ uses.363  if (!PersonalityHasOnlyCXXUses(Fn)) return;364 365  // Create the C++ personality function and kill off the old366  // function.367  llvm::FunctionCallee CXXFn = getPersonalityFn(*this, CXX);368 369  // This can happen if the user is screwing with us.370  if (Fn->getType() != CXXFn.getCallee()->getType())371    return;372 373  Fn->replaceAllUsesWith(CXXFn.getCallee());374  Fn->eraseFromParent();375}376 377/// Returns the value to inject into a selector to indicate the378/// presence of a catch-all.379static llvm::Constant *getCatchAllValue(CodeGenFunction &CGF) {380  // Possibly we should use @llvm.eh.catch.all.value here.381  return llvm::ConstantPointerNull::get(CGF.Int8PtrTy);382}383 384namespace {385  /// A cleanup to free the exception object if its initialization386  /// throws.387  struct FreeException final : EHScopeStack::Cleanup {388    llvm::Value *exn;389    FreeException(llvm::Value *exn) : exn(exn) {}390    void Emit(CodeGenFunction &CGF, Flags flags) override {391      CGF.EmitNounwindRuntimeCall(getFreeExceptionFn(CGF.CGM), exn);392    }393  };394} // end anonymous namespace395 396// Emits an exception expression into the given location.  This397// differs from EmitAnyExprToMem only in that, if a final copy-ctor398// call is required, an exception within that copy ctor causes399// std::terminate to be invoked.400void CodeGenFunction::EmitAnyExprToExn(const Expr *e, Address addr) {401  // Make sure the exception object is cleaned up if there's an402  // exception during initialization.403  pushFullExprCleanup<FreeException>(EHCleanup, addr.emitRawPointer(*this));404  EHScopeStack::stable_iterator cleanup = EHStack.stable_begin();405 406  // __cxa_allocate_exception returns a void*;  we need to cast this407  // to the appropriate type for the object.408  llvm::Type *ty = ConvertTypeForMem(e->getType());409  Address typedAddr = addr.withElementType(ty);410 411  // FIXME: this isn't quite right!  If there's a final unelided call412  // to a copy constructor, then according to [except.terminate]p1 we413  // must call std::terminate() if that constructor throws, because414  // technically that copy occurs after the exception expression is415  // evaluated but before the exception is caught.  But the best way416  // to handle that is to teach EmitAggExpr to do the final copy417  // differently if it can't be elided.418  EmitAnyExprToMem(e, typedAddr, e->getType().getQualifiers(),419                   /*IsInit*/ true);420 421  // Deactivate the cleanup block.422  DeactivateCleanupBlock(423      cleanup, cast<llvm::Instruction>(typedAddr.emitRawPointer(*this)));424}425 426Address CodeGenFunction::getExceptionSlot() {427  if (!ExceptionSlot)428    ExceptionSlot = CreateTempAlloca(Int8PtrTy, "exn.slot");429  return Address(ExceptionSlot, Int8PtrTy, getPointerAlign());430}431 432Address CodeGenFunction::getEHSelectorSlot() {433  if (!EHSelectorSlot)434    EHSelectorSlot = CreateTempAlloca(Int32Ty, "ehselector.slot");435  return Address(EHSelectorSlot, Int32Ty, CharUnits::fromQuantity(4));436}437 438llvm::Value *CodeGenFunction::getExceptionFromSlot() {439  return Builder.CreateLoad(getExceptionSlot(), "exn");440}441 442llvm::Value *CodeGenFunction::getSelectorFromSlot() {443  return Builder.CreateLoad(getEHSelectorSlot(), "sel");444}445 446void CodeGenFunction::EmitCXXThrowExpr(const CXXThrowExpr *E,447                                       bool KeepInsertionPoint) {448  // If the exception is being emitted in an OpenMP target region,449  // and the target is a GPU, we do not support exception handling.450  // Therefore, we emit a trap which will abort the program, and451  // prompt a warning indicating that a trap will be emitted.452  const llvm::Triple &T = Target.getTriple();453  if (CGM.getLangOpts().OpenMPIsTargetDevice && T.isGPU()) {454    EmitTrapCall(llvm::Intrinsic::trap);455    return;456  }457  if (const Expr *SubExpr = E->getSubExpr()) {458    QualType ThrowType = SubExpr->getType();459    if (ThrowType->isObjCObjectPointerType()) {460      const Stmt *ThrowStmt = E->getSubExpr();461      const ObjCAtThrowStmt S(E->getExprLoc(), const_cast<Stmt *>(ThrowStmt));462      CGM.getObjCRuntime().EmitThrowStmt(*this, S, false);463    } else {464      CGM.getCXXABI().emitThrow(*this, E);465    }466  } else {467    CGM.getCXXABI().emitRethrow(*this, /*isNoReturn=*/true);468  }469 470  // throw is an expression, and the expression emitters expect us471  // to leave ourselves at a valid insertion point.472  if (KeepInsertionPoint)473    EmitBlock(createBasicBlock("throw.cont"));474}475 476void CodeGenFunction::EmitStartEHSpec(const Decl *D) {477  if (!CGM.getLangOpts().CXXExceptions)478    return;479 480  const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);481  if (!FD) {482    // Check if CapturedDecl is nothrow and create terminate scope for it.483    if (const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(D)) {484      if (CD->isNothrow())485        EHStack.pushTerminate();486    }487    return;488  }489  const FunctionProtoType *Proto = FD->getType()->getAs<FunctionProtoType>();490  if (!Proto)491    return;492 493  ExceptionSpecificationType EST = Proto->getExceptionSpecType();494  // In C++17 and later, 'throw()' aka EST_DynamicNone is treated the same way495  // as noexcept. In earlier standards, it is handled in this block, along with496  // 'throw(X...)'.497  if (EST == EST_Dynamic ||498      (EST == EST_DynamicNone && !getLangOpts().CPlusPlus17)) {499    // TODO: Revisit exception specifications for the MS ABI.  There is a way to500    // encode these in an object file but MSVC doesn't do anything with it.501    if (getTarget().getCXXABI().isMicrosoft())502      return;503    // In Wasm EH we currently treat 'throw()' in the same way as 'noexcept'. In504    // case of throw with types, we ignore it and print a warning for now.505    // TODO Correctly handle exception specification in Wasm EH506    if (CGM.getCodeGenOpts().hasWasmExceptions()) {507      if (EST == EST_DynamicNone)508        EHStack.pushTerminate();509      else510        CGM.getDiags().Report(D->getLocation(),511                              diag::warn_wasm_dynamic_exception_spec_ignored)512            << FD->getExceptionSpecSourceRange();513      return;514    }515    // Currently Emscripten EH only handles 'throw()' but not 'throw' with516    // types. 'throw()' handling will be done in JS glue code so we don't need517    // to do anything in that case. Just print a warning message in case of518    // throw with types.519    // TODO Correctly handle exception specification in Emscripten EH520    if (getTarget().getCXXABI() == TargetCXXABI::WebAssembly &&521        CGM.getCodeGenOpts().getExceptionHandling() ==522            CodeGenOptions::ExceptionHandlingKind::None &&523        EST == EST_Dynamic)524      CGM.getDiags().Report(D->getLocation(),525                            diag::warn_wasm_dynamic_exception_spec_ignored)526          << FD->getExceptionSpecSourceRange();527 528    unsigned NumExceptions = Proto->getNumExceptions();529    EHFilterScope *Filter = EHStack.pushFilter(NumExceptions);530 531    for (unsigned I = 0; I != NumExceptions; ++I) {532      QualType Ty = Proto->getExceptionType(I);533      QualType ExceptType = Ty.getNonReferenceType().getUnqualifiedType();534      llvm::Value *EHType = CGM.GetAddrOfRTTIDescriptor(ExceptType,535                                                        /*ForEH=*/true);536      Filter->setFilter(I, EHType);537    }538  } else if (Proto->canThrow() == CT_Cannot) {539    // noexcept functions are simple terminate scopes.540    if (!getLangOpts().EHAsynch) // -EHa: HW exception still can occur541      EHStack.pushTerminate();542  }543}544 545/// Emit the dispatch block for a filter scope if necessary.546static void emitFilterDispatchBlock(CodeGenFunction &CGF,547                                    EHFilterScope &filterScope) {548  llvm::BasicBlock *dispatchBlock = filterScope.getCachedEHDispatchBlock();549  if (!dispatchBlock) return;550  if (dispatchBlock->use_empty()) {551    delete dispatchBlock;552    return;553  }554 555  CGF.EmitBlockAfterUses(dispatchBlock);556 557  // If this isn't a catch-all filter, we need to check whether we got558  // here because the filter triggered.559  if (filterScope.getNumFilters()) {560    // Load the selector value.561    llvm::Value *selector = CGF.getSelectorFromSlot();562    llvm::BasicBlock *unexpectedBB = CGF.createBasicBlock("ehspec.unexpected");563 564    llvm::Value *zero = CGF.Builder.getInt32(0);565    llvm::Value *failsFilter =566        CGF.Builder.CreateICmpSLT(selector, zero, "ehspec.fails");567    CGF.Builder.CreateCondBr(failsFilter, unexpectedBB,568                             CGF.getEHResumeBlock(false));569 570    CGF.EmitBlock(unexpectedBB);571  }572 573  // Call __cxa_call_unexpected.  This doesn't need to be an invoke574  // because __cxa_call_unexpected magically filters exceptions575  // according to the last landing pad the exception was thrown576  // into.  Seriously.577  llvm::Value *exn = CGF.getExceptionFromSlot();578  CGF.EmitRuntimeCall(getUnexpectedFn(CGF.CGM), exn)579    ->setDoesNotReturn();580  CGF.Builder.CreateUnreachable();581}582 583void CodeGenFunction::EmitEndEHSpec(const Decl *D) {584  if (!CGM.getLangOpts().CXXExceptions)585    return;586 587  const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);588  if (!FD) {589    // Check if CapturedDecl is nothrow and pop terminate scope for it.590    if (const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(D)) {591      if (CD->isNothrow() && !EHStack.empty())592        EHStack.popTerminate();593    }594    return;595  }596  const FunctionProtoType *Proto = FD->getType()->getAs<FunctionProtoType>();597  if (!Proto)598    return;599 600  ExceptionSpecificationType EST = Proto->getExceptionSpecType();601  if (EST == EST_Dynamic ||602      (EST == EST_DynamicNone && !getLangOpts().CPlusPlus17)) {603    // TODO: Revisit exception specifications for the MS ABI.  There is a way to604    // encode these in an object file but MSVC doesn't do anything with it.605    if (getTarget().getCXXABI().isMicrosoft())606      return;607    // In wasm we currently treat 'throw()' in the same way as 'noexcept'. In608    // case of throw with types, we ignore it and print a warning for now.609    // TODO Correctly handle exception specification in wasm610    if (CGM.getCodeGenOpts().hasWasmExceptions()) {611      if (EST == EST_DynamicNone)612        EHStack.popTerminate();613      return;614    }615    EHFilterScope &filterScope = cast<EHFilterScope>(*EHStack.begin());616    emitFilterDispatchBlock(*this, filterScope);617    EHStack.popFilter();618  } else if (Proto->canThrow() == CT_Cannot &&619              /* possible empty when under async exceptions */620             !EHStack.empty()) {621    EHStack.popTerminate();622  }623}624 625void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) {626  const llvm::Triple &T = Target.getTriple();627  // If we encounter a try statement on in an OpenMP target region offloaded to628  // a GPU, we treat it as a basic block.629  const bool IsTargetDevice =630      (CGM.getLangOpts().OpenMPIsTargetDevice && T.isGPU());631  if (!IsTargetDevice)632    EnterCXXTryStmt(S);633  EmitStmt(S.getTryBlock());634  if (!IsTargetDevice)635    ExitCXXTryStmt(S);636}637 638void CodeGenFunction::EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {639  unsigned NumHandlers = S.getNumHandlers();640  EHCatchScope *CatchScope = EHStack.pushCatch(NumHandlers);641 642  for (unsigned I = 0; I != NumHandlers; ++I) {643    const CXXCatchStmt *C = S.getHandler(I);644 645    llvm::BasicBlock *Handler = createBasicBlock("catch");646    if (C->getExceptionDecl()) {647      // FIXME: Dropping the reference type on the type into makes it648      // impossible to correctly implement catch-by-reference649      // semantics for pointers.  Unfortunately, this is what all650      // existing compilers do, and it's not clear that the standard651      // personality routine is capable of doing this right.  See C++ DR 388:652      //   http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#388653      Qualifiers CaughtTypeQuals;654      QualType CaughtType = CGM.getContext().getUnqualifiedArrayType(655          C->getCaughtType().getNonReferenceType(), CaughtTypeQuals);656 657      CatchTypeInfo TypeInfo{nullptr, 0};658      if (CaughtType->isObjCObjectPointerType())659        TypeInfo.RTTI = CGM.getObjCRuntime().GetEHType(CaughtType);660      else661        TypeInfo = CGM.getCXXABI().getAddrOfCXXCatchHandlerType(662            CaughtType, C->getCaughtType());663      CatchScope->setHandler(I, TypeInfo, Handler);664    } else {665      // No exception decl indicates '...', a catch-all.666      CatchScope->setHandler(I, CGM.getCXXABI().getCatchAllTypeInfo(), Handler);667      // Under async exceptions, catch(...) need to catch HW exception too668      // Mark scope with SehTryBegin as a SEH __try scope669      if (getLangOpts().EHAsynch)670        EmitSehTryScopeBegin();671    }672  }673}674 675llvm::BasicBlock *676CodeGenFunction::getEHDispatchBlock(EHScopeStack::stable_iterator si) {677  if (EHPersonality::get(*this).usesFuncletPads())678    return getFuncletEHDispatchBlock(si);679 680  // The dispatch block for the end of the scope chain is a block that681  // just resumes unwinding.682  if (si == EHStack.stable_end())683    return getEHResumeBlock(true);684 685  // Otherwise, we should look at the actual scope.686  EHScope &scope = *EHStack.find(si);687 688  llvm::BasicBlock *dispatchBlock = scope.getCachedEHDispatchBlock();689  if (!dispatchBlock) {690    switch (scope.getKind()) {691    case EHScope::Catch: {692      // Apply a special case to a single catch-all.693      EHCatchScope &catchScope = cast<EHCatchScope>(scope);694      if (catchScope.getNumHandlers() == 1 &&695          catchScope.getHandler(0).isCatchAll()) {696        dispatchBlock = catchScope.getHandler(0).Block;697 698      // Otherwise, make a dispatch block.699      } else {700        dispatchBlock = createBasicBlock("catch.dispatch");701      }702      break;703    }704 705    case EHScope::Cleanup:706      dispatchBlock = createBasicBlock("ehcleanup");707      break;708 709    case EHScope::Filter:710      dispatchBlock = createBasicBlock("filter.dispatch");711      break;712 713    case EHScope::Terminate:714      dispatchBlock = getTerminateHandler();715      break;716    }717    scope.setCachedEHDispatchBlock(dispatchBlock);718  }719  return dispatchBlock;720}721 722llvm::BasicBlock *723CodeGenFunction::getFuncletEHDispatchBlock(EHScopeStack::stable_iterator SI) {724  // Returning nullptr indicates that the previous dispatch block should unwind725  // to caller.726  if (SI == EHStack.stable_end())727    return nullptr;728 729  // Otherwise, we should look at the actual scope.730  EHScope &EHS = *EHStack.find(SI);731 732  llvm::BasicBlock *DispatchBlock = EHS.getCachedEHDispatchBlock();733  if (DispatchBlock)734    return DispatchBlock;735 736  if (EHS.getKind() == EHScope::Terminate)737    DispatchBlock = getTerminateFunclet();738  else739    DispatchBlock = createBasicBlock();740  CGBuilderTy Builder(*this, DispatchBlock);741 742  switch (EHS.getKind()) {743  case EHScope::Catch:744    DispatchBlock->setName("catch.dispatch");745    break;746 747  case EHScope::Cleanup:748    DispatchBlock->setName("ehcleanup");749    break;750 751  case EHScope::Filter:752    llvm_unreachable("exception specifications not handled yet!");753 754  case EHScope::Terminate:755    DispatchBlock->setName("terminate");756    break;757  }758  EHS.setCachedEHDispatchBlock(DispatchBlock);759  return DispatchBlock;760}761 762/// Check whether this is a non-EH scope, i.e. a scope which doesn't763/// affect exception handling.  Currently, the only non-EH scopes are764/// normal-only cleanup scopes.765static bool isNonEHScope(const EHScope &S) {766  switch (S.getKind()) {767  case EHScope::Cleanup:768    return !cast<EHCleanupScope>(S).isEHCleanup();769  case EHScope::Filter:770  case EHScope::Catch:771  case EHScope::Terminate:772    return false;773  }774 775  llvm_unreachable("Invalid EHScope Kind!");776}777 778llvm::BasicBlock *CodeGenFunction::getInvokeDestImpl() {779  assert(EHStack.requiresLandingPad());780  assert(!EHStack.empty());781 782  // If exceptions are disabled/ignored and SEH is not in use, then there is no783  // invoke destination. SEH "works" even if exceptions are off. In practice,784  // this means that C++ destructors and other EH cleanups don't run, which is785  // consistent with MSVC's behavior, except in the presence of -EHa786  const LangOptions &LO = CGM.getLangOpts();787  if (!LO.Exceptions || LO.IgnoreExceptions) {788    if (!LO.Borland && !LO.MicrosoftExt)789      return nullptr;790    if (!currentFunctionUsesSEHTry())791      return nullptr;792  }793 794  // CUDA device code doesn't have exceptions.795  if (LO.CUDA && LO.CUDAIsDevice)796    return nullptr;797 798  // Check the innermost scope for a cached landing pad.  If this is799  // a non-EH cleanup, we'll check enclosing scopes in EmitLandingPad.800  llvm::BasicBlock *LP = EHStack.begin()->getCachedLandingPad();801  if (LP) return LP;802 803  const EHPersonality &Personality = EHPersonality::get(*this);804 805  if (!CurFn->hasPersonalityFn())806    CurFn->setPersonalityFn(getOpaquePersonalityFn(CGM, Personality));807 808  if (Personality.usesFuncletPads()) {809    // We don't need separate landing pads in the funclet model.810    LP = getEHDispatchBlock(EHStack.getInnermostEHScope());811  } else {812    // Build the landing pad for this scope.813    LP = EmitLandingPad();814  }815 816  assert(LP);817 818  // Cache the landing pad on the innermost scope.  If this is a819  // non-EH scope, cache the landing pad on the enclosing scope, too.820  for (EHScopeStack::iterator ir = EHStack.begin(); true; ++ir) {821    ir->setCachedLandingPad(LP);822    if (!isNonEHScope(*ir)) break;823  }824 825  return LP;826}827 828llvm::BasicBlock *CodeGenFunction::EmitLandingPad() {829  assert(EHStack.requiresLandingPad());830  assert(!CGM.getLangOpts().IgnoreExceptions &&831         "LandingPad should not be emitted when -fignore-exceptions are in "832         "effect.");833  EHScope &innermostEHScope = *EHStack.find(EHStack.getInnermostEHScope());834  switch (innermostEHScope.getKind()) {835  case EHScope::Terminate:836    return getTerminateLandingPad();837 838  case EHScope::Catch:839  case EHScope::Cleanup:840  case EHScope::Filter:841    if (llvm::BasicBlock *lpad = innermostEHScope.getCachedLandingPad())842      return lpad;843  }844 845  // Save the current IR generation state.846  CGBuilderTy::InsertPoint savedIP = Builder.saveAndClearIP();847  auto DL = ApplyDebugLocation::CreateDefaultArtificial(*this, CurEHLocation);848 849  // Create and configure the landing pad.850  llvm::BasicBlock *lpad = createBasicBlock("lpad");851  EmitBlock(lpad);852 853  llvm::LandingPadInst *LPadInst =854      Builder.CreateLandingPad(llvm::StructType::get(Int8PtrTy, Int32Ty), 0);855 856  llvm::Value *LPadExn = Builder.CreateExtractValue(LPadInst, 0);857  Builder.CreateStore(LPadExn, getExceptionSlot());858  llvm::Value *LPadSel = Builder.CreateExtractValue(LPadInst, 1);859  Builder.CreateStore(LPadSel, getEHSelectorSlot());860 861  // Save the exception pointer.  It's safe to use a single exception862  // pointer per function because EH cleanups can never have nested863  // try/catches.864  // Build the landingpad instruction.865 866  // Accumulate all the handlers in scope.867  bool hasCatchAll = false;868  bool hasCleanup = false;869  bool hasFilter = false;870  SmallVector<llvm::Value*, 4> filterTypes;871  llvm::SmallPtrSet<llvm::Value*, 4> catchTypes;872  for (EHScopeStack::iterator I = EHStack.begin(), E = EHStack.end(); I != E;873       ++I) {874 875    switch (I->getKind()) {876    case EHScope::Cleanup:877      // If we have a cleanup, remember that.878      hasCleanup = (hasCleanup || cast<EHCleanupScope>(*I).isEHCleanup());879      continue;880 881    case EHScope::Filter: {882      assert(I.next() == EHStack.end() && "EH filter is not end of EH stack");883      assert(!hasCatchAll && "EH filter reached after catch-all");884 885      // Filter scopes get added to the landingpad in weird ways.886      EHFilterScope &filter = cast<EHFilterScope>(*I);887      hasFilter = true;888 889      // Add all the filter values.890      for (unsigned i = 0, e = filter.getNumFilters(); i != e; ++i)891        filterTypes.push_back(filter.getFilter(i));892      goto done;893    }894 895    case EHScope::Terminate:896      // Terminate scopes are basically catch-alls.897      assert(!hasCatchAll);898      hasCatchAll = true;899      goto done;900 901    case EHScope::Catch:902      break;903    }904 905    EHCatchScope &catchScope = cast<EHCatchScope>(*I);906    for (unsigned hi = 0, he = catchScope.getNumHandlers(); hi != he; ++hi) {907      EHCatchScope::Handler handler = catchScope.getHandler(hi);908      assert(handler.Type.Flags == 0 &&909             "landingpads do not support catch handler flags");910 911      // If this is a catch-all, register that and abort.912      if (!handler.Type.RTTI) {913        assert(!hasCatchAll);914        hasCatchAll = true;915        goto done;916      }917 918      // Check whether we already have a handler for this type.919      if (catchTypes.insert(handler.Type.RTTI).second)920        // If not, add it directly to the landingpad.921        LPadInst->addClause(handler.Type.RTTI);922    }923  }924 925 done:926  // If we have a catch-all, add null to the landingpad.927  assert(!(hasCatchAll && hasFilter));928  if (hasCatchAll) {929    LPadInst->addClause(getCatchAllValue(*this));930 931  // If we have an EH filter, we need to add those handlers in the932  // right place in the landingpad, which is to say, at the end.933  } else if (hasFilter) {934    // Create a filter expression: a constant array indicating which filter935    // types there are. The personality routine only lands here if the filter936    // doesn't match.937    SmallVector<llvm::Constant*, 8> Filters;938    llvm::ArrayType *AType =939      llvm::ArrayType::get(!filterTypes.empty() ?940                             filterTypes[0]->getType() : Int8PtrTy,941                           filterTypes.size());942 943    for (llvm::Value *filterType : filterTypes)944      Filters.push_back(cast<llvm::Constant>(filterType));945    llvm::Constant *FilterArray = llvm::ConstantArray::get(AType, Filters);946    LPadInst->addClause(FilterArray);947 948    // Also check whether we need a cleanup.949    if (hasCleanup)950      LPadInst->setCleanup(true);951 952  // Otherwise, signal that we at least have cleanups.953  } else if (hasCleanup) {954    LPadInst->setCleanup(true);955  }956 957  assert((LPadInst->getNumClauses() > 0 || LPadInst->isCleanup()) &&958         "landingpad instruction has no clauses!");959 960  // Tell the backend how to generate the landing pad.961  Builder.CreateBr(getEHDispatchBlock(EHStack.getInnermostEHScope()));962 963  // Restore the old IR generation state.964  Builder.restoreIP(savedIP);965 966  return lpad;967}968 969static void emitCatchPadBlock(CodeGenFunction &CGF, EHCatchScope &CatchScope) {970  llvm::BasicBlock *DispatchBlock = CatchScope.getCachedEHDispatchBlock();971  assert(DispatchBlock);972 973  CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveIP();974  CGF.EmitBlockAfterUses(DispatchBlock);975 976  llvm::Value *ParentPad = CGF.CurrentFuncletPad;977  if (!ParentPad)978    ParentPad = llvm::ConstantTokenNone::get(CGF.getLLVMContext());979  llvm::BasicBlock *UnwindBB =980      CGF.getEHDispatchBlock(CatchScope.getEnclosingEHScope());981 982  unsigned NumHandlers = CatchScope.getNumHandlers();983  llvm::CatchSwitchInst *CatchSwitch =984      CGF.Builder.CreateCatchSwitch(ParentPad, UnwindBB, NumHandlers);985 986  // Test against each of the exception types we claim to catch.987  for (unsigned I = 0; I < NumHandlers; ++I) {988    const EHCatchScope::Handler &Handler = CatchScope.getHandler(I);989 990    CatchTypeInfo TypeInfo = Handler.Type;991    if (!TypeInfo.RTTI)992      TypeInfo.RTTI = llvm::Constant::getNullValue(CGF.VoidPtrTy);993 994    CGF.Builder.SetInsertPoint(Handler.Block);995 996    if (EHPersonality::get(CGF).isMSVCXXPersonality()) {997      CGF.Builder.CreateCatchPad(998          CatchSwitch, {TypeInfo.RTTI, CGF.Builder.getInt32(TypeInfo.Flags),999                        llvm::Constant::getNullValue(CGF.VoidPtrTy)});1000    } else {1001      CGF.Builder.CreateCatchPad(CatchSwitch, {TypeInfo.RTTI});1002    }1003 1004    CatchSwitch->addHandler(Handler.Block);1005  }1006  CGF.Builder.restoreIP(SavedIP);1007}1008 1009// Wasm uses Windows-style EH instructions, but it merges all catch clauses into1010// one big catchpad, within which we use Itanium's landingpad-style selector1011// comparison instructions.1012static void emitWasmCatchPadBlock(CodeGenFunction &CGF,1013                                  EHCatchScope &CatchScope) {1014  llvm::BasicBlock *DispatchBlock = CatchScope.getCachedEHDispatchBlock();1015  assert(DispatchBlock);1016 1017  CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveIP();1018  CGF.EmitBlockAfterUses(DispatchBlock);1019 1020  llvm::Value *ParentPad = CGF.CurrentFuncletPad;1021  if (!ParentPad)1022    ParentPad = llvm::ConstantTokenNone::get(CGF.getLLVMContext());1023  llvm::BasicBlock *UnwindBB =1024      CGF.getEHDispatchBlock(CatchScope.getEnclosingEHScope());1025 1026  unsigned NumHandlers = CatchScope.getNumHandlers();1027  llvm::CatchSwitchInst *CatchSwitch =1028      CGF.Builder.CreateCatchSwitch(ParentPad, UnwindBB, NumHandlers);1029 1030  // We don't use a landingpad instruction, so generate intrinsic calls to1031  // provide exception and selector values.1032  llvm::BasicBlock *WasmCatchStartBlock = CGF.createBasicBlock("catch.start");1033  CatchSwitch->addHandler(WasmCatchStartBlock);1034  CGF.EmitBlockAfterUses(WasmCatchStartBlock);1035 1036  // Create a catchpad instruction.1037  SmallVector<llvm::Value *, 4> CatchTypes;1038  for (unsigned I = 0, E = NumHandlers; I < E; ++I) {1039    const EHCatchScope::Handler &Handler = CatchScope.getHandler(I);1040    CatchTypeInfo TypeInfo = Handler.Type;1041    if (!TypeInfo.RTTI)1042      TypeInfo.RTTI = llvm::Constant::getNullValue(CGF.VoidPtrTy);1043    CatchTypes.push_back(TypeInfo.RTTI);1044  }1045  auto *CPI = CGF.Builder.CreateCatchPad(CatchSwitch, CatchTypes);1046 1047  // Create calls to wasm.get.exception and wasm.get.ehselector intrinsics.1048  // Before they are lowered appropriately later, they provide values for the1049  // exception and selector.1050  llvm::Function *GetExnFn =1051      CGF.CGM.getIntrinsic(llvm::Intrinsic::wasm_get_exception);1052  llvm::Function *GetSelectorFn =1053      CGF.CGM.getIntrinsic(llvm::Intrinsic::wasm_get_ehselector);1054  llvm::CallInst *Exn = CGF.Builder.CreateCall(GetExnFn, CPI);1055  CGF.Builder.CreateStore(Exn, CGF.getExceptionSlot());1056  llvm::CallInst *Selector = CGF.Builder.CreateCall(GetSelectorFn, CPI);1057 1058  llvm::Function *TypeIDFn =1059      CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for, {CGF.VoidPtrTy});1060 1061  // If there's only a single catch-all, branch directly to its handler.1062  if (CatchScope.getNumHandlers() == 1 &&1063      CatchScope.getHandler(0).isCatchAll()) {1064    CGF.Builder.CreateBr(CatchScope.getHandler(0).Block);1065    CGF.Builder.restoreIP(SavedIP);1066    return;1067  }1068 1069  // Test against each of the exception types we claim to catch.1070  for (unsigned I = 0, E = NumHandlers;; ++I) {1071    assert(I < E && "ran off end of handlers!");1072    const EHCatchScope::Handler &Handler = CatchScope.getHandler(I);1073    CatchTypeInfo TypeInfo = Handler.Type;1074    if (!TypeInfo.RTTI)1075      TypeInfo.RTTI = llvm::Constant::getNullValue(CGF.VoidPtrTy);1076 1077    // Figure out the next block.1078    llvm::BasicBlock *NextBlock;1079 1080    bool EmitNextBlock = false, NextIsEnd = false;1081 1082    // If this is the last handler, we're at the end, and the next block is a1083    // block that contains a call to the rethrow function, so we can unwind to1084    // the enclosing EH scope. The call itself will be generated later.1085    if (I + 1 == E) {1086      NextBlock = CGF.createBasicBlock("rethrow");1087      EmitNextBlock = true;1088      NextIsEnd = true;1089 1090      // If the next handler is a catch-all, we're at the end, and the1091      // next block is that handler.1092    } else if (CatchScope.getHandler(I + 1).isCatchAll()) {1093      NextBlock = CatchScope.getHandler(I + 1).Block;1094      NextIsEnd = true;1095 1096      // Otherwise, we're not at the end and we need a new block.1097    } else {1098      NextBlock = CGF.createBasicBlock("catch.fallthrough");1099      EmitNextBlock = true;1100    }1101 1102    // Figure out the catch type's index in the LSDA's type table.1103    llvm::CallInst *TypeIndex = CGF.Builder.CreateCall(TypeIDFn, TypeInfo.RTTI);1104    TypeIndex->setDoesNotThrow();1105 1106    llvm::Value *MatchesTypeIndex =1107        CGF.Builder.CreateICmpEQ(Selector, TypeIndex, "matches");1108    CGF.Builder.CreateCondBr(MatchesTypeIndex, Handler.Block, NextBlock);1109 1110    if (EmitNextBlock)1111      CGF.EmitBlock(NextBlock);1112    if (NextIsEnd)1113      break;1114  }1115 1116  CGF.Builder.restoreIP(SavedIP);1117}1118 1119/// Emit the structure of the dispatch block for the given catch scope.1120/// It is an invariant that the dispatch block already exists.1121static void emitCatchDispatchBlock(CodeGenFunction &CGF,1122                                   EHCatchScope &catchScope) {1123  if (EHPersonality::get(CGF).isWasmPersonality())1124    return emitWasmCatchPadBlock(CGF, catchScope);1125  if (EHPersonality::get(CGF).usesFuncletPads())1126    return emitCatchPadBlock(CGF, catchScope);1127 1128  llvm::BasicBlock *dispatchBlock = catchScope.getCachedEHDispatchBlock();1129  assert(dispatchBlock);1130 1131  // If there's only a single catch-all, getEHDispatchBlock returned1132  // that catch-all as the dispatch block.1133  if (catchScope.getNumHandlers() == 1 &&1134      catchScope.getHandler(0).isCatchAll()) {1135    assert(dispatchBlock == catchScope.getHandler(0).Block);1136    return;1137  }1138 1139  CGBuilderTy::InsertPoint savedIP = CGF.Builder.saveIP();1140  CGF.EmitBlockAfterUses(dispatchBlock);1141 1142  // Select the right handler.1143  llvm::Function *llvm_eh_typeid_for =1144      CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for, {CGF.VoidPtrTy});1145  llvm::Type *argTy = llvm_eh_typeid_for->getArg(0)->getType();1146  LangAS globAS = CGF.CGM.GetGlobalVarAddressSpace(nullptr);1147 1148  // Load the selector value.1149  llvm::Value *selector = CGF.getSelectorFromSlot();1150 1151  // Test against each of the exception types we claim to catch.1152  for (unsigned i = 0, e = catchScope.getNumHandlers(); ; ++i) {1153    assert(i < e && "ran off end of handlers!");1154    const EHCatchScope::Handler &handler = catchScope.getHandler(i);1155 1156    llvm::Value *typeValue = handler.Type.RTTI;1157    assert(handler.Type.Flags == 0 &&1158           "landingpads do not support catch handler flags");1159    assert(typeValue && "fell into catch-all case!");1160    // With opaque ptrs, only the address space can be a mismatch.1161    if (typeValue->getType() != argTy)1162      typeValue = CGF.getTargetHooks().performAddrSpaceCast(CGF, typeValue,1163                                                            globAS, argTy);1164 1165    // Figure out the next block.1166    bool nextIsEnd;1167    llvm::BasicBlock *nextBlock;1168 1169    // If this is the last handler, we're at the end, and the next1170    // block is the block for the enclosing EH scope.1171    if (i + 1 == e) {1172      nextBlock = CGF.getEHDispatchBlock(catchScope.getEnclosingEHScope());1173      nextIsEnd = true;1174 1175    // If the next handler is a catch-all, we're at the end, and the1176    // next block is that handler.1177    } else if (catchScope.getHandler(i+1).isCatchAll()) {1178      nextBlock = catchScope.getHandler(i+1).Block;1179      nextIsEnd = true;1180 1181    // Otherwise, we're not at the end and we need a new block.1182    } else {1183      nextBlock = CGF.createBasicBlock("catch.fallthrough");1184      nextIsEnd = false;1185    }1186 1187    // Figure out the catch type's index in the LSDA's type table.1188    llvm::CallInst *typeIndex =1189      CGF.Builder.CreateCall(llvm_eh_typeid_for, typeValue);1190    typeIndex->setDoesNotThrow();1191 1192    llvm::Value *matchesTypeIndex =1193      CGF.Builder.CreateICmpEQ(selector, typeIndex, "matches");1194    CGF.Builder.CreateCondBr(matchesTypeIndex, handler.Block, nextBlock);1195 1196    // If the next handler is a catch-all, we're completely done.1197    if (nextIsEnd) {1198      CGF.Builder.restoreIP(savedIP);1199      return;1200    }1201    // Otherwise we need to emit and continue at that block.1202    CGF.EmitBlock(nextBlock);1203  }1204}1205 1206void CodeGenFunction::popCatchScope() {1207  EHCatchScope &catchScope = cast<EHCatchScope>(*EHStack.begin());1208  if (catchScope.hasEHBranches())1209    emitCatchDispatchBlock(*this, catchScope);1210  EHStack.popCatch();1211}1212 1213void CodeGenFunction::ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {1214  unsigned NumHandlers = S.getNumHandlers();1215  EHCatchScope &CatchScope = cast<EHCatchScope>(*EHStack.begin());1216  assert(CatchScope.getNumHandlers() == NumHandlers);1217  llvm::BasicBlock *DispatchBlock = CatchScope.getCachedEHDispatchBlock();1218 1219  // If the catch was not required, bail out now.1220  if (!CatchScope.hasEHBranches()) {1221    CatchScope.clearHandlerBlocks();1222    EHStack.popCatch();1223    return;1224  }1225 1226  // Emit the structure of the EH dispatch for this catch.1227  emitCatchDispatchBlock(*this, CatchScope);1228 1229  // Copy the handler blocks off before we pop the EH stack.  Emitting1230  // the handlers might scribble on this memory.1231  SmallVector<EHCatchScope::Handler, 8> Handlers(1232      CatchScope.begin(), CatchScope.begin() + NumHandlers);1233 1234  EHStack.popCatch();1235 1236  // The fall-through block.1237  llvm::BasicBlock *ContBB = createBasicBlock("try.cont");1238 1239  // We just emitted the body of the try; jump to the continue block.1240  if (HaveInsertPoint())1241    Builder.CreateBr(ContBB);1242 1243  // Determine if we need an implicit rethrow for all these catch handlers;1244  // see the comment below.1245  bool doImplicitRethrow = false;1246  if (IsFnTryBlock)1247    doImplicitRethrow = isa<CXXDestructorDecl>(CurCodeDecl) ||1248                        isa<CXXConstructorDecl>(CurCodeDecl);1249 1250  // Wasm uses Windows-style EH instructions, but merges all catch clauses into1251  // one big catchpad. So we save the old funclet pad here before we traverse1252  // each catch handler.1253  SaveAndRestore RestoreCurrentFuncletPad(CurrentFuncletPad);1254  llvm::BasicBlock *WasmCatchStartBlock = nullptr;1255  if (EHPersonality::get(*this).isWasmPersonality()) {1256    auto *CatchSwitch =1257        cast<llvm::CatchSwitchInst>(DispatchBlock->getFirstNonPHIIt());1258    WasmCatchStartBlock = CatchSwitch->hasUnwindDest()1259                              ? CatchSwitch->getSuccessor(1)1260                              : CatchSwitch->getSuccessor(0);1261    auto *CPI =1262        cast<llvm::CatchPadInst>(WasmCatchStartBlock->getFirstNonPHIIt());1263    CurrentFuncletPad = CPI;1264  }1265 1266  // Perversely, we emit the handlers backwards precisely because we1267  // want them to appear in source order.  In all of these cases, the1268  // catch block will have exactly one predecessor, which will be a1269  // particular block in the catch dispatch.  However, in the case of1270  // a catch-all, one of the dispatch blocks will branch to two1271  // different handlers, and EmitBlockAfterUses will cause the second1272  // handler to be moved before the first.1273  bool HasCatchAll = false;1274  for (unsigned I = NumHandlers; I != 0; --I) {1275    HasCatchAll |= Handlers[I - 1].isCatchAll();1276    llvm::BasicBlock *CatchBlock = Handlers[I-1].Block;1277    EmitBlockAfterUses(CatchBlock);1278 1279    // Catch the exception if this isn't a catch-all.1280    const CXXCatchStmt *C = S.getHandler(I-1);1281 1282    // Enter a cleanup scope, including the catch variable and the1283    // end-catch.1284    RunCleanupsScope CatchScope(*this);1285 1286    // Initialize the catch variable and set up the cleanups.1287    SaveAndRestore RestoreCurrentFuncletPad(CurrentFuncletPad);1288    CGM.getCXXABI().emitBeginCatch(*this, C);1289 1290    // Emit the PGO counter increment.1291    incrementProfileCounter(C);1292 1293    // Perform the body of the catch.1294    EmitStmt(C->getHandlerBlock());1295 1296    // [except.handle]p11:1297    //   The currently handled exception is rethrown if control1298    //   reaches the end of a handler of the function-try-block of a1299    //   constructor or destructor.1300 1301    // It is important that we only do this on fallthrough and not on1302    // return.  Note that it's illegal to put a return in a1303    // constructor function-try-block's catch handler (p14), so this1304    // really only applies to destructors.1305    if (doImplicitRethrow && HaveInsertPoint()) {1306      CGM.getCXXABI().emitRethrow(*this, /*isNoReturn*/false);1307      Builder.CreateUnreachable();1308      Builder.ClearInsertionPoint();1309    }1310 1311    // Fall out through the catch cleanups.1312    CatchScope.ForceCleanup();1313 1314    // Branch out of the try.1315    if (HaveInsertPoint())1316      Builder.CreateBr(ContBB);1317  }1318 1319  // Because in wasm we merge all catch clauses into one big catchpad, in case1320  // none of the types in catch handlers matches after we test against each of1321  // them, we should unwind to the next EH enclosing scope. We generate a call1322  // to rethrow function here to do that.1323  if (EHPersonality::get(*this).isWasmPersonality() && !HasCatchAll) {1324    assert(WasmCatchStartBlock);1325    // Navigate for the "rethrow" block we created in emitWasmCatchPadBlock().1326    // Wasm uses landingpad-style conditional branches to compare selectors, so1327    // we follow the false destination for each of the cond branches to reach1328    // the rethrow block.1329    llvm::BasicBlock *RethrowBlock = WasmCatchStartBlock;1330    while (llvm::Instruction *TI = RethrowBlock->getTerminator()) {1331      auto *BI = cast<llvm::BranchInst>(TI);1332      assert(BI->isConditional());1333      RethrowBlock = BI->getSuccessor(1);1334    }1335    assert(RethrowBlock != WasmCatchStartBlock && RethrowBlock->empty());1336    Builder.SetInsertPoint(RethrowBlock);1337    llvm::Function *RethrowInCatchFn =1338        CGM.getIntrinsic(llvm::Intrinsic::wasm_rethrow);1339    EmitNoreturnRuntimeCallOrInvoke(RethrowInCatchFn, {});1340  }1341 1342  EmitBlock(ContBB);1343  incrementProfileCounter(&S);1344}1345 1346namespace {1347  struct CallEndCatchForFinally final : EHScopeStack::Cleanup {1348    llvm::Value *ForEHVar;1349    llvm::FunctionCallee EndCatchFn;1350    CallEndCatchForFinally(llvm::Value *ForEHVar,1351                           llvm::FunctionCallee EndCatchFn)1352        : ForEHVar(ForEHVar), EndCatchFn(EndCatchFn) {}1353 1354    void Emit(CodeGenFunction &CGF, Flags flags) override {1355      llvm::BasicBlock *EndCatchBB = CGF.createBasicBlock("finally.endcatch");1356      llvm::BasicBlock *CleanupContBB =1357        CGF.createBasicBlock("finally.cleanup.cont");1358 1359      llvm::Value *ShouldEndCatch =1360        CGF.Builder.CreateFlagLoad(ForEHVar, "finally.endcatch");1361      CGF.Builder.CreateCondBr(ShouldEndCatch, EndCatchBB, CleanupContBB);1362      CGF.EmitBlock(EndCatchBB);1363      CGF.EmitRuntimeCallOrInvoke(EndCatchFn); // catch-all, so might throw1364      CGF.EmitBlock(CleanupContBB);1365    }1366  };1367 1368  struct PerformFinally final : EHScopeStack::Cleanup {1369    const Stmt *Body;1370    llvm::Value *ForEHVar;1371    llvm::FunctionCallee EndCatchFn;1372    llvm::FunctionCallee RethrowFn;1373    llvm::Value *SavedExnVar;1374 1375    PerformFinally(const Stmt *Body, llvm::Value *ForEHVar,1376                   llvm::FunctionCallee EndCatchFn,1377                   llvm::FunctionCallee RethrowFn, llvm::Value *SavedExnVar)1378        : Body(Body), ForEHVar(ForEHVar), EndCatchFn(EndCatchFn),1379          RethrowFn(RethrowFn), SavedExnVar(SavedExnVar) {}1380 1381    void Emit(CodeGenFunction &CGF, Flags flags) override {1382      // Enter a cleanup to call the end-catch function if one was provided.1383      if (EndCatchFn)1384        CGF.EHStack.pushCleanup<CallEndCatchForFinally>(NormalAndEHCleanup,1385                                                        ForEHVar, EndCatchFn);1386 1387      // Save the current cleanup destination in case there are1388      // cleanups in the finally block.1389      llvm::Value *SavedCleanupDest =1390        CGF.Builder.CreateLoad(CGF.getNormalCleanupDestSlot(),1391                               "cleanup.dest.saved");1392 1393      // Emit the finally block.1394      CGF.EmitStmt(Body);1395 1396      // If the end of the finally is reachable, check whether this was1397      // for EH.  If so, rethrow.1398      if (CGF.HaveInsertPoint()) {1399        llvm::BasicBlock *RethrowBB = CGF.createBasicBlock("finally.rethrow");1400        llvm::BasicBlock *ContBB = CGF.createBasicBlock("finally.cont");1401 1402        llvm::Value *ShouldRethrow =1403          CGF.Builder.CreateFlagLoad(ForEHVar, "finally.shouldthrow");1404        CGF.Builder.CreateCondBr(ShouldRethrow, RethrowBB, ContBB);1405 1406        CGF.EmitBlock(RethrowBB);1407        if (SavedExnVar) {1408          CGF.EmitRuntimeCallOrInvoke(RethrowFn,1409            CGF.Builder.CreateAlignedLoad(CGF.Int8PtrTy, SavedExnVar,1410                                          CGF.getPointerAlign()));1411        } else {1412          CGF.EmitRuntimeCallOrInvoke(RethrowFn);1413        }1414        CGF.Builder.CreateUnreachable();1415 1416        CGF.EmitBlock(ContBB);1417 1418        // Restore the cleanup destination.1419        CGF.Builder.CreateStore(SavedCleanupDest,1420                                CGF.getNormalCleanupDestSlot());1421      }1422 1423      // Leave the end-catch cleanup.  As an optimization, pretend that1424      // the fallthrough path was inaccessible; we've dynamically proven1425      // that we're not in the EH case along that path.1426      if (EndCatchFn) {1427        CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();1428        CGF.PopCleanupBlock();1429        CGF.Builder.restoreIP(SavedIP);1430      }1431 1432      // Now make sure we actually have an insertion point or the1433      // cleanup gods will hate us.1434      CGF.EnsureInsertPoint();1435    }1436  };1437} // end anonymous namespace1438 1439/// Enters a finally block for an implementation using zero-cost1440/// exceptions.  This is mostly general, but hard-codes some1441/// language/ABI-specific behavior in the catch-all sections.1442void CodeGenFunction::FinallyInfo::enter(CodeGenFunction &CGF, const Stmt *body,1443                                         llvm::FunctionCallee beginCatchFn,1444                                         llvm::FunctionCallee endCatchFn,1445                                         llvm::FunctionCallee rethrowFn) {1446  assert((!!beginCatchFn) == (!!endCatchFn) &&1447         "begin/end catch functions not paired");1448  assert(rethrowFn && "rethrow function is required");1449 1450  BeginCatchFn = beginCatchFn;1451 1452  // The rethrow function has one of the following two types:1453  //   void (*)()1454  //   void (*)(void*)1455  // In the latter case we need to pass it the exception object.1456  // But we can't use the exception slot because the @finally might1457  // have a landing pad (which would overwrite the exception slot).1458  llvm::FunctionType *rethrowFnTy = rethrowFn.getFunctionType();1459  SavedExnVar = nullptr;1460  if (rethrowFnTy->getNumParams())1461    SavedExnVar = CGF.CreateTempAlloca(CGF.Int8PtrTy, "finally.exn");1462 1463  // A finally block is a statement which must be executed on any edge1464  // out of a given scope.  Unlike a cleanup, the finally block may1465  // contain arbitrary control flow leading out of itself.  In1466  // addition, finally blocks should always be executed, even if there1467  // are no catch handlers higher on the stack.  Therefore, we1468  // surround the protected scope with a combination of a normal1469  // cleanup (to catch attempts to break out of the block via normal1470  // control flow) and an EH catch-all (semantically "outside" any try1471  // statement to which the finally block might have been attached).1472  // The finally block itself is generated in the context of a cleanup1473  // which conditionally leaves the catch-all.1474 1475  // Jump destination for performing the finally block on an exception1476  // edge.  We'll never actually reach this block, so unreachable is1477  // fine.1478  RethrowDest = CGF.getJumpDestInCurrentScope(CGF.getUnreachableBlock());1479 1480  // Whether the finally block is being executed for EH purposes.1481  ForEHVar = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(), "finally.for-eh");1482  CGF.Builder.CreateFlagStore(false, ForEHVar);1483 1484  // Enter a normal cleanup which will perform the @finally block.1485  CGF.EHStack.pushCleanup<PerformFinally>(NormalCleanup, body,1486                                          ForEHVar, endCatchFn,1487                                          rethrowFn, SavedExnVar);1488 1489  // Enter a catch-all scope.1490  llvm::BasicBlock *catchBB = CGF.createBasicBlock("finally.catchall");1491  EHCatchScope *catchScope = CGF.EHStack.pushCatch(1);1492  catchScope->setCatchAllHandler(0, catchBB);1493}1494 1495void CodeGenFunction::FinallyInfo::exit(CodeGenFunction &CGF) {1496  // Leave the finally catch-all.1497  EHCatchScope &catchScope = cast<EHCatchScope>(*CGF.EHStack.begin());1498  llvm::BasicBlock *catchBB = catchScope.getHandler(0).Block;1499 1500  CGF.popCatchScope();1501 1502  // If there are any references to the catch-all block, emit it.1503  if (catchBB->use_empty()) {1504    delete catchBB;1505  } else {1506    CGBuilderTy::InsertPoint savedIP = CGF.Builder.saveAndClearIP();1507    CGF.EmitBlock(catchBB);1508 1509    llvm::Value *exn = nullptr;1510 1511    // If there's a begin-catch function, call it.1512    if (BeginCatchFn) {1513      exn = CGF.getExceptionFromSlot();1514      CGF.EmitNounwindRuntimeCall(BeginCatchFn, exn);1515    }1516 1517    // If we need to remember the exception pointer to rethrow later, do so.1518    if (SavedExnVar) {1519      if (!exn) exn = CGF.getExceptionFromSlot();1520      CGF.Builder.CreateAlignedStore(exn, SavedExnVar, CGF.getPointerAlign());1521    }1522 1523    // Tell the cleanups in the finally block that we're do this for EH.1524    CGF.Builder.CreateFlagStore(true, ForEHVar);1525 1526    // Thread a jump through the finally cleanup.1527    CGF.EmitBranchThroughCleanup(RethrowDest);1528 1529    CGF.Builder.restoreIP(savedIP);1530  }1531 1532  // Finally, leave the @finally cleanup.1533  CGF.PopCleanupBlock();1534}1535 1536llvm::BasicBlock *CodeGenFunction::getTerminateLandingPad() {1537  if (TerminateLandingPad)1538    return TerminateLandingPad;1539 1540  CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();1541 1542  // This will get inserted at the end of the function.1543  TerminateLandingPad = createBasicBlock("terminate.lpad");1544  Builder.SetInsertPoint(TerminateLandingPad);1545 1546  // Tell the backend that this is a landing pad.1547  const EHPersonality &Personality = EHPersonality::get(*this);1548 1549  if (!CurFn->hasPersonalityFn())1550    CurFn->setPersonalityFn(getOpaquePersonalityFn(CGM, Personality));1551 1552  llvm::LandingPadInst *LPadInst =1553      Builder.CreateLandingPad(llvm::StructType::get(Int8PtrTy, Int32Ty), 0);1554  LPadInst->addClause(getCatchAllValue(*this));1555 1556  llvm::Value *Exn = nullptr;1557  if (getLangOpts().CPlusPlus)1558    Exn = Builder.CreateExtractValue(LPadInst, 0);1559  llvm::CallInst *terminateCall =1560      CGM.getCXXABI().emitTerminateForUnexpectedException(*this, Exn);1561  terminateCall->setDoesNotReturn();1562  Builder.CreateUnreachable();1563 1564  // Restore the saved insertion state.1565  Builder.restoreIP(SavedIP);1566 1567  return TerminateLandingPad;1568}1569 1570llvm::BasicBlock *CodeGenFunction::getTerminateHandler() {1571  if (TerminateHandler)1572    return TerminateHandler;1573 1574  // Set up the terminate handler.  This block is inserted at the very1575  // end of the function by FinishFunction.1576  TerminateHandler = createBasicBlock("terminate.handler");1577  CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();1578  Builder.SetInsertPoint(TerminateHandler);1579 1580  llvm::Value *Exn = nullptr;1581  if (getLangOpts().CPlusPlus)1582    Exn = getExceptionFromSlot();1583  llvm::CallInst *terminateCall =1584      CGM.getCXXABI().emitTerminateForUnexpectedException(*this, Exn);1585  terminateCall->setDoesNotReturn();1586  Builder.CreateUnreachable();1587 1588  // Restore the saved insertion state.1589  Builder.restoreIP(SavedIP);1590 1591  return TerminateHandler;1592}1593 1594llvm::BasicBlock *CodeGenFunction::getTerminateFunclet() {1595  assert(EHPersonality::get(*this).usesFuncletPads() &&1596         "use getTerminateLandingPad for non-funclet EH");1597 1598  llvm::BasicBlock *&TerminateFunclet = TerminateFunclets[CurrentFuncletPad];1599  if (TerminateFunclet)1600    return TerminateFunclet;1601 1602  CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();1603 1604  // Set up the terminate handler.  This block is inserted at the very1605  // end of the function by FinishFunction.1606  TerminateFunclet = createBasicBlock("terminate.handler");1607  Builder.SetInsertPoint(TerminateFunclet);1608 1609  // Create the cleanuppad using the current parent pad as its token. Use 'none'1610  // if this is a top-level terminate scope, which is the common case.1611  SaveAndRestore RestoreCurrentFuncletPad(CurrentFuncletPad);1612  llvm::Value *ParentPad = CurrentFuncletPad;1613  if (!ParentPad)1614    ParentPad = llvm::ConstantTokenNone::get(CGM.getLLVMContext());1615  CurrentFuncletPad = Builder.CreateCleanupPad(ParentPad);1616 1617  // Emit the __std_terminate call.1618  llvm::CallInst *terminateCall =1619      CGM.getCXXABI().emitTerminateForUnexpectedException(*this, nullptr);1620  terminateCall->setDoesNotReturn();1621  Builder.CreateUnreachable();1622 1623  // Restore the saved insertion state.1624  Builder.restoreIP(SavedIP);1625 1626  return TerminateFunclet;1627}1628 1629llvm::BasicBlock *CodeGenFunction::getEHResumeBlock(bool isCleanup) {1630  if (EHResumeBlock) return EHResumeBlock;1631 1632  CGBuilderTy::InsertPoint SavedIP = Builder.saveIP();1633 1634  // We emit a jump to a notional label at the outermost unwind state.1635  EHResumeBlock = createBasicBlock("eh.resume");1636  Builder.SetInsertPoint(EHResumeBlock);1637 1638  const EHPersonality &Personality = EHPersonality::get(*this);1639 1640  // This can always be a call because we necessarily didn't find1641  // anything on the EH stack which needs our help.1642  const char *RethrowName = Personality.CatchallRethrowFn;1643  if (RethrowName != nullptr && !isCleanup) {1644    EmitRuntimeCall(getCatchallRethrowFn(CGM, RethrowName),1645                    getExceptionFromSlot())->setDoesNotReturn();1646    Builder.CreateUnreachable();1647    Builder.restoreIP(SavedIP);1648    return EHResumeBlock;1649  }1650 1651  // Recreate the landingpad's return value for the 'resume' instruction.1652  llvm::Value *Exn = getExceptionFromSlot();1653  llvm::Value *Sel = getSelectorFromSlot();1654 1655  llvm::Type *LPadType = llvm::StructType::get(Exn->getType(), Sel->getType());1656  llvm::Value *LPadVal = llvm::PoisonValue::get(LPadType);1657  LPadVal = Builder.CreateInsertValue(LPadVal, Exn, 0, "lpad.val");1658  LPadVal = Builder.CreateInsertValue(LPadVal, Sel, 1, "lpad.val");1659 1660  Builder.CreateResume(LPadVal);1661  Builder.restoreIP(SavedIP);1662  return EHResumeBlock;1663}1664 1665void CodeGenFunction::EmitSEHTryStmt(const SEHTryStmt &S) {1666  EnterSEHTryStmt(S);1667  {1668    JumpDest TryExit = getJumpDestInCurrentScope("__try.__leave");1669 1670    SEHTryEpilogueStack.push_back(&TryExit);1671 1672    llvm::BasicBlock *TryBB = nullptr;1673    // IsEHa: emit an invoke to _seh_try_begin() runtime for -EHa1674    if (getLangOpts().EHAsynch) {1675      EmitRuntimeCallOrInvoke(getSehTryBeginFn(CGM));1676      if (SEHTryEpilogueStack.size() == 1) // outermost only1677        TryBB = Builder.GetInsertBlock();1678    }1679 1680    EmitStmt(S.getTryBlock());1681 1682    // Volatilize all blocks in Try, till current insert point1683    if (TryBB) {1684      llvm::SmallPtrSet<llvm::BasicBlock *, 10> Visited;1685      VolatilizeTryBlocks(TryBB, Visited);1686    }1687 1688    SEHTryEpilogueStack.pop_back();1689 1690    if (!TryExit.getBlock()->use_empty())1691      EmitBlock(TryExit.getBlock(), /*IsFinished=*/true);1692    else1693      delete TryExit.getBlock();1694  }1695  ExitSEHTryStmt(S);1696}1697 1698//  Recursively walk through blocks in a _try1699//      and make all memory instructions volatile1700void CodeGenFunction::VolatilizeTryBlocks(1701    llvm::BasicBlock *BB, llvm::SmallPtrSet<llvm::BasicBlock *, 10> &V) {1702  if (BB == SEHTryEpilogueStack.back()->getBlock() /* end of Try */ ||1703      !V.insert(BB).second /* already visited */ ||1704      !BB->getParent() /* not emitted */ || BB->empty())1705    return;1706 1707  if (!BB->isEHPad()) {1708    for (llvm::BasicBlock::iterator J = BB->begin(), JE = BB->end(); J != JE;1709         ++J) {1710      if (auto LI = dyn_cast<llvm::LoadInst>(J)) {1711        LI->setVolatile(true);1712      } else if (auto SI = dyn_cast<llvm::StoreInst>(J)) {1713        SI->setVolatile(true);1714      } else if (auto* MCI = dyn_cast<llvm::MemIntrinsic>(J)) {1715        MCI->setVolatile(llvm::ConstantInt::get(Builder.getInt1Ty(), 1));1716      }1717    }1718  }1719  const llvm::Instruction *TI = BB->getTerminator();1720  if (TI) {1721    unsigned N = TI->getNumSuccessors();1722    for (unsigned I = 0; I < N; I++)1723      VolatilizeTryBlocks(TI->getSuccessor(I), V);1724  }1725}1726 1727namespace {1728struct PerformSEHFinally final : EHScopeStack::Cleanup {1729  llvm::Function *OutlinedFinally;1730  PerformSEHFinally(llvm::Function *OutlinedFinally)1731      : OutlinedFinally(OutlinedFinally) {}1732 1733  void Emit(CodeGenFunction &CGF, Flags F) override {1734    ASTContext &Context = CGF.getContext();1735    CodeGenModule &CGM = CGF.CGM;1736 1737    CallArgList Args;1738 1739    // Compute the two argument values.1740    QualType ArgTys[2] = {Context.UnsignedCharTy, Context.VoidPtrTy};1741    llvm::Value *FP = nullptr;1742    // If CFG.IsOutlinedSEHHelper is true, then we are within a finally block.1743    if (CGF.IsOutlinedSEHHelper) {1744      FP = &CGF.CurFn->arg_begin()[1];1745    } else {1746      llvm::Function *LocalAddrFn =1747          CGM.getIntrinsic(llvm::Intrinsic::localaddress);1748      FP = CGF.Builder.CreateCall(LocalAddrFn);1749    }1750 1751    llvm::Value *IsForEH =1752        llvm::ConstantInt::get(CGF.ConvertType(ArgTys[0]), F.isForEHCleanup());1753 1754    // Except _leave and fall-through at the end, all other exits in a _try1755    //   (return/goto/continue/break) are considered as abnormal terminations1756    //   since _leave/fall-through is always Indexed 0,1757    //   just use NormalCleanupDestSlot (>= 1 for goto/return/..),1758    //   as 1st Arg to indicate abnormal termination1759    if (!F.isForEHCleanup() && F.hasExitSwitch()) {1760      Address Addr = CGF.getNormalCleanupDestSlot();1761      llvm::Value *Load = CGF.Builder.CreateLoad(Addr, "cleanup.dest");1762      llvm::Value *Zero = llvm::Constant::getNullValue(CGM.Int32Ty);1763      IsForEH = CGF.Builder.CreateICmpNE(Load, Zero);1764    }1765 1766    Args.add(RValue::get(IsForEH), ArgTys[0]);1767    Args.add(RValue::get(FP), ArgTys[1]);1768 1769    // Arrange a two-arg function info and type.1770    const CGFunctionInfo &FnInfo =1771        CGM.getTypes().arrangeBuiltinFunctionCall(Context.VoidTy, Args);1772 1773    auto Callee = CGCallee::forDirect(OutlinedFinally);1774    CGF.EmitCall(FnInfo, Callee, ReturnValueSlot(), Args);1775  }1776};1777} // end anonymous namespace1778 1779namespace {1780/// Find all local variable captures in the statement.1781struct CaptureFinder : ConstStmtVisitor<CaptureFinder> {1782  CodeGenFunction &ParentCGF;1783  const VarDecl *ParentThis;1784  llvm::SmallSetVector<const VarDecl *, 4> Captures;1785  Address SEHCodeSlot = Address::invalid();1786  CaptureFinder(CodeGenFunction &ParentCGF, const VarDecl *ParentThis)1787      : ParentCGF(ParentCGF), ParentThis(ParentThis) {}1788 1789  // Return true if we need to do any capturing work.1790  bool foundCaptures() {1791    return !Captures.empty() || SEHCodeSlot.isValid();1792  }1793 1794  void Visit(const Stmt *S) {1795    // See if this is a capture, then recurse.1796    ConstStmtVisitor<CaptureFinder>::Visit(S);1797    for (const Stmt *Child : S->children())1798      if (Child)1799        Visit(Child);1800  }1801 1802  void VisitDeclRefExpr(const DeclRefExpr *E) {1803    // If this is already a capture, just make sure we capture 'this'.1804    if (E->refersToEnclosingVariableOrCapture())1805      Captures.insert(ParentThis);1806 1807    const auto *D = dyn_cast<VarDecl>(E->getDecl());1808    if (D && D->isLocalVarDeclOrParm() && D->hasLocalStorage())1809      Captures.insert(D);1810  }1811 1812  void VisitCXXThisExpr(const CXXThisExpr *E) {1813    Captures.insert(ParentThis);1814  }1815 1816  void VisitCallExpr(const CallExpr *E) {1817    // We only need to add parent frame allocations for these builtins in x86.1818    if (ParentCGF.getTarget().getTriple().getArch() != llvm::Triple::x86)1819      return;1820 1821    unsigned ID = E->getBuiltinCallee();1822    switch (ID) {1823    case Builtin::BI__exception_code:1824    case Builtin::BI_exception_code:1825      // This is the simple case where we are the outermost finally. All we1826      // have to do here is make sure we escape this and recover it in the1827      // outlined handler.1828      if (!SEHCodeSlot.isValid())1829        SEHCodeSlot = ParentCGF.SEHCodeSlotStack.back();1830      break;1831    }1832  }1833};1834} // end anonymous namespace1835 1836Address CodeGenFunction::recoverAddrOfEscapedLocal(CodeGenFunction &ParentCGF,1837                                                   Address ParentVar,1838                                                   llvm::Value *ParentFP) {1839  llvm::CallInst *RecoverCall = nullptr;1840  CGBuilderTy Builder(*this, AllocaInsertPt);1841  if (auto *ParentAlloca =1842          dyn_cast_or_null<llvm::AllocaInst>(ParentVar.getBasePointer())) {1843    // Mark the variable escaped if nobody else referenced it and compute the1844    // localescape index.1845    auto InsertPair = ParentCGF.EscapedLocals.insert(1846        std::make_pair(ParentAlloca, ParentCGF.EscapedLocals.size()));1847    int FrameEscapeIdx = InsertPair.first->second;1848    // call ptr @llvm.localrecover(ptr @parentFn, ptr %fp, i32 N)1849    llvm::Function *FrameRecoverFn = llvm::Intrinsic::getOrInsertDeclaration(1850        &CGM.getModule(), llvm::Intrinsic::localrecover);1851    RecoverCall = Builder.CreateCall(1852        FrameRecoverFn, {ParentCGF.CurFn, ParentFP,1853                         llvm::ConstantInt::get(Int32Ty, FrameEscapeIdx)});1854 1855  } else {1856    // If the parent didn't have an alloca, we're doing some nested outlining.1857    // Just clone the existing localrecover call, but tweak the FP argument to1858    // use our FP value. All other arguments are constants.1859    auto *ParentRecover = cast<llvm::IntrinsicInst>(1860        ParentVar.emitRawPointer(*this)->stripPointerCasts());1861    assert(ParentRecover->getIntrinsicID() == llvm::Intrinsic::localrecover &&1862           "expected alloca or localrecover in parent LocalDeclMap");1863    RecoverCall = cast<llvm::CallInst>(ParentRecover->clone());1864    RecoverCall->setArgOperand(1, ParentFP);1865    RecoverCall->insertBefore(AllocaInsertPt->getIterator());1866  }1867 1868  // Bitcast the variable, rename it, and insert it in the local decl map.1869  llvm::Value *ChildVar =1870      Builder.CreateBitCast(RecoverCall, ParentVar.getType());1871  ChildVar->setName(ParentVar.getName());1872  return ParentVar.withPointer(ChildVar, KnownNonNull);1873}1874 1875void CodeGenFunction::EmitCapturedLocals(CodeGenFunction &ParentCGF,1876                                         const Stmt *OutlinedStmt,1877                                         bool IsFilter) {1878  // Find all captures in the Stmt.1879  CaptureFinder Finder(ParentCGF, ParentCGF.CXXABIThisDecl);1880  Finder.Visit(OutlinedStmt);1881 1882  // We can exit early on x86_64 when there are no captures. We just have to1883  // save the exception code in filters so that __exception_code() works.1884  if (!Finder.foundCaptures() &&1885      CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {1886    if (IsFilter)1887      EmitSEHExceptionCodeSave(ParentCGF, nullptr, nullptr);1888    return;1889  }1890 1891  llvm::Value *EntryFP = nullptr;1892  CGBuilderTy Builder(CGM, AllocaInsertPt);1893  if (IsFilter && CGM.getTarget().getTriple().getArch() == llvm::Triple::x86) {1894    // 32-bit SEH filters need to be careful about FP recovery.  The end of the1895    // EH registration is passed in as the EBP physical register.  We can1896    // recover that with llvm.frameaddress(1).1897    EntryFP = Builder.CreateCall(1898        CGM.getIntrinsic(llvm::Intrinsic::frameaddress, AllocaInt8PtrTy),1899        {Builder.getInt32(1)});1900  } else {1901    // Otherwise, for x64 and 32-bit finally functions, the parent FP is the1902    // second parameter.1903    auto AI = CurFn->arg_begin();1904    ++AI;1905    EntryFP = &*AI;1906  }1907 1908  llvm::Value *ParentFP = EntryFP;1909  if (IsFilter) {1910    // Given whatever FP the runtime provided us in EntryFP, recover the true1911    // frame pointer of the parent function. We only need to do this in filters,1912    // since finally funclets recover the parent FP for us.1913    llvm::Function *RecoverFPIntrin =1914        CGM.getIntrinsic(llvm::Intrinsic::eh_recoverfp);1915    ParentFP = Builder.CreateCall(RecoverFPIntrin, {ParentCGF.CurFn, EntryFP});1916 1917    // if the parent is a _finally, the passed-in ParentFP is the FP1918    // of parent _finally, not Establisher's FP (FP of outermost function).1919    // Establkisher FP is 2nd paramenter passed into parent _finally.1920    // Fortunately, it's always saved in parent's frame. The following1921    // code retrieves it, and escapes it so that spill instruction won't be1922    // optimized away.1923    if (ParentCGF.ParentCGF != nullptr) {1924      // Locate and escape Parent's frame_pointer.addr alloca1925      // Depending on target, should be 1st/2nd one in LocalDeclMap.1926      // Let's just scan for ImplicitParamDecl with VoidPtrTy.1927      llvm::AllocaInst *FramePtrAddrAlloca = nullptr;1928      for (auto &I : ParentCGF.LocalDeclMap) {1929        const VarDecl *D = cast<VarDecl>(I.first);1930        if (isa<ImplicitParamDecl>(D) &&1931            D->getType() == getContext().VoidPtrTy) {1932          assert(D->getName().starts_with("frame_pointer"));1933          FramePtrAddrAlloca =1934              cast<llvm::AllocaInst>(I.second.getBasePointer());1935          break;1936        }1937      }1938      assert(FramePtrAddrAlloca);1939      auto InsertPair = ParentCGF.EscapedLocals.insert(1940          std::make_pair(FramePtrAddrAlloca, ParentCGF.EscapedLocals.size()));1941      int FrameEscapeIdx = InsertPair.first->second;1942 1943      // an example of a filter's prolog::1944      // %0 = call ptr @llvm.eh.recoverfp(@"?fin$0@0@main@@",..)1945      // %1 = call ptr @llvm.localrecover(@"?fin$0@0@main@@",..)1946      // %2 = load ptr, ptr %1, align 81947      //   ==> %2 is the frame-pointer of outermost host function1948      llvm::Function *FrameRecoverFn = llvm::Intrinsic::getOrInsertDeclaration(1949          &CGM.getModule(), llvm::Intrinsic::localrecover);1950      ParentFP = Builder.CreateCall(1951          FrameRecoverFn, {ParentCGF.CurFn, ParentFP,1952                           llvm::ConstantInt::get(Int32Ty, FrameEscapeIdx)});1953      ParentFP = Builder.CreateLoad(1954          Address(ParentFP, CGM.VoidPtrTy, getPointerAlign()));1955    }1956  }1957 1958  // Create llvm.localrecover calls for all captures.1959  for (const VarDecl *VD : Finder.Captures) {1960    if (VD->getType()->isVariablyModifiedType()) {1961      CGM.ErrorUnsupported(VD, "VLA captured by SEH");1962      continue;1963    }1964    assert((isa<ImplicitParamDecl>(VD) || VD->isLocalVarDeclOrParm()) &&1965           "captured non-local variable");1966 1967    auto L = ParentCGF.LambdaCaptureFields.find(VD);1968    if (L != ParentCGF.LambdaCaptureFields.end()) {1969      LambdaCaptureFields[VD] = L->second;1970      continue;1971    }1972 1973    // If this decl hasn't been declared yet, it will be declared in the1974    // OutlinedStmt.1975    auto I = ParentCGF.LocalDeclMap.find(VD);1976    if (I == ParentCGF.LocalDeclMap.end())1977      continue;1978 1979    Address ParentVar = I->second;1980    Address Recovered =1981        recoverAddrOfEscapedLocal(ParentCGF, ParentVar, ParentFP);1982    setAddrOfLocalVar(VD, Recovered);1983 1984    if (isa<ImplicitParamDecl>(VD)) {1985      CXXABIThisAlignment = ParentCGF.CXXABIThisAlignment;1986      CXXThisAlignment = ParentCGF.CXXThisAlignment;1987      CXXABIThisValue = Builder.CreateLoad(Recovered, "this");1988      if (ParentCGF.LambdaThisCaptureField) {1989        LambdaThisCaptureField = ParentCGF.LambdaThisCaptureField;1990        // We are in a lambda function where "this" is captured so the1991        // CXXThisValue need to be loaded from the lambda capture1992        LValue ThisFieldLValue =1993            EmitLValueForLambdaField(LambdaThisCaptureField);1994        if (!LambdaThisCaptureField->getType()->isPointerType()) {1995          CXXThisValue = ThisFieldLValue.getAddress().emitRawPointer(*this);1996        } else {1997          CXXThisValue = EmitLoadOfLValue(ThisFieldLValue, SourceLocation())1998                             .getScalarVal();1999        }2000      } else {2001        CXXThisValue = CXXABIThisValue;2002      }2003    }2004  }2005 2006  if (Finder.SEHCodeSlot.isValid()) {2007    SEHCodeSlotStack.push_back(2008        recoverAddrOfEscapedLocal(ParentCGF, Finder.SEHCodeSlot, ParentFP));2009  }2010 2011  if (IsFilter)2012    EmitSEHExceptionCodeSave(ParentCGF, ParentFP, EntryFP);2013}2014 2015/// Arrange a function prototype that can be called by Windows exception2016/// handling personalities. On Win64, the prototype looks like:2017/// RetTy func(void *EHPtrs, void *ParentFP);2018void CodeGenFunction::startOutlinedSEHHelper(CodeGenFunction &ParentCGF,2019                                             bool IsFilter,2020                                             const Stmt *OutlinedStmt) {2021  SourceLocation StartLoc = OutlinedStmt->getBeginLoc();2022 2023  // Get the mangled function name.2024  SmallString<128> Name;2025  {2026    llvm::raw_svector_ostream OS(Name);2027    GlobalDecl ParentSEHFn = ParentCGF.CurSEHParent;2028    assert(ParentSEHFn && "No CurSEHParent!");2029    MangleContext &Mangler = CGM.getCXXABI().getMangleContext();2030    if (IsFilter)2031      Mangler.mangleSEHFilterExpression(ParentSEHFn, OS);2032    else2033      Mangler.mangleSEHFinallyBlock(ParentSEHFn, OS);2034  }2035 2036  FunctionArgList Args;2037  if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 || !IsFilter) {2038    // All SEH finally functions take two parameters. Win64 filters take two2039    // parameters. Win32 filters take no parameters.2040    if (IsFilter) {2041      Args.push_back(ImplicitParamDecl::Create(2042          getContext(), /*DC=*/nullptr, StartLoc,2043          &getContext().Idents.get("exception_pointers"),2044          getContext().VoidPtrTy, ImplicitParamKind::Other));2045    } else {2046      Args.push_back(ImplicitParamDecl::Create(2047          getContext(), /*DC=*/nullptr, StartLoc,2048          &getContext().Idents.get("abnormal_termination"),2049          getContext().UnsignedCharTy, ImplicitParamKind::Other));2050    }2051    Args.push_back(ImplicitParamDecl::Create(2052        getContext(), /*DC=*/nullptr, StartLoc,2053        &getContext().Idents.get("frame_pointer"), getContext().VoidPtrTy,2054        ImplicitParamKind::Other));2055  }2056 2057  QualType RetTy = IsFilter ? getContext().LongTy : getContext().VoidTy;2058 2059  const CGFunctionInfo &FnInfo =2060    CGM.getTypes().arrangeBuiltinFunctionDeclaration(RetTy, Args);2061 2062  llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FnInfo);2063  llvm::Function *Fn = llvm::Function::Create(2064      FnTy, llvm::GlobalValue::InternalLinkage, Name.str(), &CGM.getModule());2065 2066  IsOutlinedSEHHelper = true;2067 2068  StartFunction(GlobalDecl(), RetTy, Fn, FnInfo, Args,2069                OutlinedStmt->getBeginLoc(), OutlinedStmt->getBeginLoc());2070  CurSEHParent = ParentCGF.CurSEHParent;2071 2072  CGM.SetInternalFunctionAttributes(GlobalDecl(), CurFn, FnInfo);2073  EmitCapturedLocals(ParentCGF, OutlinedStmt, IsFilter);2074}2075 2076/// Create a stub filter function that will ultimately hold the code of the2077/// filter expression. The EH preparation passes in LLVM will outline the code2078/// from the main function body into this stub.2079llvm::Function *2080CodeGenFunction::GenerateSEHFilterFunction(CodeGenFunction &ParentCGF,2081                                           const SEHExceptStmt &Except) {2082  const Expr *FilterExpr = Except.getFilterExpr();2083  startOutlinedSEHHelper(ParentCGF, true, FilterExpr);2084 2085  // Emit the original filter expression, convert to i32, and return.2086  llvm::Value *R = EmitScalarExpr(FilterExpr);2087  R = Builder.CreateIntCast(R, ConvertType(getContext().LongTy),2088                            FilterExpr->getType()->isSignedIntegerType());2089  Builder.CreateStore(R, ReturnValue);2090 2091  FinishFunction(FilterExpr->getEndLoc());2092 2093  return CurFn;2094}2095 2096llvm::Function *2097CodeGenFunction::GenerateSEHFinallyFunction(CodeGenFunction &ParentCGF,2098                                            const SEHFinallyStmt &Finally) {2099  const Stmt *FinallyBlock = Finally.getBlock();2100  startOutlinedSEHHelper(ParentCGF, false, FinallyBlock);2101 2102  // Emit the original filter expression, convert to i32, and return.2103  EmitStmt(FinallyBlock);2104 2105  FinishFunction(FinallyBlock->getEndLoc());2106 2107  return CurFn;2108}2109 2110void CodeGenFunction::EmitSEHExceptionCodeSave(CodeGenFunction &ParentCGF,2111                                               llvm::Value *ParentFP,2112                                               llvm::Value *EntryFP) {2113  // Get the pointer to the EXCEPTION_POINTERS struct. This is returned by the2114  // __exception_info intrinsic.2115  if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {2116    // On Win64, the info is passed as the first parameter to the filter.2117    SEHInfo = &*CurFn->arg_begin();2118    SEHCodeSlotStack.push_back(2119        CreateMemTemp(getContext().IntTy, "__exception_code"));2120  } else {2121    // On Win32, the EBP on entry to the filter points to the end of an2122    // exception registration object. It contains 6 32-bit fields, and the info2123    // pointer is stored in the second field. So, GEP 20 bytes backwards and2124    // load the pointer.2125    SEHInfo = Builder.CreateConstInBoundsGEP1_32(Int8Ty, EntryFP, -20);2126    SEHInfo = Builder.CreateAlignedLoad(Int8PtrTy, SEHInfo, getPointerAlign());2127    SEHCodeSlotStack.push_back(recoverAddrOfEscapedLocal(2128        ParentCGF, ParentCGF.SEHCodeSlotStack.back(), ParentFP));2129  }2130 2131  // Save the exception code in the exception slot to unify exception access in2132  // the filter function and the landing pad.2133  // struct EXCEPTION_POINTERS {2134  //   EXCEPTION_RECORD *ExceptionRecord;2135  //   CONTEXT *ContextRecord;2136  // };2137  // int exceptioncode = exception_pointers->ExceptionRecord->ExceptionCode;2138  llvm::Type *RecordTy = llvm::PointerType::getUnqual(getLLVMContext());2139  llvm::Type *PtrsTy = llvm::StructType::get(RecordTy, CGM.VoidPtrTy);2140  llvm::Value *Rec = Builder.CreateStructGEP(PtrsTy, SEHInfo, 0);2141  Rec = Builder.CreateAlignedLoad(RecordTy, Rec, getPointerAlign());2142  llvm::Value *Code = Builder.CreateAlignedLoad(Int32Ty, Rec, getIntAlign());2143  assert(!SEHCodeSlotStack.empty() && "emitting EH code outside of __except");2144  Builder.CreateStore(Code, SEHCodeSlotStack.back());2145}2146 2147llvm::Value *CodeGenFunction::EmitSEHExceptionInfo() {2148  // Sema should diagnose calling this builtin outside of a filter context, but2149  // don't crash if we screw up.2150  if (!SEHInfo)2151    return llvm::PoisonValue::get(Int8PtrTy);2152  assert(SEHInfo->getType() == Int8PtrTy);2153  return SEHInfo;2154}2155 2156llvm::Value *CodeGenFunction::EmitSEHExceptionCode() {2157  assert(!SEHCodeSlotStack.empty() && "emitting EH code outside of __except");2158  return Builder.CreateLoad(SEHCodeSlotStack.back());2159}2160 2161llvm::Value *CodeGenFunction::EmitSEHAbnormalTermination() {2162  // Abnormal termination is just the first parameter to the outlined finally2163  // helper.2164  auto AI = CurFn->arg_begin();2165  return Builder.CreateZExt(&*AI, Int32Ty);2166}2167 2168void CodeGenFunction::pushSEHCleanup(CleanupKind Kind,2169                                     llvm::Function *FinallyFunc) {2170  EHStack.pushCleanup<PerformSEHFinally>(Kind, FinallyFunc);2171}2172 2173void CodeGenFunction::EnterSEHTryStmt(const SEHTryStmt &S) {2174  CodeGenFunction HelperCGF(CGM, /*suppressNewContext=*/true);2175  HelperCGF.ParentCGF = this;2176  if (const SEHFinallyStmt *Finally = S.getFinallyHandler()) {2177    // Outline the finally block.2178    llvm::Function *FinallyFunc =2179        HelperCGF.GenerateSEHFinallyFunction(*this, *Finally);2180 2181    // Push a cleanup for __finally blocks.2182    EHStack.pushCleanup<PerformSEHFinally>(NormalAndEHCleanup, FinallyFunc);2183    return;2184  }2185 2186  // Otherwise, we must have an __except block.2187  const SEHExceptStmt *Except = S.getExceptHandler();2188  assert(Except);2189  EHCatchScope *CatchScope = EHStack.pushCatch(1);2190  SEHCodeSlotStack.push_back(2191      CreateMemTemp(getContext().IntTy, "__exception_code"));2192 2193  // If the filter is known to evaluate to 1, then we can use the clause2194  // "catch i8* null". We can't do this on x86 because the filter has to save2195  // the exception code.2196  llvm::Constant *C =2197    ConstantEmitter(*this).tryEmitAbstract(Except->getFilterExpr(),2198                                           getContext().IntTy);2199  if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 && C &&2200      C->isOneValue()) {2201    CatchScope->setCatchAllHandler(0, createBasicBlock("__except"));2202    return;2203  }2204 2205  // In general, we have to emit an outlined filter function. Use the function2206  // in place of the RTTI typeinfo global that C++ EH uses.2207  llvm::Function *FilterFunc =2208      HelperCGF.GenerateSEHFilterFunction(*this, *Except);2209  CatchScope->setHandler(0, FilterFunc, createBasicBlock("__except.ret"));2210}2211 2212void CodeGenFunction::ExitSEHTryStmt(const SEHTryStmt &S) {2213  // Just pop the cleanup if it's a __finally block.2214  if (S.getFinallyHandler()) {2215    PopCleanupBlock();2216    return;2217  }2218 2219  // IsEHa: emit an invoke _seh_try_end() to mark end of FT flow2220  if (getLangOpts().EHAsynch && Builder.GetInsertBlock()) {2221    llvm::FunctionCallee SehTryEnd = getSehTryEndFn(CGM);2222    EmitRuntimeCallOrInvoke(SehTryEnd);2223  }2224 2225  // Otherwise, we must have an __except block.2226  const SEHExceptStmt *Except = S.getExceptHandler();2227  assert(Except && "__try must have __finally xor __except");2228  EHCatchScope &CatchScope = cast<EHCatchScope>(*EHStack.begin());2229 2230  // Don't emit the __except block if the __try block lacked invokes.2231  // TODO: Model unwind edges from instructions, either with iload / istore or2232  // a try body function.2233  if (!CatchScope.hasEHBranches()) {2234    CatchScope.clearHandlerBlocks();2235    EHStack.popCatch();2236    SEHCodeSlotStack.pop_back();2237    return;2238  }2239 2240  // The fall-through block.2241  llvm::BasicBlock *ContBB = createBasicBlock("__try.cont");2242 2243  // We just emitted the body of the __try; jump to the continue block.2244  if (HaveInsertPoint())2245    Builder.CreateBr(ContBB);2246 2247  // Check if our filter function returned true.2248  emitCatchDispatchBlock(*this, CatchScope);2249 2250  // Grab the block before we pop the handler.2251  llvm::BasicBlock *CatchPadBB = CatchScope.getHandler(0).Block;2252  EHStack.popCatch();2253 2254  EmitBlockAfterUses(CatchPadBB);2255 2256  // __except blocks don't get outlined into funclets, so immediately do a2257  // catchret.2258  llvm::CatchPadInst *CPI =2259      cast<llvm::CatchPadInst>(CatchPadBB->getFirstNonPHIIt());2260  llvm::BasicBlock *ExceptBB = createBasicBlock("__except");2261  Builder.CreateCatchRet(CPI, ExceptBB);2262  EmitBlock(ExceptBB);2263 2264  // On Win64, the exception code is returned in EAX. Copy it into the slot.2265  if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {2266    llvm::Function *SEHCodeIntrin =2267        CGM.getIntrinsic(llvm::Intrinsic::eh_exceptioncode);2268    llvm::Value *Code = Builder.CreateCall(SEHCodeIntrin, {CPI});2269    Builder.CreateStore(Code, SEHCodeSlotStack.back());2270  }2271 2272  // Emit the __except body.2273  EmitStmt(Except->getBlock());2274 2275  // End the lifetime of the exception code.2276  SEHCodeSlotStack.pop_back();2277 2278  if (HaveInsertPoint())2279    Builder.CreateBr(ContBB);2280 2281  EmitBlock(ContBB);2282}2283 2284void CodeGenFunction::EmitSEHLeaveStmt(const SEHLeaveStmt &S) {2285  // If this code is reachable then emit a stop point (if generating2286  // debug info). We have to do this ourselves because we are on the2287  // "simple" statement path.2288  if (HaveInsertPoint())2289    EmitStopPoint(&S);2290 2291  // This must be a __leave from a __finally block, which we warn on and is UB.2292  // Just emit unreachable.2293  if (!isSEHTryScope()) {2294    Builder.CreateUnreachable();2295    Builder.ClearInsertionPoint();2296    return;2297  }2298 2299  EmitBranchThroughCleanup(*SEHTryEpilogueStack.back());2300}2301