Skip to content

Commit 51fa9ff

Browse files
committed
[std] Add Annex for undefined and IFNDR behavior
1 parent 9e75be6 commit 51fa9ff

14 files changed

+2457
-84
lines changed

source/basic.tex

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,7 @@
645645
\pnum
646646
Every program shall contain at least one definition of every
647647
function or variable that is odr-used in that program
648-
outside of a discarded statement\iref{stmt.if}; no diagnostic required.
648+
outside of a discarded statement\iref{stmt.if}; no diagnostic required\ifndrdef{basic.def.odr.exact.one.def}.
649649
The definition can appear explicitly in the program, it can be found in
650650
the standard or a user-defined library, or (when appropriate) it is
651651
implicitly defined (see~\ref{class.default.ctor}, \ref{class.copy.ctor},
@@ -928,7 +928,7 @@
928928
reachable unnamed enumeration definition in the same scope
929929
that have the same first enumerator name and
930930
do not have typedef names for linkage purposes\iref{dcl.enum},
931-
those unnamed enumeration types shall be the same; no diagnostic required.
931+
those unnamed enumeration types shall be the same; no diagnostic required\ifndrdef{basic.def.odr.unnamed.enum.same.type}.
932932
\indextext{one-definition rule|)}
933933

934934
\rSec1[basic.scope]{Scope}%
@@ -1803,7 +1803,7 @@
18031803
If it is an invalid set, the program is ill-formed.
18041804
If it differs from the result of a search in $T$ for $M$
18051805
in a complete-class context\iref{class.mem} of $T$,
1806-
the program is ill-formed, no diagnostic required.
1806+
the program is ill-formed, no diagnostic required\ifndrdef{class.member.lookup.name.refers.diff.decl}.
18071807
\begin{example}
18081808
\begin{codeblock}
18091809
struct A { int x; }; // S(x,A) = \{ \{ \tcode{A::x} \}, \{ \tcode{A} \} \}
@@ -3662,7 +3662,7 @@
36623662
zero or more objects of implicit-lifetime types\iref{term.implicit.lifetime.type}
36633663
in its specified region of storage
36643664
if doing so would result in the program having defined behavior.
3665-
If no such set of objects would give the program defined behavior,
3665+
If no such set of objects would give the program defined behavior\ubdef{intro.object.implicit.create},
36663666
the behavior of the program is undefined.
36673667
If multiple such sets of objects would give the program defined behavior,
36683668
it is unspecified which such set of objects is created.
@@ -3924,7 +3924,7 @@
39243924
if the pointer were of type \tcode{\keyword{void}*} is
39253925
well-defined. Indirection through such a pointer is permitted but the resulting lvalue may only be used in
39263926
limited ways, as described below. The
3927-
program has undefined behavior if
3927+
program has undefined behavior\ubdef{lifetime.outside.pointer} if:
39283928
\begin{itemize}
39293929
\item
39303930
the pointer is used as the operand of a \grammarterm{delete-expression},
@@ -3987,7 +3987,7 @@
39873987
a glvalue refers to
39883988
allocated storage\iref{basic.stc.dynamic.allocation}, and using the
39893989
properties of the glvalue that do not depend on its value is
3990-
well-defined. The program has undefined behavior if
3990+
well-defined. The program has undefined behavior\ubdef{lifetime.outside.glvalue} if:
39913991
\begin{itemize}
39923992
\item the glvalue is used to access the object, or
39933993
\item the glvalue is used to call a non-static member function of the object, or
@@ -4077,7 +4077,7 @@
40774077
\end{footnote}
40784078
and another object of the original type does not occupy
40794079
that same storage location when the implicit destructor call takes
4080-
place, the behavior of the program is undefined. This is true
4080+
place, the behavior of the program is undefined\ubdef{original.type.implicit.destructor}. This is true
40814081
even if the block is exited with an exception.
40824082
\begin{example}
40834083
\begin{codeblock}
@@ -4097,7 +4097,7 @@
40974097
Creating a new object within the storage that a const, complete
40984098
object with static, thread, or automatic storage duration occupies,
40994099
or within the storage that such a const object used to occupy before
4100-
its lifetime ended, results in undefined behavior.
4100+
its lifetime ended, results in undefined behavior\ubdef{creating.within.const.complete.obj}.
41014101
\begin{example}
41024102
\begin{codeblock}
41034103
struct B {
@@ -4436,7 +4436,7 @@
44364436
does not satisfy the semantic constraints
44374437
specified in~\ref{basic.stc.dynamic.allocation}
44384438
and~\ref{basic.stc.dynamic.deallocation},
4439-
the behavior is undefined.
4439+
the behavior is undefined\ubdef{basic.stc.alloc.dealloc.constraint}.
44404440

44414441
\indextext{storage duration!dynamic|)}
44424442

