Skip to content

Commit

Permalink
Merge 2024-11 CWG Motion 1
Browse files Browse the repository at this point in the history
P3524R0 Core Language Working Group "ready" Issues
  • Loading branch information
tkoeppe authored Dec 16, 2024
2 parents 10668dc + 8f6236e commit 9e41261
Show file tree
Hide file tree
Showing 11 changed files with 419 additions and 203 deletions.
66 changes: 53 additions & 13 deletions source/basic.tex
Original file line number Diff line number Diff line change
Expand Up @@ -511,7 +511,8 @@
either:
\begin{itemize}
\item the intervening scope is a block scope, or
\item the intervening scope is the function parameter scope of a \grammarterm{lambda-expression}, or
\item the intervening scope is the function parameter scope of
a \grammarterm{lambda-expression} or \grammarterm{requires-expression}, or
\item the intervening scope is the lambda scope of
a \grammarterm{lambda-expression}
that has a \grammarterm{simple-capture}
Expand Down Expand Up @@ -3115,7 +3116,9 @@
\end{note}

\pnum
A \defn{memory location} is either an object of scalar type that is not a bit-field
A \defn{memory location} is
the storage occupied by the object representation of
either an object of scalar type that is not a bit-field
or a maximal sequence of adjacent bit-fields all having nonzero width.
\begin{note}
Various
Expand Down Expand Up @@ -5515,7 +5518,7 @@
A pointer value $P$ is
\indextext{value!valid in the context of an evaluation}%
\defn{valid in the context of} an evaluation $E$
if $P$ is a null pointer value, or
if $P$ is a pointer to function or a null pointer value, or
if it is a pointer to or past the end of an object $O$ and
$E$ happens before the end of the duration of the region of storage for $O$.
If a pointer value $P$ is used in an evaluation $E$ and
Expand Down Expand Up @@ -6037,13 +6040,30 @@
\end{note}
The value computations of the operands of an
operator are sequenced before the value computation of the result of the
operator. If a
operator.
The behavior is undefined if
\begin{itemize}
\item
\indextext{side effects}%
side effect on a memory location\iref{intro.memory} is unsequenced
relative to either another side effect on the same memory location or
a side effect on a memory location\iref{intro.memory} or
\item
starting or ending the lifetime of an object in a memory location
\end{itemize}
is unsequenced relative to
\begin{itemize}
\item
another side effect on the same memory location,
\item
starting or ending the lifetime of an object occupying storage that
overlaps with the memory location, or
\item
a value computation using the value of any object in the same memory location,
and they are not potentially concurrent\iref{intro.multithread},
the behavior is undefined.
\end{itemize}
and the two evaluations are not potentially concurrent\iref{intro.multithread}.
\begin{note}
Starting the lifetime of an object in a memory location can end the lifetime of
objects in other memory locations\iref{basic.life}.
\end{note}
\begin{note}
The next subclause imposes similar, but more complex restrictions on
potentially concurrent computations.
Expand All @@ -6057,6 +6077,9 @@
i = i++ + 1; // the value of \tcode{i} is incremented
i = i++ + i; // undefined behavior
i = i + 1; // the value of \tcode{i} is incremented

union U { int x, y; } u;
(u.x = 1, 0) + (u.y = 2, 0); // undefined behavior
}
\end{codeblock}
\end{example}
Expand All @@ -6067,8 +6090,13 @@
the postfix expression designating the called function
are sequenced before every expression or statement
in the body of the called function.
For each function invocation or
evaluation of an \grammarterm{await-expression} \placeholder{F},
For each
\begin{itemize}
\item function invocation,
\item evaluation of an \grammarterm{await-expression}\iref{expr.await}, or
\item evaluation of a \grammarterm{throw-expression}\iref{expr.throw}
\end{itemize}
\placeholder{F},
each evaluation that does not occur within \placeholder{F} but
is evaluated on the same thread and as part of the same signal handler (if any)
is either sequenced before all evaluations that occur within \placeholder{F}
Expand Down Expand Up @@ -6167,9 +6195,21 @@
\end{note}

