diff options
Diffstat (limited to 'llvm/docs')
-rw-r--r-- | llvm/docs/ExceptionHandling.rst | 151 | ||||
-rw-r--r-- | llvm/docs/LangRef.rst | 362 |
2 files changed, 225 insertions, 288 deletions
diff --git a/llvm/docs/ExceptionHandling.rst b/llvm/docs/ExceptionHandling.rst index 5b495d9863c..12899ed8380 100644 --- a/llvm/docs/ExceptionHandling.rst +++ b/llvm/docs/ExceptionHandling.rst @@ -522,16 +522,12 @@ table. Exception Handling using the Windows Runtime ================================================= -(Note: Windows C++ exception handling support is a work in progress and is not -yet fully implemented. The text below describes how it will work when -completed.) - Background on Windows exceptions --------------------------------- -Interacting with exceptions on Windows is significantly more complicated than on -Itanium C++ ABI platforms. The fundamental difference between the two models is -that Itanium EH is designed around the idea of "successive unwinding," while +Interacting with exceptions on Windows is significantly more complicated than +on Itanium C++ ABI platforms. The fundamental difference between the two models +is that Itanium EH is designed around the idea of "successive unwinding," while Windows EH is not. Under Itanium, throwing an exception typically involes allocating thread local @@ -618,10 +614,11 @@ purposes. The following new instructions are considered "exception handling pads", in that they must be the first non-phi instruction of a basic block that may be the -unwind destination of an invoke: ``catchpad``, ``cleanuppad``, and -``terminatepad``. As with landingpads, when entering a try scope, if the +unwind destination of an EH flow edge: +``catchswitch``, ``catchpad``, ``cleanuppad``, and ``terminatepad``. +As with landingpads, when entering a try scope, if the frontend encounters a call site that may throw an exception, it should emit an -invoke that unwinds to a ``catchpad`` block. Similarly, inside the scope of a +invoke that unwinds to a ``catchswitch`` block. Similarly, inside the scope of a C++ object with a destructor, invokes should unwind to a ``cleanuppad``. The ``terminatepad`` instruction exists to represent ``noexcept`` and throw specifications with one combined instruction. All potentially throwing calls in @@ -634,26 +631,20 @@ generated funclet). A catch handler which reaches its end by normal execution executes a ``catchret`` instruction, which is a terminator indicating where in the function control is returned to. A cleanup handler which reaches its end by normal execution executes a ``cleanupret`` instruction, which is a terminator -indicating where the active exception will unwind to next. A catch or cleanup -handler which is exited by another exception being raised during its execution will -unwind through a ``catchendpad`` or ``cleanuupendpad`` (respectively). The -``catchendpad`` and ``cleanupendpad`` instructions are considered "exception -handling pads" in the same sense that ``catchpad``, ``cleanuppad``, and -``terminatepad`` are. - -Each of these new EH pad instructions has a way to identify which -action should be considered after this action. The ``catchpad`` and -``terminatepad`` instructions are terminators, and have a label operand considered -to be an unwind destination analogous to the unwind destination of an invoke. The -``cleanuppad`` instruction is different from the other two in that it is not a -terminator. The code inside a cleanuppad runs before transferring control to the -next action, so the ``cleanupret`` and ``cleanupendpad`` instructions are the -instructions that hold a label operand and unwind to the next EH pad. All of -these "unwind edges" may refer to a basic block that contains an EH pad instruction, -or they may simply unwind to the caller. Unwinding to the caller has roughly the -same semantics as the ``resume`` instruction in the ``landingpad`` model. When -inlining through an invoke, instructions that unwind to the caller are hooked -up to unwind to the unwind destination of the call site. +indicating where the active exception will unwind to next. + +Each of these new EH pad instructions has a way to identify which action should +be considered after this action. The ``catchswitch`` and ``terminatepad`` +instructions are terminators, and have a unwind destination operand analogous +to the unwind destination of an invoke. The ``cleanuppad`` instruction is not +a terminator, so the unwind destination is stored on the ``cleanupret`` +instruction instead. Successfully executing a catch handler should resume +normal control flow, so neither ``catchpad`` nor ``catchret`` instructions can +unwind. All of these "unwind edges" may refer to a basic block that contains an +EH pad instruction, or they may unwind to the caller. Unwinding to the caller +has roughly the same semantics as the ``resume`` instruction in the landingpad +model. When inlining through an invoke, instructions that unwind to the caller +are hooked up to unwind to the unwind destination of the call site. Putting things together, here is a hypothetical lowering of some C++ that uses all of the new IR instructions: @@ -694,33 +685,95 @@ all of the new IR instructions: call void @"\01??_DCleanup@@QEAA@XZ"(%struct.Cleanup* nonnull %obj) nounwind br label %return - return: ; preds = %invoke.cont.2, %invoke.cont.3 - %retval.0 = phi i32 [ 0, %invoke.cont.2 ], [ %9, %catch ] + return: ; preds = %invoke.cont.3, %invoke.cont.2 + %retval.0 = phi i32 [ 0, %invoke.cont.2 ], [ %3, %invoke.cont.3 ] ret i32 %retval.0 - ; EH scope code, ordered innermost to outermost: - - lpad.cleanup: ; preds = %invoke.cont - %cleanup = cleanuppad [] - call void @"\01??_DCleanup@@QEAA@XZ"(%struct.Cleanup* nonnull %obj) nounwind - cleanupret %cleanup unwind label %lpad.catch + lpad.cleanup: ; preds = %invoke.cont.2 + %0 = cleanuppad within none [] + call void @"\01??1Cleanup@@QEAA@XZ"(%struct.Cleanup* nonnull %obj) nounwind + cleanupret %0 unwind label %lpad.catch - lpad.catch: ; preds = %entry, %lpad.cleanup - %catch = catchpad [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i32* %e] - to label %catch.body unwind label %catchend + lpad.catch: ; preds = %lpad.cleanup, %entry + %1 = catchswitch within none [label %catch.body] unwind label %lpad.terminate catch.body: ; preds = %lpad.catch + %catch = catchpad within %1 [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i32* %e] invoke void @"\01?may_throw@@YAXXZ"() - to label %invoke.cont.3 unwind label %catchend + to label %invoke.cont.3 unwind label %lpad.terminate invoke.cont.3: ; preds = %catch.body - %9 = load i32, i32* %e, align 4 - catchret %catch to label %return + %3 = load i32, i32* %e, align 4 + catchret from %catch to label %return + + lpad.terminate: ; preds = %catch.body, %lpad.catch + terminatepad within none [void ()* @"\01?terminate@@YAXXZ"] unwind to caller + } + +Funclet parent tokens +----------------------- - catchend: ; preds = %lpad.catch, %catch.body - catchendpad unwind label %lpad.terminate +In order to produce tables for EH personalities that use funclets, it is +necessary to recover the nesting that was present in the source. This funclet +parent relationship is encoded in the IR using tokens produced by the new "pad" +instructions. The token operand of a "pad" or "ret" instruction indicates which +funclet it is in, or "none" if it is not nested within another funclet. - lpad.terminate: ; preds = %catchend - terminatepad [void ()* @"\01?terminate@@YAXXZ"] - unwind to caller +The ``catchpad`` and ``cleanuppad`` instructions establish new funclets, and +their tokens are consumed by other "pad" instructions to establish membership. +The ``catchswitch`` instruction does not create a funclet, but it produces a +token that is always consumed by its immediate successor ``catchpad`` +instructions. This ensures that every catch handler modelled by a ``catchpad`` +belongs to exactly one ``catchswitch``, which models the dispatch point after a +C++ try. The ``terminatepad`` instruction cannot contain lexically nested +funclets inside the termination action, so it does not produce a token. + +Here is an example of what this nesting looks like using some hypothetical +C++ code: + +.. code-block:: c + + void f() { + try { + throw; + } catch (...) { + try { + throw; + } catch (...) { + } + } } + +.. code-block:: llvm + define void @f() #0 personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) { + entry: + invoke void @_CxxThrowException(i8* null, %eh.ThrowInfo* null) #1 + to label %unreachable unwind label %catch.dispatch + + catch.dispatch: ; preds = %entry + %0 = catchswitch within none [label %catch] unwind to caller + + catch: ; preds = %catch.dispatch + %1 = catchpad within %0 [i8* null, i32 64, i8* null] + invoke void @_CxxThrowException(i8* null, %eh.ThrowInfo* null) #1 + to label %unreachable unwind label %catch.dispatch2 + + catch.dispatch2: ; preds = %catch + %2 = catchswitch within %1 [label %catch3] unwind to caller + + catch3: ; preds = %catch.dispatch2 + %3 = catchpad within %2 [i8* null, i32 64, i8* null] + catchret from %3 to label %try.cont + + try.cont: ; preds = %catch3 + catchret from %1 to label %try.cont6 + + try.cont6: ; preds = %try.cont + ret void + + unreachable: ; preds = %catch, %entry + unreachable + } + +The "inner" ``catchswitch`` consumes ``%1`` which is produced by the outer +catchswitch. diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst index 58198f7af7d..09efa75515c 100644 --- a/llvm/docs/LangRef.rst +++ b/llvm/docs/LangRef.rst @@ -5001,10 +5001,8 @@ control flow, not values (the one exception being the The terminator instructions are: ':ref:`ret <i_ret>`', ':ref:`br <i_br>`', ':ref:`switch <i_switch>`', ':ref:`indirectbr <i_indirectbr>`', ':ref:`invoke <i_invoke>`', -':ref:`resume <i_resume>`', ':ref:`catchpad <i_catchpad>`', -':ref:`catchendpad <i_catchendpad>`', +':ref:`resume <i_resume>`', ':ref:`catchswitch <i_catchswitch>`', ':ref:`catchret <i_catchret>`', -':ref:`cleanupendpad <i_cleanupendpad>`', ':ref:`cleanupret <i_cleanupret>`', ':ref:`terminatepad <i_terminatepad>`', and ':ref:`unreachable <i_unreachable>`'. @@ -5362,9 +5360,9 @@ Example: resume { i8*, i32 } %exn -.. _i_catchpad: +.. _i_catchswitch: -'``catchpad``' Instruction +'``catchswitch``' Instruction ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Syntax: @@ -5372,155 +5370,125 @@ Syntax: :: - <resultval> = catchpad [<args>*] - to label <normal label> unwind label <exception label> + <resultval> = catchswitch within <parent> [ label <handler1>, label <handler2>, ... ] unwind to caller + <resultval> = catchswitch within <parent> [ label <handler1>, label <handler2>, ... ] unwind label <default> Overview: """"""""" -The '``catchpad``' instruction is used by `LLVM's exception handling -system <ExceptionHandling.html#overview>`_ to specify that a basic block -is a catch block --- one where a personality routine attempts to transfer -control to catch an exception. -The ``args`` correspond to whatever information the personality -routine requires to know if this is an appropriate place to catch the -exception. Control is transfered to the ``exception`` label if the -``catchpad`` is not an appropriate handler for the in-flight exception. -The ``normal`` label should contain the code found in the ``catch`` -portion of a ``try``/``catch`` sequence. The ``resultval`` has the type -:ref:`token <t_token>` and is used to match the ``catchpad`` to -corresponding :ref:`catchrets <i_catchret>`. +The '``catchswitch``' instruction is used by `LLVM's exception handling system +<ExceptionHandling.html#overview>`_ to describe the set of possible catch handlers +that may be executed by the :ref:`EH personality routine <personalityfn>`. Arguments: """""""""" -The instruction takes a list of arbitrary values which are interpreted -by the :ref:`personality function <personalityfn>`. +The ``parent`` argument is the token of the funclet that contains the +``catchswitch`` instruction. If the ``catchswitch`` is not inside a funclet, +this operand may be the token ``none``. -The ``catchpad`` must be provided a ``normal`` label to transfer control -to if the ``catchpad`` matches the exception and an ``exception`` -label to transfer control to if it doesn't. +The ``default`` argument is the label of another basic block beginning with a +"pad" instruction, one of ``cleanuppad``, ``terminatepad``, or +``catchswitch``. + +The ``handlers`` are a list of successor blocks that each begin with a +:ref:`catchpad <i_catchpad>` instruction. Semantics: """""""""" -When the call stack is being unwound due to an exception being thrown, -the exception is compared against the ``args``. If it doesn't match, -then control is transfered to the ``exception`` basic block. -As with calling conventions, how the personality function results are -represented in LLVM IR is target specific. +Executing this instruction transfers control to one of the successors in +``handlers``, if appropriate, or continues to unwind via the unwind label if +present. -The ``catchpad`` instruction has several restrictions: - -- A catch block is a basic block which is the unwind destination of - an exceptional instruction. -- A catch block must have a '``catchpad``' instruction as its - first non-PHI instruction. -- A catch block's ``exception`` edge must refer to a catch block or a - catch-end block. -- There can be only one '``catchpad``' instruction within the - catch block. -- A basic block that is not a catch block may not include a - '``catchpad``' instruction. -- A catch block which has another catch block as a predecessor may not have - any other predecessors. -- It is undefined behavior for control to transfer from a ``catchpad`` to a - ``ret`` without first executing a ``catchret`` that consumes the - ``catchpad`` or unwinding through its ``catchendpad``. -- It is undefined behavior for control to transfer from a ``catchpad`` to - itself without first executing a ``catchret`` that consumes the - ``catchpad`` or unwinding through its ``catchendpad``. +The ``catchswitch`` is both a terminator and a "pad" instruction, meaning that +it must be both the first non-phi instruction and last instruction in the basic +block. Therefore, it must be the only non-phi instruction in the block. Example: """""""" .. code-block:: llvm - ;; A catch block which can catch an integer. - %tok = catchpad [i8** @_ZTIi] - to label %int.handler unwind label %terminate + dispatch1: + %cs1 = catchswitch within none [label %handler0, label %handler1] unwind to caller + dispatch2: + %cs2 = catchswitch within %parenthandler [label %handler0] unwind label %cleanup -.. _i_catchendpad: +.. _i_catchpad: -'``catchendpad``' Instruction -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +'``catchpad``' Instruction +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Syntax: """"""" :: - catchendpad unwind label <nextaction> - catchendpad unwind to caller + <resultval> = catchpad within <catchswitch> [<args>*] Overview: """"""""" -The '``catchendpad``' instruction is used by `LLVM's exception handling -system <ExceptionHandling.html#overview>`_ to communicate to the -:ref:`personality function <personalityfn>` which invokes are associated -with a chain of :ref:`catchpad <i_catchpad>` instructions; propagating an -exception out of a catch handler is represented by unwinding through its -``catchendpad``. Unwinding to the outer scope when a chain of catch handlers -do not handle an exception is also represented by unwinding through their -``catchendpad``. - -The ``nextaction`` label indicates where control should transfer to if -none of the ``catchpad`` instructions are suitable for catching the -in-flight exception. - -If a ``nextaction`` label is not present, the instruction unwinds out of -its parent function. The -:ref:`personality function <personalityfn>` will continue processing -exception handling actions in the caller. +The '``catchpad``' instruction is used by `LLVM's exception handling +system <ExceptionHandling.html#overview>`_ to specify that a basic block +begins a catch handler --- one where a personality routine attempts to transfer +control to catch an exception. Arguments: """""""""" -The instruction optionally takes a label, ``nextaction``, indicating -where control should transfer to if none of the preceding -``catchpad`` instructions are suitable for the in-flight exception. +The ``catchswitch`` operand must always be a token produced by a +:ref:`catchswitch <i_catchswitch>` instruction in a predecessor block. This +ensures that each ``catchpad`` has exactly one predecessor block, and it always +terminates in a ``catchswitch``. + +The ``args`` correspond to whatever information the personality routine +requires to know if this is an appropriate handler for the exception. Control +will transfer to the ``catchpad`` if this is the first appropriate handler for +the exception. + +The ``resultval`` has the type :ref:`token <t_token>` and is used to match the +``catchpad`` to corresponding :ref:`catchrets <i_catchret>` and other nested EH +pads. Semantics: """""""""" -When the call stack is being unwound due to an exception being thrown -and none of the constituent ``catchpad`` instructions match, then -control is transfered to ``nextaction`` if it is present. If it is not -present, control is transfered to the caller. +When the call stack is being unwound due to an exception being thrown, the +exception is compared against the ``args``. If it doesn't match, control will +not reach the ``catchpad`` instruction. The representation of ``args`` is +entirely target and personality function-specific. -The ``catchendpad`` instruction has several restrictions: +Like the :ref:`landingpad <i_landingpad>` instruction, the ``catchpad`` +instruction must be the first non-phi of its parent basic block. -- A catch-end block is a basic block which is the unwind destination of - an exceptional instruction. -- A catch-end block must have a '``catchendpad``' instruction as its - first non-PHI instruction. -- There can be only one '``catchendpad``' instruction within the - catch-end block. -- A basic block that is not a catch-end block may not include a - '``catchendpad``' instruction. -- Exactly one catch block may unwind to a ``catchendpad``. -- It is undefined behavior to execute a ``catchendpad`` if none of the - '``catchpad``'s chained to it have been executed. -- It is undefined behavior to execute a ``catchendpad`` twice without an - intervening execution of one or more of the '``catchpad``'s chained to it. -- It is undefined behavior to execute a ``catchendpad`` if, after the most - recent execution of the normal successor edge of any ``catchpad`` chained - to it, some ``catchret`` consuming that ``catchpad`` has already been - executed. -- It is undefined behavior to execute a ``catchendpad`` if, after the most - recent execution of the normal successor edge of any ``catchpad`` chained - to it, any other ``catchpad`` or ``cleanuppad`` has been executed but has - not had a corresponding - ``catchret``/``cleanupret``/``catchendpad``/``cleanupendpad`` executed. +The meaning of the tokens produced and consumed by ``catchpad`` and other "pad" +instructions is described in the +`Windows exception handling documentation <ExceptionHandling.html#wineh>`. + +Executing a ``catchpad`` instruction constitutes "entering" that pad. +The pad may then be "exited" in one of three ways: +1) explicitly via a ``catchret`` that consumes it. Executing such a ``catchret`` + is undefined behavior if any descendant pads have been entered but not yet + exited. +2) implicitly via a call (which unwinds all the way to the current function's caller), + or via a ``catchswitch``, ``cleanupret``, or ``terminatepad`` that unwinds to caller. +3) implicitly via an unwind edge whose destination EH pad isn't a descendant of + the ``catchpad``. When the ``catchpad`` is exited in this manner, it is + undefined behavior if the destination EH pad has a parent which is not an + ancestor of the ``catchpad`` being exited. Example: """""""" .. code-block:: llvm - catchendpad unwind label %terminate - catchendpad unwind to caller + dispatch: + %cs = catchswitch within none [label %handler0] unwind to caller + ;; A catch block which can catch an integer. + handler0: + %tok = catchpad within %cs [i8** @_ZTIi] .. _i_catchret: @@ -5532,7 +5500,7 @@ Syntax: :: - catchret <value> to label <normal> + catchret from <token> to label <normal> Overview: """"""""" @@ -5552,105 +5520,24 @@ transfer to next. Semantics: """""""""" -The '``catchret``' instruction ends the existing (in-flight) exception -whose unwinding was interrupted with a -:ref:`catchpad <i_catchpad>` instruction. -The :ref:`personality function <personalityfn>` gets a chance to execute -arbitrary code to, for example, run a C++ destructor. -Control then transfers to ``normal``. -It may be passed an optional, personality specific, value. - -It is undefined behavior to execute a ``catchret`` whose ``catchpad`` has -not been executed. - -It is undefined behavior to execute a ``catchret`` if, after the most recent -execution of its ``catchpad``, some ``catchret`` or ``catchendpad`` linked -to the same ``catchpad`` has already been executed. - -It is undefined behavior to execute a ``catchret`` if, after the most recent -execution of its ``catchpad``, any other ``catchpad`` or ``cleanuppad`` has -been executed but has not had a corresponding -``catchret``/``cleanupret``/``catchendpad``/``cleanupendpad`` executed. - -Example: -"""""""" - -.. code-block:: llvm - - catchret %catch label %continue - -.. _i_cleanupendpad: - -'``cleanupendpad``' Instruction -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Syntax: -""""""" - -:: - - cleanupendpad <value> unwind label <nextaction> - cleanupendpad <value> unwind to caller - -Overview: -""""""""" - -The '``cleanupendpad``' instruction is used by `LLVM's exception handling -system <ExceptionHandling.html#overview>`_ to communicate to the -:ref:`personality function <personalityfn>` which invokes are associated -with a :ref:`cleanuppad <i_cleanuppad>` instructions; propagating an exception -out of a cleanup is represented by unwinding through its ``cleanupendpad``. - -The ``nextaction`` label indicates where control should unwind to next, in the -event that a cleanup is exited by means of an(other) exception being raised. - -If a ``nextaction`` label is not present, the instruction unwinds out of -its parent function. The -:ref:`personality function <personalityfn>` will continue processing -exception handling actions in the caller. - -Arguments: -"""""""""" - -The '``cleanupendpad``' instruction requires one argument, which indicates -which ``cleanuppad`` it exits, and must be a :ref:`cleanuppad <i_cleanuppad>`. -It also has an optional successor, ``nextaction``, indicating where control -should transfer to. - -Semantics: -"""""""""" - -When and exception propagates to a ``cleanupendpad``, control is transfered to -``nextaction`` if it is present. If it is not present, control is transfered to -the caller. +The '``catchret``' instruction ends an existing (in-flight) exception whose +unwinding was interrupted with a :ref:`catchpad <i_catchpad>` instruction. The +:ref:`personality function <personalityfn>` gets a chance to execute arbitrary +code to, for example, destroy the active exception. Control then transfers to +``normal``. -The ``cleanupendpad`` instruction has several restrictions: - -- A cleanup-end block is a basic block which is the unwind destination of - an exceptional instruction. -- A cleanup-end block must have a '``cleanupendpad``' instruction as its - first non-PHI instruction. -- There can be only one '``cleanupendpad``' instruction within the - cleanup-end block. -- A basic block that is not a cleanup-end block may not include a - '``cleanupendpad``' instruction. -- It is undefined behavior to execute a ``cleanupendpad`` whose ``cleanuppad`` - has not been executed. -- It is undefined behavior to execute a ``cleanupendpad`` if, after the most - recent execution of its ``cleanuppad``, some ``cleanupret`` or ``cleanupendpad`` - consuming the same ``cleanuppad`` has already been executed. -- It is undefined behavior to execute a ``cleanupendpad`` if, after the most - recent execution of its ``cleanuppad``, any other ``cleanuppad`` or - ``catchpad`` has been executed but has not had a corresponding - ``cleanupret``/``catchret``/``cleanupendpad``/``catchendpad`` executed. +The ``token`` argument must be a token produced by a dominating ``catchpad`` +instruction. The ``catchret`` destroys the physical frame established by +``catchpad``, so executing multiple returns on the same token without +re-executing the ``catchpad`` will result in undefined behavior. +See :ref:`catchpad <i_catchpad>` for more details. Example: """""""" .. code-block:: llvm - cleanupendpad %cleanup unwind label %terminate - cleanupendpad %cleanup unwind to caller + catchret from %catch label %continue .. _i_cleanupret: @@ -5662,8 +5549,8 @@ Syntax: :: - cleanupret <value> unwind label <continue> - cleanupret <value> unwind to caller + cleanupret from <value> unwind label <continue> + cleanupret from <value> unwind to caller Overview: """"""""" @@ -5687,25 +5574,20 @@ The '``cleanupret``' instruction indicates to the :ref:`cleanuppad <i_cleanuppad>` it transferred control to has ended. It transfers control to ``continue`` or unwinds out of the function. -It is undefined behavior to execute a ``cleanupret`` whose ``cleanuppad`` has -not been executed. - -It is undefined behavior to execute a ``cleanupret`` if, after the most recent -execution of its ``cleanuppad``, some ``cleanupret`` or ``cleanupendpad`` -consuming the same ``cleanuppad`` has already been executed. - -It is undefined behavior to execute a ``cleanupret`` if, after the most recent -execution of its ``cleanuppad``, any other ``cleanuppad`` or ``catchpad`` has -been executed but has not had a corresponding -``cleanupret``/``catchret``/``cleanupendpad``/``catchendpad`` executed. +The unwind destination ``continue``, if present, must be an EH pad +whose parent is either ``none`` or an ancestor of the ``cleanuppad`` +being returned from. This constitutes an exceptional exit from all +ancestors of the completed ``cleanuppad``, up to but not including +the parent of ``continue``. +See :ref:`cleanuppad <i_cleanuppad>` for more details. Example: """""""" .. code-block:: llvm - cleanupret %cleanup unwind to caller - cleanupret %cleanup unwind label %continue + cleanupret from %cleanup unwind to caller + cleanupret from %cleanup unwind label %continue .. _i_terminatepad: @@ -5717,8 +5599,8 @@ Syntax: :: - terminatepad [<args>*] unwind label <exception label> - terminatepad [<args>*] unwind to caller + terminatepad within <token> [<args>*] unwind label <exception label> + terminatepad within <token> [<args>*] unwind to caller Overview: """"""""" @@ -5752,16 +5634,8 @@ the program is terminated via personality-specific means. Typically, the first argument to ``terminatepad`` specifies what function the personality should defer to in order to terminate the program. -The ``terminatepad`` instruction has several restrictions: - -- A terminate block is a basic block which is the unwind destination of - an exceptional instruction. -- A terminate block must have a '``terminatepad``' instruction as its - first non-PHI instruction. -- There can be only one '``terminatepad``' instruction within the - terminate block. -- A basic block that is not a terminate block may not include a - '``terminatepad``' instruction. +The ``terminatepad`` instruction is both a terminator and a "pad" instruction, +meaning that is always the only non-phi instruction in the basic block. Example: """""""" @@ -5769,7 +5643,7 @@ Example: .. code-block:: llvm ;; A terminate block which only permits integers. - terminatepad [i8** @_ZTIi] unwind label %continue + terminatepad within none [i8** @_ZTIi] unwind label %continue .. _i_unreachable: @@ -8762,7 +8636,7 @@ Syntax: :: - <resultval> = cleanuppad [<args>*] + <resultval> = cleanuppad within <parent> [<args>*] Overview: """"""""" @@ -8775,8 +8649,10 @@ The ``args`` correspond to whatever additional information the :ref:`personality function <personalityfn>` requires to execute the cleanup. The ``resultval`` has the type :ref:`token <t_token>` and is used to -match the ``cleanuppad`` to corresponding :ref:`cleanuprets <i_cleanupret>` -and :ref:`cleanupendpads <i_cleanupendpad>`. +match the ``cleanuppad`` to corresponding :ref:`cleanuprets <i_cleanupret>`. +The ``parent`` argument is the token of the funclet that contains the +``cleanuppad`` instruction. If the ``cleanuppad`` is not inside a funclet, +this operand may be the token ``none``. Arguments: """""""""" @@ -8803,21 +8679,29 @@ The ``cleanuppad`` instruction has several restrictions: cleanup block. - A basic block that is not a cleanup block may not include a '``cleanuppad``' instruction. -- All '``cleanupret``'s and '``cleanupendpad``'s which consume a ``cleanuppad`` - must have the same exceptional successor. -- It is undefined behavior for control to transfer from a ``cleanuppad`` to a - ``ret`` without first executing a ``cleanupret`` or ``cleanupendpad`` that - consumes the ``cleanuppad``. -- It is undefined behavior for control to transfer from a ``cleanuppad`` to - itself without first executing a ``cleanupret`` or ``cleanupendpad`` that - consumes the ``cleanuppad``. + +Executing a ``cleanuppad`` instruction constitutes "entering" that pad. +The pad may then be "exited" in one of three ways: +1) explicitly via a ``cleanupret`` that consumes it. Executing such a ``cleanupret`` + is undefined behavior if any descendant pads have been entered but not yet + exited. +2) implicitly via a call (which unwinds all the way to the current function's caller), + or via a ``catchswitch``, ``cleanupret``, or ``terminatepad`` that unwinds to caller. +3) implicitly via an unwind edge whose destination EH pad isn't a descendant of + the ``cleanuppad``. When the ``cleanuppad`` is exited in this manner, it is + undefined behavior if the destination EH pad has a parent which is not an + ancestor of the ``cleanuppad`` being exited. + +It is undefined behavior for the ``cleanuppad`` to exit via an unwind edge which +does not transitively unwind to the same destination as a constituent +``cleanupret``. Example: """""""" .. code-block:: llvm - %tok = cleanuppad [] + %tok = cleanuppad within %cs [] .. _intrinsics: |