summaryrefslogtreecommitdiffstats
path: root/llvm/docs
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/docs')
-rw-r--r--llvm/docs/ExceptionHandling.rst43
-rw-r--r--llvm/docs/LangRef.rst149
2 files changed, 154 insertions, 38 deletions
diff --git a/llvm/docs/ExceptionHandling.rst b/llvm/docs/ExceptionHandling.rst
index fce875b9b8a..2f09155dff2 100644
--- a/llvm/docs/ExceptionHandling.rst
+++ b/llvm/docs/ExceptionHandling.rst
@@ -614,19 +614,32 @@ specifications with one combined instruction. All potentially throwing calls in
a ``noexcept`` function should transitively unwind to a terminateblock. Throw
specifications are not implemented by MSVC, and are not yet supported.
+New instructions are also used to mark the points where control is transferred
+out of a catch/cleanup handler (which will correspond to exits from the
+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`` instruction is the instruction that holds a
-label operand and unwinds 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.
+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.
Putting things together, here is a hypothetical lowering of some C++ that uses
all of the new IR instructions:
@@ -644,6 +657,7 @@ all of the new IR instructions:
Cleanup obj;
may_throw();
} catch (int e) {
+ may_throw();
return e;
}
return 0;
@@ -666,7 +680,7 @@ 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, %catch
+ return: ; preds = %invoke.cont.2, %invoke.cont.3
%retval.0 = phi i32 [ 0, %invoke.cont.2 ], [ %9, %catch ]
ret i32 %retval.0
@@ -679,13 +693,20 @@ all of the new IR instructions:
lpad.catch: ; preds = %entry, %lpad.cleanup
%catch = catchpad [%rtti.TypeDescriptor2* @"\01??_R0H@8", i32 0, i32* %e]
- to label %catch unwind label %lpad.terminate
+ to label %catch.body unwind label %catchend
- catch: ; preds = %lpad.catch
+ catch.body: ; preds = %lpad.catch
+ invoke void @"\01?may_throw@@YAXXZ"()
+ to label %invoke.cont.3 unwind label %catchend
+
+ invoke.cont.3: ; preds = %catch.body
%9 = load i32, i32* %e, align 4
catchret %catch label %return
- lpad.terminate:
+ catchend: ; preds = %lpad.catch, %catch.body
+ catchendpad unwind label %lpad.terminate
+
+ lpad.terminate: ; preds = %catchend
terminatepad [void ()* @"\01?terminate@@YAXXZ"]
unwind to caller
}
diff --git a/llvm/docs/LangRef.rst b/llvm/docs/LangRef.rst
index 1209e1db5a2..b58fcf9b5ae 100644
--- a/llvm/docs/LangRef.rst
+++ b/llvm/docs/LangRef.rst
@@ -4782,6 +4782,7 @@ The terminator instructions are: ':ref:`ret <i_ret>`',
':ref:`resume <i_resume>`', ':ref:`catchpad <i_catchpad>`',
':ref:`catchendpad <i_catchendpad>`',
':ref:`catchret <i_catchret>`',
+':ref:`cleanupendpad <i_cleanupendpad>`',
':ref:`cleanupret <i_cleanupret>`',
':ref:`terminatepad <i_terminatepad>`',
and ':ref:`unreachable <i_unreachable>`'.
@@ -5235,7 +5236,11 @@ 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.
+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
@@ -5268,13 +5273,23 @@ The ``catchendpad`` instruction has several restrictions:
- 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 block.
+ 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``.
-- The unwind target of invokes between a ``catchpad`` and a
- corresponding ``catchret`` must be its ``catchendpad`` or
- an inner EH pad.
+- 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.
Example:
""""""""
@@ -5321,14 +5336,18 @@ 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 any ``catchpad`` or
-``cleanuppad`` has been executed, without subsequently executing a
-corresponding ``catchret``/``cleanupret`` or unwinding out of the inner
-pad, following the most recent execution of the ``catchret``'s corresponding
-``catchpad``.
+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:
""""""""
@@ -5337,6 +5356,79 @@ Example:
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 ``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.
+
+Example:
+""""""""
+
+.. code-block:: llvm
+
+ cleanupendpad %cleanup unwind label %terminate
+ cleanupendpad %cleanup unwind to caller
+
.. _i_cleanupret:
'``cleanupret``' Instruction
@@ -5371,13 +5463,18 @@ The '``cleanupret``' instruction indicates to the
:ref:`personality function <personalityfn>` that one
: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 any ``catchpad`` or
-``cleanuppad`` has been executed, without subsequently executing a
-corresponding ``catchret``/``cleanupret`` or unwinding out of the inner pad,
-following the most recent execution of the ``cleanupret``'s corresponding
-``cleanuppad``.
+
+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.
Example:
""""""""
@@ -8431,7 +8528,8 @@ 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>`.
+match the ``cleanuppad`` to corresponding :ref:`cleanuprets <i_cleanupret>`
+and :ref:`cleanupendpads <i_cleanupendpad>`.
Arguments:
""""""""""
@@ -8442,14 +8540,11 @@ by the :ref:`personality function <personalityfn>`.
Semantics:
""""""""""
-The '``cleanuppad``' instruction defines the values which are set by the
-:ref:`personality function <personalityfn>` upon re-entry to the function.
-As with calling conventions, how the personality function results are
-represented in LLVM IR is target specific.
-
When the call stack is being unwound due to an exception being thrown,
the :ref:`personality function <personalityfn>` transfers control to the
``cleanuppad`` with the aid of the personality-specific arguments.
+As with calling conventions, how the personality function results are
+represented in LLVM IR is target specific.
The ``cleanuppad`` instruction has several restrictions:
@@ -8461,14 +8556,14 @@ 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 which exit a ``cleanuppad`` must have the same
- exceptional successor.
+- 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`` that consumes the
- ``cleanuppad`` or unwinding out of the ``cleanuppad``.
+ ``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`` that consumes the
- ``cleanuppad`` or unwinding out of the ``cleanuppad``.
+ itself without first executing a ``cleanupret`` or ``cleanupendpad`` that
+ consumes the ``cleanuppad``.
Example:
""""""""
OpenPOWER on IntegriCloud