@@ -6445,7 +6445,7 @@
64456445
The value computations of the operands of an
64466446
operator are sequenced before the value computation of the result of the
64476447
operator.
6448-
The behavior is undefined if
6448+
The behavior is undefined\iref{intro.multithread}\ubdef{intro.execution.unsequenced.modification} if
64496449
\begin{itemize}
64506450
\item
64516451
\indextext{side effects}%
@@ -6853,7 +6853,7 @@
68536853
and neither happens before the other,
68546854
except for the special case for signal handlers described below.
68556855
Any such data race results in undefined
6856-
behavior.
6856+
behavior\ubdef{intro.races.data}.
68576857
\begin{note}
68586858
It can be shown that programs that correctly use mutexes
68596859
and \tcode{memory_order::seq_cst} operations to prevent all data races and use no
@@ -7219,7 +7219,7 @@
72197219
objects with automatic storage duration\iref{class.dtor}. If
72207220
\tcode{std::exit} is invoked during the destruction of
72217221
an object with static or thread storage duration, the program has undefined
7222-
behavior.
7222+
behavior\ubdef{basic.start.main.exit.during.destruction}.
72237223

72247224
\pnum
72257225
\indextext{termination!program}%
@@ -7513,7 +7513,7 @@
75137513
\pnum
75147514
If a function contains a block variable of static or thread storage duration that has been
75157515
destroyed and the function is called during the destruction of an object with static or
7516-
thread storage duration, the program has undefined behavior if the flow of control
7516+
thread storage duration, the program has undefined behavior\ubdef{basic.start.term.use.after.destruction} if the flow of control
75177517
passes through the definition of the previously destroyed block variable.
75187518
\begin{note}
75197519
Likewise, the behavior is undefined
@@ -7540,7 +7540,7 @@
75407540
handlers\iref{support.runtime} that does not happen before\iref{intro.multithread}
75417541
completion of destruction of objects with static storage duration and execution of
75427542
\tcode{std::atexit} registered functions\iref{support.start.term}, the program has
7543-
undefined behavior.
7543+
undefined behavior\ubdef{basic.start.term.signal.handler}.
75447544
\begin{note}
75457545
If there is a use of an object with static storage
75467546
duration that does not happen before the object's destruction, the program has undefined

source/classes.tex

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2341,7 +2341,7 @@
23412341
that is, if the object is not of the destructor's class type and
23422342
not of a class derived from the destructor's class type (including when
23432343
the destructor is invoked via a null pointer value), the program has
2344-
undefined behavior.
2344+
undefined behavior\ubdef{class.dtor.not.class.type}.
23452345
\begin{note}
23462346
Invoking \keyword{delete} on a null pointer does not call the
23472347
destructor; see \ref{expr.delete}.
@@ -2408,7 +2408,7 @@
24082408

