Coverage Report

Created: 2020-02-15 09:57

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