Skip to content

Commit

Permalink
[except.pre] Clean-up pass to ensure consistency
Browse files Browse the repository at this point in the history
  • Loading branch information
AlisdairM committed Oct 18, 2024
1 parent f142ecc commit 55d85db
Show file tree
Hide file tree
Showing 8 changed files with 487 additions and 483 deletions.
271 changes: 266 additions & 5 deletions source/basic.tex
Original file line number Diff line number Diff line change
Expand Up @@ -6760,7 +6760,14 @@
\indextext{atomic!operation|)}%
\indextext{threads!multiple|)}

\rSec2[except.throw]{Throwing an exception}%
\rSec2[except.flow]{Exceptional control flow}

\rSec3[except.general]{General}
\pnum
In this Clause, ``before'' and ``after'' refer to the
``sequenced before'' relation\iref{intro.execution}.

\rSec3[except.throw]{Throwing an exception}%
\indextext{exception handling!throwing}%
\indextext{throwing|see{exception handling, throwing}}

Expand Down Expand Up @@ -6951,7 +6958,7 @@
\tcode{std::terminate} is invoked.
\end{note}

\rSec2[except.ctor]{Stack unwinding}%
\rSec3[except.ctor]{Stack unwinding}%
\indextext{exception handling!constructors and destructors}%
\indextext{constructor!exception handling|see{exception handling, constructors and destructors}}%
\indextext{destructor!exception handling|see{exception handling, constructors and destructors}}
Expand Down Expand Up @@ -7066,6 +7073,260 @@
if any, is called to free the storage occupied by the object.
\end{note}

