Skip to content

Commit 743c775

Browse files
committed
[std] Add Annex for undefined and IFNDR behavior
1 parent f79a0f6 commit 743c775

15 files changed

+2468
-93
lines changed

source/basic.tex

+14-14
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,7 @@
614614
\pnum
615615
Every program shall contain at least one definition of every
616616
function or variable that is odr-used in that program
617-
outside of a discarded statement\iref{stmt.if}; no diagnostic required.
617+
outside of a discarded statement\iref{stmt.if}; no diagnostic required\ifndrdef{basic.def.odr.exact.one.def}.
618618
The definition can appear explicitly in the program, it can be found in
619619
the standard or a user-defined library, or (when appropriate) it is
620620
implicitly defined (see~\ref{class.default.ctor}, \ref{class.copy.ctor},
@@ -882,7 +882,7 @@
882882
reachable unnamed enumeration definition in the same scope
883883
that have the same first enumerator name and
884884
do not have typedef names for linkage purposes\iref{dcl.enum},
885-
those unnamed enumeration types shall be the same; no diagnostic required.
885+
those unnamed enumeration types shall be the same; no diagnostic required\ifndrdef{basic.def.odr.unnamed.enum.same.type}.
886886
\indextext{one-definition rule|)}
887887

888888
\rSec1[basic.scope]{Scope}%
@@ -1751,7 +1751,7 @@
17511751
If it is an invalid set, the program is ill-formed.
17521752
If it differs from the result of a search in $T$ for $M$
17531753
in a complete-class context\iref{class.mem} of $T$,
1754-
the program is ill-formed, no diagnostic required.
1754+
the program is ill-formed, no diagnostic required\ifndrdef{class.member.lookup.name.refers.diff.decl}.
17551755
\begin{example}
17561756
\begin{codeblock}
17571757
struct A { int x; }; // S(x,A) = \{ \{ \tcode{A::x} \}, \{ \tcode{A} \} \}
@@ -3486,7 +3486,7 @@
34863486
zero or more objects of implicit-lifetime types\iref{term.implicit.lifetime.type}
34873487
in its specified region of storage
34883488
if doing so would result in the program having defined behavior.
3489-
If no such set of objects would give the program defined behavior,
3489+
If no such set of objects would give the program defined behavior\ubdef{intro.object.implicit.create},
34903490
the behavior of the program is undefined.
34913491
If multiple such sets of objects would give the program defined behavior,
34923492
it is unspecified which such set of objects is created.
@@ -3748,7 +3748,7 @@
37483748
if the pointer were of type \tcode{\keyword{void}*} is
37493749
well-defined. Indirection through such a pointer is permitted but the resulting lvalue may only be used in
37503750
limited ways, as described below. The
3751-
program has undefined behavior if
3751+
program has undefined behavior\ubdef{lifetime.outside.pointer} if:
37523752
\begin{itemize}
37533753
\item
37543754
the pointer is used as the operand of a \grammarterm{delete-expression},
@@ -3811,7 +3811,7 @@
38113811
a glvalue refers to
38123812
allocated storage\iref{basic.stc.dynamic.allocation}, and using the
38133813
properties of the glvalue that do not depend on its value is
3814-
well-defined. The program has undefined behavior if
3814+
well-defined. The program has undefined behavior\ubdef{lifetime.outside.glvalue} if:
38153815
\begin{itemize}
38163816
\item the glvalue is used to access the object, or
38173817
\item the glvalue is used to call a non-static member function of the object, or
@@ -3901,7 +3901,7 @@
39013901
\end{footnote}
39023902
and another object of the original type does not occupy
39033903
that same storage location when the implicit destructor call takes
3904-
place, the behavior of the program is undefined. This is true
3904+
place, the behavior of the program is undefined\ubdef{original.type.implicit.destructor}. This is true
39053905
even if the block is exited with an exception.
39063906
\begin{example}
39073907
\begin{codeblock}
@@ -3921,7 +3921,7 @@
39213921
Creating a new object within the storage that a const, complete
39223922
object with static, thread, or automatic storage duration occupies,
39233923
or within the storage that such a const object used to occupy before
3924-
its lifetime ended, results in undefined behavior.
3924+
its lifetime ended, results in undefined behavior\ubdef{creating.within.const.complete.obj}.
39253925
\begin{example}
39263926
\begin{codeblock}
39273927
struct B {
@@ -4260,7 +4260,7 @@
42604260
does not satisfy the semantic constraints
42614261
specified in~\ref{basic.stc.dynamic.allocation}
42624262
and~\ref{basic.stc.dynamic.deallocation},
4263-
the behavior is undefined.
4263+
the behavior is undefined\ubdef{basic.stc.alloc.dealloc.constraint}.
42644264

42654265
\indextext{storage duration!dynamic|)}
42664266

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

