From 47469c02f92b09a1d54d2bd889ef20ee5482ece5 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 26 Mar 2024 15:29:28 -0700 Subject: [PATCH 01/47] =?UTF-8?q?CWG453=20References=20may=20only=20bind?= =?UTF-8?q?=20to=20=E2=80=9Cvalid=E2=80=9D=20objects?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/declarations.tex | 40 +++++++++++++++++++++++++++++++++++----- source/expressions.tex | 41 ++++++++++++++++++++++++----------------- 2 files changed, 59 insertions(+), 22 deletions(-) diff --git a/source/declarations.tex b/source/declarations.tex index 6a7b78e9a5..f3c96fac90 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -3069,16 +3069,46 @@ specifier\iref{dcl.stc}, is a class member\iref{class.mem} declaration within a class definition, or is the declaration of a parameter or a return type\iref{dcl.fct}; see~\ref{basic.def}. -A reference shall be initialized to refer to a valid object or function. + +\pnum +Attempting to bind a reference to a function where +the converted initializer is a glvalue whose +type is not call-compatible\iref{expr.call} +with the type of the function's definition +results in undefined behavior. +Attempting to bind a reference to an object where +the converted initializer is a glvalue through which +the object is not type-accessible\iref{basic.lval} +results in undefined behavior. \begin{note} \indextext{reference!null}% -In particular, a null reference cannot exist in a well-defined program, -because the only way to create such a reference would be to bind it to -the ``object'' obtained by indirection through a null pointer, -which causes undefined behavior. +The object designated by such a glvalue can be +outside its lifetime\iref{basic.life}. +Because a null pointer value or a pointer past the end of an object +does not point to an object, +a reference in a well-defined program cannot refer to such things; +see~\ref{expr.unary.op}. As described in~\ref{class.bit}, a reference cannot be bound directly to a bit-field. \end{note} +The behavior of an evaluation of a reference\iref{expr.prim.id, expr.ref} that +does not happen after\iref{intro.races} the initialization of the reference +is undefined. +\begin{example} +\begin{codeblock} +int &f(int&); +int &g(); +extern int &ir3; +int *ip = 0; +int &ir1 = *ip; // undefined behavior: null pointer +int &ir2 = f(ir3); // undefined behavior: \tcode{ir3} not yet initialized +int &ir3 = g(); +int &ir4 = f(ir4); // undefined behavior: \tcode{ir4} used in its own initializer + +char x alignas(int); +int &ir5 = *reinterpret_cast(&x); // undefined behavior: initializer refers to char object +\end{codeblock} +\end{example} \pnum \indextext{reference collapsing}% diff --git a/source/expressions.tex b/source/expressions.tex index 7b09b36d39..34e268290b 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -300,23 +300,24 @@ \end{note} \pnum +An object of dynamic type $\tcode{T}_\text{obj}$ is +\defn{type-accessible} through a glvalue of type $\tcode{T}_\text{ref}$ +if $\tcode{T}_\text{ref}$ is similar\iref{conv.qual} to: +\begin{itemize} +\item $\tcode{T}_\text{obj}$, + +\item a type that is the signed or unsigned type corresponding to $\tcode{T}_\text{obj}$, or + +\item a \keyword{char}, \tcode{\keyword{unsigned} \keyword{char}}, or \tcode{std::byte} type. +\end{itemize} If a program attempts to access\iref{defns.access} the stored value of an object through a glvalue -whose type is not similar\iref{conv.qual} to -one of the following types the behavior is -undefined: +through which it is not type-accessible, +the behavior is undefined. \begin{footnote} The intent of this list is to specify those circumstances in which an object can or cannot be aliased. \end{footnote} -\begin{itemize} -\item the dynamic type of the object, - -\item a type that is the signed or unsigned type corresponding to the -dynamic type of the object, or - -\item a \keyword{char}, \tcode{\keyword{unsigned} \keyword{char}}, or \tcode{std::byte} type. -\end{itemize} If a program invokes a defaulted copy/move constructor or copy/move assignment operator for a union of type \tcode{U} with a glvalue argument @@ -3270,14 +3271,20 @@ of the class member access\iref{expr.ref,basic.life}. \pnum +A type $\tcode{T}_\text{call}$ is +\defn{call-compatible} with a function type $\tcode{T}_\text{func}$ +if $\tcode{T}_\text{call}$ is the same type as $\tcode{T}_\text{func}$ or +if the type ``pointer to $\tcode{T}_\text{func}$'' can be +converted to type ``pointer to $\tcode{T}_\text{call}$'' +via a function pointer conversion\iref{conv.fctptr}. Calling a function through an -expression whose function type \tcode{E} is different -from the function type \tcode{F} of the called function's -definition results in undefined behavior -unless the type ``pointer to \tcode{F}'' can be converted -to the type ``pointer to \tcode{E}'' via a function pointer conversion\iref{conv.fctptr}. +expression whose function type +is not call-compatible with the +type of the called function's +definition results in undefined behavior. \begin{note} -The exception applies when the expression has the type of a +This requirement allows the case +when the expression has the type of a potentially-throwing function, but the called function has a non-throwing exception specification, and the function types are otherwise the same. From 6bd8d0a7a0bf0fc85017d75c731d692269c2b196 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 26 Mar 2024 15:41:44 -0700 Subject: [PATCH 02/47] CWG1954 typeid null dereference check in subexpressions --- source/expressions.tex | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/source/expressions.tex b/source/expressions.tex index 34e268290b..6c23233c0b 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -3914,26 +3914,27 @@ a reference to (possibly cv-qualified) class type, that class shall be completely defined. +\pnum +If an \grammarterm{expression} operand of \keyword{typeid} is +a possibly-parenthesized \grammarterm{unary-expression} +whose \grammarterm{unary-operator} is \tcode{*} and +whose operand evaluates to a null pointer value\iref{basic.compound}, +the \keyword{typeid} expression throws an exception\iref{except.throw} +of a type that would match a handler of type +\indextext{\idxcode{bad_typeid}}% +\indexlibraryglobal{bad_typeid}% +\tcode{std::bad_typeid}\iref{bad.typeid}. +\begin{note} +In other contexts, evaluating such a \grammarterm{unary-expression} +results in undefined behavior\iref{expr.unary.op}. +\end{note} + \pnum When \keyword{typeid} is applied to a glvalue whose type is a polymorphic class type\iref{class.virtual}, the result refers to a \tcode{std::type_info} object representing the type of the most derived object\iref{intro.object} (that is, the dynamic type) to which the -glvalue refers. If the glvalue is obtained by applying the -unary \tcode{*} operator to a pointer -\begin{footnote} -If \tcode{p} is an expression of -pointer type, then \tcode{*p}, -\tcode{(*p)}, \tcode{*(p)}, \tcode{((*p))}, \tcode{*((p))}, and so on -all meet this requirement. -\end{footnote} -and the pointer is a null pointer value\iref{basic.compound}, the -\keyword{typeid} expression throws an exception\iref{except.throw} of -a type that would match a handler of type -\indextext{\idxcode{bad_typeid}}% -\indexlibraryglobal{bad_typeid}% -\tcode{std::bad_typeid} -exception\iref{bad.typeid}. +glvalue refers. \pnum When \keyword{typeid} is applied to an expression other than a glvalue of From 939d5a54a2875364a0cc5ca0608064c616dce622 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 26 Mar 2024 17:04:32 -0700 Subject: [PATCH 03/47] CWG2476 placeholder-type-specifiers and function declarators --- source/classes.tex | 13 +--- source/declarations.tex | 152 ++++++++++++++++++++-------------------- 2 files changed, 80 insertions(+), 85 deletions(-) diff --git a/source/classes.tex b/source/classes.tex index 6cf92daee0..25bcd28f18 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -2435,10 +2435,9 @@ its \grammarterm{declarator} shall be a function declarator\iref{dcl.fct} of the form \begin{ncsimplebnf} -ptr-declarator \terminal{(} parameter-declaration-clause \terminal{)} \opt{cv-qualifier-seq}\br -\bnfindent \opt{ref-qualifier} \opt{noexcept-specifier} \opt{attribute-specifier-seq} +noptr-declarator parameters-and-qualifiers \end{ncsimplebnf} -where the \grammarterm{ptr-declarator} consists solely of +where the \grammarterm{noptr-declarator} consists solely of an \grammarterm{id-expression}, an optional \grammarterm{attribute-specifier-seq}, and optional surrounding parentheses, and @@ -2457,6 +2456,7 @@ \pnum A conversion function shall have no non-object parameters and shall be a non-static member function of a class or class template \tcode{X}; +its declared return type is the \grammarterm{conversion-type-id} and it specifies a conversion from \tcode{X} to the type specified by the \grammarterm{conversion-type-id}, interpreted as a \grammarterm{type-id}\iref{dcl.name}. @@ -2464,13 +2464,6 @@ of a conversion function (if any) shall not be a \grammarterm{defining-type-specifier}. -\pnum -\indextext{conversion!type of}% -The type of the conversion function is -``\opt{\tcode{noexcept}} function taking no parameter -\opt{\grammarterm{cv-qualifier-seq}} \opt{\grammarterm{ref-qualifier}} -returning \grammarterm{conversion-type-id}''. - \pnum \begin{note} A conversion function is never invoked for diff --git a/source/declarations.tex b/source/declarations.tex index f3c96fac90..beb73af178 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -1716,20 +1716,31 @@ \pnum A \grammarterm{placeholder-type-specifier} -designates a placeholder type that will be replaced later by deduction +designates a placeholder type that will be replaced later, +typically by deduction from an initializer. \pnum -A \grammarterm{placeholder-type-specifier} of the form -\opt{\grammarterm{type-constraint}} \keyword{auto} -can be used as a \grammarterm{decl-specifier} of -the \grammarterm{decl-specifier-seq} of -a \grammarterm{parameter-declaration} of -a function declaration or \grammarterm{lambda-expression} and, -if it is not the \keyword{auto} \grammarterm{type-specifier} -introducing a \grammarterm{trailing-return-type} (see below), +The type of a \grammarterm{parameter-declaration} of a +function declaration\iref{dcl.fct}, +\grammarterm{lambda-expression}\iref{expr.prim.lambda}, or +\grammarterm{template-parameter}\iref{temp.param} +can be declared using +a \grammarterm{placeholder-type-specifier} of the form +\opt{\grammarterm{type-constraint}} \keyword{auto}. +The placeholder type shall appear +as one of the \grammarterm{decl-specifier}{s} in +the \grammarterm{decl-specifier-seq} or +as one of the \grammarterm{type-specifier}{s} in +a \grammarterm{trailing-return-type} +that specifies the type that replaces such +a \grammarterm{decl-specifier} (see below); +the placeholder type is a \defn{generic parameter type placeholder} -of the function declaration or \grammarterm{lambda-expression}. +of the +function declaration, +\grammarterm{lambda-expression}, or +\grammarterm{template-parameter}, respectively. \begin{note} Having a generic parameter type placeholder signifies that the function is @@ -1738,15 +1749,15 @@ \end{note} \pnum -A placeholder type can appear with a function declarator in the -\grammarterm{decl-specifier-seq}, \grammarterm{type-specifier-seq}, -\grammarterm{conversion-function-id}, or \grammarterm{trailing-return-type}, -in any context where such a declarator is valid. If the function declarator -includes a \grammarterm{trailing-return-type}\iref{dcl.fct}, that -\grammarterm{trailing-return-type} specifies -the declared return type of the function. Otherwise, the function declarator -shall declare a function. If the declared return type of the -function contains a placeholder type, the return type of the function is +A placeholder type can appear in +the \grammarterm{decl-specifier-seq} for a function declarator +that includes a \grammarterm{trailing-return-type}\iref{dcl.fct}. + +\pnum +A placeholder type can appear in +the \grammarterm{decl-specifier-seq} or \grammarterm{type-specifier-seq} +in the declared return type of a function declarator that declares a function; +the return type of the function is deduced from non-discarded \tcode{return} statements, if any, in the body of the function\iref{stmt.if}. @@ -1756,9 +1767,11 @@ This use is allowed in an initializing declaration\iref{dcl.init} of a variable. The placeholder type shall appear as one of the -\grammarterm{decl-specifier}{s} in the -\grammarterm{decl-specifier-seq} and the -\grammarterm{decl-specifier-seq} +\grammarterm{decl-specifier}{s} in the \grammarterm{decl-specifier-seq} +or as one of the +\grammarterm{type-specifier}{s} in a \grammarterm{trailing-return-type} +that specifies the type that replaces such a \grammarterm{decl-specifier}; +the \grammarterm{decl-specifier-seq} shall be followed by one or more \grammarterm{declarator}{s}, each of which shall @@ -1772,6 +1785,7 @@ auto int r; // error: \keyword{auto} is not a \grammarterm{storage-class-specifier} auto f() -> int; // OK, \tcode{f} returns \tcode{int} auto g() { return 0.0; } // OK, \tcode{g} returns \tcode{double} +auto (*fp)() -> auto = f; // OK auto h(); // OK, \tcode{h}'s return type will be deduced when it is defined \end{codeblock} \end{example} @@ -1781,13 +1795,19 @@ \pnum A placeholder type can also be used -in the \grammarterm{type-specifier-seq} in -the \grammarterm{new-type-id} or \grammarterm{type-id} of a -\grammarterm{new-expression}\iref{expr.new} -and as a \grammarterm{decl-specifier} -of the \grammarterm{parameter-declaration}{'s} -\grammarterm{decl-specifier-seq} -in a \grammarterm{template-parameter}\iref{temp.param}. +in the \grammarterm{type-specifier-seq} of +the \grammarterm{new-type-id} or +in the \grammarterm{type-id} of a +\grammarterm{new-expression}\iref{expr.new}. +In such a \grammarterm{type-id}, +the placeholder type shall appear +as one of the \grammarterm{type-specifier}{s} in +the \grammarterm{type-specifier-seq} or +as one of the \grammarterm{type-specifier}{s} in +a \grammarterm{trailing-return-type} +that specifies the type that replaces such a \grammarterm{type-specifier}. + +\pnum The \tcode{auto} \grammarterm{type-specifier} can also be used as the \grammarterm{simple-type-specifier} in an explicit type conversion (functional notation)\iref{expr.type.conv}. @@ -3466,60 +3486,44 @@ \tcode{T} \tcode{D} where +\tcode{T} may be empty and \tcode{D} has the form \begin{ncsimplebnf} \terminal{D1} \terminal{(} parameter-declaration-clause \terminal{)} \opt{cv-qualifier-seq}\br -\bnfindent\opt{ref-qualifier} \opt{noexcept-specifier} \opt{attribute-specifier-seq} +\bnfindent\opt{ref-qualifier} \opt{noexcept-specifier} \opt{attribute-specifier-seq} \opt{trailing-return-type} \end{ncsimplebnf} -and the type of the contained +a \placeholder{derived-declarator-type-list} is determined as follows: +\begin{itemize} +\item +If the \grammarterm{unqualified-id} of the \grammarterm{declarator-id} +is a \grammarterm{conversion-function-id}, +the \placeholder{derived-declarator-type-list} is empty. + +\item +Otherwise, the \placeholder{derived-declarator-type-list} is as appears in +the type ``\placeholder{derived-declarator-type-list} \tcode{T}'' +of the contained \grammarterm{declarator-id} in the declaration \tcode{T} -\tcode{D1} -is -``\placeholder{derived-declarator-type-list} -\tcode{T}'', -the type of the -\grammarterm{declarator-id} -in -\tcode{D} -is -``\placeholder{derived-declarator-type-list} -\opt{\keyword{noexcept}} -function of parameter-type-list -\opt{\grammarterm{cv-qualifier-seq}} \opt{\grammarterm{ref-qualifier}} -returning \tcode{T}'', where +\tcode{D1}. +\end{itemize} +The declared return type \tcode{U} of the function type +is determined as follows: \begin{itemize} \item -the parameter-type-list is derived from -the \grammarterm{parameter-declaration-clause} as described below and +If the \grammarterm{trailing-return-type} is present, +\tcode{T} shall be the single \grammarterm{type-specifier} \keyword{auto}, and +\tcode{U} is the type specified by the \grammarterm{trailing-return-type}. + \item -the optional \keyword{noexcept} is present if and only if -the exception specification\iref{except.spec} is non-throwing. -\end{itemize} -The optional \grammarterm{attribute-specifier-seq} -appertains to the function type. +Otherwise, if the declaration declares a conversion function, +see~\ref{class.conv.fct}. -\pnum -In a declaration -\tcode{T} -\tcode{D} -where -\tcode{D} -has the form -\begin{ncsimplebnf} -\terminal{D1} \terminal{(} parameter-declaration-clause \terminal{)} \opt{cv-qualifier-seq}\br -\bnfindent\opt{ref-qualifier} \opt{noexcept-specifier} \opt{attribute-specifier-seq} trailing-return-type -\end{ncsimplebnf} -and the type of the contained -\grammarterm{declarator-id} -in the declaration -\tcode{T} -\tcode{D1} -is -``\placeholder{derived-declarator-type-list} \tcode{T}'', -\tcode{T} shall be the single \grammarterm{type-specifier} \keyword{auto}. +\item +Otherwise, \tcode{U} is \tcode{T}. +\end{itemize} The type of the \grammarterm{declarator-id} in @@ -3533,12 +3537,10 @@ \begin{itemize} \item the parameter-type-list is derived from -the \grammarterm{parameter-declaration-clause} as described below, -\item -\tcode{U} is the type specified by the \grammarterm{trailing-return-type}, and +the \grammarterm{parameter-declaration-clause} as described below and \item the optional \keyword{noexcept} is present if and only if -the exception specification is non-throwing. +the exception specification\iref{except.spec} is non-throwing. \end{itemize} The optional \grammarterm{attribute-specifier-seq} appertains to the function type. From 44a6d8177917c551d42aaa73fc716dacf69ca681 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 26 Mar 2024 17:14:11 -0700 Subject: [PATCH 04/47] CWG2533 Storage duration of implicitly created objects --- source/basic.tex | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/source/basic.tex b/source/basic.tex index a6d708976f..2d246761d2 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -3816,10 +3816,12 @@ \indextext{storage duration!automatic}% \indextext{storage duration!dynamic}% Static, thread, and automatic storage durations are associated with objects -introduced by declarations\iref{basic.def} and implicitly created by -the implementation\iref{class.temporary}. The dynamic storage duration +introduced by declarations\iref{basic.def} and +with temporary objects\iref{class.temporary}. +The dynamic storage duration is associated with objects created by a -\grammarterm{new-expression}\iref{expr.new}. +\grammarterm{new-expression}\iref{expr.new} or +with implicitly created objects\iref{intro.object}. \pnum The storage duration categories apply to references as well. From eef4c2ba0d3952605e6ab839705f769690b92f7e Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 26 Mar 2024 17:27:02 -0700 Subject: [PATCH 05/47] CWG2546 Defaulted secondary comparison operators defined as deleted --- source/classes.tex | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/source/classes.tex b/source/classes.tex index 25bcd28f18..6ec51c43ba 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -6688,18 +6688,29 @@ is defined as deleted if \begin{itemize} \item -overload resolution\iref{over.match}, +a first overload resolution\iref{over.match}, as applied to \tcode{x @ y}, +\begin{itemize} +\item does not result in a usable candidate, or - \item -the candidate selected by overload resolution -is not a rewritten candidate. +the selected candidate is not a rewritten candidate, or \end{itemize} +\item +a second overload resolution for +the expression resulting from the interpretation of \tcode{x @ y} +using the selected rewritten candidate\iref{over.match.oper} +does not result in a usable candidate +(for example, that expression might be \tcode{(x <=> y) @ 0}), or + +\item +\tcode{x @ y} cannot be implicitly converted to \tcode{bool}. +\end{itemize} +In any of the two overload resolutions above, +the defaulted operator function is not considered as +a candidate for the \tcode{@} operator. Otherwise, the operator function yields \tcode{x @ y}. -The defaulted operator function is not considered as a candidate -in the overload resolution for the \tcode{@} operator. \pnum \begin{example} From 5cd87e2bc2c140984d4b7030e9394aae2dea96d8 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 26 Mar 2024 17:55:52 -0700 Subject: [PATCH 06/47] CWG2547 Defaulted comparison operator function for non-classes --- source/classes.tex | 23 ++++++++++++++++++++--- source/declarations.tex | 6 +++--- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/source/classes.tex b/source/classes.tex index 6ec51c43ba..93d5122947 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -6400,12 +6400,15 @@ \pnum A defaulted comparison operator function\iref{over.binary} -for some class \tcode{C} shall be a non-template function -that is +that \begin{itemize} \item -a non-static member or friend of \tcode{C} and +is a non-static member or friend of some class \tcode{C}, + +\item +is defined as defaulted in \tcode{C} or in +a context where \tcode{C} is complete, and \item either has @@ -6414,6 +6417,9 @@ where the implicit object parameter (if any) is considered to be the first parameter. \end{itemize} +Such a comparison operator function is termed +\indextext{operator!defaulted comparison operator function}% +a defaulted comparison operator function for class \tcode{C}. Name lookups in the implicit definition\iref{dcl.fct.def.default} of a comparison operator function are performed from a context equivalent to @@ -6421,6 +6427,17 @@ A definition of a comparison operator as defaulted that appears in a class shall be the first declaration of that function. +\begin{example} +\begin{codeblock} +struct S; +bool operator==(S, S) = default; // error: \tcode{S} is not complete +struct S { + friend bool operator==(S, const S&) = default; // error: parameters of different types +}; +enum E { }; +bool operator==(E, E) = default; // error: not a member or friend of a class +\end{codeblock} +\end{example} \pnum A defaulted \tcode{<=>} or \tcode{==} operator function for class \tcode{C} diff --git a/source/declarations.tex b/source/declarations.tex index beb73af178..7c1d8fa644 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -6403,9 +6403,9 @@ is called an \defnx{explicitly-defaulted}{definition!function!explicitly-defaulted} definition. A function that is explicitly defaulted shall \begin{itemize} -\item be a special member function or -a comparison operator function\iref{over.binary}, and -\item not have default arguments. +\item be a special member function\iref{special} or +a comparison operator function\iref{over.binary, class.compare.default}, and +\item not have default arguments\iref{dcl.fct.default}. \end{itemize} \pnum From bc3b802f2df401b86d7e0d0192b769ba1b6cf837 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 26 Mar 2024 18:12:49 -0700 Subject: [PATCH 07/47] CWG2560 Parameter type determination in a requirement-parameter-list --- source/expressions.tex | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/source/expressions.tex b/source/expressions.tex index 6c23233c0b..ea64c0850a 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -2876,9 +2876,11 @@ \pnum A \grammarterm{requires-expression} may introduce local parameters using a -\grammarterm{parameter-declaration-clause}\iref{dcl.fct}. +\grammarterm{parameter-declaration-clause}. A local parameter of a \grammarterm{requires-expression} shall not have a default argument. +The type of such a parameter is determined as specified for +a function parameter in~\ref{dcl.fct}. These parameters have no linkage, storage, or lifetime; they are only used as notation for the purpose of defining \grammarterm{requirement}s. The \grammarterm{parameter-declaration-clause} of a @@ -2890,6 +2892,10 @@ concept C = requires(T t, ...) { // error: terminates with an ellipsis t; }; +template +concept C2 = requires(T p[2]) { + (decltype(p))nullptr; // OK, \tcode{p} has type ``pointer to \tcode{T}'' +}; \end{codeblock} \end{example} From 5227675eb71b003edd7a180ce190d7f60557616f Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 26 Mar 2024 18:17:24 -0700 Subject: [PATCH 08/47] CWG2568 Access checking during synthesis of defaulted comparison operator --- source/classes.tex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/classes.tex b/source/classes.tex index 93d5122947..740a24b7c2 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -6420,7 +6420,8 @@ Such a comparison operator function is termed \indextext{operator!defaulted comparison operator function}% a defaulted comparison operator function for class \tcode{C}. -Name lookups in the implicit definition\iref{dcl.fct.def.default} +Name lookups and access checks in +the implicit definition\iref{dcl.fct.def.default} of a comparison operator function are performed from a context equivalent to its \grammarterm{function-body}. From 90558dbd19437372e15edb2118851fb646e82414 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 26 Mar 2024 18:25:44 -0700 Subject: [PATCH 09/47] CWG2634 Avoid circularity in specification of scope for friend class declarations --- source/declarations.tex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/declarations.tex b/source/declarations.tex index 7c1d8fa644..6222314449 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -1529,7 +1529,8 @@ \keyword{friend} class-key nested-name-specifier \opt{\keyword{template}} simple-template-id \terminal{;} \end{ncsimplebnf} Any unqualified lookup for the \grammarterm{identifier} (in the first case) -does not consider scopes that contain the target scope; no name is bound. +does not consider scopes that contain +the nearest enclosing namespace or block scope; no name is bound. \begin{note} A \grammarterm{using-directive} in the target scope is ignored if it refers to a namespace not contained by that scope. From b391810ec2cb5bb53fba65a77c1e781fab11ed47 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 26 Mar 2024 18:29:42 -0700 Subject: [PATCH 10/47] CWG2637 Injected-class-name as a simple-template-id --- source/classes.tex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/classes.tex b/source/classes.tex index 740a24b7c2..fdb7647b6c 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -72,7 +72,8 @@ it is not looked up, and the \grammarterm{class-specifier} introduces it. \pnum -The +\indextext{component name}% +The component name of the \grammarterm{class-name} is also bound in the scope of the class (template) itself; this is known as the \defn{injected-class-name}. For purposes of access checking, the injected-class-name is treated as From 54e3829797cb70b68545e2532a3eb1213d0f07b6 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 26 Mar 2024 18:39:34 -0700 Subject: [PATCH 11/47] CWG2638 Improve the example for initializing by initializer list --- source/declarations.tex | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/declarations.tex b/source/declarations.tex index 6222314449..db40275e48 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -5941,12 +5941,14 @@ struct S { S(std::initializer_list); // \#1 S(std::initializer_list); // \#2 - S(); // \#3 + S(std::initializer_list); // \#3 + S(); // \#4 // ... }; S s1 = { 1.0, 2.0, 3.0 }; // invoke \#1 S s2 = { 1, 2, 3 }; // invoke \#2 -S s3 = { }; // invoke \#3 +S s3{s2}; // invoke \#3 (not the copy constructor) +S s4 = { }; // invoke \#4 \end{codeblock} \end{example} From f0eb8e87caaaade13ba3094f24e2fd26c0eb8793 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 26 Mar 2024 18:52:30 -0700 Subject: [PATCH 12/47] CWG2657 Cv-qualification adjustment when binding reference to temporary --- source/declarations.tex | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/source/declarations.tex b/source/declarations.tex index db40275e48..ff33b3c1ee 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -5714,8 +5714,10 @@ the converted expression in the second case is called the converted initializer. If the converted initializer is a prvalue, -its type \tcode{T4} is adjusted to type ``\cvqual{cv1} \tcode{T4}''\iref{conv.qual} -and the temporary materialization conversion\iref{conv.rval} is applied. +let its type be denoted by \tcode{T4}; +the temporary materialization conversion\iref{conv.rval} is applied, +considering the type of the prvalue to be +``\cvqual{cv1} \tcode{T4}''\iref{conv.qual}. In any case, the reference binds to the resulting glvalue (or to an appropriate base class subobject). @@ -5735,6 +5737,13 @@ int i2 = 42; int&& rri = static_cast(i2); // binds directly to \tcode{i2} B&& rrb = x; // binds directly to the result of \tcode{operator B} + +constexpr int f() { + const int &x = 42; + const_cast(x) = 1; // undefined behavior + return x; +} +constexpr int z = f(); // error: not a constant expression \end{codeblock} \end{example} @@ -5773,7 +5782,7 @@ Banana &&banana3 = Alaska(); // error } -const double& rcd2 = 2; // \tcode{rcd2} refers to temporary with value \tcode{2.0} +const double& rcd2 = 2; // \tcode{rcd2} refers to temporary with type \tcode{const double} and value \tcode{2.0} double&& rrd = 2; // \tcode{rrd} refers to temporary with value \tcode{2.0} const volatile int cvi = 1; const int& r2 = cvi; // error: cv-qualifier dropped From 2dc0d7275164c4fbf0a87fef05af8be1ff96cbf9 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 26 Mar 2024 19:06:59 -0700 Subject: [PATCH 13/47] CWG2661 Missing disambiguation rule for pure-specifier vs. brace-or-equal-initializer --- source/classes.tex | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/source/classes.tex b/source/classes.tex index fdb7647b6c..1cf36a8787 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -483,7 +483,7 @@ \nontermdef{member-declarator}\br declarator \opt{virt-specifier-seq} \opt{pure-specifier}\br declarator requires-clause\br - declarator \opt{brace-or-equal-initializer}\br + declarator brace-or-equal-initializer\br \opt{identifier} \opt{attribute-specifier-seq} \terminal{:} constant-expression \opt{brace-or-equal-initializer} \end{bnf} @@ -504,6 +504,18 @@ \terminal{=} \terminal{0} \end{bnf} +\pnum +In the absence of a \grammarterm{virt-specifier-seq}, +the token sequence \tcode{= 0} is treated as a \grammarterm{pure-specifier} +if the type of the \grammarterm{declarator-id}\iref{dcl.meaning.general} +is a function type, and +is otherwise treated as a \grammarterm{brace-or-equal-initializer}. +\begin{note} +If the member declaration acquires a function type through +template instantiation, +the program is ill-formed; see~\ref{temp.spec.general}. +\end{note} + \pnum \indextext{definition!class}% The \grammarterm{member-specification} in a class definition declares the From 6a2476a73f8e0a2bcc9b6a7d7ef67a8efdf22490 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 26 Mar 2024 21:01:36 -0700 Subject: [PATCH 14/47] CWG2668 co_await in a lambda-expression --- source/expressions.tex | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/expressions.tex b/source/expressions.tex index ea64c0850a..273ac6e40d 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -4798,9 +4798,11 @@ \end{bnf} \pnum -An \grammarterm{await-expression} shall appear only in a potentially-evaluated +An \grammarterm{await-expression} shall appear only as a potentially-evaluated expression within the \grammarterm{compound-statement} of a -\grammarterm{function-body} outside of a \grammarterm{handler}\iref{except.pre}. +\grammarterm{function-body} or \grammarterm{lambda-expression}, +in either case +outside of a \grammarterm{handler}\iref{except.pre}. In a \grammarterm{declaration-statement} or in the \grammarterm{simple-declaration} (if any) of an \grammarterm{init-statement}, an \grammarterm{await-expression} From c720e60fa3718682ac9a9f6bcb38fcbde6c1e7dc Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 26 Mar 2024 21:07:14 -0700 Subject: [PATCH 15/47] CWG2689 Are cv-qualified std::nullptr_t fundamental types? --- source/basic.tex | 1 + 1 file changed, 1 insertion(+) diff --git a/source/basic.tex b/source/basic.tex index 2d246761d2..711e008627 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -5209,6 +5209,7 @@ to type \cv{}~\keyword{void}. \pnum +The types denoted by \cv~\tcode{std::nullptr_t} are distinct types. A value of type \tcode{std::nullptr_t} is a null pointer constant\iref{conv.ptr}. Such values participate in the pointer and the pointer-to-member conversions\iref{conv.ptr,conv.mem}. From 2e4a6034d39538916e4e00d1aa4ab61c56243641 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 26 Mar 2024 22:05:52 -0700 Subject: [PATCH 16/47] CWG2700 #error disallows existing implementation practice --- source/intro.tex | 27 +++++++++++++++++---------- source/lex.tex | 5 ++++- source/preprocessor.tex | 16 +++++++++++----- 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/source/intro.tex b/source/intro.tex index a4fff15300..9c997007d9 100644 --- a/source/intro.tex +++ b/source/intro.tex @@ -730,11 +730,22 @@ If a program contains a violation of a rule for which no diagnostic is required, this document places no requirement on implementations with respect to that program. + \item \indextext{message!diagnostic}% -Otherwise, if a program contains a violation of any diagnosable rule or an occurrence +Otherwise, if a program contains +\begin{itemize} +\item +a violation of any diagnosable rule, +\item +a preprocessing translation unit with +a \tcode{\#warning} preprocessing directive\iref{cpp.error}, or +\item +an occurrence of a construct described in this document as ``conditionally-supported'' when -the implementation does not support that construct, a conforming implementation +the implementation does not support that construct, +\end{itemize} +a conforming implementation shall issue at least one diagnostic message. \end{itemize} \begin{note} @@ -744,17 +755,13 @@ see~\ref{temp.deduct}. \end{note} Furthermore, a conforming implementation +shall not accept \begin{itemize} \item -shall not accept a preprocessing translation unit containing -a \tcode{\#error} preprocessing directive\iref{cpp.error}, -\item -shall issue at least one diagnostic message for -each \tcode{\#warning} or \tcode{\#error} preprocessing directive -not following a \tcode{\#error} preprocessing directive in -a preprocessing translation unit, and +a preprocessing translation unit containing +a \tcode{\#error} preprocessing directive\iref{cpp.error} or \item -shall not accept a translation unit with +a translation unit with a \grammarterm{static_assert-declaration} that fails\iref{dcl.pre}. \end{itemize} diff --git a/source/lex.tex b/source/lex.tex index cd23d40013..03d086d26a 100644 --- a/source/lex.tex +++ b/source/lex.tex @@ -32,7 +32,10 @@ A source file together with all the headers\iref{headers} and source files included\iref{cpp.include} via the preprocessing directive \tcode{\#include}, less any source lines skipped by any of the -conditional inclusion\iref{cpp.cond} preprocessing directives, is +conditional inclusion\iref{cpp.cond} preprocessing directives, +as modified by the implementation-defined behavior of any +conditionally-supported-directives\iref{cpp.pre} and pragmas\iref{cpp.pragma}, +if any, is called a \defnadj{preprocessing}{translation unit}. \begin{note} A \Cpp{} program need not all be translated at the same time. diff --git a/source/preprocessor.tex b/source/preprocessor.tex index 7ca4deabb0..827497f2e3 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -1624,14 +1624,20 @@ \indextext{\idxcode{\#error}|see{preprocessing directive, error}} \pnum -A preprocessing directive of either of the following forms +A preprocessing directive of the form +\begin{ncsimplebnf} +\terminal{\# error} \opt{pp-tokens} new-line +\end{ncsimplebnf} +renders the program ill-formed. +A preprocessing directive of the form \begin{ncsimplebnf} -\terminal{\# error} \opt{pp-tokens} new-line\br \terminal{\# warning} \opt{pp-tokens} new-line \end{ncsimplebnf} -causes the implementation to produce -a diagnostic message that should include the specified sequence of preprocessing tokens; -the \tcode{\# error} directive renders the program ill-formed. +requires the implementation to produce at least one diagnostic message +for the preprocessing translation unit\iref{intro.compliance.general}. +\recommended +Any diagnostic message caused by either of these directives +should include the specified sequence of preprocessing tokens. \rSec1[cpp.pragma]{Pragma directive}% \indextext{preprocessing directive!pragma}% From 5c8666064e32809fadf29a2ce3752154ff1a0e06 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 26 Mar 2024 22:08:06 -0700 Subject: [PATCH 17/47] CWG2707 Deduction guides cannot have a trailing requires-clause --- source/templates.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/templates.tex b/source/templates.tex index 44235f9d48..0013f71f25 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -2421,7 +2421,7 @@ \begin{bnf} \nontermdef{deduction-guide}\br - \opt{explicit-specifier} template-name \terminal{(} parameter-declaration-clause \terminal{)} \terminal{->} simple-template-id \terminal{;} + \opt{explicit-specifier} template-name \terminal{(} parameter-declaration-clause \terminal{)} \opt{requires-clause} \terminal{->} simple-template-id \terminal{;} \end{bnf} \pnum From 5d64fb7efea1eaafb0e09ba633e78e10983106e0 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 26 Mar 2024 22:43:23 -0700 Subject: [PATCH 18/47] CWG2714 Implicit deduction guides omit properties from the parameter-declaration-clause of a constructor Editorial notes: * [over.match.class.deduct] Non-existent "trailing-requires-clause" changed to "trailing \grammarterm{requires-clause}". * Builds on wording from CWG2628 added in bd1822653a601a5e5bad6e392fe00059b785a006. --- source/overloading.tex | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/source/overloading.tex b/source/overloading.tex index 52de08ebe9..27d1148b3b 100644 --- a/source/overloading.tex +++ b/source/overloading.tex @@ -1200,9 +1200,16 @@ \item The associated constraints\iref{temp.constr.decl} are the conjunction of the associated constraints of \tcode{C} and -the associated constraints of the constructor. +the associated constraints of the constructor, if any. +\begin{note} +A \grammarterm{constraint-expression} in +the \grammarterm{template-head} of \tcode{C} +is checked for satisfaction before any constraints from +the \grammarterm{template-head} or trailing \grammarterm{requires-clause} +of the constructor. +\end{note} \item -The types of the function parameters are those of the constructor. +The \grammarterm{parameter-declaration-clause} is that of the constructor. \item The return type is the class template specialization designated by \tcode{C} @@ -1228,8 +1235,8 @@ \begin{itemize} \item -The template parameters, if any, -and function parameters +The \grammarterm{template-head}, if any, +and \grammarterm{parameter-declaration-clause} are those of the \grammarterm{deduction-guide}. \item The return type From 46556558a524d3733ac5ceb6cbc453693a540f34 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 26 Mar 2024 22:53:42 -0700 Subject: [PATCH 19/47] CWG2745 Dependent odr-use in generic lambdas --- source/basic.tex | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/source/basic.tex b/source/basic.tex index 711e008627..7fe7b59f1b 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -537,6 +537,27 @@ \end{codeblock} \end{example} +\pnum +\begin{example} +\begin{codeblock} +void g() { + constexpr int x = 1; + auto lambda = [] {}; // OK + lambda.operator()(); // OK, does not consider \tcode{x} at all + lambda.operator()(); // OK, does not odr-use \tcode{x} + lambda.operator()(); // error: odr-uses \tcode{x} from a context where \tcode{x} is not odr-usable +} + +void h() { + constexpr int x = 1; + auto lambda = [] { (T)x; }; // OK + lambda.operator()(); // OK, does not odr-use \tcode{x} + lambda.operator()(); // OK, does not odr-use \tcode{x} + lambda.operator()(); // error: odr-uses \tcode{x} from a context where \tcode{x} is not odr-usable +} +\end{codeblock} +\end{example} + \pnum Every program shall contain at least one definition of every function or variable that is odr-used in that program From 1a2c3907b3a458c3acc9c780c601e0fc65053888 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 26 Mar 2024 22:58:18 -0700 Subject: [PATCH 20/47] CWG2746 Checking of default template arguments --- source/templates.tex | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/templates.tex b/source/templates.tex index 0013f71f25..b7eb73a2ca 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -4508,6 +4508,11 @@ within a templated entity and the innermost enclosing template is not instantiated, or \item +no valid specialization, +ignoring \grammarterm{static_assert-declaration}{s} that fail, +can be generated for a default \grammarterm{template-argument} and +the default \grammarterm{template-argument} is not used in any instantiation, or +\item no specialization of an alias template\iref{temp.alias} is valid and no specialization of the alias template is named in the program, or \item From 5bd604c6d3a3927a62b7841383f7990c25f4c6a5 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Tue, 26 Mar 2024 23:05:41 -0700 Subject: [PATCH 21/47] CWG2748 Accessing static data members via null pointer --- source/expressions.tex | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/source/expressions.tex b/source/expressions.tex index 273ac6e40d..161734be00 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -3556,18 +3556,7 @@ A postfix expression followed by a dot \tcode{.} or an arrow \tcode{->}, optionally followed by the keyword \keyword{template}, and then followed by an -\grammarterm{id-expression}, is a postfix expression. The postfix -expression before the dot or arrow is evaluated; -\begin{footnote} -If the class member -access expression is evaluated, the subexpression evaluation happens even if the -result is unnecessary to determine -the value of the entire postfix expression, for example if the -\grammarterm{id-expression} denotes a static member. -\end{footnote} -the result of that evaluation, together with the -\grammarterm{id-expression}, determines the result of the entire postfix -expression. +\grammarterm{id-expression}, is a postfix expression. \begin{note} If the keyword \keyword{template} is used, the following unqualified name @@ -3589,6 +3578,19 @@ \tcode{(*(E1))} is an lvalue. \end{footnote} +\pnum +The postfix expression before the dot is evaluated; +\begin{footnote} +If the class member +access expression is evaluated, the subexpression evaluation happens even if the +result is unnecessary to determine +the value of the entire postfix expression, for example if the +\grammarterm{id-expression} denotes a static member. +\end{footnote} +the result of that evaluation, +together with the \grammarterm{id-expression}, +determines the result of the entire postfix expression. + \pnum Abbreviating \grammarterm{postfix-expression}\tcode{.}\grammarterm{id-expression} From 14a05c9b07560f79c2e3d8fd455a7db823e0be1f Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Mar 2024 00:03:47 -0700 Subject: [PATCH 22/47] CWG2771 Transformation for unqualified-ids in address operator --- source/basic.tex | 4 +-- source/classes.tex | 60 ------------------------------------------ source/expressions.tex | 44 ++++++++++++++++++++++++------- source/templates.tex | 2 +- 4 files changed, 37 insertions(+), 73 deletions(-) diff --git a/source/basic.tex b/source/basic.tex index 7fe7b59f1b..c3d25a6876 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -465,8 +465,8 @@ \pnum \tcode{*\keyword{this}} is odr-used if \keyword{this} appears as a potentially-evaluated expression -(including as the result of the implicit transformation in the body of a non-static -member function\iref{class.mfct.non.static}). +(including as the result of any implicit transformation to +a class member access expression\iref{expr.prim.id.general}). \pnum A virtual member diff --git a/source/classes.tex b/source/classes.tex index 1cf36a8787..5fa418f705 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -956,66 +956,6 @@ its class or a class derived from its class, or a member thereof, as described below. -\pnum -When an \grammarterm{id-expression}\iref{expr.prim.id} that is -neither part of a class member access syntax\iref{expr.ref} -nor the unparenthesized operand of -the unary \tcode{\&} operator\iref{expr.unary.op} is used -where the current class is \tcode{X}\iref{expr.prim.this}, -if name -lookup\iref{basic.lookup} resolves the name in the -\grammarterm{id-expression} to a non-static non-type member of some class -\tcode{C}, -and if either the \grammarterm{id-expression} is potentially evaluated or -\tcode{C} is \tcode{X} or a base class of \tcode{X}, -the \grammarterm{id-expression} is transformed into a class -member access expression\iref{expr.ref} using -\tcode{(*this)} as the \grammarterm{postfix-expression} -to the left of the \tcode{.} operator. -\begin{note} -If \tcode{C} is not \tcode{X} or a base class of \tcode{X}, the class -member access expression is ill-formed. -\end{note} -This transformation does not apply in the -template definition context\iref{temp.dep.type}. -\begin{example} -\begin{codeblock} -struct tnode { - char tword[20]; - int count; - tnode* left; - tnode* right; - void set(const char*, tnode* l, tnode* r); -}; - -void tnode::set(const char* w, tnode* l, tnode* r) { - count = strlen(w)+1; - if (sizeof(tword)<=count) - perror("tnode string too long"); - strcpy(tword,w); - left = l; - right = r; -} - -void f(tnode n1, tnode n2) { - n1.set("abc",&n2,0); - n2.set("def",0,0); -} -\end{codeblock} - -In the body of the member function \tcode{tnode::set}, the member names -\tcode{tword}, \tcode{count}, \tcode{left}, and \tcode{right} refer to -members of the object for which the function is called. Thus, in the -call \tcode{n1.set("abc",\&n2,0)}, \tcode{tword} refers to -\tcode{n1.tword}, and in the call \tcode{n2.set("def",0,0)}, it refers -to \tcode{n2.tword}. The functions \tcode{strlen}, \tcode{perror}, and -\tcode{strcpy} are not members of the class \tcode{tnode} and should be -declared elsewhere. -\begin{footnote} -See, for example, \libheaderref{cstring}. -\end{footnote} -\end{example} - \pnum \indextext{member function!const}% \indextext{member function!volatile}% diff --git a/source/expressions.tex b/source/expressions.tex index 161734be00..ef273c9767 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -1336,14 +1336,43 @@ operators\iref{expr.ref}. \end{note} +\pnum +If an \grammarterm{id-expression} $E$ denotes +a non-static non-type member of some class \tcode{C} at a point where +the current class\iref{expr.prim.this} is \tcode{X} and +\begin{itemize} +\item +$E$ is potentially evaluated or +\tcode{C} is \tcode{X} or a base class of \tcode{X}, and +\item +$E$ is not the \grammarterm{id-expression} of +a class member access expression\iref{expr.ref}, and +\item +if $E$ is a \grammarterm{qualified-id}, +$E$ is not the un-parenthesized operand of +the unary \tcode{\&} operator\iref{expr.unary.op}, +\end{itemize} +the \grammarterm{id-expression} is transformed into +a class member access expression using \tcode{(*this)} as the object expression. +\begin{note} +If \tcode{C} is not \tcode{X} or a base class of \tcode{X}, +the class member access expression is ill-formed. +Also, if the \grammarterm{id-expression} occurs within +a static or explicit object member function, +the class member access is ill-formed. +\end{note} +This transformation does not apply in +the template definition context\iref{temp.dep.type}. + \pnum If an \grammarterm{id-expression} $E$ denotes a member $M$ of an anonymous union\iref{class.union.anon} $U$: \begin{itemize} \item If $U$ is a non-static data member, -$E$ refers to $M$ as a member of the lookup context of the terminal name of $E$ (after any transformation to -a class member access expression\iref{class.mfct.non.static}). +$E$ refers to $M$ as a member of the lookup context of the terminal name of $E$ +(after any implicit transformation to +a class member access expression). \begin{example} \tcode{o.x} is interpreted as \tcode{o.$u$.x}, where $u$ names the anonymous union member. @@ -1365,13 +1394,11 @@ An \grammarterm{id-expression} that denotes a non-static data member or implicit object member function of a class can only be used: \begin{itemize} -\item as part of a class member access\iref{expr.ref} in which the +\item as part of a class member access +(after any implicit transformation (see above)) +in which the object expression refers to the member's class -\begin{footnote} -This also applies when the object expression -is an implicit \tcode{(*\keyword{this})}\iref{class.mfct.non.static}. -\end{footnote} or a class derived from that class, or @@ -1448,9 +1475,6 @@ A \grammarterm{type-name} or \grammarterm{computed-type-specifier} prefixed by \tcode{\~} denotes the destructor of the type so named; see~\ref{expr.prim.id.dtor}. -Within the definition of a non-static member function, an -\grammarterm{identifier} that names a non-static member is transformed to a -class member access expression\iref{class.mfct.non.static}. \end{note} \pnum diff --git a/source/templates.tex b/source/templates.tex index b7eb73a2ca..84e567d804 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -5067,7 +5067,7 @@ template int C::f(); // error: finds both \tcode{A::m} and \tcode{B::m} template int C::g(); // OK, transformation to class member access syntax - // does not occur in the template definition context; see~\ref{class.mfct.non.static} + // does not occur in the template definition context; see~\ref{expr.prim.id.general} \end{codeblock} \end{example} From c37fc847b953d3df41266537c6ef9b88ebf80a99 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Mar 2024 00:16:25 -0700 Subject: [PATCH 23/47] CWG2775 Unclear argument type for copy of exception object --- source/exceptions.tex | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/source/exceptions.tex b/source/exceptions.tex index 8dc2fcbc05..9cbe49ac7a 100644 --- a/source/exceptions.tex +++ b/source/exceptions.tex @@ -309,12 +309,13 @@ \pnum \indextext{exception handling!exception object!constructor}% \indextext{exception handling!exception object!destructor}% -When the thrown object is a class object, the constructor selected for -the copy-initialization as well as the constructor selected for -a copy-initialization considering the thrown object as an lvalue -shall be non-deleted and accessible, even if the copy/move operation is -elided\iref{class.copy.elision}. -The destructor is potentially invoked\iref{class.dtor}. +Let \tcode{T} denote the type of the exception object. +Copy-initialization of an object of type \tcode{T} from +an lvalue of type \tcode{const T} in a context unrelated to \tcode{T} +shall be well-formed. +If \tcode{T} is a class type, +the selected constructor is odr-used\iref{basic.def.odr} and +the destructor of \tcode{T} is potentially invoked\iref{class.dtor}. \pnum \indextext{exception handling!rethrow}% From 03f6db12b5b3cd02cea2602bd2ff18afbedf7bb0 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Mar 2024 00:20:47 -0700 Subject: [PATCH 24/47] CWG2777 Type of id-expression denoting a template parameter object --- source/expressions.tex | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/expressions.tex b/source/expressions.tex index ef273c9767..bcc98f6824 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -1527,11 +1527,10 @@ is in $E$'s \grammarterm{parameter-declaration-clause}), the type of the expression is the type of the result. \end{itemize} -\begin{note} If the entity is a template parameter object for a template parameter of type \tcode{T}\iref{temp.param}, the type of the expression is \tcode{const T}. -\end{note} +In all other cases, the type of the expression is the type of the entity. \begin{note} The type will be adjusted as described in \ref{expr.type} if it is cv-qualified or is a reference type. From 8fb93183e4f00820a9407ac1d94969087e5020d8 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Mar 2024 01:32:51 -0700 Subject: [PATCH 25/47] CWG2803 Overload resolution for reference binding of similar types [over.ics.ref]p1 Use "can" instead of "may" inside note. --- source/overloading.tex | 67 ++++++++++++++++++++++++++++++++---------- 1 file changed, 51 insertions(+), 16 deletions(-) diff --git a/source/overloading.tex b/source/overloading.tex index 27d1148b3b..63872ba1df 100644 --- a/source/overloading.tex +++ b/source/overloading.tex @@ -2317,11 +2317,32 @@ \rSec4[over.ics.ref]{Reference binding} \pnum -When a parameter of reference type binds directly\iref{dcl.init.ref} to an -argument expression, the implicit conversion sequence is the identity conversion, -unless the argument expression has a type that is a derived class of the parameter -type, in which case the implicit conversion sequence is a derived-to-base +When a parameter of type ``reference to \cv \tcode{T}'' +binds directly\iref{dcl.init.ref} to an argument expression: +\begin{itemize} +\item +If the argument expression has a type that +is a derived class of the parameter type, +the implicit conversion sequence is a derived-to-base conversion\iref{over.best.ics}. + +\item +Otherwise, +if \tcode{T} is a function type, or +if the type of the argument is possibly cv-qualified \tcode{T}, or +if \tcode{T} is an array type of unknown bound with element type \tcode{U} and +the argument has an array type of known bound whose +element type is possibly cv-qualified \tcode{U}, +the implicit conversion sequence is the identity conversion. +\begin{note} +When \tcode{T} is a function type, +the type of the argument can differ only by the presence of \keyword{noexcept}. +\end{note} + +\item +Otherwise, the implicit conversion sequence is a qualification conversion. +\end{itemize} + \begin{example} \begin{codeblock} struct A {}; @@ -2334,9 +2355,8 @@ If the parameter binds directly to the result of applying a conversion function to the argument expression, the implicit conversion sequence is a user-defined conversion sequence\iref{over.ics.user} -whose second standard conversion sequence is either an identity conversion or, -if the conversion function returns an entity of a type that is a derived class -of the parameter type, a derived-to-base conversion. +whose second standard conversion sequence is +determined by the above rules. \pnum When a parameter of reference type is not bound directly to an argument @@ -2767,14 +2787,21 @@ \item \tcode{S1} and \tcode{S2} differ only in their qualification conversion\iref{conv.qual} and -yield similar types \tcode{T1} and \tcode{T2}, respectively, -where \tcode{T1} can be converted to \tcode{T2} by a qualification conversion. +yield similar types \tcode{T1} and \tcode{T2}, respectively +(where a standard conversion sequence that is a reference binding +is considered to yield the cv-unqualified referenced type), +where \tcode{T1} and \tcode{T2} are not the same type, and +\tcode{const T2} is reference-compatible with \tcode{T1}\iref{dcl.init.ref}. \begin{example} \begin{codeblock} int f(const volatile int *); int f(const int *); int i; int j = f(&i); // calls \tcode{f(const int*)} +int g(const int*); +int g(const volatile int* const&); +int* p; +int k = g(p); // calls \tcode{g(const int*)} \end{codeblock} \end{example} or, if not that, @@ -2782,13 +2809,10 @@ \tcode{S1} and \tcode{S2} -include reference bindings\iref{dcl.init.ref}, and the types to which the references -refer are the same type except for top-level cv-qualifiers, and the type to -which the reference initialized by -\tcode{S2} -refers is more cv-qualified than the type to which the reference initialized by -\tcode{S1} -refers. +bind ``reference to \tcode{T1}'' and ``reference to \tcode{T2}'', +respectively\iref{dcl.init.ref}, +where \tcode{T1} and \tcode{T2} are not the same type, and +\tcode{T2} is reference-compatible with \tcode{T1}. \begin{example} \begin{codeblock} int f(const int &); @@ -2808,6 +2832,17 @@ a.f(); // calls \tcode{X::f() const} b.f(); // calls \tcode{X::f()} } + +int h1(int (&)[]); +int h1(int (&)[1]); +int h2(void (&)()); +int h2(void (&)() noexcept); +void g2() { + int a[1]; + h1(a); // calls \tcode{h1(int (\&)[1])} + extern void f2() noexcept; + h2(f2); // calls \tcode{h2(void (\&)() noexcept)} +} \end{codeblock} \end{example} \end{itemize} From 440cef313dfbc591527a4c461add7b442b49f2ef Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Mar 2024 02:03:35 -0700 Subject: [PATCH 26/47] CWG2809 An implicit definition does not redeclare a function --- source/declarations.tex | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/source/declarations.tex b/source/declarations.tex index ff33b3c1ee..a12e3773ab 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -6512,15 +6512,18 @@ (i.e., explicitly defaulted after its first declaration) is implicitly defined at the point where it is explicitly defaulted; if such a function is implicitly defined as deleted, the program is ill-formed. +\begin{note} +Declaring a function as defaulted after its first declaration +can provide efficient execution and concise definition +while enabling a stable binary interface to an evolving code base. +\end{note} A non-user-provided defaulted function (i.e., implicitly declared or explicitly defaulted in the class) that is not defined as deleted is implicitly defined when it is odr-used\iref{basic.def.odr} or needed for constant evaluation\iref{expr.const}. \begin{note} -Declaring a function as defaulted after its first declaration can provide -efficient execution and concise -definition while enabling a stable binary interface to an evolving code -base. +The implicit definition of a non-user-provided defaulted function +does not bind any names. \end{note} \pnum From 76fcfea4a82b89c27252863e1363c03d5560c87e Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Mar 2024 02:07:53 -0700 Subject: [PATCH 27/47] CWG2810 Requiring the absence of diagnostics for templates --- source/templates.tex | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/templates.tex b/source/templates.tex index 84e567d804..ecfd727176 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -4570,8 +4570,6 @@ \end{itemize} \end{note} -Otherwise, no diagnostic shall be issued for a template -for which a valid specialization can be generated. \begin{note} If a template is instantiated, errors will be diagnosed according to the other rules in this document. From 36961e85d6be38e381f46a0dbe68a332b302f74f Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Mar 2024 02:11:03 -0700 Subject: [PATCH 28/47] CWG2811 Clarify "use" of main --- source/basic.tex | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/basic.tex b/source/basic.tex index c3d25a6876..86e05182da 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -6727,8 +6727,7 @@ Any further (optional) parameters should be added after \tcode{argv}. \pnum -The function \tcode{main} shall not be used within -a program. +The function \tcode{main} shall not be named by an expression. \indextext{\idxcode{main} function!implementation-defined linkage of}% The linkage\iref{basic.link} of \tcode{main} is \impldef{linkage of \tcode{main}}. A program that defines \tcode{main} as From 03408d1b6e55230ba000ae134182e9c2105a0cf8 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Mar 2024 02:29:52 -0700 Subject: [PATCH 29/47] CWG2813 Class member access with prvalues --- source/basic.tex | 4 +++- source/expressions.tex | 12 +++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/source/basic.tex b/source/basic.tex index 86e05182da..b4fdb40db3 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -4341,7 +4341,9 @@ when binding a reference to a prvalue\iref{dcl.init.ref,expr.type.conv, expr.dynamic.cast,expr.static.cast,expr.const.cast,expr.cast}, \item -when performing member access on a class prvalue\iref{expr.ref,expr.mptr.oper}, +when performing certain member accesses on a class prvalue\iref{expr.ref,expr.mptr.oper}, +\item +when invoking an implicit object member function on a class prvalue\iref{expr.call}, \item when performing an array-to-pointer conversion or subscripting on an array prvalue\iref{conv.array,expr.sub}, \item diff --git a/source/expressions.tex b/source/expressions.tex index bcc98f6824..a26ec22f87 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -3339,7 +3339,9 @@ \end{codeblock} \end{example} If the function is an implicit object member -function, the \keyword{this} parameter of the function\iref{expr.prim.this} +function, +the object expression of the class member access shall be a glvalue and +the \keyword{this} parameter of the function\iref{expr.prim.this} is initialized with a pointer to the object of the call, converted as if by an explicit type conversion\iref{expr.cast}. \begin{note} @@ -3590,8 +3592,12 @@ \pnum \indextext{type!incomplete}% -For the first option (dot) the first expression shall be a glvalue. -For the second option (arrow) the first expression +For the first option (dot), +if the \grammarterm{id-expression} names a static member or an enumerator, +the first expression is a discarded-value expression\iref{expr.context}; +if the \grammarterm{id-expression} names a non-static data member, +the first expression shall be a glvalue. +For the second option (arrow), the first expression shall be a prvalue having pointer type. The expression \tcode{E1->E2} is converted to the equivalent form \tcode{(*(E1)).E2}; the remainder of From c6000ad2af608e5755f72f88dcc52849d6a352f9 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Mar 2024 02:33:39 -0700 Subject: [PATCH 30/47] CWG2820 Value-initialization and default constructors --- source/declarations.tex | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/source/declarations.tex b/source/declarations.tex index a12e3773ab..e343fcffd0 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -4607,9 +4607,7 @@ constructor that is user-provided or deleted, then the object is default-initialized; \item otherwise, -the object is zero-initialized and the semantic constraints for -default-initialization are checked, and if \tcode{T} has a -non-trivial default constructor, the object is default-initialized. +the object is zero-initialized and then default-initialized. \end{itemize} \item From f6228d32c5c94361150f66b08ccc049a76dcf11f Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Mar 2024 03:12:11 -0700 Subject: [PATCH 31/47] CWG2822 Side-effect-free pointer zap --- source/basic.tex | 50 ++++++++++++++++++++++++------------------ source/expressions.tex | 4 ++-- 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/source/basic.tex b/source/basic.tex index b4fdb40db3..1ac8b83d6a 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -3830,6 +3830,10 @@ \item automatic storage duration \item dynamic storage duration \end{itemize} +\begin{note} +After the duration of a region of storage has ended, +the use of pointers to that region of storage is limited\iref{basic.compound}. +\end{note} \pnum \indextext{storage duration!static}% @@ -3847,23 +3851,6 @@ \pnum The storage duration categories apply to references as well. -\pnum -When the end of the duration of a region of storage is reached, -the values of all pointers -representing the address of any part of that region of storage -become invalid pointer values\iref{basic.compound}. -Indirection through an invalid pointer value and -passing an invalid pointer value to a deallocation function -have undefined behavior. -Any other use of an invalid pointer value has -\impldef{any use of an invalid pointer other than to perform indirection or deallocate} -behavior. -\begin{footnote} -Some implementations might define that -copying an invalid pointer value -causes a system-generated runtime fault. -\end{footnote} - \rSec3[basic.stc.static]{Static storage duration} \pnum @@ -5442,10 +5429,6 @@ is not considered to point to an unrelated object of the object's type, even if the unrelated object is located at that address. -A pointer value becomes invalid -when the storage it denotes -reaches the end of its storage duration; -see \ref{basic.stc}. \end{note} For purposes of pointer arithmetic\iref{expr.add} and comparison\iref{expr.rel,expr.eq}, @@ -5466,6 +5449,31 @@ alignment requirement. \end{note} +\pnum +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 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 +$P$ is not valid in the context of $E$, +then the behavior is undefined if $E$ is +an indirection\iref{expr.unary.op} or +an invocation of a deallocation function\iref{basic.stc.dynamic.deallocation}, +and \impldef{invalid pointer value in the context of an evaluation} otherwise. +\begin{footnote} +Some implementations might define that +copying such a pointer value causes a system-generated runtime fault. +\end{footnote} +\begin{note} +$P$ can be valid in the context of $E$ even +if it points to a type unrelated to that of $O$ or +if $O$ is not within its lifetime, +although further restrictions apply +to such pointer values\iref{basic.life, basic.lval, expr.add}. +\end{note} + \pnum Two objects \placeholder{a} and \placeholder{b} are \defn{pointer-interconvertible} if: \begin{itemize} diff --git a/source/expressions.tex b/source/expressions.tex index a26ec22f87..b7e235523d 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -4265,7 +4265,7 @@ If the original pointer value represents the address \tcode{A} of a byte in memory and \tcode{A} does not satisfy the alignment requirement of \tcode{T}, -then the resulting pointer value is unspecified. +then the resulting pointer value\iref{basic.compound} is unspecified. Otherwise, if the original pointer value points to an object \placeholder{a}, and there is an object \placeholder{b} of type similar to \tcode{T} that is pointer-interconvertible\iref{basic.compound} with \placeholder{a}, @@ -4335,7 +4335,7 @@ A value of integral type or enumeration type can be explicitly converted to a pointer. A pointer converted to an integer of sufficient size (if any such exists on the implementation) and back to the same pointer type -will have its original value; +will have its original value\iref{basic.compound}; \indextext{conversion!implementation-defined pointer integer}% mappings between pointers and integers are otherwise \impldef{conversions between pointers and integers}. From 6a3636449e29168e82f032ab0a45359ac3d54c0b Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Mar 2024 03:18:52 -0700 Subject: [PATCH 32/47] CWG2824 Copy-initialization of arrays --- source/declarations.tex | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/declarations.tex b/source/declarations.tex index e343fcffd0..ab1843498a 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -4722,6 +4722,8 @@ \item Otherwise, if the destination type is an array, the object is initialized as follows. +The \grammarterm{initializer} shall be of the form +\tcode{(} \grammarterm{expression-list} \tcode{)}. Let $x_1$, $\dotsc$, $x_k$ be the elements of the \grammarterm{expression-list}. If the destination type is an array of unknown bound, From 3bf7dac1febb32748564292f35e1aa91c1e2b22e Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Mar 2024 03:24:03 -0700 Subject: [PATCH 33/47] CWG2825 Range-based for statement using a braced-init-list --- source/statements.tex | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/statements.tex b/source/statements.tex index 4ebc6e7309..b9c08bf17d 100644 --- a/source/statements.tex +++ b/source/statements.tex @@ -677,15 +677,15 @@ \exposid{begin-expr} and \exposid{end-expr} are determined as follows: \begin{itemize} -\item if the \grammarterm{for-range-initializer} is an expression of +\item if the type of \exposid{range} is a reference to an array type \tcode{R}, \exposid{begin-expr} and \exposid{end-expr} are \exposid{range} and \exposid{range} \tcode{+} \tcode{N}, respectively, where \tcode{N} is the array bound. If \tcode{R} is an array of unknown bound or an array of incomplete type, the program is ill-formed; -\item if the \grammarterm{for-range-initializer} is -an expression of class type \tcode{C}, and +\item if the type of \exposid{range} is a reference to a +class type \tcode{C}, and searches in the scope of \tcode{C}\iref{class.member.lookup} for the names \tcode{begin} and \tcode{end} each find at least one declaration, From 0e026f5f3f1ce59be33f482dc1127225591d2aef Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Mar 2024 03:33:20 -0700 Subject: [PATCH 34/47] CWG2828 Ambiguous interpretation of C-style cast --- source/expressions.tex | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/source/expressions.tex b/source/expressions.tex index b7e235523d..766a021724 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -6102,8 +6102,9 @@ If a conversion can be interpreted in more than one of the ways listed above, the interpretation that appears first in the list is used, even if a cast resulting from that interpretation is ill-formed. If a -conversion can be interpreted in more than one way as a -\keyword{static_cast} followed by a \keyword{const_cast}, the conversion is +\keyword{static_cast} followed by a \keyword{const_cast} is used and +the conversion can be interpreted in more than one way as such, +the conversion is ill-formed. \begin{example} \begin{codeblock} @@ -6114,6 +6115,15 @@ A* foo( D* p ) { return (A*)( p ); // ill-formed \keyword{static_cast} interpretation } + +int*** ptr = 0; +auto t = (int const*const*const*)ptr; // OK, \keyword{const_cast} interpretation + +struct S { + operator const int*(); + operator volatile int*(); +}; +int *p = (int*)S(); // error: two possible interpretations using \keyword{static_cast} followed by \keyword{const_cast} \end{codeblock} \end{example} From b37a8ce05e45b5f7cb6dd38643be92a11b190df0 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Mar 2024 03:36:32 -0700 Subject: [PATCH 35/47] CWG2830 Top-level cv-qualification should be ignored for list-initialization --- source/declarations.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/declarations.tex b/source/declarations.tex index ab1843498a..5678a936da 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -5882,7 +5882,7 @@ the program is ill-formed. \pnum -List-initialization of an object or reference of type \tcode{T} is defined as follows: +List-initialization of an object or reference of type \cvqual{cv} \tcode{T} is defined as follows: \begin{itemize} \item If the \grammarterm{braced-init-list} @@ -5905,7 +5905,7 @@ \end{example} \item If \tcode{T} is an aggregate class and the initializer list has a single element -of type \cvqual{cv} \tcode{U}, +of type \cvqual{cv1} \tcode{U}, where \tcode{U} is \tcode{T} or a class derived from \tcode{T}, the object is initialized from that element (by copy-initialization for copy-list-initialization, or by direct-initialization for From 5b089c38adc92d264c14faa5609b0ca1e55999d9 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Mar 2024 03:40:33 -0700 Subject: [PATCH 36/47] CWG2831 Non-templated function definitions and requires-clauses --- source/declarations.tex | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/source/declarations.tex b/source/declarations.tex index 5678a936da..1060d2259a 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -6305,8 +6305,10 @@ a \grammarterm{mem-initializer-id}\iref{class.base.init}. The optional \grammarterm{attribute-specifier-seq} in a \grammarterm{function-definition} appertains to the function. -A \grammarterm{virt-specifier-seq} can be part of a \grammarterm{function-definition} -only if it is a \grammarterm{member-declaration}\iref{class.mem}. +A \grammarterm{function-definition} with a \grammarterm{virt-specifier-seq} +shall be a \grammarterm{member-declaration}\iref{class.mem}. +A \grammarterm{function-definition} with a \grammarterm{requires-clause} +shall define a templated function. \pnum In a \grammarterm{function-definition}, From 01499093f6550b4c4b5476206ec95b874b0d877a Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Mar 2024 03:45:55 -0700 Subject: [PATCH 37/47] CWG2845 Make the closure type of a captureless lambda a structural type --- source/expressions.tex | 5 +++-- source/templates.tex | 3 +++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/source/expressions.tex b/source/expressions.tex index 766a021724..d768b9d656 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -1923,8 +1923,9 @@ \end{note} \pnum -The closure type is not an aggregate type\iref{dcl.init.aggr} and -not a structural type\iref{term.structural.type}. +The closure type is not an aggregate type\iref{dcl.init.aggr}; +it is a structural type\iref{term.structural.type} if and only if +the lambda has no \grammarterm{lambda-capture}. An implementation may define the closure type differently from what is described below provided this does not alter the observable behavior of the program other than by changing: diff --git a/source/templates.tex b/source/templates.tex index ecfd727176..f1bccd275e 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -2109,6 +2109,9 @@ they both have no active member or they have the same active member and their active members are template-argument-equivalent, or +\item +they are of a closure type\iref{expr.prim.lambda.closure}, or + \item they are of class type and their corresponding direct subobjects and reference members are template-argument-equivalent. From a41b34e85134e7890631cc58c62121545bd3b699 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Mar 2024 03:52:57 -0700 Subject: [PATCH 38/47] CWG2846 Out-of-class definitions of explicit object member functions --- source/declarations.tex | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/source/declarations.tex b/source/declarations.tex index 1060d2259a..a806f0d417 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -3685,11 +3685,15 @@ a \grammarterm{parameter-declaration} with a \keyword{this} specifier. An explicit-object-parameter-declaration shall appear only as the first \grammarterm{parameter-declaration} of -a \grammarterm{parameter-declaration-list} of either: +a \grammarterm{parameter-declaration-list} of one of: \begin{itemize} \item -a \grammarterm{member-declarator} -that declares a member function\iref{class.mem}, or +a declaration of +a member function or member function template\iref{class.mem}, or +\item +an explicit instantiation\iref{temp.explicit} or +explicit specialization\iref{temp.expl.spec} of +a templated member function, or \item a \grammarterm{lambda-declarator}\iref{expr.prim.lambda}. \end{itemize} From 69c86fa57bef526e7f7110337fb3889ac2041b33 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Mar 2024 04:12:30 -0700 Subject: [PATCH 39/47] CWG2848 Omitting an empty template argument list for explicit instantiation --- source/templates.tex | 53 ++++++++------------------------------------ 1 file changed, 9 insertions(+), 44 deletions(-) diff --git a/source/templates.tex b/source/templates.tex index f1bccd275e..9549d9d1de 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -6292,7 +6292,7 @@ template void Array::mf(); template void sort(Array& v) { @\commentellip@ } -template void sort(Array&); // argument is deduced here +template void sort(Array&); // argument is deduced here\iref{temp.arg.explicit} namespace N { template void f(T&) { } @@ -6353,24 +6353,6 @@ data member of a class template shall be present in every translation unit in which it is explicitly instantiated. -\pnum -A trailing -\grammarterm{template-argument} -can be left unspecified in an explicit instantiation of a function template -specialization or of a member function template specialization provided -it can be deduced\iref{temp.deduct.decl}. -If all template arguments can be deduced, -the empty template argument list \tcode{<>} may be omitted. -\begin{example} -\begin{codeblock} -template class Array { @\commentellip@ }; -template void sort(Array& v) { @\commentellip@ } - -// instantiate \tcode{sort(Array\&)} -- template-argument deduced -template void sort<>(Array&); -\end{codeblock} -\end{example} - \pnum \begin{note} An explicit instantiation of a constrained template needs @@ -6480,28 +6462,29 @@ \begin{codeblock} template class stream; -template<> class stream { @\commentellip@ }; +template<> class stream { @\commentellip@ }; // \#1 template class Array { @\commentellip@ }; template void sort(Array& v) { @\commentellip@ } -template<> void sort(Array&); +template<> void sort(Array&); // \#2 +template<> void sort(Array&); // \#3 template argument is deduced\iref{temp.arg.explicit} \end{codeblock} Given these declarations, -\tcode{stream} -will be used as the definition of streams of +\#1 will be used as the definition of streams of \tcode{char}s; other streams will be handled by class template specializations instantiated from the class template. Similarly, -\tcode{sort} -will be used as the sort function for arguments +\#2 will be used as the sort function for arguments of +type \tcode{Array} and +\#3 will be used for arguments of type \tcode{Array}; other \tcode{Array} -types will be sorted by functions generated from the template. +types will be sorted by functions generated from the function template. \end{example} \pnum @@ -6693,24 +6676,6 @@ \end{codeblock} \end{example} -\pnum -A trailing -\grammarterm{template-argument} -can be left unspecified in the -\grammarterm{template-id} -naming an explicit function template specialization -provided it can be deduced\iref{temp.deduct.decl}. -\begin{example} -\begin{codeblock} -template class Array { @\commentellip@ }; -template void sort(Array& v); - -// explicit specialization for \tcode{sort(Array\&)} -// with deduced template-argument of type \tcode{int} -template<> void sort(Array&); -\end{codeblock} -\end{example} - \pnum \begin{note} An explicit specialization of a constrained template needs From aef74c9f5da6cb26a31c8cbfeb8422827a90a974 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Mar 2024 04:24:35 -0700 Subject: [PATCH 40/47] CWG2849 Parameter objects are not temporary objects --- source/basic.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/basic.tex b/source/basic.tex index 1ac8b83d6a..4be242588a 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -4553,7 +4553,7 @@ \end{itemize} \pnum -The fourth context is when a temporary object other than a function parameter object +The fourth context is when a temporary object is created in the \grammarterm{for-range-initializer} of a range-based \keyword{for} statement. If such a temporary object would otherwise be destroyed at the end of the \grammarterm{for-range-initializer} full-expression, From f8b0b5fa947a87ba2171ed0302fc96dfdf15ead9 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Mar 2024 05:00:37 -0700 Subject: [PATCH 41/47] CWG2850 Unclear storage duration for function parameter objects --- source/basic.tex | 20 ++++++++++++-------- source/expressions.tex | 10 ++++++---- source/statements.tex | 6 +++--- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/source/basic.tex b/source/basic.tex index 4be242588a..0827f48bb4 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -3907,15 +3907,16 @@ \pnum \indextext{storage duration!local object}% -Variables that belong to a block or parameter scope and are +Variables that belong to a block scope and are not explicitly declared \keyword{static}, \keyword{thread_local}, or \keyword{extern} have \defnadj{automatic}{storage duration}. The storage -for these entities lasts until the block in which they are created exits. - -\pnum +for such variables lasts until the block in which they are created exits. \begin{note} These variables are initialized and destroyed as described in~\ref{stmt.dcl}. \end{note} +Variables that belong to a parameter scope also have automatic storage duration. +The storage for a function parameter lasts until +immediately after its destruction\iref{expr.call}. \pnum If a variable with automatic storage duration has initialization or a destructor with side @@ -4561,10 +4562,13 @@ initialized by the \grammarterm{for-range-initializer}. \pnum -The destruction of a temporary whose lifetime is not extended -beyond the full-expression in which it was created -is sequenced before the destruction of every -temporary which is constructed earlier in the same full-expression. +Let \tcode{x} and \tcode{y} each be either +a temporary object whose lifetime is not extended, or +a function parameter. +If the lifetimes of \tcode{x} and \tcode{y} end at +the end of the same full-expression, and +\tcode{x} is initialized before \tcode{y}, then +the destruction of \tcode{y} is sequenced before that of \tcode{x}. If the lifetime of two or more temporaries with lifetimes extending beyond the full-expressions in which they were created ends at the same point, diff --git a/source/expressions.tex b/source/expressions.tex index d768b9d656..5dd0e8a498 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -3359,10 +3359,12 @@ a type. However, it prevents a passed-by-value parameter to have an incomplete or abstract class type. \end{note} -It is \impldef{whether the lifetime of a parameter ends when the callee -returns or at the end of the enclosing full-expression} whether the -lifetime of a parameter ends when the function in which it is defined -returns or at the end of the enclosing full-expression. +It is \impldef{whether a parameter is destroyed when the function +exits or at the end of the enclosing full-expression} +whether a parameter is destroyed +when the function in which it is defined exits\iref{stmt.return, except.ctor} +or at the end of the enclosing full-expression; +parameters are always destroyed in the reverse order of their construction. The initialization and destruction of each parameter occurs within the context of the full-expression\iref{intro.execution} where the function call appears. diff --git a/source/statements.tex b/source/statements.tex index b9c08bf17d..f2cfe2cd27 100644 --- a/source/statements.tex +++ b/source/statements.tex @@ -991,16 +991,16 @@ \indextext{block (statement)!initialization in}% \indextext{initialization!automatic}% \indextext{active|see{variable, active}}% -A variable with automatic storage duration\iref{basic.stc.auto} +A block variable with automatic storage duration\iref{basic.stc.auto} is \defnx{active}{variable!active} everywhere in the scope to which it belongs after its \grammarterm{init-declarator}. \indextext{initialization!jump past}% \indextext{\idxcode{goto}!initialization and}% Upon each transfer of control (including sequential execution of statements) within a function from point $P$ to point $Q$, -all variables with automatic storage duration +all block variables with automatic storage duration that are active at $P$ and not at $Q$ are destroyed in the reverse order of their construction. -Then, all variables with automatic storage duration +Then, all block variables with automatic storage duration that are active at $Q$ but not at $P$ are initialized in declaration order; unless all such variables have vacuous initialization\iref{basic.life}, the transfer of control shall not be a jump. From 8811f8a3459eb260285a82d25479413887f66421 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Mar 2024 05:04:22 -0700 Subject: [PATCH 42/47] CWG2851 Allow floating-point conversions in converted constant expressions --- source/expressions.tex | 3 +++ 1 file changed, 3 insertions(+) diff --git a/source/expressions.tex b/source/expressions.tex index 5dd0e8a498..2930a63ae7 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -7921,6 +7921,9 @@ \item qualification conversions\iref{conv.qual}, \item integral promotions\iref{conv.prom}, \item integral conversions\iref{conv.integral} other than narrowing conversions\iref{dcl.init.list}, +\item floating-point promotions\iref{conv.fpprom}, +\item floating-point conversions\iref{conv.double} where + the source value can be represented exactly in the destination type, \item null pointer conversions\iref{conv.ptr} from \tcode{std::nullptr_t}, \item null member pointer conversions\iref{conv.mem} from \tcode{std::nullptr_t}, and \item function pointer conversions\iref{conv.fctptr}, From e611b7524410c94d57c9d100e07e2bb83ce0edd3 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Mar 2024 05:06:52 -0700 Subject: [PATCH 43/47] CWG2853 Pointer arithmetic with pointer to hypothetical element --- source/expressions.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/expressions.tex b/source/expressions.tex index 2930a63ae7..4955b8646b 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -6357,7 +6357,7 @@ \begin{itemize} \item If \tcode{P} evaluates to a null pointer value and \tcode{J} evaluates to 0, the result is a null pointer value. -\item Otherwise, if \tcode{P} points to an array element $i$ +\item Otherwise, if \tcode{P} points to a (possibly-hypothetical) array element $i$ of an array object \tcode{x} with $n$ elements\iref{dcl.array}, \begin{footnote} As specified in \ref{basic.compound}, From 10bddc91065787a89b1f587e36ece56276da0283 Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Mar 2024 05:11:46 -0700 Subject: [PATCH 44/47] CWG2854 Storage duration of exception objects --- source/basic.tex | 10 ++-------- source/exceptions.tex | 2 +- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/source/basic.tex b/source/basic.tex index 0827f48bb4..4f1b661d15 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -4296,15 +4296,9 @@ Temporary objects are created \begin{itemize} \item -when a prvalue is converted to an xvalue\iref{conv.rval}, +when a prvalue is converted to an xvalue\iref{conv.rval} and \item -when needed by the implementation to pass or return an object of trivially copyable type (see below), -and -\item -when throwing an exception\iref{except.throw}. -\begin{note} -The lifetime of exception objects is described in~\ref{except.throw}. -\end{note} +when needed by the implementation to pass or return an object of trivially copyable type (see below). \end{itemize} Even when the creation of the temporary object is unevaluated\iref{expr.context}, diff --git a/source/exceptions.tex b/source/exceptions.tex index 9cbe49ac7a..22fc97a325 100644 --- a/source/exceptions.tex +++ b/source/exceptions.tex @@ -257,7 +257,7 @@ \pnum Throwing an exception -initializes a temporary object, +initializes an object with dynamic storage duration, called the \defnx{exception object}{exception handling!exception object}. If the type of the exception object would be From c95348afd7586d2799e52026208cd6f55584d9cf Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Mar 2024 05:35:14 -0700 Subject: [PATCH 45/47] CWG2855 Undefined behavior in postfix increment --- source/expressions.tex | 33 ++++++--------------------------- 1 file changed, 6 insertions(+), 27 deletions(-) diff --git a/source/expressions.tex b/source/expressions.tex index 4955b8646b..005a64cb10 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -3764,7 +3764,7 @@ An operand with volatile-qualified type is deprecated; see~\ref{depr.volatile.type}. The value of the operand object is modified\iref{defns.access} -by adding \tcode{1} to it. +as if it were the operand of the prefix \tcode{++} operator\iref{expr.pre.incr}. The \indextext{value computation}% value computation of the \tcode{++} expression is sequenced before the @@ -3779,11 +3779,6 @@ \end{note} The result is a prvalue. The type of the result is the cv-unqualified version of the type of the operand. -If the operand is a bit-field that cannot represent the incremented value, the -resulting value of the bit-field is -\impldefplain{value of bit-field that cannot represent!incremented value}. -See also~\ref{expr.add} -and~\ref{expr.ass}. \pnum \indextext{expression!decrement}% @@ -4785,32 +4780,16 @@ \pnum \indextext{expression!increment}% \indextext{expression!decrement}% -The operand of prefix \tcode{++} \indextext{operator!increment}% +\indextext{operator!decrement}% \indextext{prefix \tcode{++}}% -is modified\iref{defns.access} by adding \tcode{1}. \indextext{prefix \tcode{--}}% -The operand shall be a modifiable lvalue. The type of the operand shall -be an arithmetic type other than \cv{}~\tcode{bool}, -or a pointer to a completely-defined object type. +The operand of prefix \tcode{++} or \tcode{--} +shall not be of type \cv{}~\tcode{bool}. An operand with volatile-qualified type is deprecated; see~\ref{depr.volatile.type}. -The result is the updated operand; it is an lvalue, and it is a -bit-field if the operand is a bit-field. -The expression \tcode{++x} is equivalent to \tcode{x+=1}. -\indextext{operator!\idxcode{+=}}% -\begin{note} -See the discussions of addition\iref{expr.add} and assignment -operators\iref{expr.ass} for information on conversions. -\end{note} - -\pnum -The operand of prefix -\indextext{operator!decrement}% -\tcode{--} is modified\iref{defns.access} by subtracting \tcode{1}. -The requirements on the operand of prefix -\tcode{--} and the properties of its result are otherwise the same as -those of prefix \tcode{++}. +The expression \tcode{++x} is otherwise equivalent to \tcode{x+=1} and +the expression \tcode{--x} is otherwise equivalent to \tcode{x-=1}\iref{expr.ass}. \begin{note} For postfix increment and decrement, see~\ref{expr.post.incr}. \end{note} From 6b3f68b392172791813b1e77671d2fe9d9693e5a Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Mar 2024 05:41:43 -0700 Subject: [PATCH 46/47] CWG2856 Copy-list-initialization with explicit default constructors --- source/overloading.tex | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/source/overloading.tex b/source/overloading.tex index 63872ba1df..37d907e9bc 100644 --- a/source/overloading.tex +++ b/source/overloading.tex @@ -1001,17 +1001,18 @@ or default-initialized\iref{dcl.init}, overload resolution selects the constructor. For direct-initialization or default-initialization -that is not in the context of copy-initialization, the -candidate functions are +(including default-initialization in the context of copy-list-initialization), +the candidate functions are all the constructors of the class of the object being initialized. -For copy-initialization (including default initialization -in the context of copy-initialization), the candidate functions are all +Otherwise, the candidate functions are all the converting constructors\iref{class.conv.ctor} of that class. The argument list is the \grammarterm{expression-list} or \grammarterm{assignment-expression} of the \grammarterm{initializer}. +For default-initialization in the context of copy-list-initialization, +if an explicit constructor is chosen, the initialization is ill-formed. \rSec3[over.match.copy]{Copy-initialization of class by user-defined conversion}% \indextext{overloading!resolution!initialization} From d0bd27d74ce0eec9491b3864fb15fead3906e73c Mon Sep 17 00:00:00 2001 From: Dawn Perchik Date: Wed, 27 Mar 2024 05:44:26 -0700 Subject: [PATCH 47/47] CWG2857 Argument-dependent lookup with incomplete class types --- source/basic.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/basic.tex b/source/basic.tex index 4f1b661d15..6d24c315b9 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -2055,7 +2055,7 @@ its associated entities are: the class itself; the class of which it is a member, if any; -and its direct and indirect base classes. +and, if it is a complete type, its direct and indirect base classes. Furthermore, if \tcode{T} is a class template specialization, its associated entities also include: the entities