Skip to content

Commit

Permalink
[2025-02 CWG Motion 8] P2786R13 Trivial Relocation]
Browse files Browse the repository at this point in the history
Added freestanding to the lib feature-test macro, as all new parts
are marked as freestanding.

Picked the most appropriate location within the type traits spec
for each of the three new traits.
  • Loading branch information
AlisdairM committed Feb 24, 2025
1 parent 458b16a commit a672a04
Show file tree
Hide file tree
Showing 10 changed files with 347 additions and 26 deletions.
13 changes: 13 additions & 0 deletions source/basic.tex
Original file line number Diff line number Diff line change
Expand Up @@ -4956,15 +4956,28 @@
cv-qualified\iref{basic.type.qualifier} versions of these
types are collectively called
\defnadjx{scalar}{types}{type}.

\label{term.trivially.copyable.type}%
Scalar types, trivially copyable class types\iref{class.prop},
arrays of such types, and cv-qualified versions of these
types are collectively called \defnadjx{trivially copyable}{types}{type}.

\label{term.trivially.relocatable.type}%
Scalar types, trivially relocatable class types\iref{class.prop},
arrays of such types, and cv-qualified versions of these
types are collectively called \defnadjx{trivially relocatable}{types}{type}.

\label{term.replaceable.type}%
Cv-unqualified scalar types, replaceable class types\iref{class.prop}, and
arrays of such types are collectively called
\defnadjx{replaceable}{types}{type}.

\label{term.standard.layout.type}%
Scalar types, standard-layout class
types\iref{class.prop}, arrays of such types, and
cv-qualified versions of these types
are collectively called \defnadjx{standard-layout}{types}{type}.

\label{term.implicit.lifetime.type}%
Scalar types, implicit-lifetime class types\iref{class.prop},
array types, and cv-qualified versions of these types
Expand Down
122 changes: 109 additions & 13 deletions source/classes.tex
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@

\begin{bnf}
\nontermdef{class-head}\br
class-key \opt{attribute-specifier-seq} class-head-name \opt{class-virt-specifier} \opt{base-clause}\br
class-key \opt{attribute-specifier-seq} class-head-name \opt{class-property-specifier-seq} \opt{base-clause}\br
class-key \opt{attribute-specifier-seq} \opt{base-clause}
\end{bnf}

Expand All @@ -46,8 +46,15 @@
\end{bnf}

\begin{bnf}
\nontermdef{class-virt-specifier}\br
\keyword{final}
\nontermdef{class-property-specifier-seq}\br
class-property-specifier \opt{class-property-specifier-seq}
\end{bnf}

\begin{bnf}
\nontermdef{class-property-specifier}\br
\keyword{final}\br
\keyword{trivially_relocatable_if_eligible}\br
\keyword{replaceable_if_eligible}
\end{bnf}

\begin{bnf}
Expand Down Expand Up @@ -120,12 +127,15 @@
\end{note}

\pnum
If a class is marked with the \grammarterm{class-virt-specifier} \tcode{final} and it appears
as a \grammarterm{class-or-decltype} in a \grammarterm{base-clause}\iref{class.derived},
the program is ill-formed. Whenever a
\grammarterm{class-key} is followed by a \grammarterm{class-head-name}, the
\grammarterm{identifier} \tcode{final}, and a colon or left brace, \tcode{final} is
interpreted as a \grammarterm{class-virt-specifier}.
Each \grammarterm{class-property-specifier} shall appear at most once within
a single \grammarterm{class-property-specifier-seq}.

Whenever a \grammarterm{class-key} is followed by a \grammarterm{class-head-name},
the identifier \tcode{final}, \tcode{trivially_relocatable_if_eligible}, or
\tcode{replaceable_if_eligible}, and a colon or left brace,
the identifier is interpreted as a \grammarterm{class-property-specifier}.


\begin{example}
\begin{codeblock}
struct A;
Expand All @@ -134,12 +144,19 @@

