Skip to content

WIP: [std] Add Annex for undefined and IFNDR behavior #7826

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 14 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions source/basic.tex
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,7 @@
\pnum
Every program shall contain at least one definition of every
function or variable that is odr-used in that program
outside of a discarded statement\iref{stmt.if}; no diagnostic required.
outside of a discarded statement\iref{stmt.if}; no diagnostic required\ifndrdef{basic.def.odr.exact.one.def}.
The definition can appear explicitly in the program, it can be found in
the standard or a user-defined library, or (when appropriate) it is
implicitly defined (see~\ref{class.default.ctor}, \ref{class.copy.ctor},
Expand Down Expand Up @@ -882,7 +882,7 @@
reachable unnamed enumeration definition in the same scope
that have the same first enumerator name and
do not have typedef names for linkage purposes\iref{dcl.enum},
those unnamed enumeration types shall be the same; no diagnostic required.
those unnamed enumeration types shall be the same; no diagnostic required\ifndrdef{basic.def.odr.unnamed.enum.same.type}.
\indextext{one-definition rule|)}

\rSec1[basic.scope]{Scope}%
Expand Down Expand Up @@ -1751,7 +1751,7 @@
If it is an invalid set, the program is ill-formed.
If it differs from the result of a search in $T$ for $M$
in a complete-class context\iref{class.mem} of $T$,
the program is ill-formed, no diagnostic required.
the program is ill-formed, no diagnostic required\ifndrdef{class.member.lookup.name.refers.diff.decl}.
\begin{example}
\begin{codeblock}
struct A { int x; }; // S(x,A) = \{ \{ \tcode{A::x} \}, \{ \tcode{A} \} \}
Expand Down Expand Up @@ -3486,7 +3486,7 @@
zero or more objects of implicit-lifetime types\iref{term.implicit.lifetime.type}
in its specified region of storage
if doing so would result in the program having defined behavior.
If no such set of objects would give the program defined behavior,
If no such set of objects would give the program defined behavior\ubdef{intro.object.implicit.create},
the behavior of the program is undefined.
If multiple such sets of objects would give the program defined behavior,
it is unspecified which such set of objects is created.
Expand Down Expand Up @@ -3748,7 +3748,7 @@
if the pointer were of type \tcode{\keyword{void}*} is
well-defined. Indirection through such a pointer is permitted but the resulting lvalue may only be used in
limited ways, as described below. The
program has undefined behavior if
program has undefined behavior\ubdef{lifetime.outside.pointer} if:
\begin{itemize}
\item
the pointer is used as the operand of a \grammarterm{delete-expression},
Expand Down Expand Up @@ -3811,7 +3811,7 @@
a glvalue refers to
allocated storage\iref{basic.stc.dynamic.allocation}, and using the
properties of the glvalue that do not depend on its value is
well-defined. The program has undefined behavior if
well-defined. The program has undefined behavior\ubdef{lifetime.outside.glvalue} if:
\begin{itemize}
\item the glvalue is used to access the object, or
\item the glvalue is used to call a non-static member function of the object, or
Expand Down Expand Up @@ -3901,7 +3901,7 @@
\end{footnote}
and another object of the original type does not occupy
that same storage location when the implicit destructor call takes
place, the behavior of the program is undefined. This is true
place, the behavior of the program is undefined\ubdef{original.type.implicit.destructor}. This is true
even if the block is exited with an exception.
\begin{example}
\begin{codeblock}
Expand All @@ -3921,7 +3921,7 @@
Creating a new object within the storage that a const, complete
object with static, thread, or automatic storage duration occupies,
or within the storage that such a const object used to occupy before
its lifetime ended, results in undefined behavior.
its lifetime ended, results in undefined behavior\ubdef{creating.within.const.complete.obj}.
\begin{example}
\begin{codeblock}
struct B {
Expand Down Expand Up @@ -4260,7 +4260,7 @@
does not satisfy the semantic constraints
specified in~\ref{basic.stc.dynamic.allocation}
and~\ref{basic.stc.dynamic.deallocation},
the behavior is undefined.
the behavior is undefined\ubdef{basic.stc.alloc.dealloc.constraint}.

\indextext{storage duration!dynamic|)}

Expand Down Expand Up @@ -6152,7 +6152,7 @@
The value computations of the operands of an
operator are sequenced before the value computation of the result of the
operator.
The behavior is undefined if
The behavior is undefined\iref{intro.multithread}\ubdef{intro.execution.unsequenced.modification} if
\begin{itemize}
\item
\indextext{side effects}%
Expand Down Expand Up @@ -6552,7 +6552,7 @@
and neither happens before the other,
except for the special case for signal handlers described below.
Any such data race results in undefined
behavior.
behavior\ubdef{intro.races.data}.
\begin{note}
It can be shown that programs that correctly use mutexes
and \tcode{memory_order::seq_cst} operations to prevent all data races and use no
Expand Down Expand Up @@ -6916,7 +6916,7 @@
objects with automatic storage duration\iref{class.dtor}. If
\tcode{std::exit} is invoked during the destruction of
an object with static or thread storage duration, the program has undefined
behavior.
behavior\ubdef{basic.start.main.exit.during.destruction}.