24092409
\pnum
24102410
Once a destructor is invoked for an object, the object's lifetime ends;
2411-
the behavior is undefined if the destructor is invoked
2411+
the behavior is undefined\ubdef{class.dtor.no.longer.exists} if the destructor is invoked
24122412
for an object whose lifetime has ended\iref{basic.life}.
24132413
\begin{example}
24142414
If the destructor for an object with automatic storage duration is explicitly invoked,
@@ -3289,7 +3289,7 @@
32893289
each anonymous union member \tcode{X}\iref{class.union.anon} that
32903290
is a member of a union and
32913291
has such an element as an immediate subobject (recursively),
3292-
if modification of \tcode{X} would have undefined behavior under~\ref{basic.life},
3292+
if modification of \tcode{X} would have undefined behavior\ubdef{class.union.assignment.not.start.lifetime} under~\ref{basic.life},
32933293
an object of the type of \tcode{X} is implicitly created
32943294
in the nominated storage;
32953295
no initialization is performed and
@@ -4076,7 +4076,7 @@
40764076
\indextext{definition!virtual function}%
40774077
A virtual function declared in a class shall be defined, or declared
40784078
pure\iref{class.abstract} in that class, or both; no diagnostic is
4079-
required\iref{basic.def.odr}.
4079+
required\iref{basic.def.odr}\ifndrdef{class.virtual.pure.or.defined}.
40804080
\indextext{friend!\tcode{virtual} and}%
40814081

40824082
\pnum
@@ -4309,7 +4309,7 @@
43094309
\indextext{virtual function call!undefined pure}%
43104310
the effect of making a virtual call\iref{class.virtual} to a pure
43114311
virtual function directly or indirectly for the object being created (or
4312-
destroyed) from such a constructor (or destructor) is undefined.%
4312+
destroyed) from such a constructor (or destructor) is undefined\ubdef{class.abstract.pure.virtual}.%
43134313
\indextext{derived class|)}
43144314