struct X {
struct C { constexpr operator int() { return 5; } };
struct B final : C{}; // OK, definition of nested class \tcode{B},
// not declaration of a bit-field member \tcode{final}
struct B trivially_relocatable_if_eligible : C{};
// OK, definition of nested class \tcode{B},
// not declaration of a bit-field member
// \tcode{trivially_relocatable_if_eligible}
};
\end{codeblock}
\end{example}

\pnum
If a class is marked with the \grammarterm{class-property-specifier}
\tcode{final} and that class appears as a \grammarterm{class-or-decltype}
in a \grammarterm{base-clause}\iref{class.derived}, the program is ill-formed.

\pnum
\begin{note}
Complete objects of class type have nonzero size.
Expand Down Expand Up @@ -172,6 +189,87 @@
\item that has a trivial, non-deleted destructor\iref{class.dtor}.
\end{itemize}

\pnum
A class \tcode{C} is \defn{default-movable} if

\begin{itemize}
\item overload resolution for direct-initializing an object of type \tcode{C}
from an xvalue of type \tcode{C} selects a constructor that is a direct member
of \tcode{C} and is neither user-provided nor deleted,

\item overload resolution for assigning to an lvalue of type \tcode{C} from an
xvalue of type \tcode{C} selects an assignment operator function that is a
direct member of \tcode{C} and is neither user-provided nor deleted, and

\item \tcode{C} has a destructor that is neither user-provided nor deleted.
\end{itemize}

\pnum
A class is \defn{eligible for trivial relocation} unless it
\begin{itemize}
\item has any virtual base classes,
\item has a base class that is not a trivially relocatable class,
\item has a non-static data member of an object type that is not of a
trivially relocatable type, or

\item has a deleted destructor,
\end{itemize}
except that it is \impldef{whether an otherwise-eligible union having one or
more subobjects of polymorphic class type is eligible for trivial relocation}
whether an otherwise-eligible union having one or more subobjects of
polymorphic class type is eligible for trivial relocation.

\pnum
A class \tcode{C} is a \defnadj{trivially relocatable}{class}
if it is eligible for trivial relocation and
\begin{itemize}
\item has the \tcode{trivially_relocatable_if_eligible} \grammarterm{class-property-specifier},
\item is a union with no user-declared special member functions, or
\item is default-movable.
\end{itemize}

\pnum
\begin{note}
A class with const-qualified or reference non-static data members can be
trivially relocatable.
\end{note}

\pnum
A class \tcode{C} is \defn{eligible for replacement} unless
\begin{itemize}
\item it has a base class that is not a replaceable class,
\item it has a non-static data member that is not of a replaceable type,
\item overload resolution fails or selects a deleted constructor when
direct-initializing an object of type \tcode{C} from an xvalue of type
\tcode{C}\iref{dcl.init.general},

\item overload resolution fails or selects a deleted assignment operator
function when assigning to an lvalue of type \tcode{C} from an xvalue of type
\tcode{C} \iref{expr.assign,over.assign}), or

\item it has a deleted destructor.
\end{itemize}

\pnum
A class \tcode{C} is a \defnadj{replaceable}{class} if it is
eligible for replacement and
\begin{itemize}
\item has the \tcode{replaceable_if_eligible} \grammarterm{class-property-specifier},
\item is a union with no user-declared special member functions, or
\item is default-movable.
\end{itemize}

\pnum
\begin{note}
Accessibility of the special member functions is not considered when
establishing trivial relocatability or replaceability.
\end{note}

\pnum
\begin{note}
Not all trivially copyable classes are trivially relocatable or replaceable.
\end{note}

\pnum
A class \tcode{S} is a \defnadj{standard-layout}{class} if it:
\begin{itemize}
Expand All @@ -185,9 +283,7 @@
for all non-static data members,

\item has no non-standard-layout base classes,

\item has at most one base class subobject of any given type,

\item has all non-static data members and bit-fields in the class and
its base classes first declared in the same class, and

Expand Down
28 changes: 28 additions & 0 deletions source/compatibility.tex
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,23 @@

\rSec2[diff.cpp23.dcl.dcl]{\ref{dcl}: declarations}

