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