[WinEH] Verify unwind edges against EH pad tree
[oota-llvm.git] / docs / LangRef.rst
index 103d876b3cef1dadc192632365841aac0f198ee0..650d18b9ba464e5866e13d36cc2124c84f774d94 100644 (file)
@@ -1579,6 +1579,8 @@ caller's deoptimization state to the callee's deoptimization state is
 semantically equivalent to composing the caller's deoptimization
 continuation after the callee's deoptimization continuation.
 
+.. _ob_funclet:
+
 Funclet Operand Bundles
 ^^^^^^^^^^^^^^^^^^^^^^^
 
@@ -1588,6 +1590,18 @@ is within a particular funclet.  There can be at most one
 ``"funclet"`` operand bundle attached to a call site and it must have
 exactly one bundle operand.
 
+If any funclet EH pads have been "entered" but not "exited" (per the
+`description in the EH doc\ <ExceptionHandling.html#wineh-constraints>`_),
+it is undefined behavior to execute a ``call`` or ``invoke`` which:
+
+* does not have a ``"funclet"`` bundle and is not a ``call`` to a nounwind
+  intrinsic, or
+* has a ``"funclet"`` bundle whose operand is not the most-recently-entered
+  not-yet-exited funclet EH pad.
+
+Similarly, if no funclet EH pads have been entered-but-not-yet-exited,
+executing a ``call`` or ``invoke`` with a ``"funclet"`` bundle is undefined behavior.
+
 .. _moduleasm:
 
 Module-Level Inline Assembly
@@ -5404,10 +5418,12 @@ 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 ``default`` argument is the label of another basic block beginning with a
-"pad" instruction, one of ``cleanuppad`` or ``catchswitch``.
+The ``default`` argument is the label of another basic block beginning with
+either a ``cleanuppad`` or ``catchswitch`` instruction.  This unwind destination
+must be a legal target with respect to the ``parent`` links, as described in
+the `exception handling documentation\ <ExceptionHandling.html#wineh-constraints>`_.
 
-The ``handlers`` are a list of successor blocks that each begin with a
+The ``handlers`` are a nonempty list of successor blocks that each begin with a
 :ref:`catchpad <i_catchpad>` instruction.
 
 Semantics:
@@ -5481,20 +5497,12 @@ instruction must be the first non-phi of its parent basic block.
 
 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>`.
+`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`` or a ``cleanupret`` 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.
+When a ``catchpad`` has been "entered" but not yet "exited" (as
+described in the `EH documentation\ <ExceptionHandling.html#wineh-constraints>`_),
+it is undefined behavior to execute a :ref:`call <i_call>` or :ref:`invoke <i_invoke>`
+that does not carry an appropriate :ref:`"funclet" bundle <ob_funclet>`.
 
 Example:
 """"""""
@@ -5543,11 +5551,10 @@ unwinding was interrupted with a :ref:`catchpad <i_catchpad>` instruction.  The
 code to, for example, destroy the active exception.  Control then transfers to
 ``normal``.
 
-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.
+The ``token`` argument must be a token produced by a ``catchpad`` instruction.
+If the specified ``catchpad`` is not the most-recently-entered not-yet-exited
+funclet pad (as described in the `EH documentation\ <ExceptionHandling.html#wineh-constraints>`_),
+the ``catchret``'s behavior is undefined.
 
 Example:
 """"""""
@@ -5581,7 +5588,15 @@ Arguments:
 
 The '``cleanupret``' instruction requires one argument, which indicates
 which ``cleanuppad`` it exits, and must be a :ref:`cleanuppad <i_cleanuppad>`.
-It also has an optional successor, ``continue``.
+If the specified ``cleanuppad`` is not the most-recently-entered not-yet-exited
+funclet pad (as described in the `EH documentation\ <ExceptionHandling.html#wineh-constraints>`_),
+the ``cleanupret``'s behavior is undefined.
+
+The '``cleanupret``' instruction also has an optional successor, ``continue``,
+which must be the label of another basic block beginning with either a
+``cleanuppad`` or ``catchswitch`` instruction.  This unwind destination must
+be a legal target with respect to the ``parent`` links, as described in the
+`exception handling documentation\ <ExceptionHandling.html#wineh-constraints>`_.
 
 Semantics:
 """"""""""
@@ -5591,13 +5606,6 @@ 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.
 
-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:
 """"""""
 
@@ -8644,18 +8652,10 @@ The ``cleanuppad`` instruction has several restrictions:
 -  A basic block that is not a cleanup block may not include a
    '``cleanuppad``' instruction.
 
-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`` or a ``cleanupret`` 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.
+When a ``cleanuppad`` has been "entered" but not yet "exited" (as
+described in the `EH documentation\ <ExceptionHandling.html#wineh-constraints>`_),
+it is undefined behavior to execute a :ref:`call <i_call>` or :ref:`invoke <i_invoke>`
+that does not carry an appropriate :ref:`"funclet" bundle <ob_funclet>`.
 
 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