diff --git a/source/basic.tex b/source/basic.tex index c1708584a4..fc925bfc62 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -511,7 +511,8 @@ either: \begin{itemize} \item the intervening scope is a block scope, or -\item the intervening scope is the function parameter scope of a \grammarterm{lambda-expression}, or +\item the intervening scope is the function parameter scope of +a \grammarterm{lambda-expression} or \grammarterm{requires-expression}, or \item the intervening scope is the lambda scope of a \grammarterm{lambda-expression} that has a \grammarterm{simple-capture} @@ -3115,7 +3116,9 @@ \end{note} \pnum -A \defn{memory location} is either an object of scalar type that is not a bit-field +A \defn{memory location} is +the storage occupied by the object representation of +either an object of scalar type that is not a bit-field or a maximal sequence of adjacent bit-fields all having nonzero width. \begin{note} Various @@ -5515,7 +5518,7 @@ A pointer value $P$ is \indextext{value!valid in the context of an evaluation}% \defn{valid in the context of} an evaluation $E$ -if $P$ is a null pointer value, or +if $P$ is a pointer to function or a null pointer value, or if it is a pointer to or past the end of an object $O$ and $E$ happens before the end of the duration of the region of storage for $O$. If a pointer value $P$ is used in an evaluation $E$ and @@ -6037,13 +6040,30 @@ \end{note} The value computations of the operands of an operator are sequenced before the value computation of the result of the -operator. If a +operator. +The behavior is undefined if +\begin{itemize} +\item \indextext{side effects}% -side effect on a memory location\iref{intro.memory} is unsequenced -relative to either another side effect on the same memory location or +a side effect on a memory location\iref{intro.memory} or +\item +starting or ending the lifetime of an object in a memory location +\end{itemize} +is unsequenced relative to +\begin{itemize} +\item +another side effect on the same memory location, +\item +starting or ending the lifetime of an object occupying storage that +overlaps with the memory location, or +\item a value computation using the value of any object in the same memory location, -and they are not potentially concurrent\iref{intro.multithread}, -the behavior is undefined. +\end{itemize} +and the two evaluations are not potentially concurrent\iref{intro.multithread}. +\begin{note} +Starting the lifetime of an object in a memory location can end the lifetime of +objects in other memory locations\iref{basic.life}. +\end{note} \begin{note} The next subclause imposes similar, but more complex restrictions on potentially concurrent computations. @@ -6057,6 +6077,9 @@ i = i++ + 1; // the value of \tcode{i} is incremented i = i++ + i; // undefined behavior i = i + 1; // the value of \tcode{i} is incremented + + union U { int x, y; } u; + (u.x = 1, 0) + (u.y = 2, 0); // undefined behavior } \end{codeblock} \end{example} @@ -6067,8 +6090,13 @@ the postfix expression designating the called function are sequenced before every expression or statement in the body of the called function. -For each function invocation or -evaluation of an \grammarterm{await-expression} \placeholder{F}, +For each +\begin{itemize} +\item function invocation, +\item evaluation of an \grammarterm{await-expression}\iref{expr.await}, or +\item evaluation of a \grammarterm{throw-expression}\iref{expr.throw} +\end{itemize} +\placeholder{F}, each evaluation that does not occur within \placeholder{F} but is evaluated on the same thread and as part of the same signal handler (if any) is either sequenced before all evaluations that occur within \placeholder{F} @@ -6167,9 +6195,21 @@ \end{note} \pnum -Two expression evaluations \defn{conflict} if one of them modifies\iref{defns.access} a memory -location\iref{intro.memory} and the other one reads or modifies the same -memory location. +Two expression evaluations \defn{conflict} if one of them +\begin{itemize} +\item +modifies\iref{defns.access} a memory location\iref{intro.memory} or +\item +starts or ends the lifetime of an object in a memory location +\end{itemize} +and the other one +\begin{itemize} +\item +reads or modifies the same memory location or +\item +starts or ends the lifetime of an object occupying storage that +overlaps with the memory location. +\end{itemize} \begin{note} A modification can still conflict even if it does not alter the value of any bits. diff --git a/source/classes.tex b/source/classes.tex index a209ff34c8..189eff2b6e 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -3331,13 +3331,13 @@ \pnum \indextext{nested class!local class}% -If class \tcode{X} is a local class, a nested class \tcode{Y} may be -declared in class \tcode{X} and later defined in the definition of class -\tcode{X} or be later defined in the same scope as the definition of -class \tcode{X}. \indextext{restriction!local class}% A class nested within a local class is a local class. +A member of a local class \tcode{X} shall be +declared only in the definition of \tcode{X} or, +if the member is a nested class, +in the nearest enclosing block scope of \tcode{X}. \pnum \indextext{restriction!static member local class}% @@ -6178,25 +6178,26 @@ \indextext{constructor!copy!elision}% \indextext{constructor!move!elision}% When certain criteria are met, an implementation is -allowed to omit the copy/move construction of a class object, -even if the constructor selected for the copy/move operation and/or the +allowed to omit the creation of a class object from +a source object of the same type (ignoring cv-qualification), +even if the selected constructor and/or the destructor for the object have \indextext{side effects}% side effects. In such cases, the implementation treats the source and target of the -omitted copy/move operation as simply two different ways of +omitted initialization as simply two different ways of referring to the same object. If the first parameter of the selected constructor is an rvalue reference to the object's type, the destruction of that object occurs when the target would have been destroyed; otherwise, the destruction occurs at the later of the times when the two objects would have been destroyed without the optimization. -\begin{footnote} +\begin{note} Because only one object is destroyed instead of two, -and one copy/move constructor -is not executed, there is still one object destroyed for each one constructed. -\end{footnote} -This elision of copy/move operations, called +and the creation of one object is omitted, +there is still one object destroyed for each one constructed. +\end{note} +This elision of object creation, called \indexdefn{copy elision|see{constructor, copy, elision}}% \indexdefn{elision!copy|see{constructor, copy, elision}}% \indexdefn{constructor!copy!elision}\indexdefn{constructor!move!elision}\term{copy elision}, @@ -6204,34 +6205,35 @@ following circumstances (which may be combined to eliminate multiple copies): \begin{itemize} -\item in a \tcode{return} statement in a function with a class return type, +\item in a \tcode{return} statement\iref{stmt.return} in +a function with a class return type, when the \grammarterm{expression} is the name of a non-volatile -object with automatic storage duration (other than a function parameter or a variable +object $o$ with automatic storage duration (other than a function parameter or a variable introduced by the \grammarterm{exception-declaration} of a -\grammarterm{handler}\iref{except.handle}) -with the same type (ignoring cv-qualification) as -the function return type, the copy/move operation can be -omitted by constructing the object directly -into the function call's return object +\grammarterm{handler}\iref{except.handle}), +the copy-initialization of the result object can be +omitted by constructing $o$ directly +into the function call's result object; \item in a \grammarterm{throw-expression}\iref{expr.throw}, when the operand -is the name of a non-volatile object with automatic storage duration -(other than a function or catch-clause parameter) +is the name of a non-volatile object $o$ with automatic storage duration +(other than a function parameter or +a variable introduced by +the \grammarterm{exception-declaration} of a \grammarterm{handler}) that belongs to a scope that does not contain the innermost enclosing \grammarterm{compound-statement} associated with a \grammarterm{try-block} (if there is one), -the copy/move operation can be omitted by -constructing the object directly into the exception object +the copy-initialization of the exception object can be omitted by +constructing $o$ directly into the exception object; \item in a coroutine\iref{dcl.fct.def.coroutine}, a copy of a coroutine parameter can be omitted and references to that copy replaced with references to the corresponding parameter if the meaning of the program will be unchanged except for -the execution of a constructor and destructor for the parameter copy object +the execution of a constructor and destructor for the parameter copy object; \item when the \grammarterm{exception-declaration} of a -\grammarterm{handler}\iref{except.handle} declares an object of the same -type (except for cv-qualification) as the exception -object\iref{except.throw}, the copy operation can be omitted by treating +\grammarterm{handler}\iref{except.handle} declares an object $o$, +the copy-initialization of $o$ can be omitted by treating the \grammarterm{exception-declaration} as an alias for the exception object if the meaning of the program will be unchanged except for the execution of constructors and destructors for the object declared by the diff --git a/source/compatibility.tex b/source/compatibility.tex index 93baac8554..8c36a3e883 100644 --- a/source/compatibility.tex +++ b/source/compatibility.tex @@ -122,6 +122,38 @@ \end{codeblock} \end{example} +\diffref{temp.deduct.call} +\change +Template argument deduction from overload sets succeeds in more cases. +\rationale +Allow consideration of constraints to disambiguate overload sets +used as parameters in function calls. +\effect +Valid \CppXXIII{} code may become ill-formed. +\begin{example} +\begin{codeblock} +template +void f(T &&, void (*)(T &&)); + +void g(int &); // \#1 +inline namespace A { + void g(short &&); // \#2 +} +inline namespace B { + void g(short &&); // \#3 +} + +void q() { + int x; + f(x, g); // ill-formed; previously well-formed, deducing \tcode{T = int\&} +} +\end{codeblock} +There is no change to the applicable deduction rules for +the individual \tcode{g} candidates: +Type deduction from \#1 does not succeed; +type deductions from \#2 and \#3 both succeed. +\end{example} + \rSec2[diff.cpp23.library]{\ref{library}: library introduction} \diffref{headers} diff --git a/source/declarations.tex b/source/declarations.tex index b3122d3db8..481231a305 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -3639,7 +3639,7 @@ If the \grammarterm{parameter-declaration-clause} is empty, the function takes no arguments. -A parameter list consisting of a single unnamed parameter of +A parameter list consisting of a single unnamed non-object parameter of non-dependent type \keyword{void} is equivalent to an empty parameter list. \indextext{parameter!\idxcode{void}}% @@ -5808,6 +5808,10 @@ return x; } constexpr int z = f(); // error: not a constant expression + +typedef int *A[3]; // array of 3 pointer to \tcode{int} +typedef const int *const CA[3]; // array of 3 const pointer to \tcode{const int} +ACPC &&r = AP{}; // binds directly \end{codeblock} \end{example} @@ -9009,6 +9013,7 @@ \rSec2[dcl.attr.assume]{Assumption attribute} +% FIXME: Shouldn't there be a pnum here? The \grammarterm{attribute-token} \tcode{assume} may be applied to a null statement; such a statement is an \defn{assumption}. An \grammarterm{attribute-argument-clause} shall be present and @@ -9021,7 +9026,8 @@ If the converted expression would evaluate to \tcode{true} at the point where the assumption appears, the assumption has no effect. -Otherwise, the behavior is undefined. +Otherwise, +evaluation of the assumption has runtime-undefined behavior. \begin{note} The expression is potentially evaluated\iref{basic.def.odr}. The use of assumptions is intended to allow implementations @@ -9528,8 +9534,9 @@ translation unit, the program is ill-formed, no diagnostic required. \pnum -If a function \tcode{f} is called where \tcode{f} was previously declared with the \tcode{noreturn} -attribute and \tcode{f} eventually returns, the behavior is undefined. +If a function \tcode{f} is invoked where \tcode{f} was previously declared with the \tcode{noreturn} +attribute and that invocation eventually returns, +the behavior is runtime-undefined. \begin{note} The function can terminate by throwing an exception. diff --git a/source/expressions.tex b/source/expressions.tex index e8664a3cc4..6f160ffa39 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -266,7 +266,8 @@ \end{note} \pnum -Whenever a prvalue appears as an operand of an operator that +Unless otherwise specified\iref{expr.reinterpret.cast, expr.const.cast}, +whenever a prvalue appears as an operand of an operator that expects a glvalue for that operand, the temporary materialization conversion\iref{conv.rval} is applied to convert the expression to an xvalue. @@ -335,9 +336,13 @@ \indextext{expression!reference}% If an expression initially has the type ``reference to \tcode{T}''\iref{dcl.ref,dcl.init.ref}, the type is adjusted to -\tcode{T} prior to any further analysis. The expression designates the -object or function denoted by the reference, and the expression -is an lvalue or an xvalue, depending on the expression. +\tcode{T} prior to any further analysis; +the value category of the expression is not altered. +Let $X$ be the object or function denoted by the reference. +If a pointer to $X$ would be valid in +the context of the evalution of the expression\iref{basic.fundamental}, +the result designates $X$; +otherwise, the behavior is undefined. \begin{note} Before the lifetime of the reference has started or after it has ended, the behavior is undefined (see~\ref{basic.life}). @@ -433,7 +438,8 @@ \pnum \label{term.unevaluated.operand}% In some contexts, \defnx{unevaluated operands}{unevaluated operand} -appear\iref{expr.prim.req, +appear\iref{expr.prim.req.simple, +expr.prim.req.compound, expr.typeid, expr.sizeof, expr.unary.noexcept, @@ -673,11 +679,26 @@ pointer value\iref{basic.stc.dynamic.deallocation}, the behavior is \impldef{lvalue-to-rvalue conversion of an invalid pointer value}. -\item Otherwise, the object indicated by the glvalue is read\iref{defns.access}, -and the value contained in the object is the prvalue result. -If the result is an erroneous value\iref{basic.indet} and -the bits in the value representation are not valid for the object's type, -the behavior is undefined. +\item Otherwise, if the bits in the value representation of +the object to which the glvalue refers +are not valid for the object's type, the behavior is undefined. +\begin{example} +\begin{codeblock} +bool f() { + bool b = true; + char c = 42; + memcpy(&b, &c, 1); + return b; // undefined behavior if \tcode{42} is not a valid value representation for \keyword{bool} +} +\end{codeblock} +\end{example} + +\item Otherwise, the object indicated by the glvalue is read\iref{defns.access}. +Let \tcode{V} be the value contained in the object. +If \tcode{T} is an integer type, +the prvalue result is +the value of type \tcode{T} congruent\iref{basic.fundamental} to \tcode{V}, and +\tcode{V} otherwise. \end{itemize} \pnum @@ -2890,8 +2911,6 @@ \pnum A \grammarterm{requires-expression} is a prvalue of type \tcode{bool} whose value is described below. -Expressions appearing within a \grammarterm{requirement-body} -are unevaluated operands\iref{term.unevaluated.operand}. \pnum \begin{example} @@ -2983,10 +3002,10 @@ \pnum A \grammarterm{simple-requirement} asserts the validity of an \grammarterm{expression}. +The \grammarterm{expression} is an unevaluated operand. \begin{note} The enclosing \grammarterm{requires-expression} will evaluate to \keyword{false} if substitution of template arguments into the \grammarterm{expression} fails. -The \grammarterm{expression} is an unevaluated operand\iref{term.unevaluated.operand}. \end{note} \begin{example} \begin{codeblock} @@ -3054,7 +3073,9 @@ \pnum A \grammarterm{compound-requirement} asserts properties -of the \grammarterm{expression} $E$. Substitution +of the \grammarterm{expression} $E$. +The \grammarterm{expression} is an unevaluated operand. +Substitution of template arguments (if any) and verification of semantic properties proceed in the following order: @@ -3529,6 +3550,9 @@ if the result type is an lvalue reference type or an rvalue reference to function type, an xvalue if the result type is an rvalue reference to object type, and a prvalue otherwise. +If it is a non-void prvalue, +the type of the function call expression shall be complete, +except as specified in \ref{dcl.type.decltype}. \rSec3[expr.type.conv]{Explicit type conversion (functional notation)} @@ -3555,6 +3579,44 @@ Otherwise, if the type contains a placeholder type, it is replaced by the type determined by placeholder type deduction\iref{dcl.type.auto.deduct}. +Let \tcode{T} denote the resulting type. +Then: + +\begin{itemize} +\item +If the initializer is a parenthesized single expression, +the type conversion expression is equivalent +to the corresponding cast +expression\iref{expr.cast}. + +\item +\indextext{type!incomplete}% +Otherwise, if \tcode{T} is \cv{}~\keyword{void}, +the initializer shall be \tcode{()} or \tcode{\{\}} +(after pack expansion, if any), and +the expression is a prvalue of type \keyword{void} +that performs no initialization. + +\item +Otherwise, if \tcode{T} is a reference type, +the expression has the same effect as +direct-initializing an invented variable \tcode{t} of type \tcode{T} from +the initializer and then +using \tcode{t} as the result of the expression; +the result is an lvalue if +\tcode{T} is an lvalue reference type or +an rvalue reference to function type and +an xvalue otherwise. + +\item +Otherwise, +the expression is a prvalue of type \tcode{T} +whose result object is direct-initialized\iref{dcl.init} +with the initializer. +\end{itemize} + +If the initializer is a parenthesized optional \grammarterm{expression-list}, +\tcode{T} shall not be an array type. \begin{example} \begin{codeblock} struct A {}; @@ -3569,24 +3631,6 @@ \end{codeblock} \end{example} -\pnum -If the initializer is a parenthesized single expression, -the type conversion expression is equivalent -to the corresponding cast -expression\iref{expr.cast}. -\indextext{type!incomplete}% -Otherwise, if the type is \cv{}~\keyword{void} -and the initializer is \tcode{()} or \tcode{\{\}} -(after pack expansion, if any), -the expression is a prvalue of type \keyword{void} -that performs no initialization. -Otherwise, -the expression is a prvalue of the specified type -whose result object is direct-initialized\iref{dcl.init} -with the initializer. -If the initializer is a parenthesized optional \grammarterm{expression-list}, -the specified type shall not be an array type. - \rSec3[expr.ref]{Class member access} \pnum @@ -3772,8 +3816,8 @@ \indextext{operator!increment}% \indextext{\idxcode{++}|see{operator, increment}}% \indextext{postfix \tcode{++}}% -The value of a postfix \tcode{++} expression is the value of its -operand. +The value of a postfix \tcode{++} expression is the value obtained by +applying the lvalue-to-rvalue conversion\iref{conv.lval} to its operand. \begin{note} The value obtained is a copy of the original value. \end{note} @@ -4388,9 +4432,6 @@ \tcode{T2}'' (where \tcode{T1} and \tcode{T2} are function types) and back to its original type yields the original pointer value, the result of such a pointer conversion is unspecified. -\begin{note} -See also~\ref{conv.ptr} for more details of pointer conversions. -\end{note} \pnum An object pointer @@ -4465,7 +4506,7 @@ \indextext{cast!reinterpret!reference}% \indextext{cast!reference}% \indextext{type pun}% -A glvalue of type \tcode{T1}, +If \tcode{v} is a glvalue of type \tcode{T1}, designating an object or function \placeholder{x}, can be cast to the type ``reference to \tcode{T2}'' if an expression of type ``pointer to \tcode{T1}'' @@ -4474,13 +4515,16 @@ The result is that of \tcode{*reinterpret_cast(p)} where \tcode{p} is a pointer to \placeholder{x} of type ``pointer to \tcode{T1}''. -No temporary is created, no copy is made, and +\begin{note} +No temporary is materialized\iref{conv.rval} or created, +no copy is made, and no constructors\iref{class.ctor} or conversion functions\iref{class.conv} are called. \begin{footnote} This is sometimes referred to as a type pun when the result refers to the same object as the source glvalue. \end{footnote} +\end{note} \rSec3[expr.const.cast]{Const cast} @@ -4494,7 +4538,10 @@ otherwise, the result is a prvalue and the lvalue-to-rvalue\iref{conv.lval}, array-to-pointer\iref{conv.array}, and function-to-pointer\iref{conv.func} standard conversions are -performed on the expression \tcode{v}. Conversions that can be performed explicitly using +performed on the expression \tcode{v}. +The temporary materialization conversion\iref{conv.rval} is not +performed on \tcode{v}, other than as specified below. +Conversions that can be performed explicitly using \keyword{const_cast} are listed below. No other conversion shall be performed explicitly using \keyword{const_cast}. @@ -4505,23 +4552,16 @@ \end{note} \pnum -For two similar types \tcode{T1} and \tcode{T2}\iref{conv.qual}, -a prvalue of type \tcode{T1} may be explicitly +For two similar object pointer or pointer to data member types +\tcode{T1} and \tcode{T2}\iref{conv.qual}, +a prvalue of type \tcode{T1} can be explicitly converted to the type \tcode{T2} using a \keyword{const_cast} if, considering the qualification-decompositions of both types, each $P^1_i$ is the same as $P^2_i$ for all $i$. -The result of a \keyword{const_cast} refers to the original entity. -\begin{example} -\begin{codeblock} -typedef int *A[3]; // array of 3 pointer to \tcode{int} -typedef const int *const CA[3]; // array of 3 const pointer to \tcode{const int} - -CA &&r = A{}; // OK, reference binds to temporary array object - // after qualification conversion to type \tcode{CA} -A &&r1 = const_cast(CA{}); // error: temporary array decayed to pointer -A &&r2 = const_cast(CA{}); // OK -\end{codeblock} -\end{example} +If \tcode{v} is a null pointer or null member pointer, +the result is a null pointer or null member pointer, respectively. +Otherwise, the result points to or past the end of the same object, or +points to the same member, respectively, as \tcode{v}. \pnum For two object types \tcode{T1} and \tcode{T2}, if a pointer to \tcode{T1} can @@ -4534,20 +4574,22 @@ \item a glvalue of type \tcode{T1} can be explicitly converted to an xvalue of type \tcode{T2} using the cast \tcode{\keyword{const_cast}}; and -\item if \tcode{T1} is a class type, a prvalue of type \tcode{T1} can be +\item if \tcode{T1} is a class or array type, +a prvalue of type \tcode{T1} can be explicitly converted to an xvalue of type \tcode{T2} using the cast \tcode{\keyword{const_cast}}. +The temporary materialization conversion is performed on \tcode{v}. \end{itemize} -The result of a reference \keyword{const_cast} refers -to the original object if the operand is a glvalue and -to the result of applying the temporary materialization conversion\iref{conv.rval} otherwise. +The result refers to the same object as the (possibly converted) operand. +\begin{example} +\begin{codeblock} +typedef int *A[3]; // array of 3 pointer to \tcode{int} +typedef const int *const CA[3]; // array of 3 const pointer to \tcode{const int} -\pnum -A null pointer value\iref{basic.compound} is converted to the null pointer -value of the destination type. The null member pointer -value\iref{conv.mem} is converted to the null member pointer value of -the destination type. +auto &&r2 = const_cast(CA{}); // OK, temporary materialization conversion is performed +\end{codeblock} +\end{example} \pnum \begin{note} @@ -7117,30 +7159,32 @@ subclause. \pnum -Lvalue-to-rvalue\iref{conv.lval}, array-to-pointer\iref{conv.array}, +Array-to-pointer\iref{conv.array} and function-to-pointer\iref{conv.func} standard conversions are performed on the second and third operands. After those conversions, one of the following shall hold: \begin{itemize} \item The second and third operands have the same type; the result is of -that type and the result object is initialized using the selected operand. +that type and the result is copy-initialized using the selected operand. \item The second and third operands have arithmetic or enumeration type; the usual arithmetic conversions\iref{expr.arith.conv} are performed to bring them to a common type, and the result is of that type. \item One or both of the second and third operands have pointer type; -pointer conversions\iref{conv.ptr}, -function pointer conversions\iref{conv.fctptr}, and +lvalue-to-rvalue\iref{conv.lval}, +pointer\iref{conv.ptr}, +function pointer\iref{conv.fctptr}, and qualification conversions\iref{conv.qual} are performed to bring them to their composite pointer type\iref{expr.type}. The result is of the composite pointer type. \item One or both of the second and third operands have pointer-to-member type; -pointer to member conversions\iref{conv.mem}, -function pointer conversions\iref{conv.fctptr}, and +lvalue-to-rvalue\iref{conv.lval}, +pointer to member\iref{conv.mem}, +function pointer\iref{conv.fctptr}, and qualification conversions\iref{conv.qual} are performed to bring them to their composite pointer type\iref{expr.type}. The result is of the composite pointer type. @@ -7307,9 +7351,13 @@ \end{bnf} \pnum -In simple assignment (\tcode{=}), the object referred to by the left operand -is modified\iref{defns.access} -by replacing its value with the result of the right operand. +In simple assignment (\tcode{=}), +let \tcode{V} be the result of the right operand; +the object referred to by the left operand is +modified\iref{defns.access} by replacing its value +with \tcode{V} or, +if the object is of integer type, +with the value congruent\iref{basic.fundamental} to \tcode{V}. \pnum \indextext{assignment!conversion by}% @@ -7453,7 +7501,7 @@ \begin{itemize} \item either it has an initializer or - its default-initialization results in some initialization being performed, and + its type is const-default-constructible\iref{dcl.init.general}, and \item the full-expression of its initialization is a constant expression when interpreted as a \grammarterm{constant-expression}, @@ -7565,6 +7613,9 @@ an lvalue-to-rvalue conversion\iref{conv.lval} unless it is applied to \begin{itemize} + \item + a glvalue of type \cv \tcode{std::nullptr_t}, + \item a non-volatile glvalue that refers to an object that is usable in constant expressions, or @@ -7665,9 +7716,9 @@ \begin{itemize} \item the placement argument to the \grammarterm{new-expression} points to -an object that is pointer-interconvertible with an object of type \tcode{T} or, -if T is an array type, -with the first element of an object of type \tcode{T}, and +an object whose type is similar to \tcode{T}\iref{conv.qual} or, +if \tcode{T} is an array type, +to the first element of an object of a type similar to \tcode{T}, and \item the placement argument points to storage whose duration began within the evaluation of $E$; @@ -7731,6 +7782,13 @@ \end{note} \end{itemize} +\pnum +It is +\impldef{whether an expression is a core constant expression} +whether $E$ is a core constant expression +if $E$ satisfies the constraints of a core constant expression, but +evaluation of $E$ has runtime-undefined behavior. + \pnum It is unspecified whether $E$ is a core constant expression if $E$ satisfies the constraints of a core constant expression, but @@ -7738,26 +7796,9 @@ \begin{itemize} \item an operation that has undefined behavior -as specified in \ref{library} through \ref{\lastlibchapter}, -\item -an invocation of the \tcode{va_start} macro\iref{cstdarg.syn}, -\item -a call to a function -that was previously declared -with the \tcode{noreturn} attribute\iref{dcl.attr.noreturn} and -that call returns to its caller, or +as specified in \ref{library} through \ref{\lastlibchapter} or \item -a statement with an assumption\iref{dcl.attr.assume} -whose converted \grammarterm{conditional-expression}, -if evaluated where the assumption appears, -would not disqualify $E$ from being a core constant expression and -would not evaluate to \tcode{true}. -\begin{note} -$E$ is not disqualified from being a core constant expression -if the hypothetical evaluation of -the converted \grammarterm{conditional-expression} -would disqualify $E$ from being a core constant expression. -\end{note} +an invocation of the \tcode{va_start} macro\iref{cstdarg.syn}. \end{itemize} \pnum diff --git a/source/intro.tex b/source/intro.tex index 7a93f24be3..24edb7cbc7 100644 --- a/source/intro.tex +++ b/source/intro.tex @@ -206,6 +206,11 @@ constructs that it does not support. \end{defnote} +\definition{constant evaluation}{defns.const.eval} +\indexdefn{constant evaluation}% +evaluation that is performed as part of evaluating an expression +as a core constant expression\iref{expr.const} + \definition{constant subexpression}{defns.const.subexpr} \indexdefn{constant subexpression}% expression whose evaluation as subexpression of a @@ -504,6 +509,23 @@ \indextext{undefined} \end{defnote} +\definition{runtime-undefined behavior}{defns.undefined.runtime} +\indexdefn{behavior!runtime-undefined}% +behavior that is undefined except when it occurs during constant evaluation + +\begin{defnote} +During constant evaluation, +\begin{itemize} +\item +it is +\impldef{whether runtime-undefined behavior results in the expression being deemed non-constant} +whether runtime-undefined behavior results in the expression being deemed non-constant +(as specified in~\ref{expr.const} and +\item +runtime-undefined behavior has no other effect. +\end{itemize} +\end{defnote} + \indexdefn{signature}% \definition{signature}{defns.signature} \defncontext{function} diff --git a/source/lex.tex b/source/lex.tex index e10a29e55c..dda28c0271 100644 --- a/source/lex.tex +++ b/source/lex.tex @@ -162,7 +162,8 @@ directive\iref{cpp.include}. \end{example} -\item Preprocessing directives\iref{cpp} are executed, macro invocations are +\item The source file is analyzed as a \grammarterm{preprocessing-file}\iref{cpp.pre}. +Preprocessing directives\iref{cpp} are executed, macro invocations are expanded\iref{cpp.replace}, and \tcode{_Pragma} unary operator expressions are executed\iref{cpp.pragma.op}. A \tcode{\#include} preprocessing directive\iref{cpp.include} causes the named header or source file to be processed from phase 1 through phase 4, recursively. @@ -183,7 +184,8 @@ token\iref{lex.token}. The resulting tokens constitute a \defn{translation unit} and are syntactically and -semantically analyzed and translated. +semantically analyzed as a \grammarterm{translation-unit}\iref{basic.link} and +translated. \begin{note} The process of analyzing and translating the tokens can occasionally result in one token being replaced by a sequence of other diff --git a/source/modules.tex b/source/modules.tex index 2ed009a3b6..ced0320686 100644 --- a/source/modules.tex +++ b/source/modules.tex @@ -312,7 +312,7 @@ A redeclaration of an entity $X$ is implicitly exported if $X$ was introduced by an exported declaration; -otherwise it shall not be exported. +otherwise it shall not be exported if it is attached to a named module. \begin{example} \begin{codeblock} export module M; diff --git a/source/overloading.tex b/source/overloading.tex index 4ac8209ac7..cf7d80931c 100644 --- a/source/overloading.tex +++ b/source/overloading.tex @@ -1118,11 +1118,11 @@ \begin{itemize} \item ``lvalue reference to \cvqual{cv2} \tcode{T2}'' -(when initializing an lvalue reference or an rvalue reference to function) and +(when converting to an lvalue) and \item ``\cvqual{cv2} \tcode{T2}'' -and ``rvalue reference to \cvqual{cv2} \tcode{T2}'' (when initializing an -rvalue reference or an lvalue reference to function) +and ``rvalue reference to \cvqual{cv2} \tcode{T2}'' +(when converting to an rvalue or an lvalue of function type) \end{itemize} for any \tcode{T2}. The permissible types for non-explicit conversion functions are @@ -1795,19 +1795,8 @@ \item $\tcode{F}_1$ and $\tcode{F}_2$ are non-template functions and -\begin{itemize} -\item -they have the same non-object-parameter-type-lists\iref{dcl.fct}, and -\item -if they are member functions, both are direct members of the same class, and -\item -if both are non-static member functions, -they have the same types for their object parameters, and -\item -$\tcode{F}_1$ is more constrained than $\tcode{F}_2$ -according to the partial ordering of constraints described in -\ref{temp.constr.order} -\end{itemize} +$\tcode{F}_1$ is more partial-ordering-constrained than +$\tcode{F}_2$\iref{temp.constr.order} \begin{example} \begin{codeblock} template @@ -2329,16 +2318,16 @@ \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, +if \tcode{T} is a function type, +the implicit conversion sequence is a function pointer conversion. \item Otherwise, the implicit conversion sequence is a qualification conversion. @@ -2351,6 +2340,11 @@ int f(A&); int f(B&); int i = f(b); // calls \tcode{f(B\&)}, an exact match, rather than \tcode{f(A\&)}, a conversion + +void g() noexcept; +int h(void (&)() noexcept); // \#1 +int h(void (&)()); // \#2 +int j = h(g); // calls \#1, an exact match, rather than \#2, a function pointer conversion \end{codeblock} \end{example} If the parameter binds directly to the result of @@ -2835,15 +2829,11 @@ b.f(); // calls \tcode{X::f()} } -int h1(int (&)[]); -int h1(int (&)[1]); -int h2(void (&)()); -int h2(void (&)() noexcept); +int h(int (&)[]); +int h(int (&)[1]); void g2() { int a[1]; - h1(a); // calls \tcode{h1(int (\&)[1])} - extern void f2() noexcept; - h2(f2); // calls \tcode{h2(void (\&)() noexcept)} + h(a); // calls \tcode{h(int (\&)[1])} } \end{codeblock} \end{example} @@ -3116,6 +3106,9 @@ a non-type \grammarterm{template-parameter}\iref{temp.arg.nontype}. \end{itemize} +If the target type contains a placeholder type, +placeholder type deduction is performed\iref{dcl.type.auto.deduct}, and +the remainder of this subclause uses the target type so deduced. The \grammarterm{id-expression} can be preceded by the \tcode{\&} operator. \begin{note} Any redundant set of parentheses surrounding the function name is @@ -3168,10 +3161,8 @@ \tcode{F0} is eliminated if the set contains a second non-template function that -is more constrained than -\tcode{F0} -according to -the partial ordering rules of \ref{temp.constr.order}. +is more partial-ordering-constrained than +\tcode{F0}\iref{temp.constr.order}. Any given function template specialization \tcode{F1} @@ -3207,8 +3198,9 @@ with type \tcode{int(...)} has been declared, and not because of any ambiguity. -For another example, +\end{example} +\begin{example} \begin{codeblock} struct X { int f(int); @@ -3225,6 +3217,21 @@ \end{codeblock} \end{example} +\begin{example} +\begin{codeblock} +template struct X { + void f(short) requires B; + void f(long); + template void g(short) requires B; + template void g(long); +}; +void test() { + &X::f; // error: ambiguous; constraints are not considered + &X::g; // error: ambiguous; constraints are not considered +} +\end{codeblock} +\end{example} + \pnum \begin{note} If \tcode{f} and \tcode{g} are both overload sets, @@ -3351,15 +3358,10 @@ \pnum \indextext{restriction!overloading}% An operator function -shall either -\begin{itemize} -\item -be a member function or -\item -be a non-member function that -has at least one non-object parameter whose type is a class, a reference to a class, an +shall have at least one +function parameter or implicit object parameter whose type is +a class, a reference to a class, an enumeration, or a reference to an enumeration. -\end{itemize} It is not possible to change the precedence, grouping, or number of operands of operators. The meaning of diff --git a/source/preprocessor.tex b/source/preprocessor.tex index 23944f5bc4..9705fd1ca0 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -216,6 +216,16 @@ \pnum A sequence of preprocessing tokens is only a \grammarterm{text-line} if it does not begin with a directive-introducing token. +\begin{example} +\begin{codeblock} +using module = int; +module i; // not a \grammarterm{text-line} and not a \grammarterm{control-line} +int foo() { + return i; +} +\end{codeblock} +The example is not a valid \grammarterm{preprocessing-file}. +\end{example} A sequence of preprocessing tokens is only a \grammarterm{conditionally-supported-directive} if it does not begin with any of the directive names appearing after a \tcode{\#} in the syntax. @@ -1600,7 +1610,9 @@ \pnum The \defn{line number} -of the current source line is one greater than +of the current source line is +the line number of the current physical source line, +i.e., it is one greater than the number of new-line characters read or introduced in translation phase 1\iref{lex.phases} while processing the source file to the current token. diff --git a/source/templates.tex b/source/templates.tex index 251afa1c4c..b43cb72346 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -2133,6 +2133,22 @@ \end{codeblock} \end{example} +\pnum +A non-template function \tcode{F1} is \defn{more partial-ordering-constrained} +than a non-template function \tcode{F2} if +\begin{itemize} +\item +they have the same non-object-parameter-type-lists\iref{dcl.fct}, and +\item +if they are member functions, both are direct members of the same class, and +\item +if both are non-static member functions, +they have the same types for their object parameters, and +\item +the declaration of \tcode{F1} is more constrained than +the declaration of \tcode{F2}. +\end{itemize} + \rSec1[temp.type]{Type equivalence} \pnum @@ -2518,7 +2534,7 @@ \begin{bnf} \nontermdef{deduction-guide}\br - \opt{explicit-specifier} template-name \terminal{(} parameter-declaration-clause \terminal{)} \opt{requires-clause} \terminal{->} simple-template-id \terminal{;} + \opt{explicit-specifier} template-name \terminal{(} parameter-declaration-clause \terminal{)} \terminal{->} simple-template-id \terminal{;} \end{bnf} \pnum @@ -4987,13 +5003,16 @@ \item in the definition of a nested class of a class template, the name of the nested class referenced as a member of the -current instantiation, or +current instantiation, \item in the definition of a class template partial specialization or a member of a class template partial specialization, the name of the class template followed by a template argument list equivalent to that of the partial specialization\iref{temp.spec.partial} -enclosed in \tcode{<>} (or an equivalent template alias specialization). +enclosed in \tcode{<>} (or an equivalent template alias specialization), or +\item +in the definition of a templated function, +the name of a local class\iref{class.local}. \end{itemize} \pnum @@ -5447,7 +5466,6 @@ \keyword{typeid} \terminal{(} expression \terminal{)}\br \keyword{typeid} \terminal{(} type-id \terminal{)}\br \keyword{alignof} \terminal{(} type-id \terminal{)}\br -\keyword{noexcept} \terminal{(} expression \terminal{)} \end{ncsimplebnf} \begin{note} @@ -5457,20 +5475,28 @@ \pnum Expressions of the following form are value-dependent if either the -\grammarterm{type-id} -or -\grammarterm{simple-type-specifier} +\grammarterm{type-id}, +\grammarterm{simple-type-specifier}, or +\grammarterm{typename-specifier} is dependent or the \grammarterm{expression} or \grammarterm{cast-expression} +is value-dependent or +any \grammarterm{expression} in the \grammarterm{expression-list} +is value-dependent or +any \grammarterm{assignment-expression} in the \grammarterm{braced-init-list} is value-dependent: \begin{ncsimplebnf} simple-type-specifier \terminal{(} \opt{expression-list} \terminal{)}\br +typename-specifier \terminal{(} opt{expression-list} \terminal{)}\br +simple-type-specifier braced-init-list\br +typename-specifier braced-init-list\br \keyword{static_cast} \terminal{<} type-id \terminal{>} \terminal{(} expression \terminal{)}\br \keyword{const_cast} \terminal{<} type-id \terminal{>} \terminal{(} expression \terminal{)}\br \keyword{reinterpret_cast} \terminal{<} type-id \terminal{>} \terminal{(} expression \terminal{)}\br +dynamic_cast \terminal{<} type-id \terminal{>} \terminal{(} expression \terminal{)}\br \terminal{(} type-id \terminal{)} cast-expression \end{ncsimplebnf} @@ -5482,6 +5508,11 @@ fold-expression \end{ncsimplebnf} +\pnum +A \grammarterm{noexcept-expression}\iref{expr.unary.noexcept} +is value-dependent if +its \grammarterm{expression} involves a template parameter. + \pnum An expression of the form \tcode{\&}\grammarterm{qualified-id} where the \grammarterm{qualified-id} names a dependent member of the current @@ -7854,10 +7885,11 @@ the parameter is treated as a non-deduced context. \item If the argument is an overload set (not containing function templates), trial -argument deduction is attempted using each of the members of the set. If -deduction succeeds for only one of the overload set members, that member is -used as the argument value for the deduction. If deduction succeeds for more than -one member of the overload set the parameter is treated as a non-deduced context. +argument deduction is attempted using each of the members of the set +whose associated constraints\iref{temp.constr.constr} are satisfied. +If all successful deductions yield the same deduced \tcode{A}, +that deduced \tcode{A} is the result of deduction; +otherwise, the parameter is treated as a non-deduced context. \end{itemize} \pnum @@ -7893,6 +7925,21 @@ \end{codeblock} \end{example} +\pnum +\begin{example} +\begin{codeblock} +// All arguments for placeholder type deduction\iref{dcl.type.auto.deduct} yield the same deduced type. +template struct X { + static void f(short) requires B; // \#1 + static void f(short); // \#2 +}; +void test() { + auto x = &X::f; // OK, deduces \tcode{void(*)(short)}, selects \#1 + auto y = &X::f; // OK, deduces \tcode{void(*)(short)}, selects \#2 +} +\end{codeblock} +\end{example} + \rSec3[temp.deduct.funcaddr]{Deducing template arguments taking the address of a function template} \pnum @@ -8326,16 +8373,22 @@ deduction is being done. \item A function parameter for which the associated argument is an -overload set\iref{over.over}, and one or more of the following apply: +overload set such that one or more of the following apply: \begin{itemize} \item -more than one function matches the function parameter type (resulting in -an ambiguous deduction), or +functions whose associated constraints are satisfied and +that do not all have the same function type +match the function parameter type (resulting in an ambiguous deduction), or \item -no function matches the function parameter type, or +no function whose associated constraints are satisfied +matches the function parameter type, or \item the overload set supplied as an argument contains one or more function templates. \end{itemize} +\begin{tailnote} +A particular function from the overload set is selected\iref{over.over} +after template argument deduction has succeeded\iref{temp.over}. +\end{tailnote} \item A function parameter for which the associated argument is an initializer list\iref{dcl.init.list} but the parameter does not have a type for which deduction from an initializer list is specified\iref{temp.deduct.call}.