\pnum
Two expression evaluations \defn{conflict} if one of them modifies\iref{defns.access} a memory
location\iref{intro.memory} and the other one reads or modifies the same
memory location.
Two expression evaluations \defn{conflict} if one of them
\begin{itemize}
\item
modifies\iref{defns.access} a memory location\iref{intro.memory} or
\item
starts or ends the lifetime of an object in a memory location
\end{itemize}
and the other one
\begin{itemize}
\item
reads or modifies the same memory location or
\item
starts or ends the lifetime of an object occupying storage that
overlaps with the memory location.
\end{itemize}
\begin{note}
A modification can still conflict
even if it does not alter the value of any bits.
Expand Down
56 changes: 29 additions & 27 deletions source/classes.tex
Original file line number Diff line number Diff line change
Expand Up @@ -3331,13 +3331,13 @@

\pnum
\indextext{nested class!local class}%
If class \tcode{X} is a local class, a nested class \tcode{Y} may be
declared in class \tcode{X} and later defined in the definition of class
\tcode{X} or be later defined in the same scope as the definition of
class \tcode{X}.
\indextext{restriction!local class}%
A class nested within
a local class is a local class.
A member of a local class \tcode{X} shall be
declared only in the definition of \tcode{X} or,
if the member is a nested class,
in the nearest enclosing block scope of \tcode{X}.

\pnum
\indextext{restriction!static member local class}%
Expand Down Expand Up @@ -6178,60 +6178,62 @@
\indextext{constructor!copy!elision}%
\indextext{constructor!move!elision}%
When certain criteria are met, an implementation is
allowed to omit the copy/move construction of a class object,
even if the constructor selected for the copy/move operation and/or the
allowed to omit the creation of a class object from
a source object of the same type (ignoring cv-qualification),
even if the selected constructor and/or the
destructor for the object have
\indextext{side effects}%
side effects. In such cases, the
implementation treats the source and target of the
omitted copy/move operation as simply two different ways of
omitted initialization as simply two different ways of
referring to the same object. If the first parameter of the
selected constructor is an rvalue reference to the object's type,
the destruction of that object occurs when the target would have been destroyed;
otherwise, the destruction occurs at the later of the times when the
two objects would have been destroyed without the
optimization.
\begin{footnote}
\begin{note}
Because only one object is destroyed instead of two,
and one copy/move constructor
is not executed, there is still one object destroyed for each one constructed.
\end{footnote}
This elision of copy/move operations, called
and the creation of one object is omitted,
there is still one object destroyed for each one constructed.
\end{note}
This elision of object creation, called
\indexdefn{copy elision|see{constructor, copy, elision}}%
\indexdefn{elision!copy|see{constructor, copy, elision}}%
\indexdefn{constructor!copy!elision}\indexdefn{constructor!move!elision}\term{copy elision},
is permitted in the
following circumstances (which may be combined to
eliminate multiple copies):
\begin{itemize}
\item in a \tcode{return} statement in a function with a class return type,
\item in a \tcode{return} statement\iref{stmt.return} in
a function with a class return type,
when the \grammarterm{expression} is the name of a non-volatile
object with automatic storage duration (other than a function parameter or a variable
object $o$ with automatic storage duration (other than a function parameter or a variable
introduced by the \grammarterm{exception-declaration} of a
\grammarterm{handler}\iref{except.handle})
with the same type (ignoring cv-qualification) as
the function return type, the copy/move operation can be
omitted by constructing the object directly
into the function call's return object
\grammarterm{handler}\iref{except.handle}),
the copy-initialization of the result object can be
omitted by constructing $o$ directly
into the function call's result object;

\item in a \grammarterm{throw-expression}\iref{expr.throw}, when the operand
is the name of a non-volatile object with automatic storage duration
(other than a function or catch-clause parameter)
is the name of a non-volatile object $o$ with automatic storage duration
(other than a function parameter or
a variable introduced by
the \grammarterm{exception-declaration} of a \grammarterm{handler})
that belongs to a scope that does not contain
the innermost enclosing \grammarterm{compound-statement}
associated with a \grammarterm{try-block} (if there is one),
the copy/move operation can be omitted by
constructing the object directly into the exception object
the copy-initialization of the exception object can be omitted by
constructing $o$ directly into the exception object;