69216921
\pnum
69226922
\indextext{termination!program}%
@@ -7210,7 +7210,7 @@
72107210
\pnum
72117211
If a function contains a block variable of static or thread storage duration that has been
72127212
destroyed and the function is called during the destruction of an object with static or
7213-
thread storage duration, the program has undefined behavior if the flow of control
7213+
thread storage duration, the program has undefined behavior\ubdef{basic.start.term.use.after.destruction} if the flow of control
72147214
passes through the definition of the previously destroyed block variable.
72157215
\begin{note}
72167216
Likewise, the behavior is undefined
@@ -7237,7 +7237,7 @@
72377237
handlers\iref{support.runtime} that does not happen before\iref{intro.multithread}
72387238
completion of destruction of objects with static storage duration and execution of
72397239
\tcode{std::atexit} registered functions\iref{support.start.term}, the program has
7240-
undefined behavior.
7240+
undefined behavior\ubdef{basic.start.term.signal.handler}.
72417241
\begin{note}
72427242
If there is a use of an object with static storage
72437243
duration that does not happen before the object's destruction, the program has undefined

source/classes.tex

+14-14
Original file line numberDiff line numberDiff line change
@@ -2289,7 +2289,7 @@
22892289
that is, if the object is not of the destructor's class type and
22902290
not of a class derived from the destructor's class type (including when
22912291
the destructor is invoked via a null pointer value), the program has
2292-
undefined behavior.
2292+
undefined behavior\ubdef{class.dtor.not.class.type}.
22932293
\begin{note}
22942294
Invoking \keyword{delete} on a null pointer does not call the
22952295
destructor; see \ref{expr.delete}.
@@ -2356,7 +2356,7 @@
23562356

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

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