\pnum
\indextext{termination!program}%
Expand Down Expand Up @@ -7210,7 +7210,7 @@
\pnum
If a function contains a block variable of static or thread storage duration that has been
destroyed and the function is called during the destruction of an object with static or
thread storage duration, the program has undefined behavior if the flow of control
thread storage duration, the program has undefined behavior\ubdef{basic.start.term.use.after.destruction} if the flow of control
passes through the definition of the previously destroyed block variable.
\begin{note}
Likewise, the behavior is undefined
Expand All @@ -7237,7 +7237,7 @@
handlers\iref{support.runtime} that does not happen before\iref{intro.multithread}
completion of destruction of objects with static storage duration and execution of
\tcode{std::atexit} registered functions\iref{support.start.term}, the program has
undefined behavior.
undefined behavior\ubdef{basic.start.term.signal.handler}.
\begin{note}
If there is a use of an object with static storage
duration that does not happen before the object's destruction, the program has undefined
Expand Down
24 changes: 12 additions & 12 deletions source/classes.tex
Original file line number Diff line number Diff line change
Expand Up @@ -2289,7 +2289,7 @@
that is, if the object is not of the destructor's class type and
not of a class derived from the destructor's class type (including when
the destructor is invoked via a null pointer value), the program has
undefined behavior.
undefined behavior\ubdef{class.dtor.not.class.type}.
\begin{note}
Invoking \keyword{delete} on a null pointer does not call the
destructor; see \ref{expr.delete}.
Expand Down Expand Up @@ -2356,7 +2356,7 @@

\pnum
Once a destructor is invoked for an object, the object's lifetime ends;
the behavior is undefined if the destructor is invoked
the behavior is undefined\ubdef{class.dtor.no.longer.exists} if the destructor is invoked
for an object whose lifetime has ended\iref{basic.life}.
\begin{example}
If the destructor for an object with automatic storage duration is explicitly invoked,
Expand Down Expand Up @@ -3237,7 +3237,7 @@
each anonymous union member \tcode{X}\iref{class.union.anon} that
is a member of a union and
has such an element as an immediate subobject (recursively),
if modification of \tcode{X} would have undefined behavior under~\ref{basic.life},
if modification of \tcode{X} would have undefined behavior\ubdef{class.union.assignment.not.start.lifetime} under~\ref{basic.life},
an object of the type of \tcode{X} is implicitly created
in the nominated storage;
no initialization is performed and
Expand Down Expand Up @@ -4019,7 +4019,7 @@
\indextext{definition!virtual function}%
A virtual function declared in a class shall be defined, or declared
pure\iref{class.abstract} in that class, or both; no diagnostic is
required\iref{basic.def.odr}.
required\iref{basic.def.odr}\ifndrdef{class.virtual.pure.or.defined}.
\indextext{friend!\tcode{virtual} and}%

\pnum
Expand Down Expand Up @@ -4252,7 +4252,7 @@
\indextext{virtual function call!undefined pure}%
the effect of making a virtual call\iref{class.virtual} to a pure
virtual function directly or indirectly for the object being created (or
destroyed) from such a constructor (or destructor) is undefined.%
destroyed) from such a constructor (or destructor) is undefined\ubdef{class.abstract.pure.virtual}.%
\indextext{derived class|)}