\item in a coroutine\iref{dcl.fct.def.coroutine}, a copy of a coroutine parameter
can be omitted and references to that copy replaced with references to the
corresponding parameter if the meaning of the program will be unchanged except for
the execution of a constructor and destructor for the parameter copy object
the execution of a constructor and destructor for the parameter copy object;

\item when the \grammarterm{exception-declaration} of a
\grammarterm{handler}\iref{except.handle} declares an object of the same
type (except for cv-qualification) as the exception
object\iref{except.throw}, the copy operation can be omitted by treating
\grammarterm{handler}\iref{except.handle} declares an object $o$,
the copy-initialization of $o$ can be omitted by treating
the \grammarterm{exception-declaration} as an alias for the exception
object if the meaning of the program will be unchanged except for the execution
of constructors and destructors for the object declared by the
Expand Down
32 changes: 32 additions & 0 deletions source/compatibility.tex
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,38 @@
\end{codeblock}
\end{example}

\diffref{temp.deduct.call}
\change
Template argument deduction from overload sets succeeds in more cases.
\rationale
Allow consideration of constraints to disambiguate overload sets
used as parameters in function calls.
\effect
Valid \CppXXIII{} code may become ill-formed.
\begin{example}
\begin{codeblock}
template <typename T>
void f(T &&, void (*)(T &&));

void g(int &); // \#1
inline namespace A {
void g(short &&); // \#2
}
inline namespace B {
void g(short &&); // \#3
}

void q() {
int x;
f(x, g); // ill-formed; previously well-formed, deducing \tcode{T = int\&}
}
\end{codeblock}
There is no change to the applicable deduction rules for
the individual \tcode{g} candidates:
Type deduction from \#1 does not succeed;
type deductions from \#2 and \#3 both succeed.
\end{example}

\rSec2[diff.cpp23.library]{\ref{library}: library introduction}

\diffref{headers}
Expand Down
19 changes: 15 additions & 4 deletions source/declarations.tex
Original file line number Diff line number Diff line change
Expand Up @@ -3641,7 +3641,7 @@
If the
\grammarterm{parameter-declaration-clause}
is empty, the function takes no arguments.
A parameter list consisting of a single unnamed parameter of
A parameter list consisting of a single unnamed non-object parameter of
non-dependent type \keyword{void} is equivalent to an empty parameter
list.
\indextext{parameter!\idxcode{void}}%
Expand Down Expand Up @@ -5810,6 +5810,10 @@
return x;
}
constexpr int z = f(); // error: not a constant expression

typedef int *A[3]; // array of 3 pointer to \tcode{int}
typedef const int *const CA[3]; // array of 3 const pointer to \tcode{const int}
ACPC &&r = AP{}; // binds directly
\end{codeblock}
\end{example}

Expand Down Expand Up @@ -9011,6 +9015,7 @@

\rSec2[dcl.attr.assume]{Assumption attribute}

\pnum
The \grammarterm{attribute-token} \tcode{assume} may be applied to a null statement;
such a statement is an \defn{assumption}.
An \grammarterm{attribute-argument-clause} shall be present and
Expand All @@ -9023,7 +9028,10 @@
If the converted expression would evaluate to \tcode{true}
at the point where the assumption appears,
the assumption has no effect.
Otherwise, the behavior is undefined.
Otherwise,
evaluation of the assumption has runtime-undefined behavior.

\pnum
\begin{note}
The expression is potentially evaluated\iref{basic.def.odr}.
The use of assumptions is intended to allow implementations
Expand All @@ -9037,6 +9045,8 @@
if an implementation does not attempt to deduce
any such information from assumptions.
\end{note}

\pnum
\begin{example}
\begin{codeblock}
int divide_by_32(int x) {
Expand Down Expand Up @@ -9530,8 +9540,9 @@
translation unit, the program is ill-formed, no diagnostic required.

\pnum
If a function \tcode{f} is called where \tcode{f} was previously declared with the \tcode{noreturn}
attribute and \tcode{f} eventually returns, the behavior is undefined.
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.
\begin{note}
The function can
terminate by throwing an exception.
Expand Down
Loading

0 comments on commit 9e41261

Please sign in to comment.