\rSec3[except.handle]{Handling an exception}
\indextext{exception handling!handler|(}%

\pnum
The
\grammarterm{exception-declaration}
in a
\grammarterm{handler}
describes the type(s) of exceptions that can cause
that
\grammarterm{handler}
to be entered.
\indextext{exception handling!handler!incomplete type in}%
\indextext{exception handling!handler!rvalue reference in}%
\indextext{exception handling!handler!array in}%
\indextext{exception handling!handler!pointer to function in}%
The
\grammarterm{exception-declaration}
shall not denote an incomplete type, an abstract class type, or an rvalue reference type.
The
\grammarterm{exception-declaration}
shall not denote a pointer or reference to an
incomplete type, other than ``pointer to \cv{}~\keyword{void}''.

\pnum
A handler of type
\indextext{array!handler of type}%
``array of \tcode{T}'' or
\indextext{function!handler of type}%
function type \tcode{T}
is adjusted to be of type
``pointer to \tcode{T}''.

\pnum
\indextext{exception handling!handler!match|(}%
A
\grammarterm{handler}
is a match for
an exception object
of type
\tcode{E}
if
\begin{itemize}
\item%
The \grammarterm{handler} is of type \cv{}~\tcode{T} or
\cv{}~\tcode{T\&} and
\tcode{E} and \tcode{T}
are the same type (ignoring the top-level \grammarterm{cv-qualifier}{s}), or
\item%
the \grammarterm{handler} is of type \cv{}~\tcode{T} or
\cv{}~\tcode{T\&} and
\tcode{T} is an unambiguous public base class of \tcode{E}, or
\item%
the \grammarterm{handler} is of type \cv{}~\tcode{T} or \tcode{const T\&}
where \tcode{T} is a pointer or pointer-to-member type and
\tcode{E} is a pointer or pointer-to-member type
that can be converted to \tcode{T} by one or more of
\begin{itemize}

\item%
a standard pointer conversion\iref{conv.ptr} not involving conversions
to pointers to private or protected or ambiguous classes
\item%
a function pointer conversion\iref{conv.fctptr}
\item%
a qualification conversion\iref{conv.qual}, or

\end{itemize}

\item
the \grammarterm{handler} is of type \cv{}~\tcode{T} or \tcode{const T\&} where \tcode{T} is a pointer or pointer-to-member type and \tcode{E} is \tcode{std::nullptr_t}.

\end{itemize}

\begin{note}
A
\grammarterm{throw-expression}
whose operand is an integer literal with value zero does not match a handler of
pointer or pointer-to-member type.
A handler of reference to array or function type
is never a match for any exception object\iref{expr.throw}.
\end{note}

\begin{example}
\begin{codeblock}
class Matherr { @\commentellip@ virtual void vf(); };
class Overflow: public Matherr { @\commentellip@ };
class Underflow: public Matherr { @\commentellip@ };
class Zerodivide: public Matherr { @\commentellip@ };

void f() {
try {
g();
} catch (Overflow oo) {
// ...
} catch (Matherr mm) {
// ...
}
}
\end{codeblock}
Here, the
\tcode{Overflow}
handler will catch exceptions of type
\tcode{Overflow}
and the
\tcode{Matherr}
handler will catch exceptions of type
\tcode{Matherr}
and of all types publicly derived from
\tcode{Matherr}
including exceptions of type
\tcode{Underflow}
and
\tcode{Zerodivide}.
\end{example}

\pnum
The handlers for a try block are tried in order of appearance.
\begin{note}
This makes it possible to write handlers that can never be
executed, for example by placing a handler for a final derived class after
a handler for a corresponding unambiguous public base class.
\end{note}

\pnum
A
\tcode{...}
in a handler's
\grammarterm{exception-declaration}
specifies a match for any exception.
If present, a
\tcode{...}
handler shall be the last handler for its try block.

\pnum
If no match is found among the handlers for a try block,
the search for a matching
handler continues in a dynamically surrounding try block
of the same thread.

\pnum
\indextext{exception handling!terminate called@\tcode{terminate} called}%
\indextext{\idxcode{terminate}!called}%
If the search for a handler
encounters the outermost block of a function with a
non-throwing exception specification,
the function \tcode{std::terminate}\iref{except.terminate} is invoked.
\begin{note}
An implementation is not permitted to reject an expression merely because, when
executed, it throws or might
throw an exception from a function with a non-throwing exception specification.
\end{note}
\begin{example}
\begin{codeblock}
extern void f(); // potentially-throwing

void g() noexcept {
f(); // valid, even if \tcode{f} throws
throw 42; // valid, effectively a call to \tcode{std::terminate}
}
\end{codeblock}
The call to
\tcode{f}
is well-formed despite the possibility for it to throw an exception.
\end{example}

\pnum
If no matching handler is found,
the function \tcode{std::terminate} is invoked;
whether or not the stack is unwound before this invocation of
\tcode{std::terminate} is
\impldef{whether stack is unwound before invoking the function \tcode{std::terminate}
when no matching handler is found}\iref{except.terminate}

\pnum
A handler is considered \defnx{active}{exception handling!handler!active} when
initialization is complete for the parameter (if any) of the catch clause.
\begin{note}
The stack will have been unwound at that point.
\end{note}
Also, an implicit handler is considered active when
the function \tcode{std::terminate}
is entered due to a throw. A handler is no longer considered active when the
catch clause exits.

\pnum
\indextext{currently handled exception|see{exception handling, currently handled exception}}%
The exception with the most recently activated handler that is
still active is called the
\defnx{currently handled exception}{exception handling!currently handled exception}.

\pnum
Referring to any non-static member or base class of an object
in the handler for a
\grammarterm{function-try-block}
of a constructor or destructor for that object results in undefined behavior.

\pnum
Exceptions thrown in destructors of objects with static storage duration or in
constructors of objects associated with non-block variables with static storage duration are not caught by a
\grammarterm{function-try-block}
on
the \tcode{main} function\iref{basic.start.main}.
Exceptions thrown in destructors of objects with thread storage duration or in constructors of objects associated with non-block variables with thread storage duration are not caught by a
\grammarterm{function-try-block}
on the initial function of the thread.

\pnum
If a \keyword{return} statement\iref{stmt.return} appears in a handler of the
\grammarterm{function-try-block}
of a
constructor, the program is ill-formed.

\pnum
The currently handled exception
is rethrown if control reaches the end of a handler of the
\grammarterm{function-try-block}
of a constructor or destructor.
Otherwise, flowing off the end of
the \grammarterm{compound-statement}
of a \grammarterm{handler}
of a \grammarterm{function-try-block}
is equivalent to flowing off the end of
the \grammarterm{compound-statement}
of that function (see \ref{stmt.return}).

\pnum
The variable declared by the \grammarterm{exception-declaration}, of type
\cv{}~\tcode{T} or \cv{}~\tcode{T\&}, is initialized from the exception object,
of type \tcode{E}, as follows:
\begin{itemize}
\item
if \tcode{T} is a base class of \tcode{E},
the variable is copy-initialized\iref{dcl.init}
from an lvalue of type \tcode{T} designating the corresponding base class subobject
of the exception object;
\item otherwise, the variable is copy-initialized\iref{dcl.init}
from an lvalue of type \tcode{E} designating the exception object.
\end{itemize}

The lifetime of the variable ends
when the handler exits, after the
destruction of any objects with automatic storage duration initialized
within the handler.

\pnum
When the handler declares an object,
any changes to that object will not affect the exception object.
When the handler declares a reference to an object,
any changes to the referenced object are changes to the
exception object and will have effect should that object be rethrown.%
\indextext{exception handling!handler!match|)}%
\indextext{exception handling!handler|)}

\rSec2[basic.start]{Start and termination}

\rSec3[basic.start.main]{\tcode{main} function}
Expand Down Expand Up @@ -7603,9 +7864,9 @@
\pnum
\indextext{\idxcode{terminate}}%
In the situation where no matching handler is found, it is
\impldef{stack unwinding before invocation of \tcode{std::terminate}}
whether or not the stack is unwound
before \tcode{std::terminate} is invoked.
\impldef{whether stack is unwound before invoking the function \tcode{std::terminate}
when no matching handler is found}
whether or not the stack is unwound before \tcode{std::terminate} is invoked.
In the situation where the search for a handler\iref{except.handle} encounters the
outermost block of a function
with a non-throwing exception specification\iref{except.spec}, it is
Expand Down
Loading

0 comments on commit 55d85db

Please sign in to comment.