\diffref{dcl.decl.general}
\change
Introduction of \tcode{trivially_relocatable_if_eligible} and
\tcode{replaceable_if_eligible} as identifiers with special meaning\iref{lex.name}.
\rationale
Support declaration of trivially relocatable and replaceable types\iref{class.prop}.
\effect
Valid \CppXXIII{} code can become ill-formed.

\begin{example}
\begin{codeblock}
struct C {};
struct C replaceable_if_eligible {}; // was well-formed (new variable \tcode{replaceable_if_eligible})
// now ill-formed (redefines \tcode{C})
\end{codeblock}
\end{example}

\diffref{dcl.init.list}
\change
Pointer comparisons between \tcode{initializer_list} objects' backing arrays
Expand Down Expand Up @@ -194,6 +211,17 @@
Valid \CppXXIII{} code that \tcode{\#include}{s} headers with these names may be
invalid in this revision of \Cpp{}.

\diffref{res.on.macro.definitions}
\change
Additional restrictions on macro names.
\rationale
Avoid hard to diagnose or non-portable constructs.
\effect
Names of special identifiers may not be used as macro names.
Valid \CppXXIII{} code that defines \tcode{replaceable_if_eligible} or
\tcode{trivially_relocatable_if_eligible} as macros is invalid
in this revision of \Cpp{}.

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

\diffref{string.conversions}
Expand Down
6 changes: 3 additions & 3 deletions source/expressions.tex
Original file line number Diff line number Diff line change
Expand Up @@ -1963,9 +1963,9 @@
other than by changing:
\begin{itemize}
\item the size and/or alignment of the closure type,

\item whether the closure type is trivially copyable\iref{class.prop}, or

\item whether the closure type is trivially copyable\iref{class.prop},
\item whether the closure type is trivially relocatable\iref{class.prop},
\item whether the closure type is replaceable\iref{class.prop}, or
\item whether the closure type is a standard-layout class\iref{class.prop}.
\end{itemize}

Expand Down
15 changes: 9 additions & 6 deletions source/lex.tex
Original file line number Diff line number Diff line change
Expand Up @@ -907,6 +907,8 @@
\indextext{\idxcode{final}}%
\indextext{\idxcode{module}}%
\indextext{\idxcode{override}}%
\indextext{\idxcode{replaceable_if_eligible}}%
\indextext{\idxcode{trivially_relocatable_if_eligible}}%
The identifiers in \tref{lex.name.special} have a special meaning when
appearing in a certain context. When referred to in the grammar, these identifiers
are used explicitly rather than using the \grammarterm{identifier} grammar production.
Expand All @@ -915,14 +917,15 @@
token as a regular \grammarterm{identifier}.

\begin{multicolfloattable}{Identifiers with special meaning}{lex.name.special}
{llll}
\keyword{final} \\
\columnbreak
\keyword{import} \\
{lll}
\keyword{final} \\
\keyword{import} \\
\columnbreak
\keyword{module} \\
\keyword{module} \\
\keyword{override} \\
\columnbreak
\keyword{override} \\
\keyword{replaceable_if_eligible} \\
\keyword{trivially_relocatable_if_eligible} \\
\end{multicolfloattable}

\pnum
Expand Down
19 changes: 19 additions & 0 deletions source/lib-intro.tex
Original file line number Diff line number Diff line change
Expand Up @@ -3826,6 +3826,25 @@
side effects.
\end{note}

\rSec3[library.class.props]{Properties of library classes}

\pnum
Unless specifically stated, it is unspecified whether any class described in
\ref{\firstlibchapter} through \ref{\lastlibchapter} and \ref{depr} is a
trivially copyable class, a standard-layout class, or
an implicit-lifetime class\iref{class.prop}.

\pnum
Unless specifically stated, it is unspecified whether any class for which
trivial relocation (i.e., the effects of \tcode{trivially_relocate}) would be
semantically equivalent to move-construction of the destination object followed
by destruction of the source object is trivially relocatable.

\pnum
Unless specifically stated, it is unspecified whether any class for which move
assignment is semantically equivalent to destroying the assigned-to object,
then move-constructing from the source object in its place is replaceable.

\rSec3[protection.within.classes]{Protection within classes}

\pnum
Expand Down
Loading

0 comments on commit a672a04

Please sign in to comment.