diff options
Diffstat (limited to 'llvm/docs')
| -rw-r--r-- | llvm/docs/ExceptionHandling.rst | 43 | ||||
| -rw-r--r-- | llvm/docs/LangRef.rst | 149 |
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: """""""" |

