xref: /aosp_15_r20/external/clang/lib/CodeGen/CGException.cpp (revision 67e74705e28f6214e480b399dd47ea732279e315)
1*67e74705SXin Li //===--- CGException.cpp - Emit LLVM Code for C++ exceptions ----*- C++ -*-===//
2*67e74705SXin Li //
3*67e74705SXin Li //                     The LLVM Compiler Infrastructure
4*67e74705SXin Li //
5*67e74705SXin Li // This file is distributed under the University of Illinois Open Source
6*67e74705SXin Li // License. See LICENSE.TXT for details.
7*67e74705SXin Li //
8*67e74705SXin Li //===----------------------------------------------------------------------===//
9*67e74705SXin Li //
10*67e74705SXin Li // This contains code dealing with C++ exception related code generation.
11*67e74705SXin Li //
12*67e74705SXin Li //===----------------------------------------------------------------------===//
13*67e74705SXin Li 
14*67e74705SXin Li #include "CodeGenFunction.h"
15*67e74705SXin Li #include "CGCXXABI.h"
16*67e74705SXin Li #include "CGCleanup.h"
17*67e74705SXin Li #include "CGObjCRuntime.h"
18*67e74705SXin Li #include "TargetInfo.h"
19*67e74705SXin Li #include "clang/AST/Mangle.h"
20*67e74705SXin Li #include "clang/AST/StmtCXX.h"
21*67e74705SXin Li #include "clang/AST/StmtObjC.h"
22*67e74705SXin Li #include "clang/AST/StmtVisitor.h"
23*67e74705SXin Li #include "clang/Basic/TargetBuiltins.h"
24*67e74705SXin Li #include "llvm/IR/CallSite.h"
25*67e74705SXin Li #include "llvm/IR/Intrinsics.h"
26*67e74705SXin Li #include "llvm/IR/IntrinsicInst.h"
27*67e74705SXin Li #include "llvm/Support/SaveAndRestore.h"
28*67e74705SXin Li 
29*67e74705SXin Li using namespace clang;
30*67e74705SXin Li using namespace CodeGen;
31*67e74705SXin Li 
getFreeExceptionFn(CodeGenModule & CGM)32*67e74705SXin Li static llvm::Constant *getFreeExceptionFn(CodeGenModule &CGM) {
33*67e74705SXin Li   // void __cxa_free_exception(void *thrown_exception);
34*67e74705SXin Li 
35*67e74705SXin Li   llvm::FunctionType *FTy =
36*67e74705SXin Li     llvm::FunctionType::get(CGM.VoidTy, CGM.Int8PtrTy, /*IsVarArgs=*/false);
37*67e74705SXin Li 
38*67e74705SXin Li   return CGM.CreateRuntimeFunction(FTy, "__cxa_free_exception");
39*67e74705SXin Li }
40*67e74705SXin Li 
getUnexpectedFn(CodeGenModule & CGM)41*67e74705SXin Li static llvm::Constant *getUnexpectedFn(CodeGenModule &CGM) {
42*67e74705SXin Li   // void __cxa_call_unexpected(void *thrown_exception);
43*67e74705SXin Li 
44*67e74705SXin Li   llvm::FunctionType *FTy =
45*67e74705SXin Li     llvm::FunctionType::get(CGM.VoidTy, CGM.Int8PtrTy, /*IsVarArgs=*/false);
46*67e74705SXin Li 
47*67e74705SXin Li   return CGM.CreateRuntimeFunction(FTy, "__cxa_call_unexpected");
48*67e74705SXin Li }
49*67e74705SXin Li 
getTerminateFn()50*67e74705SXin Li llvm::Constant *CodeGenModule::getTerminateFn() {
51*67e74705SXin Li   // void __terminate();
52*67e74705SXin Li 
53*67e74705SXin Li   llvm::FunctionType *FTy =
54*67e74705SXin Li     llvm::FunctionType::get(VoidTy, /*IsVarArgs=*/false);
55*67e74705SXin Li 
56*67e74705SXin Li   StringRef name;
57*67e74705SXin Li 
58*67e74705SXin Li   // In C++, use std::terminate().
59*67e74705SXin Li   if (getLangOpts().CPlusPlus &&
60*67e74705SXin Li       getTarget().getCXXABI().isItaniumFamily()) {
61*67e74705SXin Li     name = "_ZSt9terminatev";
62*67e74705SXin Li   } else if (getLangOpts().CPlusPlus &&
63*67e74705SXin Li              getTarget().getCXXABI().isMicrosoft()) {
64*67e74705SXin Li     if (getLangOpts().isCompatibleWithMSVC(LangOptions::MSVC2015))
65*67e74705SXin Li       name = "__std_terminate";
66*67e74705SXin Li     else
67*67e74705SXin Li       name = "\01?terminate@@YAXXZ";
68*67e74705SXin Li   } else if (getLangOpts().ObjC1 &&
69*67e74705SXin Li              getLangOpts().ObjCRuntime.hasTerminate())
70*67e74705SXin Li     name = "objc_terminate";
71*67e74705SXin Li   else
72*67e74705SXin Li     name = "abort";
73*67e74705SXin Li   return CreateRuntimeFunction(FTy, name);
74*67e74705SXin Li }
75*67e74705SXin Li 
getCatchallRethrowFn(CodeGenModule & CGM,StringRef Name)76*67e74705SXin Li static llvm::Constant *getCatchallRethrowFn(CodeGenModule &CGM,
77*67e74705SXin Li                                             StringRef Name) {
78*67e74705SXin Li   llvm::FunctionType *FTy =
79*67e74705SXin Li     llvm::FunctionType::get(CGM.VoidTy, CGM.Int8PtrTy, /*IsVarArgs=*/false);
80*67e74705SXin Li 
81*67e74705SXin Li   return CGM.CreateRuntimeFunction(FTy, Name);
82*67e74705SXin Li }
83*67e74705SXin Li 
84*67e74705SXin Li const EHPersonality EHPersonality::GNU_C = { "__gcc_personality_v0", nullptr };
85*67e74705SXin Li const EHPersonality
86*67e74705SXin Li EHPersonality::GNU_C_SJLJ = { "__gcc_personality_sj0", nullptr };
87*67e74705SXin Li const EHPersonality
88*67e74705SXin Li EHPersonality::GNU_C_SEH = { "__gcc_personality_seh0", nullptr };
89*67e74705SXin Li const EHPersonality
90*67e74705SXin Li EHPersonality::NeXT_ObjC = { "__objc_personality_v0", nullptr };
91*67e74705SXin Li const EHPersonality
92*67e74705SXin Li EHPersonality::GNU_CPlusPlus = { "__gxx_personality_v0", nullptr };
93*67e74705SXin Li const EHPersonality
94*67e74705SXin Li EHPersonality::GNU_CPlusPlus_SJLJ = { "__gxx_personality_sj0", nullptr };
95*67e74705SXin Li const EHPersonality
96*67e74705SXin Li EHPersonality::GNU_CPlusPlus_SEH = { "__gxx_personality_seh0", nullptr };
97*67e74705SXin Li const EHPersonality
98*67e74705SXin Li EHPersonality::GNU_ObjC = {"__gnu_objc_personality_v0", "objc_exception_throw"};
99*67e74705SXin Li const EHPersonality
100*67e74705SXin Li EHPersonality::GNU_ObjCXX = { "__gnustep_objcxx_personality_v0", nullptr };
101*67e74705SXin Li const EHPersonality
102*67e74705SXin Li EHPersonality::GNUstep_ObjC = { "__gnustep_objc_personality_v0", nullptr };
103*67e74705SXin Li const EHPersonality
104*67e74705SXin Li EHPersonality::MSVC_except_handler = { "_except_handler3", nullptr };
105*67e74705SXin Li const EHPersonality
106*67e74705SXin Li EHPersonality::MSVC_C_specific_handler = { "__C_specific_handler", nullptr };
107*67e74705SXin Li const EHPersonality
108*67e74705SXin Li EHPersonality::MSVC_CxxFrameHandler3 = { "__CxxFrameHandler3", nullptr };
109*67e74705SXin Li 
110*67e74705SXin Li /// On Win64, use libgcc's SEH personality function. We fall back to dwarf on
111*67e74705SXin Li /// other platforms, unless the user asked for SjLj exceptions.
useLibGCCSEHPersonality(const llvm::Triple & T)112*67e74705SXin Li static bool useLibGCCSEHPersonality(const llvm::Triple &T) {
113*67e74705SXin Li   return T.isOSWindows() && T.getArch() == llvm::Triple::x86_64;
114*67e74705SXin Li }
115*67e74705SXin Li 
getCPersonality(const llvm::Triple & T,const LangOptions & L)116*67e74705SXin Li static const EHPersonality &getCPersonality(const llvm::Triple &T,
117*67e74705SXin Li                                             const LangOptions &L) {
118*67e74705SXin Li   if (L.SjLjExceptions)
119*67e74705SXin Li     return EHPersonality::GNU_C_SJLJ;
120*67e74705SXin Li   else if (useLibGCCSEHPersonality(T))
121*67e74705SXin Li     return EHPersonality::GNU_C_SEH;
122*67e74705SXin Li   return EHPersonality::GNU_C;
123*67e74705SXin Li }
124*67e74705SXin Li 
getObjCPersonality(const llvm::Triple & T,const LangOptions & L)125*67e74705SXin Li static const EHPersonality &getObjCPersonality(const llvm::Triple &T,
126*67e74705SXin Li                                                const LangOptions &L) {
127*67e74705SXin Li   switch (L.ObjCRuntime.getKind()) {
128*67e74705SXin Li   case ObjCRuntime::FragileMacOSX:
129*67e74705SXin Li     return getCPersonality(T, L);
130*67e74705SXin Li   case ObjCRuntime::MacOSX:
131*67e74705SXin Li   case ObjCRuntime::iOS:
132*67e74705SXin Li   case ObjCRuntime::WatchOS:
133*67e74705SXin Li     return EHPersonality::NeXT_ObjC;
134*67e74705SXin Li   case ObjCRuntime::GNUstep:
135*67e74705SXin Li     if (L.ObjCRuntime.getVersion() >= VersionTuple(1, 7))
136*67e74705SXin Li       return EHPersonality::GNUstep_ObjC;
137*67e74705SXin Li     // fallthrough
138*67e74705SXin Li   case ObjCRuntime::GCC:
139*67e74705SXin Li   case ObjCRuntime::ObjFW:
140*67e74705SXin Li     return EHPersonality::GNU_ObjC;
141*67e74705SXin Li   }
142*67e74705SXin Li   llvm_unreachable("bad runtime kind");
143*67e74705SXin Li }
144*67e74705SXin Li 
getCXXPersonality(const llvm::Triple & T,const LangOptions & L)145*67e74705SXin Li static const EHPersonality &getCXXPersonality(const llvm::Triple &T,
146*67e74705SXin Li                                               const LangOptions &L) {
147*67e74705SXin Li   if (L.SjLjExceptions)
148*67e74705SXin Li     return EHPersonality::GNU_CPlusPlus_SJLJ;
149*67e74705SXin Li   else if (useLibGCCSEHPersonality(T))
150*67e74705SXin Li     return EHPersonality::GNU_CPlusPlus_SEH;
151*67e74705SXin Li   return EHPersonality::GNU_CPlusPlus;
152*67e74705SXin Li }
153*67e74705SXin Li 
154*67e74705SXin Li /// Determines the personality function to use when both C++
155*67e74705SXin Li /// and Objective-C exceptions are being caught.
getObjCXXPersonality(const llvm::Triple & T,const LangOptions & L)156*67e74705SXin Li static const EHPersonality &getObjCXXPersonality(const llvm::Triple &T,
157*67e74705SXin Li                                                  const LangOptions &L) {
158*67e74705SXin Li   switch (L.ObjCRuntime.getKind()) {
159*67e74705SXin Li   // The ObjC personality defers to the C++ personality for non-ObjC
160*67e74705SXin Li   // handlers.  Unlike the C++ case, we use the same personality
161*67e74705SXin Li   // function on targets using (backend-driven) SJLJ EH.
162*67e74705SXin Li   case ObjCRuntime::MacOSX:
163*67e74705SXin Li   case ObjCRuntime::iOS:
164*67e74705SXin Li   case ObjCRuntime::WatchOS:
165*67e74705SXin Li     return EHPersonality::NeXT_ObjC;
166*67e74705SXin Li 
167*67e74705SXin Li   // In the fragile ABI, just use C++ exception handling and hope
168*67e74705SXin Li   // they're not doing crazy exception mixing.
169*67e74705SXin Li   case ObjCRuntime::FragileMacOSX:
170*67e74705SXin Li     return getCXXPersonality(T, L);
171*67e74705SXin Li 
172*67e74705SXin Li   // The GCC runtime's personality function inherently doesn't support
173*67e74705SXin Li   // mixed EH.  Use the C++ personality just to avoid returning null.
174*67e74705SXin Li   case ObjCRuntime::GCC:
175*67e74705SXin Li   case ObjCRuntime::ObjFW: // XXX: this will change soon
176*67e74705SXin Li     return EHPersonality::GNU_ObjC;
177*67e74705SXin Li   case ObjCRuntime::GNUstep:
178*67e74705SXin Li     return EHPersonality::GNU_ObjCXX;
179*67e74705SXin Li   }
180*67e74705SXin Li   llvm_unreachable("bad runtime kind");
181*67e74705SXin Li }
182*67e74705SXin Li 
getSEHPersonalityMSVC(const llvm::Triple & T)183*67e74705SXin Li static const EHPersonality &getSEHPersonalityMSVC(const llvm::Triple &T) {
184*67e74705SXin Li   if (T.getArch() == llvm::Triple::x86)
185*67e74705SXin Li     return EHPersonality::MSVC_except_handler;
186*67e74705SXin Li   return EHPersonality::MSVC_C_specific_handler;
187*67e74705SXin Li }
188*67e74705SXin Li 
get(CodeGenModule & CGM,const FunctionDecl * FD)189*67e74705SXin Li const EHPersonality &EHPersonality::get(CodeGenModule &CGM,
190*67e74705SXin Li                                         const FunctionDecl *FD) {
191*67e74705SXin Li   const llvm::Triple &T = CGM.getTarget().getTriple();
192*67e74705SXin Li   const LangOptions &L = CGM.getLangOpts();
193*67e74705SXin Li 
194*67e74705SXin Li   // Functions using SEH get an SEH personality.
195*67e74705SXin Li   if (FD && FD->usesSEHTry())
196*67e74705SXin Li     return getSEHPersonalityMSVC(T);
197*67e74705SXin Li 
198*67e74705SXin Li   // Try to pick a personality function that is compatible with MSVC if we're
199*67e74705SXin Li   // not compiling Obj-C. Obj-C users better have an Obj-C runtime that supports
200*67e74705SXin Li   // the GCC-style personality function.
201*67e74705SXin Li   if (T.isWindowsMSVCEnvironment() && !L.ObjC1) {
202*67e74705SXin Li     if (L.SjLjExceptions)
203*67e74705SXin Li       return EHPersonality::GNU_CPlusPlus_SJLJ;
204*67e74705SXin Li     else
205*67e74705SXin Li       return EHPersonality::MSVC_CxxFrameHandler3;
206*67e74705SXin Li   }
207*67e74705SXin Li 
208*67e74705SXin Li   if (L.CPlusPlus && L.ObjC1)
209*67e74705SXin Li     return getObjCXXPersonality(T, L);
210*67e74705SXin Li   else if (L.CPlusPlus)
211*67e74705SXin Li     return getCXXPersonality(T, L);
212*67e74705SXin Li   else if (L.ObjC1)
213*67e74705SXin Li     return getObjCPersonality(T, L);
214*67e74705SXin Li   else
215*67e74705SXin Li     return getCPersonality(T, L);
216*67e74705SXin Li }
217*67e74705SXin Li 
get(CodeGenFunction & CGF)218*67e74705SXin Li const EHPersonality &EHPersonality::get(CodeGenFunction &CGF) {
219*67e74705SXin Li   return get(CGF.CGM, dyn_cast_or_null<FunctionDecl>(CGF.CurCodeDecl));
220*67e74705SXin Li }
221*67e74705SXin Li 
getPersonalityFn(CodeGenModule & CGM,const EHPersonality & Personality)222*67e74705SXin Li static llvm::Constant *getPersonalityFn(CodeGenModule &CGM,
223*67e74705SXin Li                                         const EHPersonality &Personality) {
224*67e74705SXin Li   llvm::Constant *Fn =
225*67e74705SXin Li     CGM.CreateRuntimeFunction(llvm::FunctionType::get(CGM.Int32Ty, true),
226*67e74705SXin Li                               Personality.PersonalityFn);
227*67e74705SXin Li   return Fn;
228*67e74705SXin Li }
229*67e74705SXin Li 
getOpaquePersonalityFn(CodeGenModule & CGM,const EHPersonality & Personality)230*67e74705SXin Li static llvm::Constant *getOpaquePersonalityFn(CodeGenModule &CGM,
231*67e74705SXin Li                                         const EHPersonality &Personality) {
232*67e74705SXin Li   llvm::Constant *Fn = getPersonalityFn(CGM, Personality);
233*67e74705SXin Li   return llvm::ConstantExpr::getBitCast(Fn, CGM.Int8PtrTy);
234*67e74705SXin Li }
235*67e74705SXin Li 
236*67e74705SXin Li /// Check whether a landingpad instruction only uses C++ features.
LandingPadHasOnlyCXXUses(llvm::LandingPadInst * LPI)237*67e74705SXin Li static bool LandingPadHasOnlyCXXUses(llvm::LandingPadInst *LPI) {
238*67e74705SXin Li   for (unsigned I = 0, E = LPI->getNumClauses(); I != E; ++I) {
239*67e74705SXin Li     // Look for something that would've been returned by the ObjC
240*67e74705SXin Li     // runtime's GetEHType() method.
241*67e74705SXin Li     llvm::Value *Val = LPI->getClause(I)->stripPointerCasts();
242*67e74705SXin Li     if (LPI->isCatch(I)) {
243*67e74705SXin Li       // Check if the catch value has the ObjC prefix.
244*67e74705SXin Li       if (llvm::GlobalVariable *GV = dyn_cast<llvm::GlobalVariable>(Val))
245*67e74705SXin Li         // ObjC EH selector entries are always global variables with
246*67e74705SXin Li         // names starting like this.
247*67e74705SXin Li         if (GV->getName().startswith("OBJC_EHTYPE"))
248*67e74705SXin Li           return false;
249*67e74705SXin Li     } else {
250*67e74705SXin Li       // Check if any of the filter values have the ObjC prefix.
251*67e74705SXin Li       llvm::Constant *CVal = cast<llvm::Constant>(Val);
252*67e74705SXin Li       for (llvm::User::op_iterator
253*67e74705SXin Li               II = CVal->op_begin(), IE = CVal->op_end(); II != IE; ++II) {
254*67e74705SXin Li         if (llvm::GlobalVariable *GV =
255*67e74705SXin Li             cast<llvm::GlobalVariable>((*II)->stripPointerCasts()))
256*67e74705SXin Li           // ObjC EH selector entries are always global variables with
257*67e74705SXin Li           // names starting like this.
258*67e74705SXin Li           if (GV->getName().startswith("OBJC_EHTYPE"))
259*67e74705SXin Li             return false;
260*67e74705SXin Li       }
261*67e74705SXin Li     }
262*67e74705SXin Li   }
263*67e74705SXin Li   return true;
264*67e74705SXin Li }
265*67e74705SXin Li 
266*67e74705SXin Li /// Check whether a personality function could reasonably be swapped
267*67e74705SXin Li /// for a C++ personality function.
PersonalityHasOnlyCXXUses(llvm::Constant * Fn)268*67e74705SXin Li static bool PersonalityHasOnlyCXXUses(llvm::Constant *Fn) {
269*67e74705SXin Li   for (llvm::User *U : Fn->users()) {
270*67e74705SXin Li     // Conditionally white-list bitcasts.
271*67e74705SXin Li     if (llvm::ConstantExpr *CE = dyn_cast<llvm::ConstantExpr>(U)) {
272*67e74705SXin Li       if (CE->getOpcode() != llvm::Instruction::BitCast) return false;
273*67e74705SXin Li       if (!PersonalityHasOnlyCXXUses(CE))
274*67e74705SXin Li         return false;
275*67e74705SXin Li       continue;
276*67e74705SXin Li     }
277*67e74705SXin Li 
278*67e74705SXin Li     // Otherwise it must be a function.
279*67e74705SXin Li     llvm::Function *F = dyn_cast<llvm::Function>(U);
280*67e74705SXin Li     if (!F) return false;
281*67e74705SXin Li 
282*67e74705SXin Li     for (auto BB = F->begin(), E = F->end(); BB != E; ++BB) {
283*67e74705SXin Li       if (BB->isLandingPad())
284*67e74705SXin Li         if (!LandingPadHasOnlyCXXUses(BB->getLandingPadInst()))
285*67e74705SXin Li           return false;
286*67e74705SXin Li     }
287*67e74705SXin Li   }
288*67e74705SXin Li 
289*67e74705SXin Li   return true;
290*67e74705SXin Li }
291*67e74705SXin Li 
292*67e74705SXin Li /// Try to use the C++ personality function in ObjC++.  Not doing this
293*67e74705SXin Li /// can cause some incompatibilities with gcc, which is more
294*67e74705SXin Li /// aggressive about only using the ObjC++ personality in a function
295*67e74705SXin Li /// when it really needs it.
SimplifyPersonality()296*67e74705SXin Li void CodeGenModule::SimplifyPersonality() {
297*67e74705SXin Li   // If we're not in ObjC++ -fexceptions, there's nothing to do.
298*67e74705SXin Li   if (!LangOpts.CPlusPlus || !LangOpts.ObjC1 || !LangOpts.Exceptions)
299*67e74705SXin Li     return;
300*67e74705SXin Li 
301*67e74705SXin Li   // Both the problem this endeavors to fix and the way the logic
302*67e74705SXin Li   // above works is specific to the NeXT runtime.
303*67e74705SXin Li   if (!LangOpts.ObjCRuntime.isNeXTFamily())
304*67e74705SXin Li     return;
305*67e74705SXin Li 
306*67e74705SXin Li   const EHPersonality &ObjCXX = EHPersonality::get(*this, /*FD=*/nullptr);
307*67e74705SXin Li   const EHPersonality &CXX =
308*67e74705SXin Li       getCXXPersonality(getTarget().getTriple(), LangOpts);
309*67e74705SXin Li   if (&ObjCXX == &CXX)
310*67e74705SXin Li     return;
311*67e74705SXin Li 
312*67e74705SXin Li   assert(std::strcmp(ObjCXX.PersonalityFn, CXX.PersonalityFn) != 0 &&
313*67e74705SXin Li          "Different EHPersonalities using the same personality function.");
314*67e74705SXin Li 
315*67e74705SXin Li   llvm::Function *Fn = getModule().getFunction(ObjCXX.PersonalityFn);
316*67e74705SXin Li 
317*67e74705SXin Li   // Nothing to do if it's unused.
318*67e74705SXin Li   if (!Fn || Fn->use_empty()) return;
319*67e74705SXin Li 
320*67e74705SXin Li   // Can't do the optimization if it has non-C++ uses.
321*67e74705SXin Li   if (!PersonalityHasOnlyCXXUses(Fn)) return;
322*67e74705SXin Li 
323*67e74705SXin Li   // Create the C++ personality function and kill off the old
324*67e74705SXin Li   // function.
325*67e74705SXin Li   llvm::Constant *CXXFn = getPersonalityFn(*this, CXX);
326*67e74705SXin Li 
327*67e74705SXin Li   // This can happen if the user is screwing with us.
328*67e74705SXin Li   if (Fn->getType() != CXXFn->getType()) return;
329*67e74705SXin Li 
330*67e74705SXin Li   Fn->replaceAllUsesWith(CXXFn);
331*67e74705SXin Li   Fn->eraseFromParent();
332*67e74705SXin Li }
333*67e74705SXin Li 
334*67e74705SXin Li /// Returns the value to inject into a selector to indicate the
335*67e74705SXin Li /// presence of a catch-all.
getCatchAllValue(CodeGenFunction & CGF)336*67e74705SXin Li static llvm::Constant *getCatchAllValue(CodeGenFunction &CGF) {
337*67e74705SXin Li   // Possibly we should use @llvm.eh.catch.all.value here.
338*67e74705SXin Li   return llvm::ConstantPointerNull::get(CGF.Int8PtrTy);
339*67e74705SXin Li }
340*67e74705SXin Li 
341*67e74705SXin Li namespace {
342*67e74705SXin Li   /// A cleanup to free the exception object if its initialization
343*67e74705SXin Li   /// throws.
344*67e74705SXin Li   struct FreeException final : EHScopeStack::Cleanup {
345*67e74705SXin Li     llvm::Value *exn;
FreeException__anonaa838d2f0111::FreeException346*67e74705SXin Li     FreeException(llvm::Value *exn) : exn(exn) {}
Emit__anonaa838d2f0111::FreeException347*67e74705SXin Li     void Emit(CodeGenFunction &CGF, Flags flags) override {
348*67e74705SXin Li       CGF.EmitNounwindRuntimeCall(getFreeExceptionFn(CGF.CGM), exn);
349*67e74705SXin Li     }
350*67e74705SXin Li   };
351*67e74705SXin Li } // end anonymous namespace
352*67e74705SXin Li 
353*67e74705SXin Li // Emits an exception expression into the given location.  This
354*67e74705SXin Li // differs from EmitAnyExprToMem only in that, if a final copy-ctor
355*67e74705SXin Li // call is required, an exception within that copy ctor causes
356*67e74705SXin Li // std::terminate to be invoked.
EmitAnyExprToExn(const Expr * e,Address addr)357*67e74705SXin Li void CodeGenFunction::EmitAnyExprToExn(const Expr *e, Address addr) {
358*67e74705SXin Li   // Make sure the exception object is cleaned up if there's an
359*67e74705SXin Li   // exception during initialization.
360*67e74705SXin Li   pushFullExprCleanup<FreeException>(EHCleanup, addr.getPointer());
361*67e74705SXin Li   EHScopeStack::stable_iterator cleanup = EHStack.stable_begin();
362*67e74705SXin Li 
363*67e74705SXin Li   // __cxa_allocate_exception returns a void*;  we need to cast this
364*67e74705SXin Li   // to the appropriate type for the object.
365*67e74705SXin Li   llvm::Type *ty = ConvertTypeForMem(e->getType())->getPointerTo();
366*67e74705SXin Li   Address typedAddr = Builder.CreateBitCast(addr, ty);
367*67e74705SXin Li 
368*67e74705SXin Li   // FIXME: this isn't quite right!  If there's a final unelided call
369*67e74705SXin Li   // to a copy constructor, then according to [except.terminate]p1 we
370*67e74705SXin Li   // must call std::terminate() if that constructor throws, because
371*67e74705SXin Li   // technically that copy occurs after the exception expression is
372*67e74705SXin Li   // evaluated but before the exception is caught.  But the best way
373*67e74705SXin Li   // to handle that is to teach EmitAggExpr to do the final copy
374*67e74705SXin Li   // differently if it can't be elided.
375*67e74705SXin Li   EmitAnyExprToMem(e, typedAddr, e->getType().getQualifiers(),
376*67e74705SXin Li                    /*IsInit*/ true);
377*67e74705SXin Li 
378*67e74705SXin Li   // Deactivate the cleanup block.
379*67e74705SXin Li   DeactivateCleanupBlock(cleanup,
380*67e74705SXin Li                          cast<llvm::Instruction>(typedAddr.getPointer()));
381*67e74705SXin Li }
382*67e74705SXin Li 
getExceptionSlot()383*67e74705SXin Li Address CodeGenFunction::getExceptionSlot() {
384*67e74705SXin Li   if (!ExceptionSlot)
385*67e74705SXin Li     ExceptionSlot = CreateTempAlloca(Int8PtrTy, "exn.slot");
386*67e74705SXin Li   return Address(ExceptionSlot, getPointerAlign());
387*67e74705SXin Li }
388*67e74705SXin Li 
getEHSelectorSlot()389*67e74705SXin Li Address CodeGenFunction::getEHSelectorSlot() {
390*67e74705SXin Li   if (!EHSelectorSlot)
391*67e74705SXin Li     EHSelectorSlot = CreateTempAlloca(Int32Ty, "ehselector.slot");
392*67e74705SXin Li   return Address(EHSelectorSlot, CharUnits::fromQuantity(4));
393*67e74705SXin Li }
394*67e74705SXin Li 
getExceptionFromSlot()395*67e74705SXin Li llvm::Value *CodeGenFunction::getExceptionFromSlot() {
396*67e74705SXin Li   return Builder.CreateLoad(getExceptionSlot(), "exn");
397*67e74705SXin Li }
398*67e74705SXin Li 
getSelectorFromSlot()399*67e74705SXin Li llvm::Value *CodeGenFunction::getSelectorFromSlot() {
400*67e74705SXin Li   return Builder.CreateLoad(getEHSelectorSlot(), "sel");
401*67e74705SXin Li }
402*67e74705SXin Li 
EmitCXXThrowExpr(const CXXThrowExpr * E,bool KeepInsertionPoint)403*67e74705SXin Li void CodeGenFunction::EmitCXXThrowExpr(const CXXThrowExpr *E,
404*67e74705SXin Li                                        bool KeepInsertionPoint) {
405*67e74705SXin Li   if (const Expr *SubExpr = E->getSubExpr()) {
406*67e74705SXin Li     QualType ThrowType = SubExpr->getType();
407*67e74705SXin Li     if (ThrowType->isObjCObjectPointerType()) {
408*67e74705SXin Li       const Stmt *ThrowStmt = E->getSubExpr();
409*67e74705SXin Li       const ObjCAtThrowStmt S(E->getExprLoc(), const_cast<Stmt *>(ThrowStmt));
410*67e74705SXin Li       CGM.getObjCRuntime().EmitThrowStmt(*this, S, false);
411*67e74705SXin Li     } else {
412*67e74705SXin Li       CGM.getCXXABI().emitThrow(*this, E);
413*67e74705SXin Li     }
414*67e74705SXin Li   } else {
415*67e74705SXin Li     CGM.getCXXABI().emitRethrow(*this, /*isNoReturn=*/true);
416*67e74705SXin Li   }
417*67e74705SXin Li 
418*67e74705SXin Li   // throw is an expression, and the expression emitters expect us
419*67e74705SXin Li   // to leave ourselves at a valid insertion point.
420*67e74705SXin Li   if (KeepInsertionPoint)
421*67e74705SXin Li     EmitBlock(createBasicBlock("throw.cont"));
422*67e74705SXin Li }
423*67e74705SXin Li 
EmitStartEHSpec(const Decl * D)424*67e74705SXin Li void CodeGenFunction::EmitStartEHSpec(const Decl *D) {
425*67e74705SXin Li   if (!CGM.getLangOpts().CXXExceptions)
426*67e74705SXin Li     return;
427*67e74705SXin Li 
428*67e74705SXin Li   const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
429*67e74705SXin Li   if (!FD) {
430*67e74705SXin Li     // Check if CapturedDecl is nothrow and create terminate scope for it.
431*67e74705SXin Li     if (const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(D)) {
432*67e74705SXin Li       if (CD->isNothrow())
433*67e74705SXin Li         EHStack.pushTerminate();
434*67e74705SXin Li     }
435*67e74705SXin Li     return;
436*67e74705SXin Li   }
437*67e74705SXin Li   const FunctionProtoType *Proto = FD->getType()->getAs<FunctionProtoType>();
438*67e74705SXin Li   if (!Proto)
439*67e74705SXin Li     return;
440*67e74705SXin Li 
441*67e74705SXin Li   ExceptionSpecificationType EST = Proto->getExceptionSpecType();
442*67e74705SXin Li   if (isNoexceptExceptionSpec(EST)) {
443*67e74705SXin Li     if (Proto->getNoexceptSpec(getContext()) == FunctionProtoType::NR_Nothrow) {
444*67e74705SXin Li       // noexcept functions are simple terminate scopes.
445*67e74705SXin Li       EHStack.pushTerminate();
446*67e74705SXin Li     }
447*67e74705SXin Li   } else if (EST == EST_Dynamic || EST == EST_DynamicNone) {
448*67e74705SXin Li     // TODO: Revisit exception specifications for the MS ABI.  There is a way to
449*67e74705SXin Li     // encode these in an object file but MSVC doesn't do anything with it.
450*67e74705SXin Li     if (getTarget().getCXXABI().isMicrosoft())
451*67e74705SXin Li       return;
452*67e74705SXin Li     unsigned NumExceptions = Proto->getNumExceptions();
453*67e74705SXin Li     EHFilterScope *Filter = EHStack.pushFilter(NumExceptions);
454*67e74705SXin Li 
455*67e74705SXin Li     for (unsigned I = 0; I != NumExceptions; ++I) {
456*67e74705SXin Li       QualType Ty = Proto->getExceptionType(I);
457*67e74705SXin Li       QualType ExceptType = Ty.getNonReferenceType().getUnqualifiedType();
458*67e74705SXin Li       llvm::Value *EHType = CGM.GetAddrOfRTTIDescriptor(ExceptType,
459*67e74705SXin Li                                                         /*ForEH=*/true);
460*67e74705SXin Li       Filter->setFilter(I, EHType);
461*67e74705SXin Li     }
462*67e74705SXin Li   }
463*67e74705SXin Li }
464*67e74705SXin Li 
465*67e74705SXin Li /// Emit the dispatch block for a filter scope if necessary.
emitFilterDispatchBlock(CodeGenFunction & CGF,EHFilterScope & filterScope)466*67e74705SXin Li static void emitFilterDispatchBlock(CodeGenFunction &CGF,
467*67e74705SXin Li                                     EHFilterScope &filterScope) {
468*67e74705SXin Li   llvm::BasicBlock *dispatchBlock = filterScope.getCachedEHDispatchBlock();
469*67e74705SXin Li   if (!dispatchBlock) return;
470*67e74705SXin Li   if (dispatchBlock->use_empty()) {
471*67e74705SXin Li     delete dispatchBlock;
472*67e74705SXin Li     return;
473*67e74705SXin Li   }
474*67e74705SXin Li 
475*67e74705SXin Li   CGF.EmitBlockAfterUses(dispatchBlock);
476*67e74705SXin Li 
477*67e74705SXin Li   // If this isn't a catch-all filter, we need to check whether we got
478*67e74705SXin Li   // here because the filter triggered.
479*67e74705SXin Li   if (filterScope.getNumFilters()) {
480*67e74705SXin Li     // Load the selector value.
481*67e74705SXin Li     llvm::Value *selector = CGF.getSelectorFromSlot();
482*67e74705SXin Li     llvm::BasicBlock *unexpectedBB = CGF.createBasicBlock("ehspec.unexpected");
483*67e74705SXin Li 
484*67e74705SXin Li     llvm::Value *zero = CGF.Builder.getInt32(0);
485*67e74705SXin Li     llvm::Value *failsFilter =
486*67e74705SXin Li         CGF.Builder.CreateICmpSLT(selector, zero, "ehspec.fails");
487*67e74705SXin Li     CGF.Builder.CreateCondBr(failsFilter, unexpectedBB,
488*67e74705SXin Li                              CGF.getEHResumeBlock(false));
489*67e74705SXin Li 
490*67e74705SXin Li     CGF.EmitBlock(unexpectedBB);
491*67e74705SXin Li   }
492*67e74705SXin Li 
493*67e74705SXin Li   // Call __cxa_call_unexpected.  This doesn't need to be an invoke
494*67e74705SXin Li   // because __cxa_call_unexpected magically filters exceptions
495*67e74705SXin Li   // according to the last landing pad the exception was thrown
496*67e74705SXin Li   // into.  Seriously.
497*67e74705SXin Li   llvm::Value *exn = CGF.getExceptionFromSlot();
498*67e74705SXin Li   CGF.EmitRuntimeCall(getUnexpectedFn(CGF.CGM), exn)
499*67e74705SXin Li     ->setDoesNotReturn();
500*67e74705SXin Li   CGF.Builder.CreateUnreachable();
501*67e74705SXin Li }
502*67e74705SXin Li 
EmitEndEHSpec(const Decl * D)503*67e74705SXin Li void CodeGenFunction::EmitEndEHSpec(const Decl *D) {
504*67e74705SXin Li   if (!CGM.getLangOpts().CXXExceptions)
505*67e74705SXin Li     return;
506*67e74705SXin Li 
507*67e74705SXin Li   const FunctionDecl* FD = dyn_cast_or_null<FunctionDecl>(D);
508*67e74705SXin Li   if (!FD) {
509*67e74705SXin Li     // Check if CapturedDecl is nothrow and pop terminate scope for it.
510*67e74705SXin Li     if (const CapturedDecl* CD = dyn_cast_or_null<CapturedDecl>(D)) {
511*67e74705SXin Li       if (CD->isNothrow())
512*67e74705SXin Li         EHStack.popTerminate();
513*67e74705SXin Li     }
514*67e74705SXin Li     return;
515*67e74705SXin Li   }
516*67e74705SXin Li   const FunctionProtoType *Proto = FD->getType()->getAs<FunctionProtoType>();
517*67e74705SXin Li   if (!Proto)
518*67e74705SXin Li     return;
519*67e74705SXin Li 
520*67e74705SXin Li   ExceptionSpecificationType EST = Proto->getExceptionSpecType();
521*67e74705SXin Li   if (isNoexceptExceptionSpec(EST)) {
522*67e74705SXin Li     if (Proto->getNoexceptSpec(getContext()) == FunctionProtoType::NR_Nothrow) {
523*67e74705SXin Li       EHStack.popTerminate();
524*67e74705SXin Li     }
525*67e74705SXin Li   } else if (EST == EST_Dynamic || EST == EST_DynamicNone) {
526*67e74705SXin Li     // TODO: Revisit exception specifications for the MS ABI.  There is a way to
527*67e74705SXin Li     // encode these in an object file but MSVC doesn't do anything with it.
528*67e74705SXin Li     if (getTarget().getCXXABI().isMicrosoft())
529*67e74705SXin Li       return;
530*67e74705SXin Li     EHFilterScope &filterScope = cast<EHFilterScope>(*EHStack.begin());
531*67e74705SXin Li     emitFilterDispatchBlock(*this, filterScope);
532*67e74705SXin Li     EHStack.popFilter();
533*67e74705SXin Li   }
534*67e74705SXin Li }
535*67e74705SXin Li 
EmitCXXTryStmt(const CXXTryStmt & S)536*67e74705SXin Li void CodeGenFunction::EmitCXXTryStmt(const CXXTryStmt &S) {
537*67e74705SXin Li   EnterCXXTryStmt(S);
538*67e74705SXin Li   EmitStmt(S.getTryBlock());
539*67e74705SXin Li   ExitCXXTryStmt(S);
540*67e74705SXin Li }
541*67e74705SXin Li 
EnterCXXTryStmt(const CXXTryStmt & S,bool IsFnTryBlock)542*67e74705SXin Li void CodeGenFunction::EnterCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {
543*67e74705SXin Li   unsigned NumHandlers = S.getNumHandlers();
544*67e74705SXin Li   EHCatchScope *CatchScope = EHStack.pushCatch(NumHandlers);
545*67e74705SXin Li 
546*67e74705SXin Li   for (unsigned I = 0; I != NumHandlers; ++I) {
547*67e74705SXin Li     const CXXCatchStmt *C = S.getHandler(I);
548*67e74705SXin Li 
549*67e74705SXin Li     llvm::BasicBlock *Handler = createBasicBlock("catch");
550*67e74705SXin Li     if (C->getExceptionDecl()) {
551*67e74705SXin Li       // FIXME: Dropping the reference type on the type into makes it
552*67e74705SXin Li       // impossible to correctly implement catch-by-reference
553*67e74705SXin Li       // semantics for pointers.  Unfortunately, this is what all
554*67e74705SXin Li       // existing compilers do, and it's not clear that the standard
555*67e74705SXin Li       // personality routine is capable of doing this right.  See C++ DR 388:
556*67e74705SXin Li       //   http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#388
557*67e74705SXin Li       Qualifiers CaughtTypeQuals;
558*67e74705SXin Li       QualType CaughtType = CGM.getContext().getUnqualifiedArrayType(
559*67e74705SXin Li           C->getCaughtType().getNonReferenceType(), CaughtTypeQuals);
560*67e74705SXin Li 
561*67e74705SXin Li       CatchTypeInfo TypeInfo{nullptr, 0};
562*67e74705SXin Li       if (CaughtType->isObjCObjectPointerType())
563*67e74705SXin Li         TypeInfo.RTTI = CGM.getObjCRuntime().GetEHType(CaughtType);
564*67e74705SXin Li       else
565*67e74705SXin Li         TypeInfo = CGM.getCXXABI().getAddrOfCXXCatchHandlerType(
566*67e74705SXin Li             CaughtType, C->getCaughtType());
567*67e74705SXin Li       CatchScope->setHandler(I, TypeInfo, Handler);
568*67e74705SXin Li     } else {
569*67e74705SXin Li       // No exception decl indicates '...', a catch-all.
570*67e74705SXin Li       CatchScope->setHandler(I, CGM.getCXXABI().getCatchAllTypeInfo(), Handler);
571*67e74705SXin Li     }
572*67e74705SXin Li   }
573*67e74705SXin Li }
574*67e74705SXin Li 
575*67e74705SXin Li llvm::BasicBlock *
getEHDispatchBlock(EHScopeStack::stable_iterator si)576*67e74705SXin Li CodeGenFunction::getEHDispatchBlock(EHScopeStack::stable_iterator si) {
577*67e74705SXin Li   if (EHPersonality::get(*this).usesFuncletPads())
578*67e74705SXin Li     return getMSVCDispatchBlock(si);
579*67e74705SXin Li 
580*67e74705SXin Li   // The dispatch block for the end of the scope chain is a block that
581*67e74705SXin Li   // just resumes unwinding.
582*67e74705SXin Li   if (si == EHStack.stable_end())
583*67e74705SXin Li     return getEHResumeBlock(true);
584*67e74705SXin Li 
585*67e74705SXin Li   // Otherwise, we should look at the actual scope.
586*67e74705SXin Li   EHScope &scope = *EHStack.find(si);
587*67e74705SXin Li 
588*67e74705SXin Li   llvm::BasicBlock *dispatchBlock = scope.getCachedEHDispatchBlock();
589*67e74705SXin Li   if (!dispatchBlock) {
590*67e74705SXin Li     switch (scope.getKind()) {
591*67e74705SXin Li     case EHScope::Catch: {
592*67e74705SXin Li       // Apply a special case to a single catch-all.
593*67e74705SXin Li       EHCatchScope &catchScope = cast<EHCatchScope>(scope);
594*67e74705SXin Li       if (catchScope.getNumHandlers() == 1 &&
595*67e74705SXin Li           catchScope.getHandler(0).isCatchAll()) {
596*67e74705SXin Li         dispatchBlock = catchScope.getHandler(0).Block;
597*67e74705SXin Li 
598*67e74705SXin Li       // Otherwise, make a dispatch block.
599*67e74705SXin Li       } else {
600*67e74705SXin Li         dispatchBlock = createBasicBlock("catch.dispatch");
601*67e74705SXin Li       }
602*67e74705SXin Li       break;
603*67e74705SXin Li     }
604*67e74705SXin Li 
605*67e74705SXin Li     case EHScope::Cleanup:
606*67e74705SXin Li       dispatchBlock = createBasicBlock("ehcleanup");
607*67e74705SXin Li       break;
608*67e74705SXin Li 
609*67e74705SXin Li     case EHScope::Filter:
610*67e74705SXin Li       dispatchBlock = createBasicBlock("filter.dispatch");
611*67e74705SXin Li       break;
612*67e74705SXin Li 
613*67e74705SXin Li     case EHScope::Terminate:
614*67e74705SXin Li       dispatchBlock = getTerminateHandler();
615*67e74705SXin Li       break;
616*67e74705SXin Li 
617*67e74705SXin Li     case EHScope::PadEnd:
618*67e74705SXin Li       llvm_unreachable("PadEnd unnecessary for Itanium!");
619*67e74705SXin Li     }
620*67e74705SXin Li     scope.setCachedEHDispatchBlock(dispatchBlock);
621*67e74705SXin Li   }
622*67e74705SXin Li   return dispatchBlock;
623*67e74705SXin Li }
624*67e74705SXin Li 
625*67e74705SXin Li llvm::BasicBlock *
getMSVCDispatchBlock(EHScopeStack::stable_iterator SI)626*67e74705SXin Li CodeGenFunction::getMSVCDispatchBlock(EHScopeStack::stable_iterator SI) {
627*67e74705SXin Li   // Returning nullptr indicates that the previous dispatch block should unwind
628*67e74705SXin Li   // to caller.
629*67e74705SXin Li   if (SI == EHStack.stable_end())
630*67e74705SXin Li     return nullptr;
631*67e74705SXin Li 
632*67e74705SXin Li   // Otherwise, we should look at the actual scope.
633*67e74705SXin Li   EHScope &EHS = *EHStack.find(SI);
634*67e74705SXin Li 
635*67e74705SXin Li   llvm::BasicBlock *DispatchBlock = EHS.getCachedEHDispatchBlock();
636*67e74705SXin Li   if (DispatchBlock)
637*67e74705SXin Li     return DispatchBlock;
638*67e74705SXin Li 
639*67e74705SXin Li   if (EHS.getKind() == EHScope::Terminate)
640*67e74705SXin Li     DispatchBlock = getTerminateHandler();
641*67e74705SXin Li   else
642*67e74705SXin Li     DispatchBlock = createBasicBlock();
643*67e74705SXin Li   CGBuilderTy Builder(*this, DispatchBlock);
644*67e74705SXin Li 
645*67e74705SXin Li   switch (EHS.getKind()) {
646*67e74705SXin Li   case EHScope::Catch:
647*67e74705SXin Li     DispatchBlock->setName("catch.dispatch");
648*67e74705SXin Li     break;
649*67e74705SXin Li 
650*67e74705SXin Li   case EHScope::Cleanup:
651*67e74705SXin Li     DispatchBlock->setName("ehcleanup");
652*67e74705SXin Li     break;
653*67e74705SXin Li 
654*67e74705SXin Li   case EHScope::Filter:
655*67e74705SXin Li     llvm_unreachable("exception specifications not handled yet!");
656*67e74705SXin Li 
657*67e74705SXin Li   case EHScope::Terminate:
658*67e74705SXin Li     DispatchBlock->setName("terminate");
659*67e74705SXin Li     break;
660*67e74705SXin Li 
661*67e74705SXin Li   case EHScope::PadEnd:
662*67e74705SXin Li     llvm_unreachable("PadEnd dispatch block missing!");
663*67e74705SXin Li   }
664*67e74705SXin Li   EHS.setCachedEHDispatchBlock(DispatchBlock);
665*67e74705SXin Li   return DispatchBlock;
666*67e74705SXin Li }
667*67e74705SXin Li 
668*67e74705SXin Li /// Check whether this is a non-EH scope, i.e. a scope which doesn't
669*67e74705SXin Li /// affect exception handling.  Currently, the only non-EH scopes are
670*67e74705SXin Li /// normal-only cleanup scopes.
isNonEHScope(const EHScope & S)671*67e74705SXin Li static bool isNonEHScope(const EHScope &S) {
672*67e74705SXin Li   switch (S.getKind()) {
673*67e74705SXin Li   case EHScope::Cleanup:
674*67e74705SXin Li     return !cast<EHCleanupScope>(S).isEHCleanup();
675*67e74705SXin Li   case EHScope::Filter:
676*67e74705SXin Li   case EHScope::Catch:
677*67e74705SXin Li   case EHScope::Terminate:
678*67e74705SXin Li   case EHScope::PadEnd:
679*67e74705SXin Li     return false;
680*67e74705SXin Li   }
681*67e74705SXin Li 
682*67e74705SXin Li   llvm_unreachable("Invalid EHScope Kind!");
683*67e74705SXin Li }
684*67e74705SXin Li 
getInvokeDestImpl()685*67e74705SXin Li llvm::BasicBlock *CodeGenFunction::getInvokeDestImpl() {
686*67e74705SXin Li   assert(EHStack.requiresLandingPad());
687*67e74705SXin Li   assert(!EHStack.empty());
688*67e74705SXin Li 
689*67e74705SXin Li   // If exceptions are disabled and SEH is not in use, then there is no invoke
690*67e74705SXin Li   // destination. SEH "works" even if exceptions are off. In practice, this
691*67e74705SXin Li   // means that C++ destructors and other EH cleanups don't run, which is
692*67e74705SXin Li   // consistent with MSVC's behavior.
693*67e74705SXin Li   const LangOptions &LO = CGM.getLangOpts();
694*67e74705SXin Li   if (!LO.Exceptions) {
695*67e74705SXin Li     if (!LO.Borland && !LO.MicrosoftExt)
696*67e74705SXin Li       return nullptr;
697*67e74705SXin Li     if (!currentFunctionUsesSEHTry())
698*67e74705SXin Li       return nullptr;
699*67e74705SXin Li   }
700*67e74705SXin Li 
701*67e74705SXin Li   // Check the innermost scope for a cached landing pad.  If this is
702*67e74705SXin Li   // a non-EH cleanup, we'll check enclosing scopes in EmitLandingPad.
703*67e74705SXin Li   llvm::BasicBlock *LP = EHStack.begin()->getCachedLandingPad();
704*67e74705SXin Li   if (LP) return LP;
705*67e74705SXin Li 
706*67e74705SXin Li   const EHPersonality &Personality = EHPersonality::get(*this);
707*67e74705SXin Li 
708*67e74705SXin Li   if (!CurFn->hasPersonalityFn())
709*67e74705SXin Li     CurFn->setPersonalityFn(getOpaquePersonalityFn(CGM, Personality));
710*67e74705SXin Li 
711*67e74705SXin Li   if (Personality.usesFuncletPads()) {
712*67e74705SXin Li     // We don't need separate landing pads in the funclet model.
713*67e74705SXin Li     LP = getEHDispatchBlock(EHStack.getInnermostEHScope());
714*67e74705SXin Li   } else {
715*67e74705SXin Li     // Build the landing pad for this scope.
716*67e74705SXin Li     LP = EmitLandingPad();
717*67e74705SXin Li   }
718*67e74705SXin Li 
719*67e74705SXin Li   assert(LP);
720*67e74705SXin Li 
721*67e74705SXin Li   // Cache the landing pad on the innermost scope.  If this is a
722*67e74705SXin Li   // non-EH scope, cache the landing pad on the enclosing scope, too.
723*67e74705SXin Li   for (EHScopeStack::iterator ir = EHStack.begin(); true; ++ir) {
724*67e74705SXin Li     ir->setCachedLandingPad(LP);
725*67e74705SXin Li     if (!isNonEHScope(*ir)) break;
726*67e74705SXin Li   }
727*67e74705SXin Li 
728*67e74705SXin Li   return LP;
729*67e74705SXin Li }
730*67e74705SXin Li 
EmitLandingPad()731*67e74705SXin Li llvm::BasicBlock *CodeGenFunction::EmitLandingPad() {
732*67e74705SXin Li   assert(EHStack.requiresLandingPad());
733*67e74705SXin Li 
734*67e74705SXin Li   EHScope &innermostEHScope = *EHStack.find(EHStack.getInnermostEHScope());
735*67e74705SXin Li   switch (innermostEHScope.getKind()) {
736*67e74705SXin Li   case EHScope::Terminate:
737*67e74705SXin Li     return getTerminateLandingPad();
738*67e74705SXin Li 
739*67e74705SXin Li   case EHScope::PadEnd:
740*67e74705SXin Li     llvm_unreachable("PadEnd unnecessary for Itanium!");
741*67e74705SXin Li 
742*67e74705SXin Li   case EHScope::Catch:
743*67e74705SXin Li   case EHScope::Cleanup:
744*67e74705SXin Li   case EHScope::Filter:
745*67e74705SXin Li     if (llvm::BasicBlock *lpad = innermostEHScope.getCachedLandingPad())
746*67e74705SXin Li       return lpad;
747*67e74705SXin Li   }
748*67e74705SXin Li 
749*67e74705SXin Li   // Save the current IR generation state.
750*67e74705SXin Li   CGBuilderTy::InsertPoint savedIP = Builder.saveAndClearIP();
751*67e74705SXin Li   auto DL = ApplyDebugLocation::CreateDefaultArtificial(*this, CurEHLocation);
752*67e74705SXin Li 
753*67e74705SXin Li   // Create and configure the landing pad.
754*67e74705SXin Li   llvm::BasicBlock *lpad = createBasicBlock("lpad");
755*67e74705SXin Li   EmitBlock(lpad);
756*67e74705SXin Li 
757*67e74705SXin Li   llvm::LandingPadInst *LPadInst = Builder.CreateLandingPad(
758*67e74705SXin Li       llvm::StructType::get(Int8PtrTy, Int32Ty, nullptr), 0);
759*67e74705SXin Li 
760*67e74705SXin Li   llvm::Value *LPadExn = Builder.CreateExtractValue(LPadInst, 0);
761*67e74705SXin Li   Builder.CreateStore(LPadExn, getExceptionSlot());
762*67e74705SXin Li   llvm::Value *LPadSel = Builder.CreateExtractValue(LPadInst, 1);
763*67e74705SXin Li   Builder.CreateStore(LPadSel, getEHSelectorSlot());
764*67e74705SXin Li 
765*67e74705SXin Li   // Save the exception pointer.  It's safe to use a single exception
766*67e74705SXin Li   // pointer per function because EH cleanups can never have nested
767*67e74705SXin Li   // try/catches.
768*67e74705SXin Li   // Build the landingpad instruction.
769*67e74705SXin Li 
770*67e74705SXin Li   // Accumulate all the handlers in scope.
771*67e74705SXin Li   bool hasCatchAll = false;
772*67e74705SXin Li   bool hasCleanup = false;
773*67e74705SXin Li   bool hasFilter = false;
774*67e74705SXin Li   SmallVector<llvm::Value*, 4> filterTypes;
775*67e74705SXin Li   llvm::SmallPtrSet<llvm::Value*, 4> catchTypes;
776*67e74705SXin Li   for (EHScopeStack::iterator I = EHStack.begin(), E = EHStack.end(); I != E;
777*67e74705SXin Li        ++I) {
778*67e74705SXin Li 
779*67e74705SXin Li     switch (I->getKind()) {
780*67e74705SXin Li     case EHScope::Cleanup:
781*67e74705SXin Li       // If we have a cleanup, remember that.
782*67e74705SXin Li       hasCleanup = (hasCleanup || cast<EHCleanupScope>(*I).isEHCleanup());
783*67e74705SXin Li       continue;
784*67e74705SXin Li 
785*67e74705SXin Li     case EHScope::Filter: {
786*67e74705SXin Li       assert(I.next() == EHStack.end() && "EH filter is not end of EH stack");
787*67e74705SXin Li       assert(!hasCatchAll && "EH filter reached after catch-all");
788*67e74705SXin Li 
789*67e74705SXin Li       // Filter scopes get added to the landingpad in weird ways.
790*67e74705SXin Li       EHFilterScope &filter = cast<EHFilterScope>(*I);
791*67e74705SXin Li       hasFilter = true;
792*67e74705SXin Li 
793*67e74705SXin Li       // Add all the filter values.
794*67e74705SXin Li       for (unsigned i = 0, e = filter.getNumFilters(); i != e; ++i)
795*67e74705SXin Li         filterTypes.push_back(filter.getFilter(i));
796*67e74705SXin Li       goto done;
797*67e74705SXin Li     }
798*67e74705SXin Li 
799*67e74705SXin Li     case EHScope::Terminate:
800*67e74705SXin Li       // Terminate scopes are basically catch-alls.
801*67e74705SXin Li       assert(!hasCatchAll);
802*67e74705SXin Li       hasCatchAll = true;
803*67e74705SXin Li       goto done;
804*67e74705SXin Li 
805*67e74705SXin Li     case EHScope::Catch:
806*67e74705SXin Li       break;
807*67e74705SXin Li 
808*67e74705SXin Li     case EHScope::PadEnd:
809*67e74705SXin Li       llvm_unreachable("PadEnd unnecessary for Itanium!");
810*67e74705SXin Li     }
811*67e74705SXin Li 
812*67e74705SXin Li     EHCatchScope &catchScope = cast<EHCatchScope>(*I);
813*67e74705SXin Li     for (unsigned hi = 0, he = catchScope.getNumHandlers(); hi != he; ++hi) {
814*67e74705SXin Li       EHCatchScope::Handler handler = catchScope.getHandler(hi);
815*67e74705SXin Li       assert(handler.Type.Flags == 0 &&
816*67e74705SXin Li              "landingpads do not support catch handler flags");
817*67e74705SXin Li 
818*67e74705SXin Li       // If this is a catch-all, register that and abort.
819*67e74705SXin Li       if (!handler.Type.RTTI) {
820*67e74705SXin Li         assert(!hasCatchAll);
821*67e74705SXin Li         hasCatchAll = true;
822*67e74705SXin Li         goto done;
823*67e74705SXin Li       }
824*67e74705SXin Li 
825*67e74705SXin Li       // Check whether we already have a handler for this type.
826*67e74705SXin Li       if (catchTypes.insert(handler.Type.RTTI).second)
827*67e74705SXin Li         // If not, add it directly to the landingpad.
828*67e74705SXin Li         LPadInst->addClause(handler.Type.RTTI);
829*67e74705SXin Li     }
830*67e74705SXin Li   }
831*67e74705SXin Li 
832*67e74705SXin Li  done:
833*67e74705SXin Li   // If we have a catch-all, add null to the landingpad.
834*67e74705SXin Li   assert(!(hasCatchAll && hasFilter));
835*67e74705SXin Li   if (hasCatchAll) {
836*67e74705SXin Li     LPadInst->addClause(getCatchAllValue(*this));
837*67e74705SXin Li 
838*67e74705SXin Li   // If we have an EH filter, we need to add those handlers in the
839*67e74705SXin Li   // right place in the landingpad, which is to say, at the end.
840*67e74705SXin Li   } else if (hasFilter) {
841*67e74705SXin Li     // Create a filter expression: a constant array indicating which filter
842*67e74705SXin Li     // types there are. The personality routine only lands here if the filter
843*67e74705SXin Li     // doesn't match.
844*67e74705SXin Li     SmallVector<llvm::Constant*, 8> Filters;
845*67e74705SXin Li     llvm::ArrayType *AType =
846*67e74705SXin Li       llvm::ArrayType::get(!filterTypes.empty() ?
847*67e74705SXin Li                              filterTypes[0]->getType() : Int8PtrTy,
848*67e74705SXin Li                            filterTypes.size());
849*67e74705SXin Li 
850*67e74705SXin Li     for (unsigned i = 0, e = filterTypes.size(); i != e; ++i)
851*67e74705SXin Li       Filters.push_back(cast<llvm::Constant>(filterTypes[i]));
852*67e74705SXin Li     llvm::Constant *FilterArray = llvm::ConstantArray::get(AType, Filters);
853*67e74705SXin Li     LPadInst->addClause(FilterArray);
854*67e74705SXin Li 
855*67e74705SXin Li     // Also check whether we need a cleanup.
856*67e74705SXin Li     if (hasCleanup)
857*67e74705SXin Li       LPadInst->setCleanup(true);
858*67e74705SXin Li 
859*67e74705SXin Li   // Otherwise, signal that we at least have cleanups.
860*67e74705SXin Li   } else if (hasCleanup) {
861*67e74705SXin Li     LPadInst->setCleanup(true);
862*67e74705SXin Li   }
863*67e74705SXin Li 
864*67e74705SXin Li   assert((LPadInst->getNumClauses() > 0 || LPadInst->isCleanup()) &&
865*67e74705SXin Li          "landingpad instruction has no clauses!");
866*67e74705SXin Li 
867*67e74705SXin Li   // Tell the backend how to generate the landing pad.
868*67e74705SXin Li   Builder.CreateBr(getEHDispatchBlock(EHStack.getInnermostEHScope()));
869*67e74705SXin Li 
870*67e74705SXin Li   // Restore the old IR generation state.
871*67e74705SXin Li   Builder.restoreIP(savedIP);
872*67e74705SXin Li 
873*67e74705SXin Li   return lpad;
874*67e74705SXin Li }
875*67e74705SXin Li 
emitCatchPadBlock(CodeGenFunction & CGF,EHCatchScope & CatchScope)876*67e74705SXin Li static void emitCatchPadBlock(CodeGenFunction &CGF, EHCatchScope &CatchScope) {
877*67e74705SXin Li   llvm::BasicBlock *DispatchBlock = CatchScope.getCachedEHDispatchBlock();
878*67e74705SXin Li   assert(DispatchBlock);
879*67e74705SXin Li 
880*67e74705SXin Li   CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveIP();
881*67e74705SXin Li   CGF.EmitBlockAfterUses(DispatchBlock);
882*67e74705SXin Li 
883*67e74705SXin Li   llvm::Value *ParentPad = CGF.CurrentFuncletPad;
884*67e74705SXin Li   if (!ParentPad)
885*67e74705SXin Li     ParentPad = llvm::ConstantTokenNone::get(CGF.getLLVMContext());
886*67e74705SXin Li   llvm::BasicBlock *UnwindBB =
887*67e74705SXin Li       CGF.getEHDispatchBlock(CatchScope.getEnclosingEHScope());
888*67e74705SXin Li 
889*67e74705SXin Li   unsigned NumHandlers = CatchScope.getNumHandlers();
890*67e74705SXin Li   llvm::CatchSwitchInst *CatchSwitch =
891*67e74705SXin Li       CGF.Builder.CreateCatchSwitch(ParentPad, UnwindBB, NumHandlers);
892*67e74705SXin Li 
893*67e74705SXin Li   // Test against each of the exception types we claim to catch.
894*67e74705SXin Li   for (unsigned I = 0; I < NumHandlers; ++I) {
895*67e74705SXin Li     const EHCatchScope::Handler &Handler = CatchScope.getHandler(I);
896*67e74705SXin Li 
897*67e74705SXin Li     CatchTypeInfo TypeInfo = Handler.Type;
898*67e74705SXin Li     if (!TypeInfo.RTTI)
899*67e74705SXin Li       TypeInfo.RTTI = llvm::Constant::getNullValue(CGF.VoidPtrTy);
900*67e74705SXin Li 
901*67e74705SXin Li     CGF.Builder.SetInsertPoint(Handler.Block);
902*67e74705SXin Li 
903*67e74705SXin Li     if (EHPersonality::get(CGF).isMSVCXXPersonality()) {
904*67e74705SXin Li       CGF.Builder.CreateCatchPad(
905*67e74705SXin Li           CatchSwitch, {TypeInfo.RTTI, CGF.Builder.getInt32(TypeInfo.Flags),
906*67e74705SXin Li                         llvm::Constant::getNullValue(CGF.VoidPtrTy)});
907*67e74705SXin Li     } else {
908*67e74705SXin Li       CGF.Builder.CreateCatchPad(CatchSwitch, {TypeInfo.RTTI});
909*67e74705SXin Li     }
910*67e74705SXin Li 
911*67e74705SXin Li     CatchSwitch->addHandler(Handler.Block);
912*67e74705SXin Li   }
913*67e74705SXin Li   CGF.Builder.restoreIP(SavedIP);
914*67e74705SXin Li }
915*67e74705SXin Li 
916*67e74705SXin Li /// Emit the structure of the dispatch block for the given catch scope.
917*67e74705SXin Li /// It is an invariant that the dispatch block already exists.
emitCatchDispatchBlock(CodeGenFunction & CGF,EHCatchScope & catchScope)918*67e74705SXin Li static void emitCatchDispatchBlock(CodeGenFunction &CGF,
919*67e74705SXin Li                                    EHCatchScope &catchScope) {
920*67e74705SXin Li   if (EHPersonality::get(CGF).usesFuncletPads())
921*67e74705SXin Li     return emitCatchPadBlock(CGF, catchScope);
922*67e74705SXin Li 
923*67e74705SXin Li   llvm::BasicBlock *dispatchBlock = catchScope.getCachedEHDispatchBlock();
924*67e74705SXin Li   assert(dispatchBlock);
925*67e74705SXin Li 
926*67e74705SXin Li   // If there's only a single catch-all, getEHDispatchBlock returned
927*67e74705SXin Li   // that catch-all as the dispatch block.
928*67e74705SXin Li   if (catchScope.getNumHandlers() == 1 &&
929*67e74705SXin Li       catchScope.getHandler(0).isCatchAll()) {
930*67e74705SXin Li     assert(dispatchBlock == catchScope.getHandler(0).Block);
931*67e74705SXin Li     return;
932*67e74705SXin Li   }
933*67e74705SXin Li 
934*67e74705SXin Li   CGBuilderTy::InsertPoint savedIP = CGF.Builder.saveIP();
935*67e74705SXin Li   CGF.EmitBlockAfterUses(dispatchBlock);
936*67e74705SXin Li 
937*67e74705SXin Li   // Select the right handler.
938*67e74705SXin Li   llvm::Value *llvm_eh_typeid_for =
939*67e74705SXin Li     CGF.CGM.getIntrinsic(llvm::Intrinsic::eh_typeid_for);
940*67e74705SXin Li 
941*67e74705SXin Li   // Load the selector value.
942*67e74705SXin Li   llvm::Value *selector = CGF.getSelectorFromSlot();
943*67e74705SXin Li 
944*67e74705SXin Li   // Test against each of the exception types we claim to catch.
945*67e74705SXin Li   for (unsigned i = 0, e = catchScope.getNumHandlers(); ; ++i) {
946*67e74705SXin Li     assert(i < e && "ran off end of handlers!");
947*67e74705SXin Li     const EHCatchScope::Handler &handler = catchScope.getHandler(i);
948*67e74705SXin Li 
949*67e74705SXin Li     llvm::Value *typeValue = handler.Type.RTTI;
950*67e74705SXin Li     assert(handler.Type.Flags == 0 &&
951*67e74705SXin Li            "landingpads do not support catch handler flags");
952*67e74705SXin Li     assert(typeValue && "fell into catch-all case!");
953*67e74705SXin Li     typeValue = CGF.Builder.CreateBitCast(typeValue, CGF.Int8PtrTy);
954*67e74705SXin Li 
955*67e74705SXin Li     // Figure out the next block.
956*67e74705SXin Li     bool nextIsEnd;
957*67e74705SXin Li     llvm::BasicBlock *nextBlock;
958*67e74705SXin Li 
959*67e74705SXin Li     // If this is the last handler, we're at the end, and the next
960*67e74705SXin Li     // block is the block for the enclosing EH scope.
961*67e74705SXin Li     if (i + 1 == e) {
962*67e74705SXin Li       nextBlock = CGF.getEHDispatchBlock(catchScope.getEnclosingEHScope());
963*67e74705SXin Li       nextIsEnd = true;
964*67e74705SXin Li 
965*67e74705SXin Li     // If the next handler is a catch-all, we're at the end, and the
966*67e74705SXin Li     // next block is that handler.
967*67e74705SXin Li     } else if (catchScope.getHandler(i+1).isCatchAll()) {
968*67e74705SXin Li       nextBlock = catchScope.getHandler(i+1).Block;
969*67e74705SXin Li       nextIsEnd = true;
970*67e74705SXin Li 
971*67e74705SXin Li     // Otherwise, we're not at the end and we need a new block.
972*67e74705SXin Li     } else {
973*67e74705SXin Li       nextBlock = CGF.createBasicBlock("catch.fallthrough");
974*67e74705SXin Li       nextIsEnd = false;
975*67e74705SXin Li     }
976*67e74705SXin Li 
977*67e74705SXin Li     // Figure out the catch type's index in the LSDA's type table.
978*67e74705SXin Li     llvm::CallInst *typeIndex =
979*67e74705SXin Li       CGF.Builder.CreateCall(llvm_eh_typeid_for, typeValue);
980*67e74705SXin Li     typeIndex->setDoesNotThrow();
981*67e74705SXin Li 
982*67e74705SXin Li     llvm::Value *matchesTypeIndex =
983*67e74705SXin Li       CGF.Builder.CreateICmpEQ(selector, typeIndex, "matches");
984*67e74705SXin Li     CGF.Builder.CreateCondBr(matchesTypeIndex, handler.Block, nextBlock);
985*67e74705SXin Li 
986*67e74705SXin Li     // If the next handler is a catch-all, we're completely done.
987*67e74705SXin Li     if (nextIsEnd) {
988*67e74705SXin Li       CGF.Builder.restoreIP(savedIP);
989*67e74705SXin Li       return;
990*67e74705SXin Li     }
991*67e74705SXin Li     // Otherwise we need to emit and continue at that block.
992*67e74705SXin Li     CGF.EmitBlock(nextBlock);
993*67e74705SXin Li   }
994*67e74705SXin Li }
995*67e74705SXin Li 
popCatchScope()996*67e74705SXin Li void CodeGenFunction::popCatchScope() {
997*67e74705SXin Li   EHCatchScope &catchScope = cast<EHCatchScope>(*EHStack.begin());
998*67e74705SXin Li   if (catchScope.hasEHBranches())
999*67e74705SXin Li     emitCatchDispatchBlock(*this, catchScope);
1000*67e74705SXin Li   EHStack.popCatch();
1001*67e74705SXin Li }
1002*67e74705SXin Li 
ExitCXXTryStmt(const CXXTryStmt & S,bool IsFnTryBlock)1003*67e74705SXin Li void CodeGenFunction::ExitCXXTryStmt(const CXXTryStmt &S, bool IsFnTryBlock) {
1004*67e74705SXin Li   unsigned NumHandlers = S.getNumHandlers();
1005*67e74705SXin Li   EHCatchScope &CatchScope = cast<EHCatchScope>(*EHStack.begin());
1006*67e74705SXin Li   assert(CatchScope.getNumHandlers() == NumHandlers);
1007*67e74705SXin Li 
1008*67e74705SXin Li   // If the catch was not required, bail out now.
1009*67e74705SXin Li   if (!CatchScope.hasEHBranches()) {
1010*67e74705SXin Li     CatchScope.clearHandlerBlocks();
1011*67e74705SXin Li     EHStack.popCatch();
1012*67e74705SXin Li     return;
1013*67e74705SXin Li   }
1014*67e74705SXin Li 
1015*67e74705SXin Li   // Emit the structure of the EH dispatch for this catch.
1016*67e74705SXin Li   emitCatchDispatchBlock(*this, CatchScope);
1017*67e74705SXin Li 
1018*67e74705SXin Li   // Copy the handler blocks off before we pop the EH stack.  Emitting
1019*67e74705SXin Li   // the handlers might scribble on this memory.
1020*67e74705SXin Li   SmallVector<EHCatchScope::Handler, 8> Handlers(
1021*67e74705SXin Li       CatchScope.begin(), CatchScope.begin() + NumHandlers);
1022*67e74705SXin Li 
1023*67e74705SXin Li   EHStack.popCatch();
1024*67e74705SXin Li 
1025*67e74705SXin Li   // The fall-through block.
1026*67e74705SXin Li   llvm::BasicBlock *ContBB = createBasicBlock("try.cont");
1027*67e74705SXin Li 
1028*67e74705SXin Li   // We just emitted the body of the try; jump to the continue block.
1029*67e74705SXin Li   if (HaveInsertPoint())
1030*67e74705SXin Li     Builder.CreateBr(ContBB);
1031*67e74705SXin Li 
1032*67e74705SXin Li   // Determine if we need an implicit rethrow for all these catch handlers;
1033*67e74705SXin Li   // see the comment below.
1034*67e74705SXin Li   bool doImplicitRethrow = false;
1035*67e74705SXin Li   if (IsFnTryBlock)
1036*67e74705SXin Li     doImplicitRethrow = isa<CXXDestructorDecl>(CurCodeDecl) ||
1037*67e74705SXin Li                         isa<CXXConstructorDecl>(CurCodeDecl);
1038*67e74705SXin Li 
1039*67e74705SXin Li   // Perversely, we emit the handlers backwards precisely because we
1040*67e74705SXin Li   // want them to appear in source order.  In all of these cases, the
1041*67e74705SXin Li   // catch block will have exactly one predecessor, which will be a
1042*67e74705SXin Li   // particular block in the catch dispatch.  However, in the case of
1043*67e74705SXin Li   // a catch-all, one of the dispatch blocks will branch to two
1044*67e74705SXin Li   // different handlers, and EmitBlockAfterUses will cause the second
1045*67e74705SXin Li   // handler to be moved before the first.
1046*67e74705SXin Li   for (unsigned I = NumHandlers; I != 0; --I) {
1047*67e74705SXin Li     llvm::BasicBlock *CatchBlock = Handlers[I-1].Block;
1048*67e74705SXin Li     EmitBlockAfterUses(CatchBlock);
1049*67e74705SXin Li 
1050*67e74705SXin Li     // Catch the exception if this isn't a catch-all.
1051*67e74705SXin Li     const CXXCatchStmt *C = S.getHandler(I-1);
1052*67e74705SXin Li 
1053*67e74705SXin Li     // Enter a cleanup scope, including the catch variable and the
1054*67e74705SXin Li     // end-catch.
1055*67e74705SXin Li     RunCleanupsScope CatchScope(*this);
1056*67e74705SXin Li 
1057*67e74705SXin Li     // Initialize the catch variable and set up the cleanups.
1058*67e74705SXin Li     SaveAndRestore<llvm::Instruction *> RestoreCurrentFuncletPad(
1059*67e74705SXin Li         CurrentFuncletPad);
1060*67e74705SXin Li     CGM.getCXXABI().emitBeginCatch(*this, C);
1061*67e74705SXin Li 
1062*67e74705SXin Li     // Emit the PGO counter increment.
1063*67e74705SXin Li     incrementProfileCounter(C);
1064*67e74705SXin Li 
1065*67e74705SXin Li     // Perform the body of the catch.
1066*67e74705SXin Li     EmitStmt(C->getHandlerBlock());
1067*67e74705SXin Li 
1068*67e74705SXin Li     // [except.handle]p11:
1069*67e74705SXin Li     //   The currently handled exception is rethrown if control
1070*67e74705SXin Li     //   reaches the end of a handler of the function-try-block of a
1071*67e74705SXin Li     //   constructor or destructor.
1072*67e74705SXin Li 
1073*67e74705SXin Li     // It is important that we only do this on fallthrough and not on
1074*67e74705SXin Li     // return.  Note that it's illegal to put a return in a
1075*67e74705SXin Li     // constructor function-try-block's catch handler (p14), so this
1076*67e74705SXin Li     // really only applies to destructors.
1077*67e74705SXin Li     if (doImplicitRethrow && HaveInsertPoint()) {
1078*67e74705SXin Li       CGM.getCXXABI().emitRethrow(*this, /*isNoReturn*/false);
1079*67e74705SXin Li       Builder.CreateUnreachable();
1080*67e74705SXin Li       Builder.ClearInsertionPoint();
1081*67e74705SXin Li     }
1082*67e74705SXin Li 
1083*67e74705SXin Li     // Fall out through the catch cleanups.
1084*67e74705SXin Li     CatchScope.ForceCleanup();
1085*67e74705SXin Li 
1086*67e74705SXin Li     // Branch out of the try.
1087*67e74705SXin Li     if (HaveInsertPoint())
1088*67e74705SXin Li       Builder.CreateBr(ContBB);
1089*67e74705SXin Li   }
1090*67e74705SXin Li 
1091*67e74705SXin Li   EmitBlock(ContBB);
1092*67e74705SXin Li   incrementProfileCounter(&S);
1093*67e74705SXin Li }
1094*67e74705SXin Li 
1095*67e74705SXin Li namespace {
1096*67e74705SXin Li   struct CallEndCatchForFinally final : EHScopeStack::Cleanup {
1097*67e74705SXin Li     llvm::Value *ForEHVar;
1098*67e74705SXin Li     llvm::Value *EndCatchFn;
CallEndCatchForFinally__anonaa838d2f0211::CallEndCatchForFinally1099*67e74705SXin Li     CallEndCatchForFinally(llvm::Value *ForEHVar, llvm::Value *EndCatchFn)
1100*67e74705SXin Li       : ForEHVar(ForEHVar), EndCatchFn(EndCatchFn) {}
1101*67e74705SXin Li 
Emit__anonaa838d2f0211::CallEndCatchForFinally1102*67e74705SXin Li     void Emit(CodeGenFunction &CGF, Flags flags) override {
1103*67e74705SXin Li       llvm::BasicBlock *EndCatchBB = CGF.createBasicBlock("finally.endcatch");
1104*67e74705SXin Li       llvm::BasicBlock *CleanupContBB =
1105*67e74705SXin Li         CGF.createBasicBlock("finally.cleanup.cont");
1106*67e74705SXin Li 
1107*67e74705SXin Li       llvm::Value *ShouldEndCatch =
1108*67e74705SXin Li         CGF.Builder.CreateFlagLoad(ForEHVar, "finally.endcatch");
1109*67e74705SXin Li       CGF.Builder.CreateCondBr(ShouldEndCatch, EndCatchBB, CleanupContBB);
1110*67e74705SXin Li       CGF.EmitBlock(EndCatchBB);
1111*67e74705SXin Li       CGF.EmitRuntimeCallOrInvoke(EndCatchFn); // catch-all, so might throw
1112*67e74705SXin Li       CGF.EmitBlock(CleanupContBB);
1113*67e74705SXin Li     }
1114*67e74705SXin Li   };
1115*67e74705SXin Li 
1116*67e74705SXin Li   struct PerformFinally final : EHScopeStack::Cleanup {
1117*67e74705SXin Li     const Stmt *Body;
1118*67e74705SXin Li     llvm::Value *ForEHVar;
1119*67e74705SXin Li     llvm::Value *EndCatchFn;
1120*67e74705SXin Li     llvm::Value *RethrowFn;
1121*67e74705SXin Li     llvm::Value *SavedExnVar;
1122*67e74705SXin Li 
PerformFinally__anonaa838d2f0211::PerformFinally1123*67e74705SXin Li     PerformFinally(const Stmt *Body, llvm::Value *ForEHVar,
1124*67e74705SXin Li                    llvm::Value *EndCatchFn,
1125*67e74705SXin Li                    llvm::Value *RethrowFn, llvm::Value *SavedExnVar)
1126*67e74705SXin Li       : Body(Body), ForEHVar(ForEHVar), EndCatchFn(EndCatchFn),
1127*67e74705SXin Li         RethrowFn(RethrowFn), SavedExnVar(SavedExnVar) {}
1128*67e74705SXin Li 
Emit__anonaa838d2f0211::PerformFinally1129*67e74705SXin Li     void Emit(CodeGenFunction &CGF, Flags flags) override {
1130*67e74705SXin Li       // Enter a cleanup to call the end-catch function if one was provided.
1131*67e74705SXin Li       if (EndCatchFn)
1132*67e74705SXin Li         CGF.EHStack.pushCleanup<CallEndCatchForFinally>(NormalAndEHCleanup,
1133*67e74705SXin Li                                                         ForEHVar, EndCatchFn);
1134*67e74705SXin Li 
1135*67e74705SXin Li       // Save the current cleanup destination in case there are
1136*67e74705SXin Li       // cleanups in the finally block.
1137*67e74705SXin Li       llvm::Value *SavedCleanupDest =
1138*67e74705SXin Li         CGF.Builder.CreateLoad(CGF.getNormalCleanupDestSlot(),
1139*67e74705SXin Li                                "cleanup.dest.saved");
1140*67e74705SXin Li 
1141*67e74705SXin Li       // Emit the finally block.
1142*67e74705SXin Li       CGF.EmitStmt(Body);
1143*67e74705SXin Li 
1144*67e74705SXin Li       // If the end of the finally is reachable, check whether this was
1145*67e74705SXin Li       // for EH.  If so, rethrow.
1146*67e74705SXin Li       if (CGF.HaveInsertPoint()) {
1147*67e74705SXin Li         llvm::BasicBlock *RethrowBB = CGF.createBasicBlock("finally.rethrow");
1148*67e74705SXin Li         llvm::BasicBlock *ContBB = CGF.createBasicBlock("finally.cont");
1149*67e74705SXin Li 
1150*67e74705SXin Li         llvm::Value *ShouldRethrow =
1151*67e74705SXin Li           CGF.Builder.CreateFlagLoad(ForEHVar, "finally.shouldthrow");
1152*67e74705SXin Li         CGF.Builder.CreateCondBr(ShouldRethrow, RethrowBB, ContBB);
1153*67e74705SXin Li 
1154*67e74705SXin Li         CGF.EmitBlock(RethrowBB);
1155*67e74705SXin Li         if (SavedExnVar) {
1156*67e74705SXin Li           CGF.EmitRuntimeCallOrInvoke(RethrowFn,
1157*67e74705SXin Li             CGF.Builder.CreateAlignedLoad(SavedExnVar, CGF.getPointerAlign()));
1158*67e74705SXin Li         } else {
1159*67e74705SXin Li           CGF.EmitRuntimeCallOrInvoke(RethrowFn);
1160*67e74705SXin Li         }
1161*67e74705SXin Li         CGF.Builder.CreateUnreachable();
1162*67e74705SXin Li 
1163*67e74705SXin Li         CGF.EmitBlock(ContBB);
1164*67e74705SXin Li 
1165*67e74705SXin Li         // Restore the cleanup destination.
1166*67e74705SXin Li         CGF.Builder.CreateStore(SavedCleanupDest,
1167*67e74705SXin Li                                 CGF.getNormalCleanupDestSlot());
1168*67e74705SXin Li       }
1169*67e74705SXin Li 
1170*67e74705SXin Li       // Leave the end-catch cleanup.  As an optimization, pretend that
1171*67e74705SXin Li       // the fallthrough path was inaccessible; we've dynamically proven
1172*67e74705SXin Li       // that we're not in the EH case along that path.
1173*67e74705SXin Li       if (EndCatchFn) {
1174*67e74705SXin Li         CGBuilderTy::InsertPoint SavedIP = CGF.Builder.saveAndClearIP();
1175*67e74705SXin Li         CGF.PopCleanupBlock();
1176*67e74705SXin Li         CGF.Builder.restoreIP(SavedIP);
1177*67e74705SXin Li       }
1178*67e74705SXin Li 
1179*67e74705SXin Li       // Now make sure we actually have an insertion point or the
1180*67e74705SXin Li       // cleanup gods will hate us.
1181*67e74705SXin Li       CGF.EnsureInsertPoint();
1182*67e74705SXin Li     }
1183*67e74705SXin Li   };
1184*67e74705SXin Li } // end anonymous namespace
1185*67e74705SXin Li 
1186*67e74705SXin Li /// Enters a finally block for an implementation using zero-cost
1187*67e74705SXin Li /// exceptions.  This is mostly general, but hard-codes some
1188*67e74705SXin Li /// language/ABI-specific behavior in the catch-all sections.
enter(CodeGenFunction & CGF,const Stmt * body,llvm::Constant * beginCatchFn,llvm::Constant * endCatchFn,llvm::Constant * rethrowFn)1189*67e74705SXin Li void CodeGenFunction::FinallyInfo::enter(CodeGenFunction &CGF,
1190*67e74705SXin Li                                          const Stmt *body,
1191*67e74705SXin Li                                          llvm::Constant *beginCatchFn,
1192*67e74705SXin Li                                          llvm::Constant *endCatchFn,
1193*67e74705SXin Li                                          llvm::Constant *rethrowFn) {
1194*67e74705SXin Li   assert((beginCatchFn != nullptr) == (endCatchFn != nullptr) &&
1195*67e74705SXin Li          "begin/end catch functions not paired");
1196*67e74705SXin Li   assert(rethrowFn && "rethrow function is required");
1197*67e74705SXin Li 
1198*67e74705SXin Li   BeginCatchFn = beginCatchFn;
1199*67e74705SXin Li 
1200*67e74705SXin Li   // The rethrow function has one of the following two types:
1201*67e74705SXin Li   //   void (*)()
1202*67e74705SXin Li   //   void (*)(void*)
1203*67e74705SXin Li   // In the latter case we need to pass it the exception object.
1204*67e74705SXin Li   // But we can't use the exception slot because the @finally might
1205*67e74705SXin Li   // have a landing pad (which would overwrite the exception slot).
1206*67e74705SXin Li   llvm::FunctionType *rethrowFnTy =
1207*67e74705SXin Li     cast<llvm::FunctionType>(
1208*67e74705SXin Li       cast<llvm::PointerType>(rethrowFn->getType())->getElementType());
1209*67e74705SXin Li   SavedExnVar = nullptr;
1210*67e74705SXin Li   if (rethrowFnTy->getNumParams())
1211*67e74705SXin Li     SavedExnVar = CGF.CreateTempAlloca(CGF.Int8PtrTy, "finally.exn");
1212*67e74705SXin Li 
1213*67e74705SXin Li   // A finally block is a statement which must be executed on any edge
1214*67e74705SXin Li   // out of a given scope.  Unlike a cleanup, the finally block may
1215*67e74705SXin Li   // contain arbitrary control flow leading out of itself.  In
1216*67e74705SXin Li   // addition, finally blocks should always be executed, even if there
1217*67e74705SXin Li   // are no catch handlers higher on the stack.  Therefore, we
1218*67e74705SXin Li   // surround the protected scope with a combination of a normal
1219*67e74705SXin Li   // cleanup (to catch attempts to break out of the block via normal
1220*67e74705SXin Li   // control flow) and an EH catch-all (semantically "outside" any try
1221*67e74705SXin Li   // statement to which the finally block might have been attached).
1222*67e74705SXin Li   // The finally block itself is generated in the context of a cleanup
1223*67e74705SXin Li   // which conditionally leaves the catch-all.
1224*67e74705SXin Li 
1225*67e74705SXin Li   // Jump destination for performing the finally block on an exception
1226*67e74705SXin Li   // edge.  We'll never actually reach this block, so unreachable is
1227*67e74705SXin Li   // fine.
1228*67e74705SXin Li   RethrowDest = CGF.getJumpDestInCurrentScope(CGF.getUnreachableBlock());
1229*67e74705SXin Li 
1230*67e74705SXin Li   // Whether the finally block is being executed for EH purposes.
1231*67e74705SXin Li   ForEHVar = CGF.CreateTempAlloca(CGF.Builder.getInt1Ty(), "finally.for-eh");
1232*67e74705SXin Li   CGF.Builder.CreateFlagStore(false, ForEHVar);
1233*67e74705SXin Li 
1234*67e74705SXin Li   // Enter a normal cleanup which will perform the @finally block.
1235*67e74705SXin Li   CGF.EHStack.pushCleanup<PerformFinally>(NormalCleanup, body,
1236*67e74705SXin Li                                           ForEHVar, endCatchFn,
1237*67e74705SXin Li                                           rethrowFn, SavedExnVar);
1238*67e74705SXin Li 
1239*67e74705SXin Li   // Enter a catch-all scope.
1240*67e74705SXin Li   llvm::BasicBlock *catchBB = CGF.createBasicBlock("finally.catchall");
1241*67e74705SXin Li   EHCatchScope *catchScope = CGF.EHStack.pushCatch(1);
1242*67e74705SXin Li   catchScope->setCatchAllHandler(0, catchBB);
1243*67e74705SXin Li }
1244*67e74705SXin Li 
exit(CodeGenFunction & CGF)1245*67e74705SXin Li void CodeGenFunction::FinallyInfo::exit(CodeGenFunction &CGF) {
1246*67e74705SXin Li   // Leave the finally catch-all.
1247*67e74705SXin Li   EHCatchScope &catchScope = cast<EHCatchScope>(*CGF.EHStack.begin());
1248*67e74705SXin Li   llvm::BasicBlock *catchBB = catchScope.getHandler(0).Block;
1249*67e74705SXin Li 
1250*67e74705SXin Li   CGF.popCatchScope();
1251*67e74705SXin Li 
1252*67e74705SXin Li   // If there are any references to the catch-all block, emit it.
1253*67e74705SXin Li   if (catchBB->use_empty()) {
1254*67e74705SXin Li     delete catchBB;
1255*67e74705SXin Li   } else {
1256*67e74705SXin Li     CGBuilderTy::InsertPoint savedIP = CGF.Builder.saveAndClearIP();
1257*67e74705SXin Li     CGF.EmitBlock(catchBB);
1258*67e74705SXin Li 
1259*67e74705SXin Li     llvm::Value *exn = nullptr;
1260*67e74705SXin Li 
1261*67e74705SXin Li     // If there's a begin-catch function, call it.
1262*67e74705SXin Li     if (BeginCatchFn) {
1263*67e74705SXin Li       exn = CGF.getExceptionFromSlot();
1264*67e74705SXin Li       CGF.EmitNounwindRuntimeCall(BeginCatchFn, exn);
1265*67e74705SXin Li     }
1266*67e74705SXin Li 
1267*67e74705SXin Li     // If we need to remember the exception pointer to rethrow later, do so.
1268*67e74705SXin Li     if (SavedExnVar) {
1269*67e74705SXin Li       if (!exn) exn = CGF.getExceptionFromSlot();
1270*67e74705SXin Li       CGF.Builder.CreateAlignedStore(exn, SavedExnVar, CGF.getPointerAlign());
1271*67e74705SXin Li     }
1272*67e74705SXin Li 
1273*67e74705SXin Li     // Tell the cleanups in the finally block that we're do this for EH.
1274*67e74705SXin Li     CGF.Builder.CreateFlagStore(true, ForEHVar);
1275*67e74705SXin Li 
1276*67e74705SXin Li     // Thread a jump through the finally cleanup.
1277*67e74705SXin Li     CGF.EmitBranchThroughCleanup(RethrowDest);
1278*67e74705SXin Li 
1279*67e74705SXin Li     CGF.Builder.restoreIP(savedIP);
1280*67e74705SXin Li   }
1281*67e74705SXin Li 
1282*67e74705SXin Li   // Finally, leave the @finally cleanup.
1283*67e74705SXin Li   CGF.PopCleanupBlock();
1284*67e74705SXin Li }
1285*67e74705SXin Li 
getTerminateLandingPad()1286*67e74705SXin Li llvm::BasicBlock *CodeGenFunction::getTerminateLandingPad() {
1287*67e74705SXin Li   if (TerminateLandingPad)
1288*67e74705SXin Li     return TerminateLandingPad;
1289*67e74705SXin Li 
1290*67e74705SXin Li   CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
1291*67e74705SXin Li 
1292*67e74705SXin Li   // This will get inserted at the end of the function.
1293*67e74705SXin Li   TerminateLandingPad = createBasicBlock("terminate.lpad");
1294*67e74705SXin Li   Builder.SetInsertPoint(TerminateLandingPad);
1295*67e74705SXin Li 
1296*67e74705SXin Li   // Tell the backend that this is a landing pad.
1297*67e74705SXin Li   const EHPersonality &Personality = EHPersonality::get(*this);
1298*67e74705SXin Li 
1299*67e74705SXin Li   if (!CurFn->hasPersonalityFn())
1300*67e74705SXin Li     CurFn->setPersonalityFn(getOpaquePersonalityFn(CGM, Personality));
1301*67e74705SXin Li 
1302*67e74705SXin Li   llvm::LandingPadInst *LPadInst = Builder.CreateLandingPad(
1303*67e74705SXin Li       llvm::StructType::get(Int8PtrTy, Int32Ty, nullptr), 0);
1304*67e74705SXin Li   LPadInst->addClause(getCatchAllValue(*this));
1305*67e74705SXin Li 
1306*67e74705SXin Li   llvm::Value *Exn = nullptr;
1307*67e74705SXin Li   if (getLangOpts().CPlusPlus)
1308*67e74705SXin Li     Exn = Builder.CreateExtractValue(LPadInst, 0);
1309*67e74705SXin Li   llvm::CallInst *terminateCall =
1310*67e74705SXin Li       CGM.getCXXABI().emitTerminateForUnexpectedException(*this, Exn);
1311*67e74705SXin Li   terminateCall->setDoesNotReturn();
1312*67e74705SXin Li   Builder.CreateUnreachable();
1313*67e74705SXin Li 
1314*67e74705SXin Li   // Restore the saved insertion state.
1315*67e74705SXin Li   Builder.restoreIP(SavedIP);
1316*67e74705SXin Li 
1317*67e74705SXin Li   return TerminateLandingPad;
1318*67e74705SXin Li }
1319*67e74705SXin Li 
getTerminateHandler()1320*67e74705SXin Li llvm::BasicBlock *CodeGenFunction::getTerminateHandler() {
1321*67e74705SXin Li   if (TerminateHandler)
1322*67e74705SXin Li     return TerminateHandler;
1323*67e74705SXin Li 
1324*67e74705SXin Li   CGBuilderTy::InsertPoint SavedIP = Builder.saveAndClearIP();
1325*67e74705SXin Li 
1326*67e74705SXin Li   // Set up the terminate handler.  This block is inserted at the very
1327*67e74705SXin Li   // end of the function by FinishFunction.
1328*67e74705SXin Li   TerminateHandler = createBasicBlock("terminate.handler");
1329*67e74705SXin Li   Builder.SetInsertPoint(TerminateHandler);
1330*67e74705SXin Li   llvm::Value *Exn = nullptr;
1331*67e74705SXin Li   SaveAndRestore<llvm::Instruction *> RestoreCurrentFuncletPad(
1332*67e74705SXin Li       CurrentFuncletPad);
1333*67e74705SXin Li   if (EHPersonality::get(*this).usesFuncletPads()) {
1334*67e74705SXin Li     llvm::Value *ParentPad = CurrentFuncletPad;
1335*67e74705SXin Li     if (!ParentPad)
1336*67e74705SXin Li       ParentPad = llvm::ConstantTokenNone::get(CGM.getLLVMContext());
1337*67e74705SXin Li     CurrentFuncletPad = Builder.CreateCleanupPad(ParentPad);
1338*67e74705SXin Li   } else {
1339*67e74705SXin Li     if (getLangOpts().CPlusPlus)
1340*67e74705SXin Li       Exn = getExceptionFromSlot();
1341*67e74705SXin Li   }
1342*67e74705SXin Li   llvm::CallInst *terminateCall =
1343*67e74705SXin Li       CGM.getCXXABI().emitTerminateForUnexpectedException(*this, Exn);
1344*67e74705SXin Li   terminateCall->setDoesNotReturn();
1345*67e74705SXin Li   Builder.CreateUnreachable();
1346*67e74705SXin Li 
1347*67e74705SXin Li   // Restore the saved insertion state.
1348*67e74705SXin Li   Builder.restoreIP(SavedIP);
1349*67e74705SXin Li 
1350*67e74705SXin Li   return TerminateHandler;
1351*67e74705SXin Li }
1352*67e74705SXin Li 
getEHResumeBlock(bool isCleanup)1353*67e74705SXin Li llvm::BasicBlock *CodeGenFunction::getEHResumeBlock(bool isCleanup) {
1354*67e74705SXin Li   if (EHResumeBlock) return EHResumeBlock;
1355*67e74705SXin Li 
1356*67e74705SXin Li   CGBuilderTy::InsertPoint SavedIP = Builder.saveIP();
1357*67e74705SXin Li 
1358*67e74705SXin Li   // We emit a jump to a notional label at the outermost unwind state.
1359*67e74705SXin Li   EHResumeBlock = createBasicBlock("eh.resume");
1360*67e74705SXin Li   Builder.SetInsertPoint(EHResumeBlock);
1361*67e74705SXin Li 
1362*67e74705SXin Li   const EHPersonality &Personality = EHPersonality::get(*this);
1363*67e74705SXin Li 
1364*67e74705SXin Li   // This can always be a call because we necessarily didn't find
1365*67e74705SXin Li   // anything on the EH stack which needs our help.
1366*67e74705SXin Li   const char *RethrowName = Personality.CatchallRethrowFn;
1367*67e74705SXin Li   if (RethrowName != nullptr && !isCleanup) {
1368*67e74705SXin Li     EmitRuntimeCall(getCatchallRethrowFn(CGM, RethrowName),
1369*67e74705SXin Li                     getExceptionFromSlot())->setDoesNotReturn();
1370*67e74705SXin Li     Builder.CreateUnreachable();
1371*67e74705SXin Li     Builder.restoreIP(SavedIP);
1372*67e74705SXin Li     return EHResumeBlock;
1373*67e74705SXin Li   }
1374*67e74705SXin Li 
1375*67e74705SXin Li   // Recreate the landingpad's return value for the 'resume' instruction.
1376*67e74705SXin Li   llvm::Value *Exn = getExceptionFromSlot();
1377*67e74705SXin Li   llvm::Value *Sel = getSelectorFromSlot();
1378*67e74705SXin Li 
1379*67e74705SXin Li   llvm::Type *LPadType = llvm::StructType::get(Exn->getType(),
1380*67e74705SXin Li                                                Sel->getType(), nullptr);
1381*67e74705SXin Li   llvm::Value *LPadVal = llvm::UndefValue::get(LPadType);
1382*67e74705SXin Li   LPadVal = Builder.CreateInsertValue(LPadVal, Exn, 0, "lpad.val");
1383*67e74705SXin Li   LPadVal = Builder.CreateInsertValue(LPadVal, Sel, 1, "lpad.val");
1384*67e74705SXin Li 
1385*67e74705SXin Li   Builder.CreateResume(LPadVal);
1386*67e74705SXin Li   Builder.restoreIP(SavedIP);
1387*67e74705SXin Li   return EHResumeBlock;
1388*67e74705SXin Li }
1389*67e74705SXin Li 
EmitSEHTryStmt(const SEHTryStmt & S)1390*67e74705SXin Li void CodeGenFunction::EmitSEHTryStmt(const SEHTryStmt &S) {
1391*67e74705SXin Li   EnterSEHTryStmt(S);
1392*67e74705SXin Li   {
1393*67e74705SXin Li     JumpDest TryExit = getJumpDestInCurrentScope("__try.__leave");
1394*67e74705SXin Li 
1395*67e74705SXin Li     SEHTryEpilogueStack.push_back(&TryExit);
1396*67e74705SXin Li     EmitStmt(S.getTryBlock());
1397*67e74705SXin Li     SEHTryEpilogueStack.pop_back();
1398*67e74705SXin Li 
1399*67e74705SXin Li     if (!TryExit.getBlock()->use_empty())
1400*67e74705SXin Li       EmitBlock(TryExit.getBlock(), /*IsFinished=*/true);
1401*67e74705SXin Li     else
1402*67e74705SXin Li       delete TryExit.getBlock();
1403*67e74705SXin Li   }
1404*67e74705SXin Li   ExitSEHTryStmt(S);
1405*67e74705SXin Li }
1406*67e74705SXin Li 
1407*67e74705SXin Li namespace {
1408*67e74705SXin Li struct PerformSEHFinally final : EHScopeStack::Cleanup {
1409*67e74705SXin Li   llvm::Function *OutlinedFinally;
PerformSEHFinally__anonaa838d2f0311::PerformSEHFinally1410*67e74705SXin Li   PerformSEHFinally(llvm::Function *OutlinedFinally)
1411*67e74705SXin Li       : OutlinedFinally(OutlinedFinally) {}
1412*67e74705SXin Li 
Emit__anonaa838d2f0311::PerformSEHFinally1413*67e74705SXin Li   void Emit(CodeGenFunction &CGF, Flags F) override {
1414*67e74705SXin Li     ASTContext &Context = CGF.getContext();
1415*67e74705SXin Li     CodeGenModule &CGM = CGF.CGM;
1416*67e74705SXin Li 
1417*67e74705SXin Li     CallArgList Args;
1418*67e74705SXin Li 
1419*67e74705SXin Li     // Compute the two argument values.
1420*67e74705SXin Li     QualType ArgTys[2] = {Context.UnsignedCharTy, Context.VoidPtrTy};
1421*67e74705SXin Li     llvm::Value *LocalAddrFn = CGM.getIntrinsic(llvm::Intrinsic::localaddress);
1422*67e74705SXin Li     llvm::Value *FP = CGF.Builder.CreateCall(LocalAddrFn);
1423*67e74705SXin Li     llvm::Value *IsForEH =
1424*67e74705SXin Li         llvm::ConstantInt::get(CGF.ConvertType(ArgTys[0]), F.isForEHCleanup());
1425*67e74705SXin Li     Args.add(RValue::get(IsForEH), ArgTys[0]);
1426*67e74705SXin Li     Args.add(RValue::get(FP), ArgTys[1]);
1427*67e74705SXin Li 
1428*67e74705SXin Li     // Arrange a two-arg function info and type.
1429*67e74705SXin Li     const CGFunctionInfo &FnInfo =
1430*67e74705SXin Li         CGM.getTypes().arrangeBuiltinFunctionCall(Context.VoidTy, Args);
1431*67e74705SXin Li 
1432*67e74705SXin Li     CGF.EmitCall(FnInfo, OutlinedFinally, ReturnValueSlot(), Args);
1433*67e74705SXin Li   }
1434*67e74705SXin Li };
1435*67e74705SXin Li } // end anonymous namespace
1436*67e74705SXin Li 
1437*67e74705SXin Li namespace {
1438*67e74705SXin Li /// Find all local variable captures in the statement.
1439*67e74705SXin Li struct CaptureFinder : ConstStmtVisitor<CaptureFinder> {
1440*67e74705SXin Li   CodeGenFunction &ParentCGF;
1441*67e74705SXin Li   const VarDecl *ParentThis;
1442*67e74705SXin Li   llvm::SmallSetVector<const VarDecl *, 4> Captures;
1443*67e74705SXin Li   Address SEHCodeSlot = Address::invalid();
CaptureFinder__anonaa838d2f0411::CaptureFinder1444*67e74705SXin Li   CaptureFinder(CodeGenFunction &ParentCGF, const VarDecl *ParentThis)
1445*67e74705SXin Li       : ParentCGF(ParentCGF), ParentThis(ParentThis) {}
1446*67e74705SXin Li 
1447*67e74705SXin Li   // Return true if we need to do any capturing work.
foundCaptures__anonaa838d2f0411::CaptureFinder1448*67e74705SXin Li   bool foundCaptures() {
1449*67e74705SXin Li     return !Captures.empty() || SEHCodeSlot.isValid();
1450*67e74705SXin Li   }
1451*67e74705SXin Li 
Visit__anonaa838d2f0411::CaptureFinder1452*67e74705SXin Li   void Visit(const Stmt *S) {
1453*67e74705SXin Li     // See if this is a capture, then recurse.
1454*67e74705SXin Li     ConstStmtVisitor<CaptureFinder>::Visit(S);
1455*67e74705SXin Li     for (const Stmt *Child : S->children())
1456*67e74705SXin Li       if (Child)
1457*67e74705SXin Li         Visit(Child);
1458*67e74705SXin Li   }
1459*67e74705SXin Li 
VisitDeclRefExpr__anonaa838d2f0411::CaptureFinder1460*67e74705SXin Li   void VisitDeclRefExpr(const DeclRefExpr *E) {
1461*67e74705SXin Li     // If this is already a capture, just make sure we capture 'this'.
1462*67e74705SXin Li     if (E->refersToEnclosingVariableOrCapture()) {
1463*67e74705SXin Li       Captures.insert(ParentThis);
1464*67e74705SXin Li       return;
1465*67e74705SXin Li     }
1466*67e74705SXin Li 
1467*67e74705SXin Li     const auto *D = dyn_cast<VarDecl>(E->getDecl());
1468*67e74705SXin Li     if (D && D->isLocalVarDeclOrParm() && D->hasLocalStorage())
1469*67e74705SXin Li       Captures.insert(D);
1470*67e74705SXin Li   }
1471*67e74705SXin Li 
VisitCXXThisExpr__anonaa838d2f0411::CaptureFinder1472*67e74705SXin Li   void VisitCXXThisExpr(const CXXThisExpr *E) {
1473*67e74705SXin Li     Captures.insert(ParentThis);
1474*67e74705SXin Li   }
1475*67e74705SXin Li 
VisitCallExpr__anonaa838d2f0411::CaptureFinder1476*67e74705SXin Li   void VisitCallExpr(const CallExpr *E) {
1477*67e74705SXin Li     // We only need to add parent frame allocations for these builtins in x86.
1478*67e74705SXin Li     if (ParentCGF.getTarget().getTriple().getArch() != llvm::Triple::x86)
1479*67e74705SXin Li       return;
1480*67e74705SXin Li 
1481*67e74705SXin Li     unsigned ID = E->getBuiltinCallee();
1482*67e74705SXin Li     switch (ID) {
1483*67e74705SXin Li     case Builtin::BI__exception_code:
1484*67e74705SXin Li     case Builtin::BI_exception_code:
1485*67e74705SXin Li       // This is the simple case where we are the outermost finally. All we
1486*67e74705SXin Li       // have to do here is make sure we escape this and recover it in the
1487*67e74705SXin Li       // outlined handler.
1488*67e74705SXin Li       if (!SEHCodeSlot.isValid())
1489*67e74705SXin Li         SEHCodeSlot = ParentCGF.SEHCodeSlotStack.back();
1490*67e74705SXin Li       break;
1491*67e74705SXin Li     }
1492*67e74705SXin Li   }
1493*67e74705SXin Li };
1494*67e74705SXin Li } // end anonymous namespace
1495*67e74705SXin Li 
recoverAddrOfEscapedLocal(CodeGenFunction & ParentCGF,Address ParentVar,llvm::Value * ParentFP)1496*67e74705SXin Li Address CodeGenFunction::recoverAddrOfEscapedLocal(CodeGenFunction &ParentCGF,
1497*67e74705SXin Li                                                    Address ParentVar,
1498*67e74705SXin Li                                                    llvm::Value *ParentFP) {
1499*67e74705SXin Li   llvm::CallInst *RecoverCall = nullptr;
1500*67e74705SXin Li   CGBuilderTy Builder(*this, AllocaInsertPt);
1501*67e74705SXin Li   if (auto *ParentAlloca = dyn_cast<llvm::AllocaInst>(ParentVar.getPointer())) {
1502*67e74705SXin Li     // Mark the variable escaped if nobody else referenced it and compute the
1503*67e74705SXin Li     // localescape index.
1504*67e74705SXin Li     auto InsertPair = ParentCGF.EscapedLocals.insert(
1505*67e74705SXin Li         std::make_pair(ParentAlloca, ParentCGF.EscapedLocals.size()));
1506*67e74705SXin Li     int FrameEscapeIdx = InsertPair.first->second;
1507*67e74705SXin Li     // call i8* @llvm.localrecover(i8* bitcast(@parentFn), i8* %fp, i32 N)
1508*67e74705SXin Li     llvm::Function *FrameRecoverFn = llvm::Intrinsic::getDeclaration(
1509*67e74705SXin Li         &CGM.getModule(), llvm::Intrinsic::localrecover);
1510*67e74705SXin Li     llvm::Constant *ParentI8Fn =
1511*67e74705SXin Li         llvm::ConstantExpr::getBitCast(ParentCGF.CurFn, Int8PtrTy);
1512*67e74705SXin Li     RecoverCall = Builder.CreateCall(
1513*67e74705SXin Li         FrameRecoverFn, {ParentI8Fn, ParentFP,
1514*67e74705SXin Li                          llvm::ConstantInt::get(Int32Ty, FrameEscapeIdx)});
1515*67e74705SXin Li 
1516*67e74705SXin Li   } else {
1517*67e74705SXin Li     // If the parent didn't have an alloca, we're doing some nested outlining.
1518*67e74705SXin Li     // Just clone the existing localrecover call, but tweak the FP argument to
1519*67e74705SXin Li     // use our FP value. All other arguments are constants.
1520*67e74705SXin Li     auto *ParentRecover =
1521*67e74705SXin Li         cast<llvm::IntrinsicInst>(ParentVar.getPointer()->stripPointerCasts());
1522*67e74705SXin Li     assert(ParentRecover->getIntrinsicID() == llvm::Intrinsic::localrecover &&
1523*67e74705SXin Li            "expected alloca or localrecover in parent LocalDeclMap");
1524*67e74705SXin Li     RecoverCall = cast<llvm::CallInst>(ParentRecover->clone());
1525*67e74705SXin Li     RecoverCall->setArgOperand(1, ParentFP);
1526*67e74705SXin Li     RecoverCall->insertBefore(AllocaInsertPt);
1527*67e74705SXin Li   }
1528*67e74705SXin Li 
1529*67e74705SXin Li   // Bitcast the variable, rename it, and insert it in the local decl map.
1530*67e74705SXin Li   llvm::Value *ChildVar =
1531*67e74705SXin Li       Builder.CreateBitCast(RecoverCall, ParentVar.getType());
1532*67e74705SXin Li   ChildVar->setName(ParentVar.getName());
1533*67e74705SXin Li   return Address(ChildVar, ParentVar.getAlignment());
1534*67e74705SXin Li }
1535*67e74705SXin Li 
EmitCapturedLocals(CodeGenFunction & ParentCGF,const Stmt * OutlinedStmt,bool IsFilter)1536*67e74705SXin Li void CodeGenFunction::EmitCapturedLocals(CodeGenFunction &ParentCGF,
1537*67e74705SXin Li                                          const Stmt *OutlinedStmt,
1538*67e74705SXin Li                                          bool IsFilter) {
1539*67e74705SXin Li   // Find all captures in the Stmt.
1540*67e74705SXin Li   CaptureFinder Finder(ParentCGF, ParentCGF.CXXABIThisDecl);
1541*67e74705SXin Li   Finder.Visit(OutlinedStmt);
1542*67e74705SXin Li 
1543*67e74705SXin Li   // We can exit early on x86_64 when there are no captures. We just have to
1544*67e74705SXin Li   // save the exception code in filters so that __exception_code() works.
1545*67e74705SXin Li   if (!Finder.foundCaptures() &&
1546*67e74705SXin Li       CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
1547*67e74705SXin Li     if (IsFilter)
1548*67e74705SXin Li       EmitSEHExceptionCodeSave(ParentCGF, nullptr, nullptr);
1549*67e74705SXin Li     return;
1550*67e74705SXin Li   }
1551*67e74705SXin Li 
1552*67e74705SXin Li   llvm::Value *EntryFP = nullptr;
1553*67e74705SXin Li   CGBuilderTy Builder(CGM, AllocaInsertPt);
1554*67e74705SXin Li   if (IsFilter && CGM.getTarget().getTriple().getArch() == llvm::Triple::x86) {
1555*67e74705SXin Li     // 32-bit SEH filters need to be careful about FP recovery.  The end of the
1556*67e74705SXin Li     // EH registration is passed in as the EBP physical register.  We can
1557*67e74705SXin Li     // recover that with llvm.frameaddress(1).
1558*67e74705SXin Li     EntryFP = Builder.CreateCall(
1559*67e74705SXin Li         CGM.getIntrinsic(llvm::Intrinsic::frameaddress), {Builder.getInt32(1)});
1560*67e74705SXin Li   } else {
1561*67e74705SXin Li     // Otherwise, for x64 and 32-bit finally functions, the parent FP is the
1562*67e74705SXin Li     // second parameter.
1563*67e74705SXin Li     auto AI = CurFn->arg_begin();
1564*67e74705SXin Li     ++AI;
1565*67e74705SXin Li     EntryFP = &*AI;
1566*67e74705SXin Li   }
1567*67e74705SXin Li 
1568*67e74705SXin Li   llvm::Value *ParentFP = EntryFP;
1569*67e74705SXin Li   if (IsFilter) {
1570*67e74705SXin Li     // Given whatever FP the runtime provided us in EntryFP, recover the true
1571*67e74705SXin Li     // frame pointer of the parent function. We only need to do this in filters,
1572*67e74705SXin Li     // since finally funclets recover the parent FP for us.
1573*67e74705SXin Li     llvm::Function *RecoverFPIntrin =
1574*67e74705SXin Li         CGM.getIntrinsic(llvm::Intrinsic::x86_seh_recoverfp);
1575*67e74705SXin Li     llvm::Constant *ParentI8Fn =
1576*67e74705SXin Li         llvm::ConstantExpr::getBitCast(ParentCGF.CurFn, Int8PtrTy);
1577*67e74705SXin Li     ParentFP = Builder.CreateCall(RecoverFPIntrin, {ParentI8Fn, EntryFP});
1578*67e74705SXin Li   }
1579*67e74705SXin Li 
1580*67e74705SXin Li   // Create llvm.localrecover calls for all captures.
1581*67e74705SXin Li   for (const VarDecl *VD : Finder.Captures) {
1582*67e74705SXin Li     if (isa<ImplicitParamDecl>(VD)) {
1583*67e74705SXin Li       CGM.ErrorUnsupported(VD, "'this' captured by SEH");
1584*67e74705SXin Li       CXXThisValue = llvm::UndefValue::get(ConvertTypeForMem(VD->getType()));
1585*67e74705SXin Li       continue;
1586*67e74705SXin Li     }
1587*67e74705SXin Li     if (VD->getType()->isVariablyModifiedType()) {
1588*67e74705SXin Li       CGM.ErrorUnsupported(VD, "VLA captured by SEH");
1589*67e74705SXin Li       continue;
1590*67e74705SXin Li     }
1591*67e74705SXin Li     assert((isa<ImplicitParamDecl>(VD) || VD->isLocalVarDeclOrParm()) &&
1592*67e74705SXin Li            "captured non-local variable");
1593*67e74705SXin Li 
1594*67e74705SXin Li     // If this decl hasn't been declared yet, it will be declared in the
1595*67e74705SXin Li     // OutlinedStmt.
1596*67e74705SXin Li     auto I = ParentCGF.LocalDeclMap.find(VD);
1597*67e74705SXin Li     if (I == ParentCGF.LocalDeclMap.end())
1598*67e74705SXin Li       continue;
1599*67e74705SXin Li 
1600*67e74705SXin Li     Address ParentVar = I->second;
1601*67e74705SXin Li     setAddrOfLocalVar(
1602*67e74705SXin Li         VD, recoverAddrOfEscapedLocal(ParentCGF, ParentVar, ParentFP));
1603*67e74705SXin Li   }
1604*67e74705SXin Li 
1605*67e74705SXin Li   if (Finder.SEHCodeSlot.isValid()) {
1606*67e74705SXin Li     SEHCodeSlotStack.push_back(
1607*67e74705SXin Li         recoverAddrOfEscapedLocal(ParentCGF, Finder.SEHCodeSlot, ParentFP));
1608*67e74705SXin Li   }
1609*67e74705SXin Li 
1610*67e74705SXin Li   if (IsFilter)
1611*67e74705SXin Li     EmitSEHExceptionCodeSave(ParentCGF, ParentFP, EntryFP);
1612*67e74705SXin Li }
1613*67e74705SXin Li 
1614*67e74705SXin Li /// Arrange a function prototype that can be called by Windows exception
1615*67e74705SXin Li /// handling personalities. On Win64, the prototype looks like:
1616*67e74705SXin Li /// RetTy func(void *EHPtrs, void *ParentFP);
startOutlinedSEHHelper(CodeGenFunction & ParentCGF,bool IsFilter,const Stmt * OutlinedStmt)1617*67e74705SXin Li void CodeGenFunction::startOutlinedSEHHelper(CodeGenFunction &ParentCGF,
1618*67e74705SXin Li                                              bool IsFilter,
1619*67e74705SXin Li                                              const Stmt *OutlinedStmt) {
1620*67e74705SXin Li   SourceLocation StartLoc = OutlinedStmt->getLocStart();
1621*67e74705SXin Li 
1622*67e74705SXin Li   // Get the mangled function name.
1623*67e74705SXin Li   SmallString<128> Name;
1624*67e74705SXin Li   {
1625*67e74705SXin Li     llvm::raw_svector_ostream OS(Name);
1626*67e74705SXin Li     const FunctionDecl *ParentSEHFn = ParentCGF.CurSEHParent;
1627*67e74705SXin Li     assert(ParentSEHFn && "No CurSEHParent!");
1628*67e74705SXin Li     MangleContext &Mangler = CGM.getCXXABI().getMangleContext();
1629*67e74705SXin Li     if (IsFilter)
1630*67e74705SXin Li       Mangler.mangleSEHFilterExpression(ParentSEHFn, OS);
1631*67e74705SXin Li     else
1632*67e74705SXin Li       Mangler.mangleSEHFinallyBlock(ParentSEHFn, OS);
1633*67e74705SXin Li   }
1634*67e74705SXin Li 
1635*67e74705SXin Li   FunctionArgList Args;
1636*67e74705SXin Li   if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 || !IsFilter) {
1637*67e74705SXin Li     // All SEH finally functions take two parameters. Win64 filters take two
1638*67e74705SXin Li     // parameters. Win32 filters take no parameters.
1639*67e74705SXin Li     if (IsFilter) {
1640*67e74705SXin Li       Args.push_back(ImplicitParamDecl::Create(
1641*67e74705SXin Li           getContext(), nullptr, StartLoc,
1642*67e74705SXin Li           &getContext().Idents.get("exception_pointers"),
1643*67e74705SXin Li           getContext().VoidPtrTy));
1644*67e74705SXin Li     } else {
1645*67e74705SXin Li       Args.push_back(ImplicitParamDecl::Create(
1646*67e74705SXin Li           getContext(), nullptr, StartLoc,
1647*67e74705SXin Li           &getContext().Idents.get("abnormal_termination"),
1648*67e74705SXin Li           getContext().UnsignedCharTy));
1649*67e74705SXin Li     }
1650*67e74705SXin Li     Args.push_back(ImplicitParamDecl::Create(
1651*67e74705SXin Li         getContext(), nullptr, StartLoc,
1652*67e74705SXin Li         &getContext().Idents.get("frame_pointer"), getContext().VoidPtrTy));
1653*67e74705SXin Li   }
1654*67e74705SXin Li 
1655*67e74705SXin Li   QualType RetTy = IsFilter ? getContext().LongTy : getContext().VoidTy;
1656*67e74705SXin Li 
1657*67e74705SXin Li   llvm::Function *ParentFn = ParentCGF.CurFn;
1658*67e74705SXin Li   const CGFunctionInfo &FnInfo =
1659*67e74705SXin Li     CGM.getTypes().arrangeBuiltinFunctionDeclaration(RetTy, Args);
1660*67e74705SXin Li 
1661*67e74705SXin Li   llvm::FunctionType *FnTy = CGM.getTypes().GetFunctionType(FnInfo);
1662*67e74705SXin Li   llvm::Function *Fn = llvm::Function::Create(
1663*67e74705SXin Li       FnTy, llvm::GlobalValue::InternalLinkage, Name.str(), &CGM.getModule());
1664*67e74705SXin Li   // The filter is either in the same comdat as the function, or it's internal.
1665*67e74705SXin Li   if (llvm::Comdat *C = ParentFn->getComdat()) {
1666*67e74705SXin Li     Fn->setComdat(C);
1667*67e74705SXin Li   } else if (ParentFn->hasWeakLinkage() || ParentFn->hasLinkOnceLinkage()) {
1668*67e74705SXin Li     llvm::Comdat *C = CGM.getModule().getOrInsertComdat(ParentFn->getName());
1669*67e74705SXin Li     ParentFn->setComdat(C);
1670*67e74705SXin Li     Fn->setComdat(C);
1671*67e74705SXin Li   } else {
1672*67e74705SXin Li     Fn->setLinkage(llvm::GlobalValue::InternalLinkage);
1673*67e74705SXin Li   }
1674*67e74705SXin Li 
1675*67e74705SXin Li   IsOutlinedSEHHelper = true;
1676*67e74705SXin Li 
1677*67e74705SXin Li   StartFunction(GlobalDecl(), RetTy, Fn, FnInfo, Args,
1678*67e74705SXin Li                 OutlinedStmt->getLocStart(), OutlinedStmt->getLocStart());
1679*67e74705SXin Li   CurSEHParent = ParentCGF.CurSEHParent;
1680*67e74705SXin Li 
1681*67e74705SXin Li   CGM.SetLLVMFunctionAttributes(nullptr, FnInfo, CurFn);
1682*67e74705SXin Li   EmitCapturedLocals(ParentCGF, OutlinedStmt, IsFilter);
1683*67e74705SXin Li }
1684*67e74705SXin Li 
1685*67e74705SXin Li /// Create a stub filter function that will ultimately hold the code of the
1686*67e74705SXin Li /// filter expression. The EH preparation passes in LLVM will outline the code
1687*67e74705SXin Li /// from the main function body into this stub.
1688*67e74705SXin Li llvm::Function *
GenerateSEHFilterFunction(CodeGenFunction & ParentCGF,const SEHExceptStmt & Except)1689*67e74705SXin Li CodeGenFunction::GenerateSEHFilterFunction(CodeGenFunction &ParentCGF,
1690*67e74705SXin Li                                            const SEHExceptStmt &Except) {
1691*67e74705SXin Li   const Expr *FilterExpr = Except.getFilterExpr();
1692*67e74705SXin Li   startOutlinedSEHHelper(ParentCGF, true, FilterExpr);
1693*67e74705SXin Li 
1694*67e74705SXin Li   // Emit the original filter expression, convert to i32, and return.
1695*67e74705SXin Li   llvm::Value *R = EmitScalarExpr(FilterExpr);
1696*67e74705SXin Li   R = Builder.CreateIntCast(R, ConvertType(getContext().LongTy),
1697*67e74705SXin Li                             FilterExpr->getType()->isSignedIntegerType());
1698*67e74705SXin Li   Builder.CreateStore(R, ReturnValue);
1699*67e74705SXin Li 
1700*67e74705SXin Li   FinishFunction(FilterExpr->getLocEnd());
1701*67e74705SXin Li 
1702*67e74705SXin Li   return CurFn;
1703*67e74705SXin Li }
1704*67e74705SXin Li 
1705*67e74705SXin Li llvm::Function *
GenerateSEHFinallyFunction(CodeGenFunction & ParentCGF,const SEHFinallyStmt & Finally)1706*67e74705SXin Li CodeGenFunction::GenerateSEHFinallyFunction(CodeGenFunction &ParentCGF,
1707*67e74705SXin Li                                             const SEHFinallyStmt &Finally) {
1708*67e74705SXin Li   const Stmt *FinallyBlock = Finally.getBlock();
1709*67e74705SXin Li   startOutlinedSEHHelper(ParentCGF, false, FinallyBlock);
1710*67e74705SXin Li 
1711*67e74705SXin Li   // Emit the original filter expression, convert to i32, and return.
1712*67e74705SXin Li   EmitStmt(FinallyBlock);
1713*67e74705SXin Li 
1714*67e74705SXin Li   FinishFunction(FinallyBlock->getLocEnd());
1715*67e74705SXin Li 
1716*67e74705SXin Li   return CurFn;
1717*67e74705SXin Li }
1718*67e74705SXin Li 
EmitSEHExceptionCodeSave(CodeGenFunction & ParentCGF,llvm::Value * ParentFP,llvm::Value * EntryFP)1719*67e74705SXin Li void CodeGenFunction::EmitSEHExceptionCodeSave(CodeGenFunction &ParentCGF,
1720*67e74705SXin Li                                                llvm::Value *ParentFP,
1721*67e74705SXin Li                                                llvm::Value *EntryFP) {
1722*67e74705SXin Li   // Get the pointer to the EXCEPTION_POINTERS struct. This is returned by the
1723*67e74705SXin Li   // __exception_info intrinsic.
1724*67e74705SXin Li   if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
1725*67e74705SXin Li     // On Win64, the info is passed as the first parameter to the filter.
1726*67e74705SXin Li     SEHInfo = &*CurFn->arg_begin();
1727*67e74705SXin Li     SEHCodeSlotStack.push_back(
1728*67e74705SXin Li         CreateMemTemp(getContext().IntTy, "__exception_code"));
1729*67e74705SXin Li   } else {
1730*67e74705SXin Li     // On Win32, the EBP on entry to the filter points to the end of an
1731*67e74705SXin Li     // exception registration object. It contains 6 32-bit fields, and the info
1732*67e74705SXin Li     // pointer is stored in the second field. So, GEP 20 bytes backwards and
1733*67e74705SXin Li     // load the pointer.
1734*67e74705SXin Li     SEHInfo = Builder.CreateConstInBoundsGEP1_32(Int8Ty, EntryFP, -20);
1735*67e74705SXin Li     SEHInfo = Builder.CreateBitCast(SEHInfo, Int8PtrTy->getPointerTo());
1736*67e74705SXin Li     SEHInfo = Builder.CreateAlignedLoad(Int8PtrTy, SEHInfo, getPointerAlign());
1737*67e74705SXin Li     SEHCodeSlotStack.push_back(recoverAddrOfEscapedLocal(
1738*67e74705SXin Li         ParentCGF, ParentCGF.SEHCodeSlotStack.back(), ParentFP));
1739*67e74705SXin Li   }
1740*67e74705SXin Li 
1741*67e74705SXin Li   // Save the exception code in the exception slot to unify exception access in
1742*67e74705SXin Li   // the filter function and the landing pad.
1743*67e74705SXin Li   // struct EXCEPTION_POINTERS {
1744*67e74705SXin Li   //   EXCEPTION_RECORD *ExceptionRecord;
1745*67e74705SXin Li   //   CONTEXT *ContextRecord;
1746*67e74705SXin Li   // };
1747*67e74705SXin Li   // int exceptioncode = exception_pointers->ExceptionRecord->ExceptionCode;
1748*67e74705SXin Li   llvm::Type *RecordTy = CGM.Int32Ty->getPointerTo();
1749*67e74705SXin Li   llvm::Type *PtrsTy = llvm::StructType::get(RecordTy, CGM.VoidPtrTy, nullptr);
1750*67e74705SXin Li   llvm::Value *Ptrs = Builder.CreateBitCast(SEHInfo, PtrsTy->getPointerTo());
1751*67e74705SXin Li   llvm::Value *Rec = Builder.CreateStructGEP(PtrsTy, Ptrs, 0);
1752*67e74705SXin Li   Rec = Builder.CreateAlignedLoad(Rec, getPointerAlign());
1753*67e74705SXin Li   llvm::Value *Code = Builder.CreateAlignedLoad(Rec, getIntAlign());
1754*67e74705SXin Li   assert(!SEHCodeSlotStack.empty() && "emitting EH code outside of __except");
1755*67e74705SXin Li   Builder.CreateStore(Code, SEHCodeSlotStack.back());
1756*67e74705SXin Li }
1757*67e74705SXin Li 
EmitSEHExceptionInfo()1758*67e74705SXin Li llvm::Value *CodeGenFunction::EmitSEHExceptionInfo() {
1759*67e74705SXin Li   // Sema should diagnose calling this builtin outside of a filter context, but
1760*67e74705SXin Li   // don't crash if we screw up.
1761*67e74705SXin Li   if (!SEHInfo)
1762*67e74705SXin Li     return llvm::UndefValue::get(Int8PtrTy);
1763*67e74705SXin Li   assert(SEHInfo->getType() == Int8PtrTy);
1764*67e74705SXin Li   return SEHInfo;
1765*67e74705SXin Li }
1766*67e74705SXin Li 
EmitSEHExceptionCode()1767*67e74705SXin Li llvm::Value *CodeGenFunction::EmitSEHExceptionCode() {
1768*67e74705SXin Li   assert(!SEHCodeSlotStack.empty() && "emitting EH code outside of __except");
1769*67e74705SXin Li   return Builder.CreateLoad(SEHCodeSlotStack.back());
1770*67e74705SXin Li }
1771*67e74705SXin Li 
EmitSEHAbnormalTermination()1772*67e74705SXin Li llvm::Value *CodeGenFunction::EmitSEHAbnormalTermination() {
1773*67e74705SXin Li   // Abnormal termination is just the first parameter to the outlined finally
1774*67e74705SXin Li   // helper.
1775*67e74705SXin Li   auto AI = CurFn->arg_begin();
1776*67e74705SXin Li   return Builder.CreateZExt(&*AI, Int32Ty);
1777*67e74705SXin Li }
1778*67e74705SXin Li 
EnterSEHTryStmt(const SEHTryStmt & S)1779*67e74705SXin Li void CodeGenFunction::EnterSEHTryStmt(const SEHTryStmt &S) {
1780*67e74705SXin Li   CodeGenFunction HelperCGF(CGM, /*suppressNewContext=*/true);
1781*67e74705SXin Li   if (const SEHFinallyStmt *Finally = S.getFinallyHandler()) {
1782*67e74705SXin Li     // Outline the finally block.
1783*67e74705SXin Li     llvm::Function *FinallyFunc =
1784*67e74705SXin Li         HelperCGF.GenerateSEHFinallyFunction(*this, *Finally);
1785*67e74705SXin Li 
1786*67e74705SXin Li     // Push a cleanup for __finally blocks.
1787*67e74705SXin Li     EHStack.pushCleanup<PerformSEHFinally>(NormalAndEHCleanup, FinallyFunc);
1788*67e74705SXin Li     return;
1789*67e74705SXin Li   }
1790*67e74705SXin Li 
1791*67e74705SXin Li   // Otherwise, we must have an __except block.
1792*67e74705SXin Li   const SEHExceptStmt *Except = S.getExceptHandler();
1793*67e74705SXin Li   assert(Except);
1794*67e74705SXin Li   EHCatchScope *CatchScope = EHStack.pushCatch(1);
1795*67e74705SXin Li   SEHCodeSlotStack.push_back(
1796*67e74705SXin Li       CreateMemTemp(getContext().IntTy, "__exception_code"));
1797*67e74705SXin Li 
1798*67e74705SXin Li   // If the filter is known to evaluate to 1, then we can use the clause
1799*67e74705SXin Li   // "catch i8* null". We can't do this on x86 because the filter has to save
1800*67e74705SXin Li   // the exception code.
1801*67e74705SXin Li   llvm::Constant *C =
1802*67e74705SXin Li       CGM.EmitConstantExpr(Except->getFilterExpr(), getContext().IntTy, this);
1803*67e74705SXin Li   if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86 && C &&
1804*67e74705SXin Li       C->isOneValue()) {
1805*67e74705SXin Li     CatchScope->setCatchAllHandler(0, createBasicBlock("__except"));
1806*67e74705SXin Li     return;
1807*67e74705SXin Li   }
1808*67e74705SXin Li 
1809*67e74705SXin Li   // In general, we have to emit an outlined filter function. Use the function
1810*67e74705SXin Li   // in place of the RTTI typeinfo global that C++ EH uses.
1811*67e74705SXin Li   llvm::Function *FilterFunc =
1812*67e74705SXin Li       HelperCGF.GenerateSEHFilterFunction(*this, *Except);
1813*67e74705SXin Li   llvm::Constant *OpaqueFunc =
1814*67e74705SXin Li       llvm::ConstantExpr::getBitCast(FilterFunc, Int8PtrTy);
1815*67e74705SXin Li   CatchScope->setHandler(0, OpaqueFunc, createBasicBlock("__except.ret"));
1816*67e74705SXin Li }
1817*67e74705SXin Li 
ExitSEHTryStmt(const SEHTryStmt & S)1818*67e74705SXin Li void CodeGenFunction::ExitSEHTryStmt(const SEHTryStmt &S) {
1819*67e74705SXin Li   // Just pop the cleanup if it's a __finally block.
1820*67e74705SXin Li   if (S.getFinallyHandler()) {
1821*67e74705SXin Li     PopCleanupBlock();
1822*67e74705SXin Li     return;
1823*67e74705SXin Li   }
1824*67e74705SXin Li 
1825*67e74705SXin Li   // Otherwise, we must have an __except block.
1826*67e74705SXin Li   const SEHExceptStmt *Except = S.getExceptHandler();
1827*67e74705SXin Li   assert(Except && "__try must have __finally xor __except");
1828*67e74705SXin Li   EHCatchScope &CatchScope = cast<EHCatchScope>(*EHStack.begin());
1829*67e74705SXin Li 
1830*67e74705SXin Li   // Don't emit the __except block if the __try block lacked invokes.
1831*67e74705SXin Li   // TODO: Model unwind edges from instructions, either with iload / istore or
1832*67e74705SXin Li   // a try body function.
1833*67e74705SXin Li   if (!CatchScope.hasEHBranches()) {
1834*67e74705SXin Li     CatchScope.clearHandlerBlocks();
1835*67e74705SXin Li     EHStack.popCatch();
1836*67e74705SXin Li     SEHCodeSlotStack.pop_back();
1837*67e74705SXin Li     return;
1838*67e74705SXin Li   }
1839*67e74705SXin Li 
1840*67e74705SXin Li   // The fall-through block.
1841*67e74705SXin Li   llvm::BasicBlock *ContBB = createBasicBlock("__try.cont");
1842*67e74705SXin Li 
1843*67e74705SXin Li   // We just emitted the body of the __try; jump to the continue block.
1844*67e74705SXin Li   if (HaveInsertPoint())
1845*67e74705SXin Li     Builder.CreateBr(ContBB);
1846*67e74705SXin Li 
1847*67e74705SXin Li   // Check if our filter function returned true.
1848*67e74705SXin Li   emitCatchDispatchBlock(*this, CatchScope);
1849*67e74705SXin Li 
1850*67e74705SXin Li   // Grab the block before we pop the handler.
1851*67e74705SXin Li   llvm::BasicBlock *CatchPadBB = CatchScope.getHandler(0).Block;
1852*67e74705SXin Li   EHStack.popCatch();
1853*67e74705SXin Li 
1854*67e74705SXin Li   EmitBlockAfterUses(CatchPadBB);
1855*67e74705SXin Li 
1856*67e74705SXin Li   // __except blocks don't get outlined into funclets, so immediately do a
1857*67e74705SXin Li   // catchret.
1858*67e74705SXin Li   llvm::CatchPadInst *CPI =
1859*67e74705SXin Li       cast<llvm::CatchPadInst>(CatchPadBB->getFirstNonPHI());
1860*67e74705SXin Li   llvm::BasicBlock *ExceptBB = createBasicBlock("__except");
1861*67e74705SXin Li   Builder.CreateCatchRet(CPI, ExceptBB);
1862*67e74705SXin Li   EmitBlock(ExceptBB);
1863*67e74705SXin Li 
1864*67e74705SXin Li   // On Win64, the exception code is returned in EAX. Copy it into the slot.
1865*67e74705SXin Li   if (CGM.getTarget().getTriple().getArch() != llvm::Triple::x86) {
1866*67e74705SXin Li     llvm::Function *SEHCodeIntrin =
1867*67e74705SXin Li         CGM.getIntrinsic(llvm::Intrinsic::eh_exceptioncode);
1868*67e74705SXin Li     llvm::Value *Code = Builder.CreateCall(SEHCodeIntrin, {CPI});
1869*67e74705SXin Li     Builder.CreateStore(Code, SEHCodeSlotStack.back());
1870*67e74705SXin Li   }
1871*67e74705SXin Li 
1872*67e74705SXin Li   // Emit the __except body.
1873*67e74705SXin Li   EmitStmt(Except->getBlock());
1874*67e74705SXin Li 
1875*67e74705SXin Li   // End the lifetime of the exception code.
1876*67e74705SXin Li   SEHCodeSlotStack.pop_back();
1877*67e74705SXin Li 
1878*67e74705SXin Li   if (HaveInsertPoint())
1879*67e74705SXin Li     Builder.CreateBr(ContBB);
1880*67e74705SXin Li 
1881*67e74705SXin Li   EmitBlock(ContBB);
1882*67e74705SXin Li }
1883*67e74705SXin Li 
EmitSEHLeaveStmt(const SEHLeaveStmt & S)1884*67e74705SXin Li void CodeGenFunction::EmitSEHLeaveStmt(const SEHLeaveStmt &S) {
1885*67e74705SXin Li   // If this code is reachable then emit a stop point (if generating
1886*67e74705SXin Li   // debug info). We have to do this ourselves because we are on the
1887*67e74705SXin Li   // "simple" statement path.
1888*67e74705SXin Li   if (HaveInsertPoint())
1889*67e74705SXin Li     EmitStopPoint(&S);
1890*67e74705SXin Li 
1891*67e74705SXin Li   // This must be a __leave from a __finally block, which we warn on and is UB.
1892*67e74705SXin Li   // Just emit unreachable.
1893*67e74705SXin Li   if (!isSEHTryScope()) {
1894*67e74705SXin Li     Builder.CreateUnreachable();
1895*67e74705SXin Li     Builder.ClearInsertionPoint();
1896*67e74705SXin Li     return;
1897*67e74705SXin Li   }
1898*67e74705SXin Li 
1899*67e74705SXin Li   EmitBranchThroughCleanup(*SEHTryEpilogueStack.back());
1900*67e74705SXin Li }
1901