llvm.org GIT mirror llvm / d4a765f
[WinEH] Require token linkage in EH pad/ret signatures Summary: WinEHPrepare is going to require that cleanuppad and catchpad produce values of token type which are consumed by any cleanupret or catchret exiting the pad. This change updates the signatures of those operators to require/enforce that the type produced by the pads is token type and that the rets have an appropriate argument. The catchpad argument of a `CatchReturnInst` must be a `CatchPadInst` (and similarly for `CleanupReturnInst`/`CleanupPadInst`). To accommodate that restriction, this change adds a notion of an operator constraint to both LLParser and BitcodeReader, allowing appropriate sentinels to be constructed for forward references and appropriate error messages to be emitted for illegal inputs. Also add a verifier rule (noted in LangRef) that a catchpad with a catchpad predecessor must have no other predecessors; this ensures that WinEHPrepare will see the expected linear relationship between sibling catches on the same try. Lastly, remove some superfluous/vestigial casts from instruction operand setters operating on BasicBlocks. Reviewers: rnk, majnemer Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D12108 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@245797 91177308-0d34-0410-b5e6-96231b3b80d8 Joseph Tremoulet 5 years ago
21 changed file(s) with 764 addition(s) and 558 deletion(s). Raw diff Collapse all Expand all
613613 a ``noexcept`` function should transitively unwind to a terminateblock. Throw
614614 specifications are not implemented by MSVC, and are not yet supported.
615615
616 Each of these new EH pad instructions has a label operand that indicates which
616 Each of these new EH pad instructions has a way to identify which
617617 action should be considered after this action. The ``catchpad`` and
618 ``terminatepad`` instructions are terminators, and this label is considered to
619 be an unwind destination analogous to the unwind destination of an invoke. The
618 ``terminatepad`` instructions are terminators, and have a label operand considered
619 to be an unwind destination analogous to the unwind destination of an invoke. The
620620 ``cleanuppad`` instruction is different from the other two in that it is not a
621 terminator, and this label operand is not an edge in the CFG. The code inside a
622 cleanuppad runs before transferring control to the next action, so the
623 ``cleanupret`` instruction is the instruction that unwinds to the next EH pad.
624 All of these "unwind edges" may refer to a basic block that contains an EH pad
625 instruction, or they may simply unwind to the caller. Unwinding to the caller
626 has roughly the same semantics as the ``resume`` instruction in the
627 ``landingpad`` model. When inlining through an invoke, instructions that unwind
628 to the caller are hooked up to unwind to the unwind destination of the call
629 site.
621 terminator. The code inside a cleanuppad runs before transferring control to the
622 next action, so the ``cleanupret`` instruction is the instruction that holds a
623 label operand and unwinds to the next EH pad. All of these "unwind edges" may
624 refer to a basic block that contains an EH pad instruction, or they may simply
625 unwind to the caller. Unwinding to the caller has roughly the same semantics as
626 the ``resume`` instruction in the ``landingpad`` model. When inlining through an
627 invoke, instructions that unwind to the caller are hooked up to unwind to the
628 unwind destination of the call site.
630629
631630 Putting things together, here is a hypothetical lowering of some C++ that uses
632631 all of the new IR instructions:
673672 ; EH scope code, ordered innermost to outermost:
674673
675674 lpad.cleanup: ; preds = %invoke.cont
676 cleanuppad [label %lpad.catch]
675 %cleanup = cleanuppad []
677676 call void @"\01??_DCleanup@@QEAA@XZ"(%struct.Cleanup* nonnull %obj) nounwind
678 cleanupret unwind label %lpad.catch
677 cleanupret %cleanup unwind label %lpad.catch
679678
680679 lpad.catch: ; preds = %entry, %lpad.cleanup
681 catchpad void [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i32* %e]
680 %catch = catchpad [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i32* %e]
682681 to label %catch unwind label %lpad.terminate
683682
684683 catch: ; preds = %lpad.catch
685684 %9 = load i32, i32* %e, align 4
686 catchret label %return
685 catchret %catch label %return
687686
688687 lpad.terminate:
689688 terminatepad [void ()* @"\01?terminate@@YAXXZ"]
51375137
51385138 ::
51395139
5140 = catchpad [*]
5140 = catchpad [*]
51415141 to label unwind label
51425142
51435143 Overview:
51525152 exception. Control is tranfered to the ``exception`` label if the
51535153 ``catchpad`` is not an appropriate handler for the in-flight exception.
51545154 The ``normal`` label should contain the code found in the ``catch``
5155 portion of a ``try``/``catch`` sequence. It defines values supplied by
5156 the :ref:`personality function ` upon re-entry to the
5157 function. The ``resultval`` has the type ``resultty``.
5155 portion of a ``try``/``catch`` sequence. The ``resultval`` has the type
5156 :ref:`token ` and is used to match the ``catchpad`` to
5157 corresponding :ref:`catchrets `.
51585158
51595159 Arguments:
51605160 """"""""""
51695169 Semantics:
51705170 """"""""""
51715171
5172 The '``catchpad``' instruction defines the values which are set by the
5173 :ref:`personality function ` upon re-entry to the function, and
5174 therefore the "result type" of the ``catchpad`` instruction. As with
5175 calling conventions, how the personality function results are
5176 represented in LLVM IR is target specific.
5177
51785172 When the call stack is being unwound due to an exception being thrown,
51795173 the exception is compared against the ``args``. If it doesn't match,
51805174 then control is transfered to the ``exception`` basic block.
5175 As with calling conventions, how the personality function results are
5176 represented in LLVM IR is target specific.
51815177
51825178 The ``catchpad`` instruction has several restrictions:
51835179
51915187 catch block.
51925188 - A basic block that is not a catch block may not include a
51935189 '``catchpad``' instruction.
5190 - A catch block which has another catch block as a predecessor may not have
5191 any other predecessors.
51945192 - It is undefined behavior for control to transfer from a ``catchpad`` to a
5195 ``cleanupret`` without first executing a ``catchret`` and a subsequent
5196 ``cleanuppad``.
5197 - It is undefined behavior for control to transfer from a ``catchpad`` to a
5198 ``ret`` without first executing a ``catchret``.
5193 ``ret`` without first executing a ``catchret`` that consumes the
5194 ``catchpad`` or unwinding through its ``catchendpad``.
5195 - It is undefined behavior for control to transfer from a ``catchpad`` to
5196 itself without first executing a ``catchret`` that consumes the
5197 ``catchpad`` or unwinding through its ``catchendpad``.
51995198
52005199 Example:
52015200 """"""""
52035202 .. code-block:: llvm
52045203
52055204 ;; A catch block which can catch an integer.
5206 %res = catchpad { i8*, i32 } [i8** @_ZTIi]
5205 %tok = catchpad [i8** @_ZTIi]
52075206 to label %int.handler unwind label %terminate
52085207
52095208 .. _i_catchendpad:
52635262 '``catchendpad``' instruction.
52645263 - Exactly one catch block may unwind to a ``catchendpad``.
52655264 - The unwind target of invokes between a ``catchpad`` and a
5266 corresponding ``catchret`` must be its ``catchendpad``.
5265 corresponding ``catchret`` must be its ``catchendpad`` or
5266 an inner EH pad.
52675267
52685268 Example:
52695269 """"""""
52835283
52845284 ::
52855285
5286 catchret <type> <value> to label
5286 catchret <value> to label
52875287
52885288 Overview:
52895289 """""""""
52955295 Arguments:
52965296 """"""""""
52975297
5298 The '``catchret``' instruction requires one argument which specifies
5299 where control will transfer to next.
5298 The first argument to a '``catchret``' indicates which ``catchpad`` it
5299 exits. It must be a :ref:`catchpad `.
5300 The second argument to a '``catchret``' specifies where control will
5301 transfer to next.
53005302
53015303 Semantics:
53025304 """"""""""
53085310 arbitrary code to, for example, run a C++ destructor.
53095311 Control then transfers to ``normal``.
53105312 It may be passed an optional, personality specific, value.
5313 It is undefined behavior to execute a ``catchret`` whose ``catchpad`` has
5314 not been executed.
5315 It is undefined behavior to execute a ``catchret`` if any ``catchpad`` or
5316 ``cleanuppad`` has been executed, without subsequently executing a
5317 corresponding ``catchret``/``cleanupret`` or unwinding out of the inner
5318 pad, following the most recent execution of the ``catchret``'s corresponding
5319 ``catchpad``.
5320
53115321
53125322 Example:
53135323 """"""""
53145324
53155325 .. code-block:: llvm
53165326
5317 catchret label %continue
5327 catchret %catch label %continue
53185328
53195329 .. _i_cleanupret:
53205330
53265336
53275337 ::
53285338
5329 cleanupret unwind label
5330 cleanupret <type> unwind to caller
5339 cleanupret <value> unwind label
5340 cleanupret unwind to caller
53315341
53325342 Overview:
53335343 """""""""
53395349 Arguments:
53405350 """"""""""
53415351
5342 The '``cleanupret``' instruction requires one argument, which must have the
5343 same type as the result of any '``cleanuppad``' instruction in the same
5344 function. It also has an optional successor, ``continue``.
5352 The '``cleanupret``' instruction requires one argument, which indicates
5353 which ``cleanuppad`` it exits, and must be a :ref:`cleanuppad `.
5354 It also has an optional successor, ``continue``.
53455355
53465356 Semantics:
53475357 """"""""""
53505360 :ref:`personality function ` that one
53515361 :ref:`cleanuppad ` it transferred control to has ended.
53525362 It transfers control to ``continue`` or unwinds out of the function.
5363 It is undefined behavior to execute a ``cleanupret`` whose ``cleanuppad`` has
5364 not been executed.
5365 It is undefined behavior to execute a ``cleanupret`` if any ``catchpad`` or
5366 ``cleanuppad`` has been executed, without subsequently executing a
5367 corresponding ``catchret``/``cleanupret`` or unwinding out of the inner pad,
5368 following the most recent execution of the ``cleanupret``'s corresponding
5369 ``cleanuppad``.
53535370
53545371 Example:
53555372 """"""""
53565373
53575374 .. code-block:: llvm
53585375
5359 cleanupret void unwind to caller
5360 cleanupret { i8*, i32 } %exn unwind label %continue
5376 cleanupret %cleanup unwind to caller
5377 cleanupret %cleanup unwind label %continue
53615378
53625379 .. _i_terminatepad:
53635380
83908407
83918408 ::
83928409
8393 = cleanuppad [*]
8410 = cleanuppad [*]
83948411
83958412 Overview:
83968413 """""""""
84028419 The ``args`` correspond to whatever additional
84038420 information the :ref:`personality function ` requires to
84048421 execute the cleanup.
8405 The ``resultval`` has the type ``resultty``.
8422 The ``resultval`` has the type :ref:`token ` and is used to
8423 match the ``cleanuppad`` to corresponding :ref:`cleanuprets `.
84068424
84078425 Arguments:
84088426 """"""""""
84148432 """"""""""
84158433
84168434 The '``cleanuppad``' instruction defines the values which are set by the
8417 :ref:`personality function ` upon re-entry to the function, and
8418 therefore the "result type" of the ``cleanuppad`` instruction. As with
8419 calling conventions, how the personality function results are
8435 :ref:`personality function ` upon re-entry to the function.
8436 As with calling conventions, how the personality function results are
84208437 represented in LLVM IR is target specific.
84218438
84228439 When the call stack is being unwound due to an exception being thrown,
84338450 cleanup block.
84348451 - A basic block that is not a cleanup block may not include a
84358452 '``cleanuppad``' instruction.
8453 - All ``cleanupret``s which exit a cleanuppad must have the same
8454 exceptional successor.
84368455 - It is undefined behavior for control to transfer from a ``cleanuppad`` to a
8437 ``catchret`` without first executing a ``cleanupret`` and a subsequent
8438 ``catchpad``.
8439 - It is undefined behavior for control to transfer from a ``cleanuppad`` to a
8440 ``ret`` without first executing a ``cleanupret``.
8456 ``ret`` without first executing a ``cleanupret`` that consumes the
8457 ``cleanuppad`` or unwinding out of the ``cleanuppad``.
8458 - It is undefined behavior for control to transfer from a ``cleanuppad`` to
8459 itself without first executing a ``cleanupret`` that consumes the
8460 ``cleanuppad`` or unwinding out of the ``cleanuppad``.
84418461
84428462 Example:
84438463 """"""""
84448464
84458465 .. code-block:: llvm
84468466
8447 %res = cleanuppad { i8*, i32 } [label %nextaction]
8467 %tok = cleanuppad []
84488468
84498469 .. _intrinsics:
84508470
355355 FUNC_CODE_INST_CMPXCHG = 46, // CMPXCHG: [ptrty,ptr,valty,cmp,new, align,
356356 // vol,ordering,synchscope]
357357 FUNC_CODE_INST_LANDINGPAD = 47, // LANDINGPAD: [ty,val,num,id0,val0...]
358 FUNC_CODE_INST_CLEANUPRET = 48, // CLEANUPRET: [] or [val] or [bb#] or [val,bb#]
359 FUNC_CODE_INST_CATCHRET = 49, // CATCHRET: [bb#]
360 FUNC_CODE_INST_CATCHPAD = 50, // CATCHPAD: [ty,val,val,num,args...]
358 FUNC_CODE_INST_CLEANUPRET = 48, // CLEANUPRET: [val] or [val,bb#]
359 FUNC_CODE_INST_CATCHRET = 49, // CATCHRET: [val,bb#]
360 FUNC_CODE_INST_CATCHPAD = 50, // CATCHPAD: [bb#,bb#,num,args...]
361361 FUNC_CODE_INST_TERMINATEPAD = 51, // TERMINATEPAD: [bb#,num,args...]
362362 FUNC_CODE_INST_CLEANUPPAD = 52, // CLEANUPPAD: [num,args...]
363363 FUNC_CODE_INST_CATCHENDPAD = 53, // CATCHENDPAD: [] or [bb#]
670670 return Insert(ResumeInst::Create(Exn));
671671 }
672672
673 CleanupReturnInst *CreateCleanupRet(BasicBlock *UnwindBB = nullptr,
674 Value *RetVal = nullptr) {
675 return Insert(CleanupReturnInst::Create(Context, RetVal, UnwindBB));
676 }
677
678 CatchPadInst *CreateCatchPad(Type *Ty, BasicBlock *NormalDest,
679 BasicBlock *UnwindDest, ArrayRef Args,
680 const Twine &Name = "") {
681 return Insert(CatchPadInst::Create(Ty, NormalDest, UnwindDest, Args), Name);
673 CleanupReturnInst *CreateCleanupRet(CleanupPadInst *CleanupPad,
674 BasicBlock *UnwindBB = nullptr) {
675 return Insert(CleanupReturnInst::Create(CleanupPad, UnwindBB));
676 }
677
678 CatchPadInst *CreateCatchPad(BasicBlock *NormalDest, BasicBlock *UnwindDest,
679 ArrayRef Args, const Twine &Name = "") {
680 return Insert(CatchPadInst::Create(NormalDest, UnwindDest, Args), Name);
682681 }
683682
684683 CatchEndPadInst *CreateCatchEndPad(BasicBlock *UnwindBB = nullptr) {
691690 return Insert(TerminatePadInst::Create(Context, UnwindBB, Args), Name);
692691 }
693692
694 CleanupPadInst *CreateCleanupPad(Type *Ty, ArrayRef Args,
693 CleanupPadInst *CreateCleanupPad(ArrayRef Args,
695694 const Twine &Name = "") {
696 return Insert(CleanupPadInst::Create(Ty, Args), Name);
697 }
698
699 CatchReturnInst *CreateCatchRet(BasicBlock *BB, Value *RetVal = nullptr) {
700 return Insert(CatchReturnInst::Create(BB, RetVal));
695 return Insert(CleanupPadInst::Create(Context, Args), Name);
696 }
697
698 CatchReturnInst *CreateCatchRet(CatchPadInst *CatchPad, BasicBlock *BB) {
699 return Insert(CatchReturnInst::Create(CatchPad, BB));
701700 }
702701
703702 UnreachableInst *CreateUnreachable() {
27392739
27402740 void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
27412741 assert(idx < getNumSuccessors() && "Successor # out of range for Branch!");
2742 *(&Op<-1>() - idx) = (Value*)NewSucc;
2742 *(&Op<-1>() - idx) = NewSucc;
27432743 }
27442744
27452745 /// \brief Swap the successors of this branch instruction.
30553055 }
30563056 void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
30573057 assert(idx < getNumSuccessors() && "Successor # out of range for switch!");
3058 setOperand(idx*2+1, (Value*)NewSucc);
3058 setOperand(idx * 2 + 1, NewSucc);
30593059 }
30603060
30613061 // Methods for support type inquiry through isa, cast, and dyn_cast:
31553155 return cast(getOperand(i+1));
31563156 }
31573157 void setSuccessor(unsigned i, BasicBlock *NewSucc) {
3158 setOperand(i+1, (Value*)NewSucc);
3158 setOperand(i + 1, NewSucc);
31593159 }
31603160
31613161 // Methods for support type inquiry through isa, cast, and dyn_cast:
35693569 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ResumeInst, Value)
35703570
35713571 //===----------------------------------------------------------------------===//
3572 // CleanupReturnInst Class
3573 //===----------------------------------------------------------------------===//
3574
3575 class CleanupReturnInst : public TerminatorInst {
3576 CleanupReturnInst(const CleanupReturnInst &RI);
3577
3578 private:
3579 void init(Value *RetVal, BasicBlock *UnwindBB);
3580 CleanupReturnInst(LLVMContext &C, Value *RetVal, BasicBlock *UnwindBB,
3581 unsigned Values, Instruction *InsertBefore = nullptr);
3582 CleanupReturnInst(LLVMContext &C, Value *RetVal, BasicBlock *UnwindBB,
3583 unsigned Values, BasicBlock *InsertAtEnd);
3584
3585 int getUnwindLabelOpIdx() const {
3586 assert(hasUnwindDest());
3587 return 0;
3588 }
3589
3590 int getRetValOpIdx() const {
3591 assert(hasReturnValue());
3592 if (hasUnwindDest())
3593 return 1;
3594 return 0;
3595 }
3596
3597 protected:
3598 // Note: Instruction needs to be a friend here to call cloneImpl.
3599 friend class Instruction;
3600 CleanupReturnInst *cloneImpl() const;
3601
3602 public:
3603 static CleanupReturnInst *Create(LLVMContext &C,
3604 Value *RetVal = nullptr,
3605 BasicBlock *UnwindBB = nullptr,
3606 Instruction *InsertBefore = nullptr) {
3607 unsigned Values = 0;
3608 if (RetVal)
3609 ++Values;
3610 if (UnwindBB)
3611 ++Values;
3612 return new (Values)
3613 CleanupReturnInst(C, RetVal, UnwindBB, Values, InsertBefore);
3614 }
3615 static CleanupReturnInst *Create(LLVMContext &C, Value *RetVal,
3616 BasicBlock *UnwindBB,
3617 BasicBlock *InsertAtEnd) {
3618 unsigned Values = 0;
3619 if (RetVal)
3620 ++Values;
3621 if (UnwindBB)
3622 ++Values;
3623 return new (Values)
3624 CleanupReturnInst(C, RetVal, UnwindBB, Values, InsertAtEnd);
3625 }
3626
3627 /// Provide fast operand accessors
3628 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
3629
3630 bool hasUnwindDest() const { return getSubclassDataFromInstruction() & 1; }
3631 bool unwindsToCaller() const { return !hasUnwindDest(); }
3632 bool hasReturnValue() const { return getSubclassDataFromInstruction() & 2; }
3633
3634 /// Convenience accessor. Returns null if there is no return value.
3635 Value *getReturnValue() const {
3636 if (!hasReturnValue())
3637 return nullptr;
3638 return getOperand(getRetValOpIdx());
3639 }
3640 void setReturnValue(Value *RetVal) {
3641 assert(hasReturnValue());
3642 setOperand(getRetValOpIdx(), RetVal);
3643 }
3644
3645 unsigned getNumSuccessors() const { return hasUnwindDest() ? 1 : 0; }
3646
3647 BasicBlock *getUnwindDest() const;
3648 void setUnwindDest(BasicBlock *NewDest);
3649
3650 // Methods for support type inquiry through isa, cast, and dyn_cast:
3651 static inline bool classof(const Instruction *I) {
3652 return (I->getOpcode() == Instruction::CleanupRet);
3653 }
3654 static inline bool classof(const Value *V) {
3655 return isa(V) && classof(cast(V));
3656 }
3657
3658 private:
3659 BasicBlock *getSuccessorV(unsigned Idx) const override;
3660 unsigned getNumSuccessorsV() const override;
3661 void setSuccessorV(unsigned Idx, BasicBlock *B) override;
3662
3663 // Shadow Instruction::setInstructionSubclassData with a private forwarding
3664 // method so that subclasses cannot accidentally use it.
3665 void setInstructionSubclassData(unsigned short D) {
3666 Instruction::setInstructionSubclassData(D);
3667 }
3668 };
3669
3670 template <>
3671 struct OperandTraits
3672 : public VariadicOperandTraits {};
3673
3674 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CleanupReturnInst, Value)
3675
3676 //===----------------------------------------------------------------------===//
36773572 // CatchEndPadInst Class
36783573 //===----------------------------------------------------------------------===//
36793574
37593654
37603655 CatchPadInst(const CatchPadInst &CPI);
37613656
3762 explicit CatchPadInst(Type *RetTy, BasicBlock *IfNormal,
3763 BasicBlock *IfException, ArrayRef Args,
3764 unsigned Values, const Twine &NameStr,
3765 Instruction *InsertBefore);
3766 explicit CatchPadInst(Type *RetTy, BasicBlock *IfNormal,
3767 BasicBlock *IfException, ArrayRef Args,
3768 unsigned Values, const Twine &NameStr,
3769 BasicBlock *InsertAtEnd);
3657 explicit CatchPadInst(BasicBlock *IfNormal, BasicBlock *IfException,
3658 ArrayRef Args, unsigned Values,
3659 const Twine &NameStr, Instruction *InsertBefore);
3660 explicit CatchPadInst(BasicBlock *IfNormal, BasicBlock *IfException,
3661 ArrayRef Args, unsigned Values,
3662 const Twine &NameStr, BasicBlock *InsertAtEnd);
37703663
37713664 protected:
37723665 // Note: Instruction needs to be a friend here to call cloneImpl.
37743667 CatchPadInst *cloneImpl() const;
37753668
37763669 public:
3777 static CatchPadInst *Create(Type *RetTy, BasicBlock *IfNormal,
3778 BasicBlock *IfException, ArrayRef Args,
3779 const Twine &NameStr = "",
3670 static CatchPadInst *Create(BasicBlock *IfNormal, BasicBlock *IfException,
3671 ArrayRef Args, const Twine &NameStr = "",
37803672 Instruction *InsertBefore = nullptr) {
37813673 unsigned Values = unsigned(Args.size()) + 2;
3782 return new (Values) CatchPadInst(RetTy, IfNormal, IfException, Args, Values,
3674 return new (Values) CatchPadInst(IfNormal, IfException, Args, Values,
37833675 NameStr, InsertBefore);
37843676 }
3785 static CatchPadInst *Create(Type *RetTy, BasicBlock *IfNormal,
3786 BasicBlock *IfException, ArrayRef Args,
3787 const Twine &NameStr, BasicBlock *InsertAtEnd) {
3677 static CatchPadInst *Create(BasicBlock *IfNormal, BasicBlock *IfException,
3678 ArrayRef Args, const Twine &NameStr,
3679 BasicBlock *InsertAtEnd) {
37883680 unsigned Values = unsigned(Args.size()) + 2;
3789 return new (Values) CatchPadInst(RetTy, IfNormal, IfException, Args, Values,
3790 NameStr, InsertAtEnd);
3681 return new (Values)
3682 CatchPadInst(IfNormal, IfException, Args, Values, NameStr, InsertAtEnd);
37913683 }
37923684
37933685 /// Provide fast operand accessors
38193711 // get*Dest - Return the destination basic blocks...
38203712 BasicBlock *getNormalDest() const { return cast(Op<-2>()); }
38213713 BasicBlock *getUnwindDest() const { return cast(Op<-1>()); }
3822 void setNormalDest(BasicBlock *B) { Op<-2>() = reinterpret_cast(B); }
3823 void setUnwindDest(BasicBlock *B) { Op<-1>() = reinterpret_cast(B); }
3714 void setNormalDest(BasicBlock *B) { Op<-2>() = B; }
3715 void setUnwindDest(BasicBlock *B) { Op<-1>() = B; }
38243716
38253717 BasicBlock *getSuccessor(unsigned i) const {
38263718 assert(i < 2 && "Successor # out of range for catchpad!");
38293721
38303722 void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
38313723 assert(idx < 2 && "Successor # out of range for catchpad!");
3832 *(&Op<-2>() + idx) = reinterpret_cast(NewSucc);
3724 *(&Op<-2>() + idx) = NewSucc;
38333725 }
38343726
38353727 unsigned getNumSuccessors() const { return 2; }
39483840 }
39493841 void setUnwindDest(BasicBlock *B) {
39503842 assert(B && hasUnwindDest());
3951 Op<-1>() = reinterpret_cast(B);
3843 Op<-1>() = B;
39523844 }
39533845
39543846 unsigned getNumSuccessors() const { return hasUnwindDest() ? 1 : 0; }
39893881
39903882 CleanupPadInst(const CleanupPadInst &CPI);
39913883
3992 explicit CleanupPadInst(Type *RetTy, ArrayRef Args,
3884 explicit CleanupPadInst(LLVMContext &C, ArrayRef Args,
39933885 const Twine &NameStr, Instruction *InsertBefore);
3994 explicit CleanupPadInst(Type *RetTy, ArrayRef Args,
3886 explicit CleanupPadInst(LLVMContext &C, ArrayRef Args,
39953887 const Twine &NameStr, BasicBlock *InsertAtEnd);
39963888
39973889 protected:
40003892 CleanupPadInst *cloneImpl() const;
40013893
40023894 public:
4003 static CleanupPadInst *Create(Type *RetTy, ArrayRef Args,
3895 static CleanupPadInst *Create(LLVMContext &C, ArrayRef Args,
40043896 const Twine &NameStr = "",
40053897 Instruction *InsertBefore = nullptr) {
4006 return new (Args.size()) CleanupPadInst(RetTy, Args, NameStr, InsertBefore);
4007 }
4008 static CleanupPadInst *Create(Type *RetTy, ArrayRef Args,
3898 return new (Args.size()) CleanupPadInst(C, Args, NameStr, InsertBefore);
3899 }
3900 static CleanupPadInst *Create(LLVMContext &C, ArrayRef Args,
40093901 const Twine &NameStr, BasicBlock *InsertAtEnd) {
4010 return new (Args.size()) CleanupPadInst(RetTy, Args, NameStr, InsertAtEnd);
3902 return new (Args.size()) CleanupPadInst(C, Args, NameStr, InsertAtEnd);
40113903 }
40123904
40133905 /// Provide fast operand accessors
40363928 CatchReturnInst(const CatchReturnInst &RI);
40373929
40383930 private:
4039 void init(BasicBlock *BB, Value *RetVal);
4040 CatchReturnInst(BasicBlock *BB, Value *RetVal, unsigned Values,
3931 void init(CatchPadInst *CatchPad, BasicBlock *BB);
3932 CatchReturnInst(CatchPadInst *CatchPad, BasicBlock *BB,
40413933 Instruction *InsertBefore = nullptr);
4042 CatchReturnInst(BasicBlock *BB, Value *RetVal, unsigned Values,
3934 CatchReturnInst(CatchPadInst *CatchPad, BasicBlock *BB,
40433935 BasicBlock *InsertAtEnd);
40443936
40453937 protected:
40483940 CatchReturnInst *cloneImpl() const;
40493941
40503942 public:
4051 static CatchReturnInst *Create(BasicBlock *BB, Value *RetVal = nullptr,
3943 static CatchReturnInst *Create(CatchPadInst *CatchPad, BasicBlock *BB,
40523944 Instruction *InsertBefore = nullptr) {
3945 assert(CatchPad);
40533946 assert(BB);
4054 unsigned Values = 1;
4055 if (RetVal)
4056 ++Values;
4057 return new (Values) CatchReturnInst(BB, RetVal, Values, InsertBefore);
4058 }
4059 static CatchReturnInst *Create(BasicBlock *BB, Value *RetVal,
3947 return new (2) CatchReturnInst(CatchPad, BB, InsertBefore);
3948 }
3949 static CatchReturnInst *Create(CatchPadInst *CatchPad, BasicBlock *BB,
40603950 BasicBlock *InsertAtEnd) {
3951 assert(CatchPad);
40613952 assert(BB);
4062 unsigned Values = 1;
4063 if (RetVal)
4064 ++Values;
4065 return new (Values) CatchReturnInst(BB, RetVal, Values, InsertAtEnd);
3953 return new (2) CatchReturnInst(CatchPad, BB, InsertAtEnd);
40663954 }
40673955
40683956 /// Provide fast operand accessors
40693957 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
40703958
40713959 /// Convenience accessors.
4072 BasicBlock *getSuccessor() const { return cast(Op<-1>()); }
4073 void setSuccessor(BasicBlock *NewSucc) { Op<-1>() = (Value *)NewSucc; }
3960 CatchPadInst *getCatchPad() const { return cast(Op<0>()); }
3961 void setCatchPad(CatchPadInst *CatchPad) {
3962 assert(CatchPad);
3963 Op<0>() = CatchPad;
3964 }
3965
3966 BasicBlock *getSuccessor() const { return cast(Op<1>()); }
3967 void setSuccessor(BasicBlock *NewSucc) {
3968 assert(NewSucc);
3969 Op<1>() = NewSucc;
3970 }
40743971 unsigned getNumSuccessors() const { return 1; }
4075
4076 bool hasReturnValue() const { return getNumOperands() > 1; }
4077 Value *getReturnValue() const { return Op<-2>(); }
4078 void setReturnValue(Value *RetVal) { Op<-2>() = RetVal; }
40793972
40803973 // Methods for support type inquiry through isa, cast, and dyn_cast:
40813974 static inline bool classof(const Instruction *I) {
40933986
40943987 template <>
40953988 struct OperandTraits
4096 : public VariadicOperandTraits> {};
3989 : public FixedNumOperandTraits> {};
40973990
40983991 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CatchReturnInst, Value)
3992
3993 //===----------------------------------------------------------------------===//
3994 // CleanupReturnInst Class
3995 //===----------------------------------------------------------------------===//
3996
3997 class CleanupReturnInst : public TerminatorInst {
3998 CleanupReturnInst(const CleanupReturnInst &RI);
3999
4000 private:
4001 void init(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB);
4002 CleanupReturnInst(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB,
4003 unsigned Values, Instruction *InsertBefore = nullptr);
4004 CleanupReturnInst(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB,
4005 unsigned Values, BasicBlock *InsertAtEnd);
4006
4007 int getUnwindLabelOpIdx() const {
4008 assert(hasUnwindDest());
4009 return 0;
4010 }
4011
4012 protected:
4013 // Note: Instruction needs to be a friend here to call cloneImpl.
4014 friend class Instruction;
4015 CleanupReturnInst *cloneImpl() const;
4016
4017 public:
4018 static CleanupReturnInst *Create(CleanupPadInst *CleanupPad,
4019 BasicBlock *UnwindBB = nullptr,
4020 Instruction *InsertBefore = nullptr) {
4021 assert(CleanupPad);
4022 unsigned Values = 1;
4023 if (UnwindBB)
4024 ++Values;
4025 return new (Values)
4026 CleanupReturnInst(CleanupPad, UnwindBB, Values, InsertBefore);
4027 }
4028 static CleanupReturnInst *Create(CleanupPadInst *CleanupPad,
4029 BasicBlock *UnwindBB,
4030 BasicBlock *InsertAtEnd) {
4031 assert(CleanupPad);
4032 unsigned Values = 1;
4033 if (UnwindBB)
4034 ++Values;
4035 return new (Values)
4036 CleanupReturnInst(CleanupPad, UnwindBB, Values, InsertAtEnd);
4037 }
4038
4039 /// Provide fast operand accessors
4040 DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
4041
4042 bool hasUnwindDest() const { return getSubclassDataFromInstruction() & 1; }
4043 bool unwindsToCaller() const { return !hasUnwindDest(); }
4044
4045 /// Convenience accessor.
4046 CleanupPadInst *getCleanupPad() const {
4047 return cast(Op<-1>());
4048 }
4049 void setCleanupPad(CleanupPadInst *CleanupPad) {
4050 assert(CleanupPad);
4051 Op<-1>() = CleanupPad;
4052 }
4053
4054 unsigned getNumSuccessors() const { return hasUnwindDest() ? 1 : 0; }
4055
4056 BasicBlock *getUnwindDest() const {
4057 return hasUnwindDest() ? cast(Op<-2>()) : nullptr;
4058 }
4059 void setUnwindDest(BasicBlock *NewDest) {
4060 assert(NewDest);
4061 assert(hasUnwindDest());
4062 Op<-2>() = NewDest;
4063 }
4064
4065 // Methods for support type inquiry through isa, cast, and dyn_cast:
4066 static inline bool classof(const Instruction *I) {
4067 return (I->getOpcode() == Instruction::CleanupRet);
4068 }
4069 static inline bool classof(const Value *V) {
4070 return isa(V) && classof(cast(V));
4071 }
4072
4073 private:
4074 BasicBlock *getSuccessorV(unsigned Idx) const override;
4075 unsigned getNumSuccessorsV() const override;
4076 void setSuccessorV(unsigned Idx, BasicBlock *B) override;
4077
4078 // Shadow Instruction::setInstructionSubclassData with a private forwarding
4079 // method so that subclasses cannot accidentally use it.
4080 void setInstructionSubclassData(unsigned short D) {
4081 Instruction::setInstructionSubclassData(D);
4082 }
4083 };
4084
4085 template <>
4086 struct OperandTraits
4087 : public VariadicOperandTraits {};
4088
4089 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(CleanupReturnInst, Value)
40994090
41004091 //===----------------------------------------------------------------------===//
41014092 // UnreachableInst Class
912912
913913 bool CallAnalyzer::visitCatchReturnInst(CatchReturnInst &CRI) {
914914 // FIXME: It's not clear that a single instruction is an accurate model for
915 // the inline cost of a cleanupret instruction.
915 // the inline cost of a catchret instruction.
916916 return false;
917917 }
918918
22362236 /// GetVal - Get a value with the specified name or ID, creating a
22372237 /// forward reference record if needed. This can return null if the value
22382238 /// exists but does not have the right type.
2239 Value *LLParser::PerFunctionState::GetVal(const std::string &Name,
2240 Type *Ty, LocTy Loc) {
2239 Value *LLParser::PerFunctionState::GetVal(const std::string &Name, Type *Ty,
2240 LocTy Loc, OperatorConstraint OC) {
22412241 // Look this name up in the normal function symbol table.
22422242 Value *Val = F.getValueSymbolTable().lookup(Name);
22432243
22522252
22532253 // If we have the value in the symbol table or fwd-ref table, return it.
22542254 if (Val) {
2255 // Check operator constraints.
2256 switch (OC) {
2257 case OC_None:
2258 // no constraint
2259 break;
2260 case OC_CatchPad:
2261 if (!isa(Val)) {
2262 P.Error(Loc, "'%" + Name + "' is not a catchpad");
2263 return nullptr;
2264 }
2265 break;
2266 case OC_CleanupPad:
2267 if (!isa(Val)) {
2268 P.Error(Loc, "'%" + Name + "' is not a cleanuppad");
2269 return nullptr;
2270 }
2271 break;
2272 }
22552273 if (Val->getType() == Ty) return Val;
22562274 if (Ty->isLabelTy())
22572275 P.Error(Loc, "'%" + Name + "' is not a basic block");
22692287
22702288 // Otherwise, create a new forward reference for this value and remember it.
22712289 Value *FwdVal;
2272 if (Ty->isLabelTy())
2290 if (Ty->isLabelTy()) {
2291 assert(!OC);
22732292 FwdVal = BasicBlock::Create(F.getContext(), Name, &F);
2274 else
2293 } else if (!OC) {
22752294 FwdVal = new Argument(Ty, Name);
2295 } else {
2296 switch (OC) {
2297 case OC_CatchPad:
2298 FwdVal = CatchPadInst::Create(&F.getEntryBlock(), &F.getEntryBlock(), {},
2299 Name);
2300 break;
2301 case OC_CleanupPad:
2302 FwdVal = CleanupPadInst::Create(F.getContext(), {}, Name);
2303 break;
2304 default:
2305 llvm_unreachable("unexpected constraint");
2306 }
2307 }
22762308
22772309 ForwardRefVals[Name] = std::make_pair(FwdVal, Loc);
22782310 return FwdVal;
22792311 }
22802312
2281 Value *LLParser::PerFunctionState::GetVal(unsigned ID, Type *Ty,
2282 LocTy Loc) {
2313 Value *LLParser::PerFunctionState::GetVal(unsigned ID, Type *Ty, LocTy Loc,
2314 OperatorConstraint OC) {
22832315 // Look this name up in the normal function symbol table.
22842316 Value *Val = ID < NumberedVals.size() ? NumberedVals[ID] : nullptr;
22852317
22942326
22952327 // If we have the value in the symbol table or fwd-ref table, return it.
22962328 if (Val) {
2329 // Check operator constraint.
2330 switch (OC) {
2331 case OC_None:
2332 // no constraint
2333 break;
2334 case OC_CatchPad:
2335 if (!isa(Val)) {
2336 P.Error(Loc, "'%" + Twine(ID) + "' is not a catchpad");
2337 return nullptr;
2338 }
2339 break;
2340 case OC_CleanupPad:
2341 if (!isa(Val)) {
2342 P.Error(Loc, "'%" + Twine(ID) + "' is not a cleanuppad");
2343 return nullptr;
2344 }
2345 break;
2346 }
22972347 if (Val->getType() == Ty) return Val;
22982348 if (Ty->isLabelTy())
22992349 P.Error(Loc, "'%" + Twine(ID) + "' is not a basic block");
23102360
23112361 // Otherwise, create a new forward reference for this value and remember it.
23122362 Value *FwdVal;
2313 if (Ty->isLabelTy())
2363 if (Ty->isLabelTy()) {
2364 assert(!OC);
23142365 FwdVal = BasicBlock::Create(F.getContext(), "", &F);
2315 else
2366 } else if (!OC) {
23162367 FwdVal = new Argument(Ty);
2368 } else {
2369 switch (OC) {
2370 case OC_CatchPad:
2371 FwdVal = CatchPadInst::Create(&F.getEntryBlock(), &F.getEntryBlock(), {});
2372 break;
2373 case OC_CleanupPad:
2374 FwdVal = CleanupPadInst::Create(F.getContext(), {});
2375 break;
2376 default:
2377 llvm_unreachable("unexpected constraint");
2378 }
2379 }
23172380
23182381 ForwardRefValIDs[ID] = std::make_pair(FwdVal, Loc);
23192382 return FwdVal;
23452408 std::map >::iterator FI =
23462409 ForwardRefValIDs.find(NameID);
23472410 if (FI != ForwardRefValIDs.end()) {
2348 if (FI->second.first->getType() != Inst->getType())
2411 Value *Sentinel = FI->second.first;
2412 if (Sentinel->getType() != Inst->getType())
23492413 return P.Error(NameLoc, "instruction forward referenced with type '" +
23502414 getTypeString(FI->second.first->getType()) + "'");
2351 FI->second.first->replaceAllUsesWith(Inst);
2352 delete FI->second.first;
2415 // Check operator constraints. We only put cleanuppads or catchpads in
2416 // the forward value map if the value is constrained to match.
2417 if (isa(Sentinel)) {
2418 if (!isa(Inst))
2419 return P.Error(FI->second.second,
2420 "'%" + Twine(NameID) + "' is not a catchpad");
2421 } else if (isa(Sentinel)) {
2422 if (!isa(Inst))
2423 return P.Error(FI->second.second,
2424 "'%" + Twine(NameID) + "' is not a cleanuppad");
2425 }
2426
2427 Sentinel->replaceAllUsesWith(Inst);
2428 delete Sentinel;
23532429 ForwardRefValIDs.erase(FI);
23542430 }
23552431
23612437 std::map >::iterator
23622438 FI = ForwardRefVals.find(NameStr);
23632439 if (FI != ForwardRefVals.end()) {
2364 if (FI->second.first->getType() != Inst->getType())
2440 Value *Sentinel = FI->second.first;
2441 if (Sentinel->getType() != Inst->getType())
23652442 return P.Error(NameLoc, "instruction forward referenced with type '" +
23662443 getTypeString(FI->second.first->getType()) + "'");
2367 FI->second.first->replaceAllUsesWith(Inst);
2368 delete FI->second.first;
2444 // Check operator constraints. We only put cleanuppads or catchpads in
2445 // the forward value map if the value is constrained to match.
2446 if (isa(Sentinel)) {
2447 if (!isa(Inst))
2448 return P.Error(FI->second.second,
2449 "'%" + NameStr + "' is not a catchpad");
2450 } else if (isa(Sentinel)) {
2451 if (!isa(Inst))
2452 return P.Error(FI->second.second,
2453 "'%" + NameStr + "' is not a cleanuppad");
2454 }
2455
2456 Sentinel->replaceAllUsesWith(Inst);
2457 delete Sentinel;
23692458 ForwardRefVals.erase(FI);
23702459 }
23712460
40064095 //===----------------------------------------------------------------------===//
40074096
40084097 bool LLParser::ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V,
4009 PerFunctionState *PFS) {
4098 PerFunctionState *PFS,
4099 OperatorConstraint OC) {
40104100 if (Ty->isFunctionTy())
40114101 return Error(ID.Loc, "functions are not values, refer to them as pointers");
4102
4103 if (OC && ID.Kind != ValID::t_LocalID && ID.Kind != ValID::t_LocalName) {
4104 switch (OC) {
4105 case OC_CatchPad:
4106 return Error(ID.Loc, "Catchpad value required in this position");
4107 case OC_CleanupPad:
4108 return Error(ID.Loc, "Cleanuppad value required in this position");
4109 default:
4110 llvm_unreachable("Unexpected constraint kind");
4111 }
4112 }
40124113
40134114 switch (ID.Kind) {
40144115 case ValID::t_LocalID:
40154116 if (!PFS) return Error(ID.Loc, "invalid use of function-local name");
4016 V = PFS->GetVal(ID.UIntVal, Ty, ID.Loc);
4117 V = PFS->GetVal(ID.UIntVal, Ty, ID.Loc, OC);
40174118 return V == nullptr;
40184119 case ValID::t_LocalName:
40194120 if (!PFS) return Error(ID.Loc, "invalid use of function-local name");
4020 V = PFS->GetVal(ID.StrVal, Ty, ID.Loc);
4121 V = PFS->GetVal(ID.StrVal, Ty, ID.Loc, OC);
40214122 return V == nullptr;
40224123 case ValID::t_InlineAsm: {
40234124 assert(ID.FTy);
41394240 }
41404241 }
41414242
4142 bool LLParser::ParseValue(Type *Ty, Value *&V, PerFunctionState *PFS) {
4243 bool LLParser::ParseValue(Type *Ty, Value *&V, PerFunctionState *PFS,
4244 OperatorConstraint OC) {
41434245 V = nullptr;
41444246 ValID ID;
4145 return ParseValID(ID, PFS) ||
4146 ConvertValIDToValue(Ty, ID, V, PFS);
4247 return ParseValID(ID, PFS) || ConvertValIDToValue(Ty, ID, V, PFS, OC);
41474248 }
41484249
41494250 bool LLParser::ParseTypeAndValue(Value *&V, PerFunctionState *PFS) {
49845085
49855086 bool LLParser::ParseExceptionArgs(SmallVectorImpl &Args,
49865087 PerFunctionState &PFS) {
4987 if (ParseToken(lltok::lsquare, "expected '[' in cleanuppad"))
5088 if (ParseToken(lltok::lsquare, "expected '[' in catchpad/cleanuppad"))
49885089 return true;
49895090
49905091 while (Lex.getKind() != lltok::rsquare) {
50155116 }
50165117
50175118 /// ParseCleanupRet
5018 /// ::= 'cleanupret' ('void' | TypeAndValue) unwind ('to' 'caller' | TypeAndValue)
5119 /// ::= 'cleanupret' Value unwind ('to' 'caller' | TypeAndValue)
50195120 bool LLParser::ParseCleanupRet(Instruction *&Inst, PerFunctionState &PFS) {
5020 Type *RetTy = nullptr;
5021 Value *RetVal = nullptr;
5022 if (ParseType(RetTy, /*AllowVoid=*/true))
5023 return true;
5024
5025 if (!RetTy->isVoidTy())
5026 if (ParseValue(RetTy, RetVal, PFS))
5027 return true;
5121 Value *CleanupPad = nullptr;
5122
5123 if (ParseValue(Type::getTokenTy(Context), CleanupPad, PFS, OC_CleanupPad))
5124 return true;
50285125
50295126 if (ParseToken(lltok::kw_unwind, "expected 'unwind' in cleanupret"))
50305127 return true;
50405137 }
50415138 }
50425139
5043 Inst = CleanupReturnInst::Create(Context, RetVal, UnwindBB);
5140 Inst = CleanupReturnInst::Create(cast(CleanupPad), UnwindBB);
50445141 return false;
50455142 }
50465143
50475144 /// ParseCatchRet
5048 /// ::= 'catchret' ('void' | TypeAndValue) 'to' TypeAndValue
5145 /// ::= 'catchret' Value 'to' TypeAndValue
50495146 bool LLParser::ParseCatchRet(Instruction *&Inst, PerFunctionState &PFS) {
5050 Type *RetTy = nullptr;
5051 Value *RetVal = nullptr;
5052
5053 if (ParseType(RetTy, /*AllowVoid=*/true))
5054 return true;
5055
5056 if (!RetTy->isVoidTy())
5057 if (ParseValue(RetTy, RetVal, PFS))
5058 return true;
5147 Value *CatchPad = nullptr;
5148
5149 if (ParseValue(Type::getTokenTy(Context), CatchPad, PFS, OC_CatchPad))
5150 return true;
50595151
50605152 BasicBlock *BB;
50615153 if (ParseToken(lltok::kw_to, "expected 'to' in catchret") ||
50625154 ParseTypeAndBasicBlock(BB, PFS))
50635155 return true;
50645156
5065 Inst = CatchReturnInst::Create(BB, RetVal);
5157 Inst = CatchReturnInst::Create(cast(CatchPad), BB);
50665158 return false;
50675159 }
50685160
50695161 /// ParseCatchPad
5070 /// ::= 'catchpad' Type ParamList 'to' TypeAndValue 'unwind' TypeAndValue
5162 /// ::= 'catchpad' ParamList 'to' TypeAndValue 'unwind' TypeAndValue
50715163 bool LLParser::ParseCatchPad(Instruction *&Inst, PerFunctionState &PFS) {
5072 Type *RetType = nullptr;
5073
50745164 SmallVector Args;
5075 if (ParseType(RetType, /*AllowVoid=*/true) || ParseExceptionArgs(Args, PFS))
5165 if (ParseExceptionArgs(Args, PFS))
50765166 return true;
50775167
50785168 BasicBlock *NormalBB, *UnwindBB;
50825172 ParseTypeAndBasicBlock(UnwindBB, PFS))
50835173 return true;
50845174
5085 Inst = CatchPadInst::Create(RetType, NormalBB, UnwindBB, Args);
5175 Inst = CatchPadInst::Create(NormalBB, UnwindBB, Args);
50865176 return false;
50875177 }
50885178
51145204 /// ParseCleanupPad
51155205 /// ::= 'cleanuppad' ParamList
51165206 bool LLParser::ParseCleanupPad(Instruction *&Inst, PerFunctionState &PFS) {
5117 Type *RetType = nullptr;
5118
51195207 SmallVector Args;
5120 if (ParseType(RetType, /*AllowVoid=*/true) || ParseExceptionArgs(Args, PFS))
5121 return true;
5122
5123 Inst = CleanupPadInst::Create(RetType, Args);
5208 if (ParseExceptionArgs(Args, PFS))
5209 return true;
5210
5211 Inst = CleanupPadInst::Create(Context, Args);
51245212 return false;
51255213 }
51265214
105105 struct MDRef {
106106 SMLoc Loc;
107107 unsigned MDKind, MDSlot;
108 };
109
110 /// Indicates which operator an operand allows (for the few operands that
111 /// may only reference a certain operator).
112 enum OperatorConstraint {
113 OC_None = 0, // No constraint
114 OC_CatchPad, // Must be CatchPadInst
115 OC_CleanupPad // Must be CleanupPadInst
108116 };
109117
110118 SmallVector InstsWithTBAATag;
328336 /// GetVal - Get a value with the specified name or ID, creating a
329337 /// forward reference record if needed. This can return null if the value
330338 /// exists but does not have the right type.
331 Value *GetVal(const std::string &Name, Type *Ty, LocTy Loc);
332 Value *GetVal(unsigned ID, Type *Ty, LocTy Loc);
339 Value *GetVal(const std::string &Name, Type *Ty, LocTy Loc,
340 OperatorConstraint OC = OC_None);
341 Value *GetVal(unsigned ID, Type *Ty, LocTy Loc,
342 OperatorConstraint OC = OC_None);
333343
334344 /// SetInstName - After an instruction is parsed and inserted into its
335345 /// basic block, this installs its name.
351361 };
352362
353363 bool ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V,
354 PerFunctionState *PFS);
364 PerFunctionState *PFS,
365 OperatorConstraint OC = OC_None);
355366
356367 bool parseConstantValue(Type *Ty, Constant *&C);
357 bool ParseValue(Type *Ty, Value *&V, PerFunctionState *PFS);
358 bool ParseValue(Type *Ty, Value *&V, PerFunctionState &PFS) {
359 return ParseValue(Ty, V, &PFS);
368 bool ParseValue(Type *Ty, Value *&V, PerFunctionState *PFS,
369 OperatorConstraint OC = OC_None);
370 bool ParseValue(Type *Ty, Value *&V, PerFunctionState &PFS,
371 OperatorConstraint OC = OC_None) {
372 return ParseValue(Ty, V, &PFS, OC);
360373 }
361374 bool ParseValue(Type *Ty, Value *&V, LocTy &Loc,
362375 PerFunctionState &PFS) {
4040 SWITCH_INST_MAGIC = 0x4B5 // May 2012 => 1205 => Hex
4141 };
4242
43 /// Indicates which operator an operand allows (for the few operands that may
44 /// only reference a certain operator).
45 enum OperatorConstraint {
46 OC_None = 0, // No constraint
47 OC_CatchPad, // Must be CatchPadInst
48 OC_CleanupPad // Must be CleanupPadInst
49 };
50
4351 class BitcodeReaderValueList {
4452 std::vector ValuePtrs;
4553
8391 }
8492
8593 Constant *getConstantFwdRef(unsigned Idx, Type *Ty);
86 Value *getValueFwdRef(unsigned Idx, Type *Ty);
87
88 void assignValue(Value *V, unsigned Idx);
94 Value *getValueFwdRef(unsigned Idx, Type *Ty,
95 OperatorConstraint OC = OC_None);
96
97 bool assignValue(Value *V, unsigned Idx);
8998
9099 /// Once all constants are read, this method bulk resolves any forward
91100 /// references.
261270 StructType *createIdentifiedStructType(LLVMContext &Context);
262271
263272 Type *getTypeByID(unsigned ID);
264 Value *getFnValueByID(unsigned ID, Type *Ty) {
273 Value *getFnValueByID(unsigned ID, Type *Ty,
274 OperatorConstraint OC = OC_None) {
265275 if (Ty && Ty->isMetadataTy())
266276 return MetadataAsValue::get(Ty->getContext(), getFnMetadataByID(ID));
267 return ValueList.getValueFwdRef(ID, Ty);
277 return ValueList.getValueFwdRef(ID, Ty, OC);
268278 }
269279 Metadata *getFnMetadataByID(unsigned ID) {
270280 return MDValueList.getValueFwdRef(ID);
307317 /// past the number of slots used by the value in the record. Return true if
308318 /// there is an error.
309319 bool popValue(SmallVectorImpl &Record, unsigned &Slot,
310 unsigned InstNum, Type *Ty, Value *&ResVal) {
311 if (getValue(Record, Slot, InstNum, Ty, ResVal))
320 unsigned InstNum, Type *Ty, Value *&ResVal,
321 OperatorConstraint OC = OC_None) {
322 if (getValue(Record, Slot, InstNum, Ty, ResVal, OC))
312323 return true;
313324 // All values currently take a single record slot.
314325 ++Slot;
317328
318329 /// Like popValue, but does not increment the Slot number.
319330 bool getValue(SmallVectorImpl &Record, unsigned Slot,
320 unsigned InstNum, Type *Ty, Value *&ResVal) {
321 ResVal = getValue(Record, Slot, InstNum, Ty);
331 unsigned InstNum, Type *Ty, Value *&ResVal,
332 OperatorConstraint OC = OC_None) {
333 ResVal = getValue(Record, Slot, InstNum, Ty, OC);
322334 return ResVal == nullptr;
323335 }
324336
325337 /// Version of getValue that returns ResVal directly, or 0 if there is an
326338 /// error.
327339 Value *getValue(SmallVectorImpl &Record, unsigned Slot,
328 unsigned InstNum, Type *Ty) {
340 unsigned InstNum, Type *Ty, OperatorConstraint OC = OC_None) {
329341 if (Slot == Record.size()) return nullptr;
330342 unsigned ValNo = (unsigned)Record[Slot];
331343 // Adjust the ValNo, if it was encoded relative to the InstNum.
332344 if (UseRelativeIDs)
333345 ValNo = InstNum - ValNo;
334 return getFnValueByID(ValNo, Ty);
346 return getFnValueByID(ValNo, Ty, OC);
335347 }
336348
337349 /// Like getValue, but decodes signed VBRs.
338350 Value *getValueSigned(SmallVectorImpl &Record, unsigned Slot,
339 unsigned InstNum, Type *Ty) {
351 unsigned InstNum, Type *Ty,
352 OperatorConstraint OC = OC_None) {
340353 if (Slot == Record.size()) return nullptr;
341354 unsigned ValNo = (unsigned)decodeSignRotatedValue(Record[Slot]);
342355 // Adjust the ValNo, if it was encoded relative to the InstNum.
343356 if (UseRelativeIDs)
344357 ValNo = InstNum - ValNo;
345 return getFnValueByID(ValNo, Ty);
358 return getFnValueByID(ValNo, Ty, OC);
346359 }
347360
348361 /// Converts alignment exponent (i.e. power of two (or zero)) to the
752765 DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantPlaceHolder, Value)
753766 }
754767
755 void BitcodeReaderValueList::assignValue(Value *V, unsigned Idx) {
768 bool BitcodeReaderValueList::assignValue(Value *V, unsigned Idx) {
756769 if (Idx == size()) {
757770 push_back(V);
758 return;
771 return false;
759772 }
760773
761774 if (Idx >= size())
764777 WeakVH &OldV = ValuePtrs[Idx];
765778 if (!OldV) {
766779 OldV = V;
767 return;
780 return false;
768781 }
769782
770783 // Handle constants and non-constants (e.g. instrs) differently for
775788 } else {
776789 // If there was a forward reference to this value, replace it.
777790 Value *PrevVal = OldV;
791 // Check operator constraints. We only put cleanuppads or catchpads in
792 // the forward value map if the value is constrained to match.
793 if (CatchPadInst *CatchPad = dyn_cast(PrevVal)) {
794 if (!isa(V))
795 return true;
796 // Delete the dummy basic block that was created with the sentinel
797 // catchpad.
798 BasicBlock *DummyBlock = CatchPad->getUnwindDest();
799 assert(DummyBlock == CatchPad->getNormalDest());
800 CatchPad->dropAllReferences();
801 delete DummyBlock;
802 } else if (isa(PrevVal)) {
803 if (!isa(V))
804 return true;
805 }
778806 OldV->replaceAllUsesWith(V);
779807 delete PrevVal;
780808 }
809
810 return false;
781811 }
782812
783813
798828 return C;
799829 }
800830
801 Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, Type *Ty) {
831 Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, Type *Ty,
832 OperatorConstraint OC) {
802833 // Bail out for a clearly invalid value. This would make us call resize(0)
803834 if (Idx == UINT_MAX)
804835 return nullptr;
810841 // If the types don't match, it's invalid.
811842 if (Ty && Ty != V->getType())
812843 return nullptr;
813 return V;
844 if (!OC)
845 return V;
846 // Use dyn_cast to enforce operator constraints
847 switch (OC) {
848 case OC_CatchPad:
849 return dyn_cast(V);
850 case OC_CleanupPad:
851 return dyn_cast(V);
852 default:
853 llvm_unreachable("Unexpected operator constraint");
854 }
814855 }
815856
816857 // No type specified, must be invalid reference.
817858 if (!Ty) return nullptr;
818859
819860 // Create and return a placeholder, which will later be RAUW'd.
820 Value *V = new Argument(Ty);
861 Value *V;
862 switch (OC) {
863 case OC_None:
864 V = new Argument(Ty);
865 break;
866 case OC_CatchPad: {
867 BasicBlock *BB = BasicBlock::Create(Context);
868 V = CatchPadInst::Create(BB, BB, {});
869 break;
870 }
871 default:
872 assert(OC == OC_CleanupPad && "unexpected operator constraint");
873 V = CleanupPadInst::Create(Context, {});
874 break;
875 }
876
821877 ValuePtrs[Idx] = V;
822878 return V;
823879 }
26092665 }
26102666 }
26112667
2612 ValueList.assignValue(V, NextCstNo);
2668 if (ValueList.assignValue(V, NextCstNo))
2669 return error("Invalid forward reference");
26132670 ++NextCstNo;
26142671 }
26152672 }
38183875 }
38193876 break;
38203877 }
3821 // CLEANUPRET: [] or [ty,val] or [bb#] or [ty,val,bb#]
3878 // CLEANUPRET: [val] or [val,bb#]
38223879 case bitc::FUNC_CODE_INST_CLEANUPRET: {
3823 if (Record.size() < 2)
3880 if (Record.size() != 1 && Record.size() != 2)
38243881 return error("Invalid record");
38253882 unsigned Idx = 0;
3826 bool HasReturnValue = !!Record[Idx++];
3827 bool HasUnwindDest = !!Record[Idx++];
3828 Value *RetVal = nullptr;
3883 Value *CleanupPad = getValue(Record, Idx++, NextValueNo,
3884 Type::getTokenTy(Context), OC_CleanupPad);
3885 if (!CleanupPad)
3886 return error("Invalid record");
38293887 BasicBlock *UnwindDest = nullptr;
3830
3831 if (HasReturnValue && getValueTypePair(Record, Idx, NextValueNo, RetVal))
3832 return error("Invalid record");
3833 if (HasUnwindDest) {
3834 if (Idx == Record.size())
3835 return error("Invalid record");
3888 if (Record.size() == 2) {
38363889 UnwindDest = getBasicBlock(Record[Idx++]);
38373890 if (!UnwindDest)
38383891 return error("Invalid record");
38393892 }
38403893
3841 if (Record.size() != Idx)
3842 return error("Invalid record");
3843
3844 I = CleanupReturnInst::Create(Context, RetVal, UnwindDest);
3894 I = CleanupReturnInst::Create(cast(CleanupPad),
3895 UnwindDest);
38453896 InstructionList.push_back(I);
38463897 break;
38473898 }
3848 case bitc::FUNC_CODE_INST_CATCHRET: { // CATCHRET: [bb#]
3849 if (Record.size() != 1 && Record.size() != 3)
3899 case bitc::FUNC_CODE_INST_CATCHRET: { // CATCHRET: [val,bb#]
3900 if (Record.size() != 2)
38503901 return error("Invalid record");
38513902 unsigned Idx = 0;
3903 Value *CatchPad = getValue(Record, Idx++, NextValueNo,
3904 Type::getTokenTy(Context), OC_CatchPad);
3905 if (!CatchPad)
3906 return error("Invalid record");
38523907 BasicBlock *BB = getBasicBlock(Record[Idx++]);
38533908 if (!BB)
38543909 return error("Invalid record");
3855 Value *RetVal = nullptr;
3856 if (Record.size() == 3 &&
3857 getValueTypePair(Record, Idx, NextValueNo, RetVal))
3858 return error("Invalid record");
3859
3860 I = CatchReturnInst::Create(BB, RetVal);
3910
3911 I = CatchReturnInst::Create(cast(CatchPad), BB);
38613912 InstructionList.push_back(I);
38623913 break;
38633914 }
3864 case bitc::FUNC_CODE_INST_CATCHPAD: { // CATCHPAD: [ty,bb#,bb#,num,(ty,val)*]
3865 if (Record.size() < 4)
3915 case bitc::FUNC_CODE_INST_CATCHPAD: { // CATCHPAD: [bb#,bb#,num,(ty,val)*]
3916 if (Record.size() < 3)
38663917 return error("Invalid record");
38673918 unsigned Idx = 0;
3868 Type *Ty = getTypeByID(Record[Idx++]);
3869 if (!Ty)
3870 return error("Invalid record");
38713919 BasicBlock *NormalBB = getBasicBlock(Record[Idx++]);
38723920 if (!NormalBB)
38733921 return error("Invalid record");
38853933 if (Record.size() != Idx)
38863934 return error("Invalid record");
38873935
3888 I = CatchPadInst::Create(Ty, NormalBB, UnwindBB, Args);
3936 I = CatchPadInst::Create(NormalBB, UnwindBB, Args);
38893937 InstructionList.push_back(I);
38903938 break;
38913939 }
39173965 InstructionList.push_back(I);
39183966 break;
39193967 }
3920 case bitc::FUNC_CODE_INST_CLEANUPPAD: { // CLEANUPPAD: [ty, num,(ty,val)*]
3921 if (Record.size() < 2)
3968 case bitc::FUNC_CODE_INST_CLEANUPPAD: { // CLEANUPPAD: [num,(ty,val)*]
3969 if (Record.size() < 1)
39223970 return error("Invalid record");
39233971 unsigned Idx = 0;
3924 Type *Ty = getTypeByID(Record[Idx++]);
3925 if (!Ty)
3926 return error("Invalid record");
39273972 unsigned NumArgOperands = Record[Idx++];
39283973 SmallVector Args;
39293974 for (unsigned Op = 0; Op != NumArgOperands; ++Op) {
39353980 if (Record.size() != Idx)
39363981 return error("Invalid record");
39373982
3938 I = CleanupPadInst::Create(Ty, Args);
3983 I = CleanupPadInst::Create(Context, Args);
39393984 InstructionList.push_back(I);
39403985 break;
39413986 }
45404585
45414586 // Non-void values get registered in the value table for future use.
45424587 if (I && !I->getType()->isVoidTy())
4543 ValueList.assignValue(I, NextValueNo++);
4588 if (ValueList.assignValue(I, NextValueNo++))
4589 return error("Invalid forward reference");
45444590 }
45454591
45464592 OutOfRecordLoop:
18541854 case Instruction::CleanupRet: {
18551855 Code = bitc::FUNC_CODE_INST_CLEANUPRET;
18561856 const auto &CRI = cast(I);
1857 Vals.push_back(CRI.hasReturnValue());
1858 Vals.push_back(CRI.hasUnwindDest());
1859 if (CRI.hasReturnValue())
1860 PushValueAndType(CRI.getReturnValue(), InstID, Vals, VE);
1857 pushValue(CRI.getCleanupPad(), InstID, Vals, VE);
18611858 if (CRI.hasUnwindDest())
18621859 Vals.push_back(VE.getValueID(CRI.getUnwindDest()));
18631860 break;
18651862 case Instruction::CatchRet: {
18661863 Code = bitc::FUNC_CODE_INST_CATCHRET;
18671864 const auto &CRI = cast(I);
1865 pushValue(CRI.getCatchPad(), InstID, Vals, VE);
18681866 Vals.push_back(VE.getValueID(CRI.getSuccessor()));
1869 if (CRI.hasReturnValue())
1870 PushValueAndType(CRI.getReturnValue(), InstID, Vals, VE);
18711867 break;
18721868 }
18731869 case Instruction::CatchPad: {
18741870 Code = bitc::FUNC_CODE_INST_CATCHPAD;
18751871 const auto &CPI = cast(I);
1876 Vals.push_back(VE.getTypeID(CPI.getType()));
18771872 Vals.push_back(VE.getValueID(CPI.getNormalDest()));
18781873 Vals.push_back(VE.getValueID(CPI.getUnwindDest()));
18791874 unsigned NumArgOperands = CPI.getNumArgOperands();
18971892 case Instruction::CleanupPad: {
18981893 Code = bitc::FUNC_CODE_INST_CLEANUPPAD;
18991894 const auto &CPI = cast(I);
1900 Vals.push_back(VE.getTypeID(CPI.getType()));
19011895 unsigned NumOperands = CPI.getNumOperands();
19021896 Vals.push_back(NumOperands);
19031897 for (unsigned Op = 0; Op != NumOperands; ++Op)
29552955 if (isa(TI) || isa(TI) ||
29562956 isa(TI))
29572957 return BB;
2958 return cast(cast(TI)->getReturnValue())
2959 ->getParent();
2958 return cast(TI)->getCleanupPad()->getParent();
29602959 }
29612960
29622961 static void calculateExplicitStateNumbers(WinEHFuncInfo &FuncInfo,
32413240 // The token consumed by a CatchReturnInst must match the funclet token.
32423241 bool IsUnreachableCatchret = false;
32433242 if (auto *CRI = dyn_cast(TI))
3244 IsUnreachableCatchret = CRI->getReturnValue() != CatchPad;
3243 IsUnreachableCatchret = CRI->getCatchPad() != CatchPad;
32453244 // The token consumed by a CleanupPadInst must match the funclet token.
32463245 bool IsUnreachableCleanupret = false;
32473246 if (auto *CRI = dyn_cast(TI))
3248 IsUnreachableCleanupret = CRI->getReturnValue() != CleanupPad;
3247 IsUnreachableCleanupret = CRI->getCleanupPad() != CleanupPad;
32493248 if (IsUnreachableRet || IsUnreachableCatchret || IsUnreachableCleanupret) {
32503249 new UnreachableInst(BB->getContext(), TI);
32513250 TI->eraseFromParent();
28592859 writeOperand(LPI->getClause(i), true);
28602860 }
28612861 } else if (const auto *CPI = dyn_cast(&I)) {
2862 Out << ' ';
2863 TypePrinter.print(I.getType(), Out);
2864
28652862 Out << " [";
28662863 for (unsigned Op = 0, NumOps = CPI->getNumArgOperands(); Op < NumOps;
28672864 ++Op) {
28872884 else
28882885 Out << "to caller";
28892886 } else if (const auto *CPI = dyn_cast(&I)) {
2890 Out << ' ';
2891 TypePrinter.print(I.getType(), Out);
2892
28932887 Out << " [";
28942888 for (unsigned Op = 0, NumOps = CPI->getNumOperands(); Op < NumOps; ++Op) {
28952889 if (Op > 0)
29002894 } else if (isa(I) && !Operand) {
29012895 Out << " void";
29022896 } else if (const auto *CRI = dyn_cast(&I)) {
2903 if (CRI->hasReturnValue()) {
2904 Out << ' ';
2905 writeOperand(CRI->getReturnValue(), /*PrintType=*/true);
2906 } else {
2907 Out << " void";
2908 }
2897 Out << ' ';
2898 writeOperand(CRI->getCatchPad(), /*PrintType=*/false);
29092899
29102900 Out << " to ";
29112901 writeOperand(CRI->getSuccessor(), /*PrintType=*/true);
29122902 } else if (const auto *CRI = dyn_cast(&I)) {
2913 if (CRI->hasReturnValue()) {
2914 Out << ' ';
2915 writeOperand(CRI->getReturnValue(), /*PrintType=*/true);
2916 } else {
2917 Out << " void";
2918 }
2903 Out << ' ';
2904 writeOperand(CRI->getCleanupPad(), /*PrintType=*/false);
29192905
29202906 Out << " unwind ";
29212907 if (CRI->hasUnwindDest())
260260 case ExtractValue: return "extractvalue";
261261 case InsertValue: return "insertvalue";
262262 case LandingPad: return "landingpad";
263 case CleanupPad: return "cleanuppad";
263 case CleanupPad: return "cleanuppad";
264264
265265 default: return " ";
266266 }
683683 CRI.getNumOperands()) {
684684 SubclassOptionalData = CRI.SubclassOptionalData;
685685 setInstructionSubclassData(CRI.getSubclassDataFromInstruction());
686 if (Value *RetVal = CRI.getReturnValue())
687 setReturnValue(RetVal);
688 if (BasicBlock *UnwindDest = CRI.getUnwindDest())
689 setUnwindDest(UnwindDest);
690 }
691
692 void CleanupReturnInst::init(Value *RetVal, BasicBlock *UnwindBB) {
686 Op<-1>() = CRI.Op<-1>();
687 if (CRI.hasUnwindDest())
688 Op<-2>() = CRI.Op<-2>();
689 }
690
691 void CleanupReturnInst::init(CleanupPadInst *CleanupPad, BasicBlock *UnwindBB) {
693692 SubclassOptionalData = 0;
694693 if (UnwindBB)
695694 setInstructionSubclassData(getSubclassDataFromInstruction() | 1);
696 if (RetVal)
697 setInstructionSubclassData(getSubclassDataFromInstruction() | 2);
698
695
696 Op<-1>() = CleanupPad;
699697 if (UnwindBB)
700 setUnwindDest(UnwindBB);
701 if (RetVal)
702 setReturnValue(RetVal);
703 }
704
705 CleanupReturnInst::CleanupReturnInst(LLVMContext &C, Value *RetVal,
698 Op<-2>() = UnwindBB;
699 }
700
701 CleanupReturnInst::CleanupReturnInst(CleanupPadInst *CleanupPad,
706702 BasicBlock *UnwindBB, unsigned Values,
707703 Instruction *InsertBefore)
708 : TerminatorInst(Type::getVoidTy(C), Instruction::CleanupRet,
704 : TerminatorInst(Type::getVoidTy(CleanupPad->getContext()),
705 Instruction::CleanupRet,
709706 OperandTraits::op_end(this) - Values,
710707 Values, InsertBefore) {
711 init(RetVal, UnwindBB);
712 }
713
714 CleanupReturnInst::CleanupReturnInst(LLVMContext &C, Value *RetVal,
708 init(CleanupPad, UnwindBB);
709 }
710
711 CleanupReturnInst::CleanupReturnInst(CleanupPadInst *CleanupPad,
715712 BasicBlock *UnwindBB, unsigned Values,
716713 BasicBlock *InsertAtEnd)
717 : TerminatorInst(Type::getVoidTy(C), Instruction::CleanupRet,
714 : TerminatorInst(Type::getVoidTy(CleanupPad->getContext()),
715 Instruction::CleanupRet,
718716 OperandTraits::op_end(this) - Values,
719717 Values, InsertAtEnd) {
720 init(RetVal, UnwindBB);
721 }
722
723 BasicBlock *CleanupReturnInst::getUnwindDest() const {
724 if (hasUnwindDest())
725 return cast(getOperand(getUnwindLabelOpIdx()));
726 return nullptr;
727 }
728 void CleanupReturnInst::setUnwindDest(BasicBlock *NewDest) {
729 assert(NewDest);
730 setOperand(getUnwindLabelOpIdx(), NewDest);
718 init(CleanupPad, UnwindBB);
731719 }
732720
733721 BasicBlock *CleanupReturnInst::getSuccessorV(unsigned Idx) const {
796784 //===----------------------------------------------------------------------===//
797785 // CatchReturnInst Implementation
798786 //===----------------------------------------------------------------------===//
799 void CatchReturnInst::init(BasicBlock *BB, Value *RetVal) {
800 Op<-1>() = BB;
801 if (RetVal)
802 Op<-2>() = RetVal;
787 void CatchReturnInst::init(CatchPadInst *CatchPad, BasicBlock *BB) {
788 Op<0>() = CatchPad;
789 Op<1>() = BB;
803790 }
804791
805792 CatchReturnInst::CatchReturnInst(const CatchReturnInst &CRI)
806793 : TerminatorInst(Type::getVoidTy(CRI.getContext()), Instruction::CatchRet,
807 OperandTraits::op_end(this) -
808 CRI.getNumOperands(),
809 CRI.getNumOperands()) {
810 Op<-1>() = CRI.Op<-1>();
811 if (CRI.getNumOperands() != 1) {
812 assert(CRI.getNumOperands() == 2);
813 Op<-2>() = CRI.Op<-2>();
814 }
815 }
816
817 CatchReturnInst::CatchReturnInst(BasicBlock *BB, Value *RetVal, unsigned Values,
794 OperandTraits::op_begin(this), 2) {
795 Op<0>() = CRI.Op<0>();
796 Op<1>() = CRI.Op<1>();
797 }
798
799 CatchReturnInst::CatchReturnInst(CatchPadInst *CatchPad, BasicBlock *BB,
818800 Instruction *InsertBefore)
819801 : TerminatorInst(Type::getVoidTy(BB->getContext()), Instruction::CatchRet,
820 OperandTraits::op_end(this) - Values,
821 Values, InsertBefore) {
822 init(BB, RetVal);
823 }
824
825 CatchReturnInst::CatchReturnInst(BasicBlock *BB, Value *RetVal, unsigned Values,
802 OperandTraits::op_begin(this), 2,
803 InsertBefore) {
804 init(CatchPad, BB);
805 }
806
807 CatchReturnInst::CatchReturnInst(CatchPadInst *CatchPad, BasicBlock *BB,
826808 BasicBlock *InsertAtEnd)
827809 : TerminatorInst(Type::getVoidTy(BB->getContext()), Instruction::CatchRet,
828 OperandTraits::op_end(this) - Values,
829 Values, InsertAtEnd) {
830 init(BB, RetVal);
810 OperandTraits::op_begin(this), 2,
811 InsertAtEnd) {
812 init(CatchPad, BB);
831813 }
832814
833815 BasicBlock *CatchReturnInst::getSuccessorV(unsigned Idx) const {
862844 std::copy(CPI.op_begin(), CPI.op_end(), op_begin());
863845 }
864846
865 CatchPadInst::CatchPadInst(Type *RetTy, BasicBlock *IfNormal,
866 BasicBlock *IfException, ArrayRef Args,
867 unsigned Values, const Twine &NameStr,
868 Instruction *InsertBefore)
869 : TerminatorInst(RetTy, Instruction::CatchPad,
847 CatchPadInst::CatchPadInst(BasicBlock *IfNormal, BasicBlock *IfException,
848 ArrayRef Args, unsigned Values,
849 const Twine &NameStr, Instruction *InsertBefore)
850 : TerminatorInst(Type::getTokenTy(IfNormal->getContext()),
851 Instruction::CatchPad,
870852 OperandTraits::op_end(this) - Values, Values,
871853 InsertBefore) {
872854 init(IfNormal, IfException, Args, NameStr);
873855 }
874856
875 CatchPadInst::CatchPadInst(Type *RetTy, BasicBlock *IfNormal,
876 BasicBlock *IfException, ArrayRef Args,
877 unsigned Values, const Twine &NameStr,
878 BasicBlock *InsertAtEnd)
879 : TerminatorInst(RetTy, Instruction::CatchPad,
857 CatchPadInst::CatchPadInst(BasicBlock *IfNormal, BasicBlock *IfException,
858 ArrayRef Args, unsigned Values,
859 const Twine &NameStr, BasicBlock *InsertAtEnd)
860 : TerminatorInst(Type::getTokenTy(IfNormal->getContext()),
861 Instruction::CatchPad,
880862 OperandTraits::op_end(this) - Values, Values,
881863 InsertAtEnd) {
882864 init(IfNormal, IfException, Args, NameStr);
961943 std::copy(CPI.op_begin(), CPI.op_end(), op_begin());
962944 }
963945
964 CleanupPadInst::CleanupPadInst(Type *RetTy, ArrayRef Args,
946 CleanupPadInst::CleanupPadInst(LLVMContext &C, ArrayRef Args,
965947 const Twine &NameStr, Instruction *InsertBefore)
966 : Instruction(RetTy, Instruction::CleanupPad,
948 : Instruction(Type::getTokenTy(C), Instruction::CleanupPad,
967949 OperandTraits::op_end(this) - Args.size(),
968950 Args.size(), InsertBefore) {
969951 init(Args, NameStr);
970952 }
971953
972 CleanupPadInst::CleanupPadInst(Type *RetTy, ArrayRef Args,
954 CleanupPadInst::CleanupPadInst(LLVMContext &C, ArrayRef Args,
973955 const Twine &NameStr, BasicBlock *InsertAtEnd)
974 : Instruction(RetTy, Instruction::CleanupPad,
956 : Instruction(Type::getTokenTy(C), Instruction::CleanupPad,
975957 OperandTraits::op_end(this) - Args.size(),
976958 Args.size(), InsertAtEnd) {
977959 init(Args, NameStr);
183183 /// \brief Track unresolved string-based type references.
184184 SmallDenseMap UnresolvedTypeRefs;
185185
186 /// \brief The result type for a catchpad.
187 Type *CatchPadResultTy;
188
189 /// \brief The result type for a cleanuppad.
190 Type *CleanupPadResultTy;
191
192186 /// \brief The result type for a landingpad.
193187 Type *LandingPadResultTy;
194188
202196
203197 public:
204198 explicit Verifier(raw_ostream &OS)
205 : VerifierSupport(OS), Context(nullptr), CatchPadResultTy(nullptr),
206 CleanupPadResultTy(nullptr), LandingPadResultTy(nullptr),
199 : VerifierSupport(OS), Context(nullptr), LandingPadResultTy(nullptr),
207200 SawFrameEscape(false) {}
208201
209202 bool verify(const Function &F) {
238231 // FIXME: We strip const here because the inst visitor strips const.
239232 visit(const_cast(F));
240233 InstsInThisBlock.clear();
241 CatchPadResultTy = nullptr;
242 CleanupPadResultTy = nullptr;
243234 LandingPadResultTy = nullptr;
244235 SawFrameEscape = false;
245236
28762867 void Verifier::visitCatchPadInst(CatchPadInst &CPI) {
28772868 visitEHPadPredecessors(CPI);
28782869
2879 if (!CatchPadResultTy)
2880 CatchPadResultTy = CPI.getType();
2881 else
2882 Assert(CatchPadResultTy == CPI.getType(),
2883 "The catchpad instruction should have a consistent result type "
2884 "inside a function.",
2885 &CPI);
2886
28872870 BasicBlock *BB = CPI.getParent();
28882871 Function *F = BB->getParent();
28892872 Assert(F->hasPersonalityFn(),
28942877 Assert(BB->getFirstNonPHI() == &CPI,
28952878 "CatchPadInst not the first non-PHI instruction in the block.",
28962879 &CPI);
2880
2881 if (!BB->getSinglePredecessor())
2882 for (BasicBlock *PredBB : predecessors(BB)) {
2883 Assert(!isa(PredBB->getTerminator()),
2884 "CatchPadInst with CatchPadInst predecessor cannot have any other "
2885 "predecessors.",
2886 &CPI);
2887 }
28972888
28982889 BasicBlock *UnwindDest = CPI.getUnwindDest();
28992890 Instruction *I = UnwindDest->getFirstNonPHI();
29452936
29462937 BasicBlock *BB = CPI.getParent();
29472938
2948 if (!CleanupPadResultTy)
2949 CleanupPadResultTy = CPI.getType();
2950 else
2951 Assert(CleanupPadResultTy == CPI.getType(),
2952 "The cleanuppad instruction should have a consistent result type "
2953 "inside a function.",
2954 &CPI);
2955
29562939 Function *F = BB->getParent();
29572940 Assert(F->hasPersonalityFn(),
29582941 "CleanupPadInst needs to be in a function with a personality.", &CPI);
29622945 Assert(BB->getFirstNonPHI() == &CPI,
29632946 "CleanupPadInst not the first non-PHI instruction in the block.",
29642947 &CPI);
2948
2949 CleanupReturnInst *FirstCRI = nullptr;
2950 for (User *U : CPI.users())
2951 if (CleanupReturnInst *CRI = dyn_cast(U)) {
2952 if (!FirstCRI)
2953 FirstCRI = CRI;
2954 else
2955 Assert(CRI->getUnwindDest() == FirstCRI->getUnwindDest(),
2956 "Cleanuprets from same cleanuppad have different exceptional "
2957 "successors.",
2958 FirstCRI, CRI);
2959 }
29652960
29662961 visitInstruction(CPI);
29672962 }
26732673 }
26742674
26752675 void visitCleanupPadInst(CleanupPadInst &I) {
2676 if (!I.getType()->isVoidTy()) {
2677 setShadow(&I, getCleanShadow(&I));
2678 setOrigin(&I, getCleanOrigin());
2679 }
2676 setShadow(&I, getCleanShadow(&I));
2677 setOrigin(&I, getCleanOrigin());
26802678 }
26812679
26822680 void visitCatchPad(CatchPadInst &I) {
2683 if (!I.getType()->isVoidTy()) {
2684 setShadow(&I, getCleanShadow(&I));
2685 setOrigin(&I, getCleanOrigin());
2686 }
2681 setShadow(&I, getCleanShadow(&I));
2682 setOrigin(&I, getCleanOrigin());
26872683 }
26882684
26892685 void visitTerminatePad(TerminatePadInst &I) {
343343
344344 if (auto *CRI = dyn_cast(BB->getTerminator())) {
345345 if (CRI->unwindsToCaller()) {
346 CleanupReturnInst::Create(CRI->getContext(), CRI->getReturnValue(),
347 UnwindDest, CRI);
346 CleanupReturnInst::Create(CRI->getCleanupPad(), UnwindDest, CRI);
348347 CRI->eraseFromParent();
349348 UpdatePHINodes(BB);
350349 }
0 ; RUN: sed -e s/.T1:// %s | not llvm-as -disable-output 2>&1 | FileCheck --check-prefix=CHECK1 %s
1 ; RUN: sed -e s/.T2:// %s | not llvm-as -disable-output 2>&1 | FileCheck --check-prefix=CHECK2 %s
2 ; RUN: sed -e s/.T3:// %s | not llvm-as -disable-output 2>&1 | FileCheck --check-prefix=CHECK3 %s
3 ; RUN: sed -e s/.T4:// %s | not llvm-as -disable-output 2>&1 | FileCheck --check-prefix=CHECK4 %s
4 ; RUN: sed -e s/.T5:// %s | not llvm-as -disable-output 2>&1 | FileCheck --check-prefix=CHECK5 %s
5 ; RUN: sed -e s/.T6:// %s | not llvm-as -disable-output 2>&1 | FileCheck --check-prefix=CHECK6 %s
6
7 ;T1: define void @f() {
8 ;T1: entry:
9 ;T1: ; operator constraint requires an operator
10 ;T1: catchret undef to label %entry
11 ;T1: ; CHECK1: [[@LINE-1]]:15: error: Catchpad value required in this position
12 ;T1: }
13
14 ;T2: define void @f() {
15 ;T2: entry:
16 ;T2: %x = cleanuppad []
17 ;T2: ; catchret's first operand's operator must be catchpad
18 ;T2: catchret %x to label %entry
19 ;T2: ; CHECK2: [[@LINE-1]]:15: error: '%x' is not a catchpad
20 ;T2: }
21
22 ;T3: define void @f() {
23 ;T3: entry:
24 ;T3: ; catchret's first operand's operator must be catchpad
25 ;T3: ; (forward reference case)
26 ;T3: catchret %x to label %next
27 ;T3: ; CHECK3: [[@LINE-1]]:15: error: '%x' is not a catchpad
28 ;T3: next:
29 ;T3: %x = cleanuppad []
30 ;T3: ret void
31 ;T3: }
32
33 ;T4: define void @f() {
34 ;T4: entry:
35 ;T4: ; operator constraint requires an operator
36 ;T4: cleanupret undef unwind label %entry
37 ;T4: ; CHECK4: [[@LINE-1]]:17: error: Cleanuppad value required in this position
38 ;T4: }
39
40 ;T5: define void @f() {
41 ;T5: entry:
42 ;T5: %x = catchpad []
43 ;T5: to label %next unwind label %entry
44 ;T5: next:
45 ;T5: ; cleanupret first operand's operator must be cleanuppad
46 ;T5: cleanupret %x unwind to caller
47 ;T5: ; CHECK5: [[@LINE-1]]:17: error: '%x' is not a cleanuppad
48 ;T5: }
49
50 ;T6: define void @f() {
51 ;T6: entry:
52 ;T6: ; cleanupret's first operand's operator must be cleanuppad
53 ;T6: ; (forward reference case)
54 ;T6: cleanupret %x unwind label %next
55 ;T6: ; CHECK6: [[@LINE-1]]:17: error: '%x' is not a cleanuppad
56 ;T6: next:
57 ;T6: %x = catchpad [] to label %entry unwind label %next
58 ;T6: }
3535 ; CHECK: merge:
3636 ; CHECK-NOT: = phi
3737 %phi = phi i32 [ %x, %left ], [ %y, %right ]
38 %cp = catchpad token [] to label %catch unwind label %catchend
38 %cp = catchpad [] to label %catch unwind label %catchend
3939
4040 catch:
4141 ; CHECK: catch:
4242 ; CHECK: [[Reload:%[^ ]+]] = load i32, i32* [[Slot]]
4343 ; CHECK-NEXT: call void @h(i32 [[Reload]])
4444 call void @h(i32 %phi)
45 catchret token %cp to label %exit
45 catchret %cp to label %exit
4646
4747 catchend:
4848 catchendpad unwind to caller
7474 merge.inner:
7575 ; CHECK: merge.inner:
7676 ; CHECK-NOT: = phi
77 ; CHECK: catchpad token
77 ; CHECK: catchpad []
7878 %x = phi i32 [ 1, %left ], [ 2, %right ]
79 %cpinner = catchpad token [] to label %catch.inner unwind label %catchend.inner
79 %cpinner = catchpad [] to label %catch.inner unwind label %catchend.inner
8080
8181 catch.inner:
8282 ; Need just one store here because only %y is affected
8888 to label %catchret.inner unwind label %merge.outer
8989
9090 catchret.inner:
91 catchret token %cpinner to label %exit
91 catchret %cpinner to label %exit
9292 catchend.inner:
9393 catchendpad unwind label %merge.outer
9494
9595 merge.outer:
9696 ; CHECK: merge.outer:
9797 ; CHECK-NOT: = phi
98 ; CHECK: [[CatchPad:%[^ ]+]] = catchpad token
98 ; CHECK: [[CatchPad:%[^ ]+]] = catchpad []
9999 %y = phi i32 [ %x, %catchend.inner ], [ %z, %catch.inner ]
100 %cpouter = catchpad token [] to label %catch.outer unwind label %catchend.outer
100 %cpouter = catchpad [] to label %catch.outer unwind label %catchend.outer
101101
102102 catchend.outer:
103103 catchendpad unwind to caller
108108 ; CHECK: catch.outer:
109109 ; CHECK-DAG: load i32, i32* [[Slot1]]
110110 ; CHECK-DAG: load i32, i32* [[Slot2]]
111 ; CHECK: catchret token [[CatchPad]] to label
111 ; CHECK: catchret [[CatchPad]] to label
112112 call void @h(i32 %x)
113113 call void @h(i32 %y)
114 catchret token %cpouter to label %exit
114 catchret %cpouter to label %exit
115115
116116 exit:
117117 ret void
130130 to label %exit unwind label %catchpad
131131
132132 catchpad:
133 %cp = catchpad token [] to label %catch unwind label %catchend
133 %cp = catchpad [] to label %catch unwind label %catchend
134134
135135 catch:
136136 ; Need to reload %B here
151151 ; CHECK: %phi = phi i32 [ [[ReloadX]], %left ]
152152 %phi = phi i32 [ %x, %left ], [ 42, %right ]
153153 call void @h(i32 %phi)
154 catchret token %cp to label %exit
154 catchret %cp to label %exit
155155
156156 catchend:
157157 catchendpad unwind to caller
187187 to label %join unwind label %catchpad.inner
188188 catchpad.inner:
189189 ; CHECK: catchpad.inner:
190 ; CHECK-NEXT: catchpad token
190 ; CHECK-NEXT: catchpad []
191191 %phi.inner = phi i32 [ %l, %left ], [ %r, %right ]
192 %cp1 = catchpad token [] to label %catch.inner unwind label %catchend.inner
192 %cp1 = catchpad [] to label %catch.inner unwind label %catchend.inner
193193 catch.inner:
194 catchret token %cp1 to label %join
194 catchret %cp1 to label %join
195195 catchend.inner:
196196 catchendpad unwind label %catchpad.outer
197197 join:
204204 to label %exit unwind label %catchpad.outer
205205 catchpad.outer:
206206 ; CHECK: catchpad.outer:
207 ; CHECK-NEXT: catchpad token
207 ; CHECK-NEXT: catchpad []
208208 %phi.outer = phi i32 [ %phi.inner, %catchend.inner ], [ %j, %join ]
209 %cp2 = catchpad token [] to label %catch.outer unwind label %catchend.outer
209 %cp2 = catchpad [] to label %catch.outer unwind label %catchend.outer
210210 catch.outer:
211211 ; CHECK: catch.outer:
212212 ; CHECK: [[Reload:%[^ ]+]] = load i32, i32* [[Slot]]
213213 ; CHECK: call void @h(i32 [[Reload]])
214214 call void @h(i32 %phi.outer)
215 catchret token %cp2 to label %exit
215 catchret %cp2 to label %exit
216216 catchend.outer:
217217 catchendpad unwind to caller
218218 exit:
240240 cleanup:
241241 ; cleanup phi can be loaded at cleanup entry
242242 ; CHECK: cleanup:
243 ; CHECK-NEXT: cleanuppad token
243 ; CHECK-NEXT: cleanuppad []
244244 ; CHECK: [[CleanupReload:%[^ ]+]] = load i32, i32* [[CleanupSlot]]
245245 %phi.cleanup = phi i32 [ 1, %entry ], [ 2, %invoke.cont ]
246 %cp = cleanuppad token []
246 %cp = cleanuppad []
247247 %b = call i1 @i()
248248 br i1 %b, label %left, label %right
249249
263263 ; need store for %phi.catch
264264 ; CHECK: merge:
265265 ; CHECK-NEXT: store i32 [[CleanupReload]], i32* [[CatchSlot:%[^ ]+]]
266 ; CHECK-NEXT: cleanupret token
267 cleanupret token %cp unwind label %catchpad
266 ; CHECK-NEXT: cleanupret
267 cleanupret %cp unwind label %catchpad
268268
269269 invoke.cont2:
270270 ; need store for %phi.catch
276276
277277 catchpad:
278278 ; CHECK: catchpad:
279 ; CHECK-NEXT: catchpad token
279 ; CHECK-NEXT: catchpad []
280280 %phi.catch = phi i32 [ %phi.cleanup, %merge ], [ 3, %invoke.cont2 ]
281 %cp2 = catchpad token [] to label %catch unwind label %catchend
281 %cp2 = catchpad [] to label %catch unwind label %catchend
282282
283283 catch:
284284 ; CHECK: catch:
285285 ; CHECK: [[CatchReload:%[^ ]+]] = load i32, i32* [[CatchSlot]]
286286 ; CHECK: call void @h(i32 [[CatchReload]]
287287 call void @h(i32 %phi.catch)
288 catchret token %cp2 to label %exit
288 catchret %cp2 to label %exit
289289
290290 catchend:
291291 catchendpad unwind to caller
309309 ; CHECK: store i32 %x, i32* [[SpillSlot:%[^ ]+]]
310310 ; CHECK: br label %loop
311311 to_caller:
312 %cp1 = cleanuppad token []
313 cleanupret token %cp1 unwind to caller
312 %cp1 = cleanuppad []
313 cleanupret %cp1 unwind to caller
314314 loop:
315315 invoke void @f()
316316 to label %loop unwind label %cleanup
318318 ; CHECK: cleanup:
319319 ; CHECK: [[Load:%[^ ]+]] = load i32, i32* [[SpillSlot]]
320320 ; CHECK: call void @h(i32 [[Load]])
321 %cp2 = cleanuppad token []
321 %cp2 = cleanuppad []
322322 call void @h(i32 %x)
323 cleanupret token %cp2 unwind to caller
323 cleanupret %cp2 unwind to caller
324324 }
325325
326326 ; CHECK-LABEL: @test7(
342342 catchpad:
343343 ; %x phi should be eliminated
344344 ; CHECK: catchpad:
345 ; CHECK-NEXT: %[[CatchPad:[^ ]+]] = catchpad token
345 ; CHECK-NEXT: %[[CatchPad:[^ ]+]] = catchpad []
346346 %x = phi i32 [ 1, %entry ], [ 2, %invoke.cont ]
347 %cp = catchpad token [] to label %catch unwind label %catchend
347 %cp = catchpad [] to label %catch unwind label %catchend
348348 catch:
349349 %b = call i1 @i()
350350 br i1 %b, label %left, label %right
352352 ; Edge from %left to %join needs to be split so that
353353 ; the load of %x can be inserted *after* the catchret
354354 ; CHECK: left:
355 ; CHECK-NEXT: catchret token %[[CatchPad]] to label %[[SplitLeft:[^ ]+]]
356 catchret token %cp to label %join
355 ; CHECK-NEXT: catchret %[[CatchPad]] to label %[[SplitLeft:[^ ]+]]
356 catchret %cp to label %join
357357 ; CHECK: [[SplitLeft]]:
358358 ; CHECK: [[LoadX:%[^ ]+]] = load i32, i32* [[SlotX]]
359359 ; CHECK: br label %join
362362 ; the load of %y can be inserted *after* the catchret
363363 ; CHECK: right:
364364 ; CHECK: store i32 %y, i32* [[SlotY:%[^ ]+]]
365 ; CHECK: catchret token %[[CatchPad]] to label %[[SplitRight:[^ ]+]]
365 ; CHECK: catchret %[[CatchPad]] to label %[[SplitRight:[^ ]+]]
366366 %y = call i32 @g()
367 catchret token %cp to label %join
367 catchret %cp to label %join
368368 ; CHECK: [[SplitRight]]:
369369 ; CHECK: [[LoadY:%[^ ]+]] = load i32, i32* [[SlotY]]
370370 ; CHECK: br label %join
391391 ret void
392392
393393 cleanup1:
394 ; CHECK: [[CleanupPad1:%[^ ]+]] = cleanuppad token
394 ; CHECK: [[CleanupPad1:%[^ ]+]] = cleanuppad []
395395 ; CHECK-NEXT: call void @f()
396 ; CHECK-NEXT: cleanupret token [[CleanupPad1]]
397 %cp0 = cleanuppad token []
396 ; CHECK-NEXT: cleanupret [[CleanupPad1]]
397 %cp0 = cleanuppad []
398398 br label %cleanupexit
399399
400400 cleanup2:
401 ; CHECK: cleanuppad token
401 ; CHECK: cleanuppad []
402402 ; CHECK-NEXT: call void @f()
403403 ; CHECK-NEXT: unreachable
404 %cp1 = cleanuppad token []
404 %cp1 = cleanuppad []
405405 br label %cleanupexit
406406
407407 cleanupexit:
408408 call void @f()
409 cleanupret token %cp0 unwind label %cleanup2
410 }
409 cleanupret %cp0 unwind label %cleanup2
410 }
3636 to label %unreachable.for.entry unwind label %catch.dispatch
3737
3838 catch.dispatch: ; preds = %entry
39 %1 = catchpad token [i8* null, i8* null] to label %catch unwind label %catchendblock
39 %1 = catchpad [i8* null, i8* null] to label %catch unwind label %catchendblock
4040
4141 catch: ; preds = %catch.dispatch
4242 ; CHECK: catch:
4646 to label %unreachable unwind label %catch.dispatch.1
4747
4848 catch.dispatch.1: ; preds = %catch
49 %2 = catchpad token [i8* null, i8* null] to label %catch.3 unwind label %catchendblock.2
49 %2 = catchpad [i8* null, i8* null] to label %catch.3 unwind label %catchendblock.2
5050
5151 catch.3: ; preds = %catch.dispatch.1
5252 ; CHECK: catch.3:
5656 to label %invoke.cont unwind label %catchendblock.2
5757
5858 invoke.cont: ; preds = %catch.3
59 catchret token %2 to label %try.cont
59 catchret %2 to label %try.cont
6060
6161 try.cont: ; preds = %invoke.cont
6262 ; CHECK: try.cont:
2727
2828 define void @cleanupret0() personality i32 (...)* @__gxx_personality_v0 {
2929 entry:
30 br label %try.cont
31
32 try.cont:
3330 invoke void @_Z3quxv() optsize
34 to label %try.cont unwind label %bb
35 bb:
36 cleanuppad void [i7 4]
37 cleanupret i8 0 unwind label %bb
31 to label %exit unwind label %pad
32 pad:
33 %cp = cleanuppad [i7 4]
34 cleanupret %cp unwind to caller
35 exit:
36 ret void
3837 }
3938
39 ; forward ref by name
4040 define void @cleanupret1() personality i32 (...)* @__gxx_personality_v0 {
4141 entry:
42 br label %try.cont
43
44 try.cont:
4542 invoke void @_Z3quxv() optsize
46 to label %try.cont unwind label %bb
47 bb:
48 cleanuppad void [i7 4]
49 cleanupret void unwind label %bb
43 to label %exit unwind label %pad
44 cleanup:
45 cleanupret %cp unwind label %pad
46 pad:
47 %cp = cleanuppad []
48 br label %cleanup
49 exit:
50 ret void
5051 }
5152
53 ; forward ref by ID
5254 define void @cleanupret2() personality i32 (...)* @__gxx_personality_v0 {
5355 entry:
54 cleanupret i8 0 unwind to caller
56 invoke void @_Z3quxv() optsize
57 to label %exit unwind label %pad
58 cleanup:
59 cleanupret %0 unwind label %pad
60 pad:
61 %0 = cleanuppad []
62 br label %cleanup
63 exit:
64 ret void
5565 }
5666
57 define void @cleanupret3() personality i32 (...)* @__gxx_personality_v0 {
58 cleanupret void unwind to caller
67 define void @catchret0() personality i32 (...)* @__gxx_personality_v0 {
68 entry:
69 invoke void @_Z3quxv() optsize
70 to label %exit unwind label %pad
71 pad:
72 %cp = catchpad [i7 4]
73 to label %catch unwind label %endpad
74 catch:
75 catchret %cp to label %exit
76 endpad:
77 catchendpad unwind to caller
78 exit:
79 ret void
5980 }
6081
61 define void @catchret() personality i32 (...)* @__gxx_personality_v0 {
82 ; forward ref by name
83 define void @catchret1() personality i32 (...)* @__gxx_personality_v0 {
6284 entry:
63 br label %bb
64 bb:
65 catchret void to label %bb
85 invoke void @_Z3quxv() optsize
86 to label %exit unwind label %pad
87 catch:
88 catchret %cp to label %exit
89 pad:
90 %cp = catchpad []
91 to label %catch unwind label %endpad
92 endpad:
93 catchendpad unwind to caller
94 exit:
95 ret void
96 }
97
98 ; forward ref by ID
99 define void @catchret2() personality i32 (...)* @__gxx_personality_v0 {
100 entry:
101 invoke void @_Z3quxv() optsize
102 to label %exit unwind label %pad
103 catch:
104 catchret %0 to label %exit
105 pad:
106 %0 = catchpad []
107 to label %catch unwind label %endpad
108 endpad:
109 catchendpad unwind to caller
110 exit:
111 ret void
66112 }
67113
68114 define i8 @catchpad() personality i32 (...)* @__gxx_personality_v0 {
69115 entry:
70 br label %try.cont
71
72 try.cont:
73116 invoke void @_Z3quxv() optsize
74117 to label %exit unwind label %bb2
75 bb:
76 catchret token %cbv to label %exit
77
118 bb2:
119 catchpad [i7 4] to label %exit unwind label %bb3
120 bb3:
121 catchendpad unwind to caller
78122 exit:
79123 ret i8 0
80 bb2:
81 %cbv = catchpad token [i7 4] to label %bb unwind label %bb3
82 bb3:
83 catchendpad unwind to caller
84124 }
85125
86126 define void @terminatepad0() personality i32 (...)* @__gxx_personality_v0 {
113153 invoke void @_Z3quxv() optsize
114154 to label %try.cont unwind label %bb
115155 bb:
116 cleanuppad void [i7 4]
156 cleanuppad [i7 4]
117157 ret void
118158 }
119159