43154315
\rSec1[class.access]{Member access control}%
@@ -5591,7 +5591,7 @@
55915591
The target constructor is selected by overload resolution.
55925592
Once the target constructor returns, the body of the delegating constructor
55935593
is executed. If a constructor delegates to itself directly or indirectly,
5594-
the program is ill-formed, no diagnostic required.
5594+
the program is ill-formed, no diagnostic required\ifndrdef{class.base.init.delegate.itself}.
55955595
\begin{example}
55965596
\begin{codeblock}
55975597
struct C {
@@ -5906,7 +5906,7 @@
59065906
\item
59075907
a postcondition assertion of a destructor\iref{dcl.contract.func},
59085908
\end{itemize}
5909-
the program has undefined behavior.
5909+
the program has undefined behavior\ubdef{class.base.init.mem.fun}.
59105910
\begin{example}
59115911
\begin{codeblock}
59125912
class A {
@@ -6103,9 +6103,9 @@
61036103
\indextext{destruction!member access}%
61046104
For an object with a non-trivial constructor, referring to any non-static member
61056105
or base class of the object before the constructor begins execution results in
6106-
undefined behavior. For an object with a non-trivial destructor, referring to
6106+
undefined behavior\ubdef{class.cdtor.before.ctor.after.dtor}. For an object with a non-trivial destructor, referring to
61076107
any non-static member or base class of the object after the destructor finishes
6108-
execution results in undefined behavior.
6108+
execution results in undefined behavior\ubdef{class.cdtor.before.ctor.after.dtor}.
61096109
\begin{example}
61106110
\begin{codeblock}
61116111
struct X { int i; };
@@ -6190,15 +6190,15 @@
61906190
indirectly derive from
61916191
\tcode{B}
61926192
shall have started and the destruction of these classes shall not have
6193-
completed, otherwise the conversion results in undefined behavior.
6193+
completed, otherwise the conversion results in undefined behavior\ubdef{class.cdtor.convert.or.form.pointer}.
61946194
To form a pointer to (or access the value of) a direct non-static member of
61956195
an object
61966196
\tcode{obj},
61976197
the construction of
61986198
\tcode{obj}
61996199
shall have started and its destruction shall not have completed,
62006200
otherwise the computation of the pointer value (or accessing the member
6201-
value) results in undefined behavior.
6201+
value) results in undefined behavior\ubdef{class.cdtor.convert.or.form.pointer}.
62026202
\begin{example}
62036203
\begin{codeblock}
62046204
struct A { };
@@ -6242,7 +6242,7 @@
62426242
and the object expression refers to
62436243
the complete object of \tcode{x} or one of that object's base class subobjects
62446244
but not \tcode{x} or one of its base class subobjects, the behavior
6245-
is undefined.
6245+
is undefined\ubdef{class.cdtor.virtual.not.x}.
62466246
\begin{example}
62476247
\begin{codeblock}
62486248
struct V {
@@ -6299,7 +6299,7 @@
62996299
\tcode{typeid}
63006300
refers to the object under construction or destruction and the static type of
63016301
the operand is neither the constructor or destructor's class nor one of its
6302-
bases, the behavior is undefined.
6302+
bases, the behavior is undefined\ubdef{class.cdtor.typeid}.
63036303

63046304
\pnum
63056305
\indextext{construction!dynamic cast and}%
@@ -6324,7 +6324,7 @@
63246324
the operand is not a pointer to or object of the constructor or destructor's
63256325
own class or one of its bases, the
63266326
\keyword{dynamic_cast}
6327-
results in undefined behavior.
6327+
results in undefined behavior\ubdef{class.cdtor.dynamic.cast}.
63286328
\begin{example}
63296329
\begin{codeblock}
63306330
struct V {

source/declarations.tex

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1304,7 +1304,7 @@
13041304
\indextext{const object!undefined change to}%
13051305
Any attempt to modify\iref{expr.assign,expr.post.incr,expr.pre.incr} a
13061306
const object\iref{basic.type.qualifier} during its
1307-
lifetime\iref{basic.life} results in undefined behavior.
1307+
lifetime\iref{basic.life} results in undefined behavior\ubdef{dcl.type.cv.modify.const.obj}.
13081308
\begin{example}
13091309
\begin{codeblock}
13101310
const int ci = 3; // cv-qualified (initialized as required)
@@ -1348,7 +1348,7 @@
13481348
\impldef{semantics of an access through a volatile glvalue}.
13491349
If an attempt is made to access an object defined with a
13501350
volatile-qualified type through the use of a non-volatile glvalue,
1351-
the behavior is undefined.
1351+
the behavior is undefined\ubdef{dcl.type.cv.access.volatile}.
13521352

13531353
\pnum
13541354
\indextext{type specifier!\idxcode{volatile}}%
@@ -7379,7 +7379,7 @@
73797379
The evaluation that invoked a resumption member function is
73807380
called the \defnx{resumer}{coroutine!resumer}.
73817381
Invoking a resumption member function for a coroutine
7382-
that is not suspended results in undefined behavior.
7382+
that is not suspended results in undefined behavior\ubdef{dcl.fct.def.coroutine.resume.not.suspended}.
73837383

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

74787478
\pnum
74797479
The deallocation function's name is looked up by searching for it in the scope of the promise type.
@@ -9630,7 +9630,7 @@
96309630
\grammarterm{alignment-specifier}{},
96319631
every defining
96329632
declaration of that entity shall specify an equivalent alignment.
9633-
No diagnostic is required if declarations of an entity have
9633+
No diagnostic is required\ifndrdef{dcl.align.diff.translation.units} if declarations of an entity have
96349634
different \grammarterm{alignment-specifier}{s}
96359635
in different translation units.
96369636
\begin{example}
@@ -9684,7 +9684,7 @@
96849684
at the point where the assumption appears,
96859685
the assumption has no effect.
96869686
Otherwise,
9687-
evaluation of the assumption has runtime-undefined behavior.
9687+
evaluation of the assumption has runtime-undefined behavior\ubdef{dcl.attr.assume.false}.
96889688

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

1011910119
\pnum
1012010120
If a function \tcode{f} is invoked where \tcode{f} was previously declared with the \tcode{noreturn}
1012110121
attribute and that invocation eventually returns,
10122-
the behavior is runtime-undefined.
10122+
the behavior is runtime-undefined\ubdef{dcl.attr.noreturn.eventually.returns}.
1012310123
\begin{note}
1012410124
The function can
1012510125
terminate by throwing an exception.

source/exceptions.tex

Lines changed: 1 addition & 1 deletion
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)