summaryrefslogtreecommitdiffstats
path: root/llvm/docs
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/docs')
-rw-r--r--llvm/docs/ExceptionHandling.rst151
-rw-r--r--llvm/docs/LangRef.rst362
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:
OpenPOWER on IntegriCloud