42584258
\rSec1[class.access]{Member access control}%
@@ -5523,7 +5523,7 @@
55235523
The target constructor is selected by overload resolution.
55245524
Once the target constructor returns, the body of the delegating constructor
55255525
is executed. If a constructor delegates to itself directly or indirectly,
5526-
the program is ill-formed, no diagnostic required.
5526+
the program is ill-formed, no diagnostic required\ifndrdef{class.base.init.delegate.itself}.
55275527
\begin{example}
55285528
\begin{codeblock}
55295529
struct C {
@@ -5838,7 +5838,7 @@
58385838
\item
58395839
a postcondition assertion of a destructor\iref{dcl.contract.func},
58405840
\end{itemize}
5841-
the program has undefined behavior.
5841+
the program has undefined behavior\ubdef{class.base.init.mem.fun}.
58425842
\begin{example}
58435843
\begin{codeblock}
58445844
class A {
@@ -6035,9 +6035,9 @@
60356035
\indextext{destruction!member access}%
60366036
For an object with a non-trivial constructor, referring to any non-static member
60376037
or base class of the object before the constructor begins execution results in
6038-
undefined behavior. For an object with a non-trivial destructor, referring to
6038+
undefined behavior\ubdef{class.cdtor.before.ctor.after.dtor}. For an object with a non-trivial destructor, referring to
60396039
any non-static member or base class of the object after the destructor finishes
6040-
execution results in undefined behavior.
6040+
execution results in undefined behavior\ubdef{class.cdtor.before.ctor.after.dtor}.
60416041
\begin{example}
60426042
\begin{codeblock}
60436043
struct X { int i; };
@@ -6122,15 +6122,15 @@
61226122
indirectly derive from
61236123
\tcode{B}
61246124
shall have started and the destruction of these classes shall not have
6125-
completed, otherwise the conversion results in undefined behavior.
6125+
completed, otherwise the conversion results in undefined behavior\ubdef{class.cdtor.convert.or.form.pointer}.
61266126
To form a pointer to (or access the value of) a direct non-static member of
61276127
an object
61286128
\tcode{obj},
61296129
the construction of
61306130
\tcode{obj}
61316131
shall have started and its destruction shall not have completed,
61326132
otherwise the computation of the pointer value (or accessing the member
6133-
value) results in undefined behavior.
6133+
value) results in undefined behavior\ubdef{class.cdtor.convert.or.form.pointer}.
61346134
\begin{example}
61356135
\begin{codeblock}
61366136
struct A { };
@@ -6174,7 +6174,7 @@
61746174
and the object expression refers to
61756175
the complete object of \tcode{x} or one of that object's base class subobjects
61766176
but not \tcode{x} or one of its base class subobjects, the behavior
6177-
is undefined.
6177+
is undefined\ubdef{class.cdtor.virtual.not.x}.
61786178
\begin{example}
61796179
\begin{codeblock}
61806180
struct V {
@@ -6231,7 +6231,7 @@
62316231
\tcode{typeid}
62326232
refers to the object under construction or destruction and the static type of
62336233
the operand is neither the constructor or destructor's class nor one of its
6234-
bases, the behavior is undefined.
6234+
bases, the behavior is undefined\ubdef{class.cdtor.typeid}.
62356235

62366236
\pnum
62376237
\indextext{construction!dynamic cast and}%
@@ -6256,7 +6256,7 @@
62566256
the operand is not a pointer to or object of the constructor or destructor's
62576257
own class or one of its bases, the
62586258
\keyword{dynamic_cast}
6259-
results in undefined behavior.
6259+
results in undefined behavior\ubdef{class.cdtor.dynamic.cast}.
62606260
\begin{example}
62616261
\begin{codeblock}
62626262
struct V {

source/declarations.tex

+8-8
Original file line numberDiff line numberDiff line change
@@ -1279,7 +1279,7 @@
12791279
\indextext{const object!undefined change to}%
12801280
Any attempt to modify\iref{expr.assign,expr.post.incr,expr.pre.incr} a
12811281
const object\iref{basic.type.qualifier} during its
1282-
lifetime\iref{basic.life} results in undefined behavior.
1282+
lifetime\iref{basic.life} results in undefined behavior\ubdef{dcl.type.cv.modify.const.obj}.
12831283
\begin{example}
12841284
\begin{codeblock}
12851285
const int ci = 3; // cv-qualified (initialized as required)
@@ -1323,7 +1323,7 @@
13231323
\impldef{semantics of an access through a volatile glvalue}.
13241324
If an attempt is made to access an object defined with a
13251325
volatile-qualified type through the use of a non-volatile glvalue,
1326-
the behavior is undefined.
1326+
the behavior is undefined\ubdef{dcl.type.cv.access.volatile}.
13271327

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

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

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

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

99539953
\pnum
99549954
If a function \tcode{f} is invoked where \tcode{f} was previously declared with the \tcode{noreturn}
99559955
attribute and that invocation eventually returns,
9956-
the behavior is runtime-undefined.
9956+
the behavior is runtime-undefined\ubdef{dcl.attr.noreturn.eventually.returns}.
99579957
\begin{note}
99589958
The function can
99599959
terminate by throwing an exception.

source/exceptions.tex

+1-1
Original file line numberDiff line numberDiff line change
@@ -690,7 +690,7 @@
690690
Referring to any non-static member or base class of an object
691691
in the handler for a
692692
\grammarterm{function-try-block}
693-
of a constructor or destructor for that object results in undefined behavior.
693+
of a constructor or destructor for that object results in undefined behavior\ubdef{except.handle.handler.ctor.dtor}.
694694

695695
\pnum
696696
Exceptions thrown in destructors of objects with static storage duration or in

0 commit comments

Comments
 (0)