\rSec1[class.access]{Member access control}%
Expand Down Expand Up @@ -5523,7 +5523,7 @@
The target constructor is selected by overload resolution.
Once the target constructor returns, the body of the delegating constructor
is executed. If a constructor delegates to itself directly or indirectly,
the program is ill-formed, no diagnostic required.
the program is ill-formed, no diagnostic required\ifndrdef{class.base.init.delegate.itself}.
\begin{example}
\begin{codeblock}
struct C {
Expand Down Expand Up @@ -5838,7 +5838,7 @@
\item
a postcondition assertion of a destructor\iref{dcl.contract.func},
\end{itemize}
the program has undefined behavior.
the program has undefined behavior\ubdef{class.base.init.mem.fun}.
\begin{example}
\begin{codeblock}
class A {
Expand Down Expand Up @@ -6035,7 +6035,7 @@
\indextext{destruction!member access}%
For an object with a non-trivial constructor, referring to any non-static member
or base class of the object before the constructor begins execution results in
undefined behavior. For an object with a non-trivial destructor, referring to
undefined behavior\ubdef{class.cdtor.before.ctor.after.dtor}. For an object with a non-trivial destructor, referring to
any non-static member or base class of the object after the destructor finishes
execution results in undefined behavior.
\begin{example}
Expand Down Expand Up @@ -6130,7 +6130,7 @@
\tcode{obj}
shall have started and its destruction shall not have completed,
otherwise the computation of the pointer value (or accessing the member
value) results in undefined behavior.
value) results in undefined behavior\ubdef{class.cdtor.convert.or.form.pointer}.
\begin{example}
\begin{codeblock}
struct A { };
Expand Down Expand Up @@ -6174,7 +6174,7 @@
and the object expression refers to
the complete object of \tcode{x} or one of that object's base class subobjects
but not \tcode{x} or one of its base class subobjects, the behavior
is undefined.
is undefined\ubdef{class.cdtor.virtual.not.x}.
\begin{example}
\begin{codeblock}
struct V {
Expand Down Expand Up @@ -6231,7 +6231,7 @@
\tcode{typeid}
refers to the object under construction or destruction and the static type of
the operand is neither the constructor or destructor's class nor one of its
bases, the behavior is undefined.
bases, the behavior is undefined\ubdef{class.cdtor.typeid}.

\pnum
\indextext{construction!dynamic cast and}%
Expand All @@ -6256,7 +6256,7 @@
the operand is not a pointer to or object of the constructor or destructor's
own class or one of its bases, the
\keyword{dynamic_cast}
results in undefined behavior.
results in undefined behavior\ubdef{class.cdtor.dynamic.cast}.
\begin{example}
\begin{codeblock}
struct V {
Expand Down
16 changes: 8 additions & 8 deletions source/declarations.tex
Original file line number Diff line number Diff line change
Expand Up @@ -1279,7 +1279,7 @@
\indextext{const object!undefined change to}%
Any attempt to modify\iref{expr.assign,expr.post.incr,expr.pre.incr} a
const object\iref{basic.type.qualifier} during its
lifetime\iref{basic.life} results in undefined behavior.
lifetime\iref{basic.life} results in undefined behavior\ubdef{dcl.type.cv.modify.const.obj}.
\begin{example}
\begin{codeblock}
const int ci = 3; // cv-qualified (initialized as required)
Expand Down Expand Up @@ -1323,7 +1323,7 @@
\impldef{semantics of an access through a volatile glvalue}.
If an attempt is made to access an object defined with a
volatile-qualified type through the use of a non-volatile glvalue,
the behavior is undefined.
the behavior is undefined\ubdef{dcl.type.cv.access.volatile}.

\pnum
\indextext{type specifier!\idxcode{volatile}}%
Expand Down Expand Up @@ -7257,7 +7257,7 @@
The evaluation that invoked a resumption member function is
called the \defnx{resumer}{coroutine!resumer}.
Invoking a resumption member function for a coroutine
that is not suspended results in undefined behavior.
that is not suspended results in undefined behavior\ubdef{dcl.fct.def.coroutine.resume.not.suspended}.

\pnum
An implementation may need to allocate additional storage for a coroutine.
Expand Down Expand Up @@ -7351,7 +7351,7 @@
The storage for the coroutine state is released by calling a
non-array deallocation function\iref{basic.stc.dynamic.deallocation}.
If \tcode{destroy} is called for a coroutine that is not suspended, the
program has undefined behavior.
program has undefined behavior\ubdef{dcl.fct.def.coroutine.destroy.not.suspended}.

\pnum
The deallocation function's name is looked up by searching for it in the scope of the promise type.
Expand Down Expand Up @@ -9464,7 +9464,7 @@
\grammarterm{alignment-specifier}{},
every defining
declaration of that entity shall specify an equivalent alignment.
No diagnostic is required if declarations of an entity have
No diagnostic is required\ifndrdef{dcl.align.diff.translation.units} if declarations of an entity have
different \grammarterm{alignment-specifier}{s}
in different translation units.
\begin{example}
Expand Down Expand Up @@ -9518,7 +9518,7 @@
at the point where the assumption appears,
the assumption has no effect.
Otherwise,
evaluation of the assumption has runtime-undefined behavior.
evaluation of the assumption has runtime-undefined behavior\ubdef{dcl.attr.assume.false}.

\pnum
\begin{note}
Expand Down Expand Up @@ -9948,12 +9948,12 @@
specify the \tcode{noreturn} attribute if any declaration of that function specifies the
\tcode{noreturn} attribute. If a function is declared with the \tcode{noreturn} attribute in one
translation unit and the same function is declared without the \tcode{noreturn} attribute in another
translation unit, the program is ill-formed, no diagnostic required.
translation unit, the program is ill-formed, no diagnostic required\ifndrdef{dcl.attr.noreturn.trans.unit.mismatch}.

\pnum
If a function \tcode{f} is invoked where \tcode{f} was previously declared with the \tcode{noreturn}
attribute and that invocation eventually returns,
the behavior is runtime-undefined.
the behavior is runtime-undefined\ubdef{dcl.attr.noreturn.eventually.returns}.
\begin{note}
The function can
terminate by throwing an exception.
Expand Down
2 changes: 1 addition & 1 deletion source/exceptions.tex
Original file line number Diff line number Diff line change
Expand Up @@ -690,7 +690,7 @@
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.
of a constructor or destructor for that object results in undefined behavior\ubdef{except.handle.handler.ctor.dtor}.

\pnum
Exceptions thrown in destructors of objects with static storage duration or in
Expand Down
Loading
Loading