From dc8961981d86af9e753255d74f59cfdb39d7f8b8 Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 10:58:14 +0100 Subject: [PATCH 01/46] CWG2555 Ineffective redeclaration prevention for using-declarators --- source/declarations.tex | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/source/declarations.tex b/source/declarations.tex index a7181750a1..e3007834b7 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -8964,9 +8964,9 @@ \indextext{name hiding!using-declaration and}% The set of declarations named by a \grammarterm{using-declarator} that inhabits a class \tcode{C} does not include -member functions and member function templates of a base class -that correspond to (and thus would conflict with) -a declaration of a function or function template in \tcode{C}. +member functions and member function templates of a base class that, +when considered as members of \tcode{C}, +correspond to a declaration of a function or function template in \tcode{C}. \begin{example} \begin{codeblock} struct B { @@ -8974,6 +8974,8 @@ virtual void f(char); void g(int); void h(int); + void i(); + void j(); }; struct D : B { @@ -8985,6 +8987,12 @@ using B::h; void h(int); // OK, \tcode{D::h(int)} hides \tcode{B::h(int)} + + using B::i; + void i(this B &); // OK + + using B::j; + void j(this D &); // OK, \tcode{D::j()} hides \tcode{B::j()} }; void k(D* p) @@ -8993,6 +9001,8 @@ p->f('a'); // calls \tcode{B::f(char)} p->g(1); // calls \tcode{B::g(int)} p->g('a'); // calls \tcode{D::g(char)} + p->i(); // calls \tcode{B::i}, because \tcode{B::i} as a member of \tcode{D} is a better match than \tcode{D::i} + p->j(); // calls \tcode{D::j} } struct B1 { From 37d12fd57bbab7fd7d5df1856aead2097fbd3ee4 Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 12:01:06 +0100 Subject: [PATCH 02/46] CWG2677 Replacing union subobjects --- source/basic.tex | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/source/basic.tex b/source/basic.tex index eeacc387db..4b19a3ef79 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -3476,7 +3476,7 @@ An object that is not a subobject of any other object is called a \defn{complete object}. If an object is created -in storage associated with a member subobject or array element \placeholder{e} +in storage associated with a subobject \placeholder{e} (which may or may not be within its lifetime), the created object is a subobject of \placeholder{e}'s containing object if @@ -3486,8 +3486,12 @@ \item the storage for the new object exactly overlays the storage location associated with \placeholder{e}, and \item +\placeholder{e} is not a potentially-overlapping subobject, and +\item the new object is of the same type as \placeholder{e} (ignoring cv-qualification). \end{itemize} +In this case, \placeholder{e} and the created object are +\defnadjx{corresponding direct}{subobjects}{subobject}. \pnum \indextext{object!providing storage for}% @@ -4012,22 +4016,24 @@ \end{note} \pnum -An object $o_1$ is \defn{transparently replaceable} by an object $o_2$ if +An object $o_1$ is \defn{transparently replaceable} by an object $o_2$ if either +\begin{itemize} +\item +$o_1$ and $o_2$ are complete objects for which: \begin{itemize} +\item $o_1$ is not const, \item the storage that $o_2$ occupies exactly overlays the storage that $o_1$ occupied, and - \item $o_1$ and $o_2$ are of the same type -(ignoring the top-level cv-qualifiers), and - -\item $o_1$ is not a const, complete object, and - -\item neither $o_1$ nor $o_2$ -is a potentially-overlapping subobject\iref{intro.object}, and +(ignoring the top-level cv-qualifiers), or +\end{itemize} -\item either $o_1$ and $o_2$ are both complete objects, or -$o_1$ and $o_2$ are direct subobjects of objects $p_1$ and $p_2$, respectively, -and $p_1$ is transparently replaceable by $p_2$. +\item +$o_1$ and $o_2$ are corresponding direct subobjects\iref{intro.object} for which: +\begin{itemize} +\item the complete object of $o_1$ is not const or +\item $o_1$ is a mutable member subobject or a subobject thereof. +\end{itemize} \end{itemize} \pnum From 9e6cdd37fbe29d9f4fbd084c96134247abc9d0b9 Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 12:08:42 +0100 Subject: [PATCH 03/46] CWG2875 Missing support for round-tripping null pointer values through indirection/address operators Fixes NB US 267-401 (C++26 CD). Editorial notes: * [diff.expr] Use "example" environment as is our new style. --- source/compatibility.tex | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/source/compatibility.tex b/source/compatibility.tex index d0b6bcec85..65f268e21b 100644 --- a/source/compatibility.tex +++ b/source/compatibility.tex @@ -3041,6 +3041,33 @@ (for instance, via the C typedef in \libheaderref{stdbool.h}) is ill-formed in \Cpp{}. +\diffref{expr.unary.op} +\change +In certain contexts, +taking the address of a dereferenced null or past-the-end pointer value +is well-defined in C (and yields the original pointer value), +but results in undefined behavior in \Cpp{}. +\begin{example} +\begin{codeblock} +void f() { + char *p = nullptr; + char *p2 = &*p; // well-defined in C, undefined behavior in \Cpp{} + char *p3 = &p[0]; // well-defined in C, undefined behavior in \Cpp{} + int a[5]; + int *q = &a[5]; // well-defined in C, undefined behavior in \Cpp{} +} +\end{codeblock} +\end{example} +\rationale +Consistent treatment of lvalues in \Cpp{}. +\effect +Well-formed and well-defined C code exhibits undefined behavior in \Cpp{}. +\difficulty +Syntactic transformation to pointer arithmetic +and possible addition of a check for null pointer values. +\howwide +Occasionally. + \diffref{expr.sizeof,expr.cast} \change In \Cpp{}, types can only be defined in declarations, not in expressions.\\ From a9cc8801e417bd2fd9143095016b3846432ce1b8 Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 12:25:25 +0100 Subject: [PATCH 04/46] CWG2900 Deduction of non-type template arguments with placeholder types --- source/declarations.tex | 6 +++- source/templates.tex | 62 ++++++++++++++++++++++++++++++++++------- 2 files changed, 57 insertions(+), 11 deletions(-) diff --git a/source/declarations.tex b/source/declarations.tex index e3007834b7..b6555fac46 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -2183,7 +2183,11 @@ \opt{\grammarterm{type-constraint}} \keyword{auto} either with a new invented type template parameter \tcode{U} or, if the initialization is copy-list-initialization, with -\tcode{std::initializer_list}. Deduce a value for \tcode{U} using the rules +\tcode{std::initializer_list}. +If $E$ is a value synthesized for a constant template parameter +of type \tcode{decltype(auto)}\iref{temp.func.order}, +the declaration is ill-formed. +Otherwise, deduce a value for \tcode{U} using the rules of template argument deduction from a function call\iref{temp.deduct.call}, where \tcode{P} is a function template parameter type and diff --git a/source/templates.tex b/source/templates.tex index 738141e87c..526a37b014 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -4373,11 +4373,9 @@ variable template, or concept, respectively, and substitute it for each occurrence of that parameter in the function type of the template. -\begin{note} -The type replacing the placeholder +The type replacing a placeholder in the type of the value synthesized for a constant template parameter -is also a unique synthesized type. -\end{note} +is a unique synthesized type. \pnum %FIXME: What's a "synthesized template"? Do we mean the synthesized @@ -9391,11 +9389,16 @@ \end{note} \pnum -If \tcode{P} has a form that contains \tcode{}, and -if the type of \tcode{i} differs from the type +If \tcode{P} has a form that contains \tcode{}, +deduction fails unless the type of \tcode{i} is the same as that of the corresponding template parameter +\tcode{p} in the specialization (from \tcode{A}) of the template named by the enclosing \grammarterm{simple-template-id} or -\grammarterm{splice-specialization-specifier}, deduction fails. +\grammarterm{splice-specialization-specifier}; +if the declared type of \tcode{i} contains a placeholder type, +the corresponding template argument for the purposes of +placeholder type deduction\iref{dcl.type.auto.deduct} +is an \grammarterm{id-expression} for \tcode{p}. If \tcode{P} has a form that contains \tcode{[i]}, and if the type of \tcode{i} is not an integral type, deduction fails. \begin{footnote} @@ -9415,15 +9418,54 @@ template void f(A); void k1() { A<1> a; - f(a); // error: deduction fails for conversion from \tcode{int} to \tcode{short} - f<1>(a); // OK + f(a); // error: deduction fails for conversion from \tcode{int} to \tcode{short} + f<1>(a); // OK } template class B { }; template void g(B); void k2() { B<1> b; - g(b); // OK, cv-qualifiers are ignored on template parameter types + g(b); // OK, cv-qualifiers are ignored on template parameter types +} + +template struct C; +template void f(C *); +void g(C<0LL> *ap) { + f(ap); // OK, deduces \tcode{long long} value from \tcode{0LL} +} + +template struct D; +template void f(D *); +void g(D<0LL> *ap) { + f(ap); // OK, deduces \tcode{x} as an \tcode{int} value +} + +template struct E; +template void f(E *); +int v; +void g(E *bp) { + f(bp); // error: type \tcode{int} of \tcode{x} does not match the \tcode{int \&} type +} // of the template parameter in the \tcode{E} specialization of \tcode{E} + +template struct F; +template void f(F *); +int i; +void g(F *ap) { + f(ap); // OK, deduces \tcode{x} as a constant template parameter of type \tcode{const int \&} +} + +template struct G; +template long *f(G *); // \#1 +template short *f(G *); // \#2 + +const int j = 0; +short *g(G<(j)> *ap) { // OK, \tcode{q} has type \tcode{const int \&} + return f(ap); // OK, only \#2 matches +} + +long *g(G *ap) { // OK, \tcode{q} has type \tcode{int} + return f(ap); // OK, \#1 is more specialized } \end{codeblock} \end{example} From 9d2bc915ce04ee1fce68a597bdfc2aa057c8ffc8 Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 12:33:28 +0100 Subject: [PATCH 05/46] CWG2929 Lifetime of trivially-destructible static or thread-local objects --- source/basic.tex | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/source/basic.tex b/source/basic.tex index 4b19a3ef79..3eb5ca6061 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -7495,7 +7495,7 @@ \indextext{program!termination|(}% \indextext{object!destructor static}% \indextext{\idxcode{main} function!return from}% -Constructed objects\iref{dcl.init} +Constructed complete objects\iref{dcl.init} with static storage duration are destroyed and functions registered with \tcode{std::atexit} are called as part of a call to @@ -7509,13 +7509,29 @@ \end{note} \pnum -Constructed objects with thread storage duration within a given thread +Constructed complete objects with thread storage duration within a given thread are destroyed as a result of returning from the initial function of that thread and as a result of that thread calling \tcode{std::exit}. -The destruction of all constructed objects with thread storage -duration within that thread strongly happens before destroying +The destruction of those constructed objects +is sequenced before releasing the storage for +any object with thread storage duration within that thread\iref{basic.stc.thread}. +The destruction of those constructed objects +strongly happens before destroying any object with static storage duration. +\pnum +The destruction of a complete object with thread storage duration within a given thread +and having constant destruction\iref{expr.const} +is sequenced after the destruction of any other complete object +with thread storage duration within the thread. +The destruction of a complete object with static storage duration +and having constant destruction +is sequenced after the destruction of any other complete object +with static storage duration +and after any call to a function passed to \tcode{std::atexit}. +The sequencing rules in the remainder of this subclause +apply only to complete objects not having constant destruction. + \pnum If the completion of the constructor or dynamic initialization of an object with static storage duration strongly happens before that of another, the completion of the destructor From c46d6e735eb571b03150ea42a50a3a34f0814700 Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 12:38:14 +0100 Subject: [PATCH 06/46] CWG2941 Lifetime extension for function-style cast to reference type Fixes NB CA 041 (C++26 CD). --- source/basic.tex | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/source/basic.tex b/source/basic.tex index 3eb5ca6061..a824a93f17 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -4836,6 +4836,15 @@ to a glvalue that refers to the object designated by the operand, or to its complete object or a subobject thereof, +\item + an explicit type conversion (functional notation)\iref{expr.type.conv} + to a reference type whose initializer is a \grammarterm{braced-init-list} + where the reference is + \begin{itemize} + \item bound directly to the glvalue result of one of these expressions + (necessarily the sole element of the \grammarterm{braced-init-list}) or + \item bound to the result of a temporary materialization conversion, + \end{itemize} \item a conditional expression\iref{expr.cond} that is a glvalue where the second or third operand is one of these expressions, or From 560c6aa6e6b984bad956b547cd3c208ef618c141 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20K=C3=B6ppe?= Date: Sat, 13 Dec 2025 15:10:47 +0000 Subject: [PATCH 07/46] CWG3001 Inconsistent restrictions for static_cast on pointers to out-of-lifetime objects --- source/basic.tex | 12 ++---------- source/expressions.tex | 3 ++- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/source/basic.tex b/source/basic.tex index a824a93f17..48d8ac0760 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -3944,16 +3944,8 @@ the pointer is used to access a non-static data member or call a non-static member function of the object, or \item - the pointer is implicitly converted\iref{conv.ptr} to a pointer - to a virtual base class, or -\item - the pointer is used as the operand of a - \keyword{static_cast}\iref{expr.static.cast}, except when the conversion - is to pointer to \cv{}~\keyword{void}, or to pointer to \cv{}~\keyword{void} - and subsequently to pointer to - \cv{}~\keyword{char}, - \cv{}~\tcode{\keyword{unsigned} \keyword{char}}, or - \cv{}~\tcode{std::byte}\iref{cstddef.syn}, or + the pointer is converted\iref{conv.ptr,expr.static.cast} to a pointer + to a virtual base class or to a base class thereof, or \item the pointer is used as the operand of a \keyword{dynamic_cast}\iref{expr.dynamic.cast}. diff --git a/source/expressions.tex b/source/expressions.tex index f9b72d9e61..1309d8cfc2 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -1063,7 +1063,8 @@ If \tcode{v} is a null pointer value, the result is a null pointer value. Otherwise, -if \tcode{B} is a virtual base class of \tcode{D} and +if \tcode{B} is a virtual base class of \tcode{D} +or is a base class of a virtual base class of \tcode{D} and \tcode{v} does not point to an object whose type is similar\iref{conv.qual} to \tcode{D} and that is From bc34c21db1d0ad9d6e43ad71cd4247e6db01abcc Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 12:44:23 +0100 Subject: [PATCH 08/46] CWG3002 Template parameter/argument confusion --- source/templates.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/templates.tex b/source/templates.tex index 526a37b014..a4f4446043 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -6082,7 +6082,7 @@ A template argument is also dependent if it is a pack expansion. \pnum -A template template parameter is dependent if +A template template argument is dependent if it names a template parameter or its terminal name is dependent. From 2006116fc99043c8d28bf7104a01e4db87771b53 Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 12:48:25 +0100 Subject: [PATCH 09/46] CWG3004 Pointer arithmetic on array of unknown bound --- source/expressions.tex | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source/expressions.tex b/source/expressions.tex index 1309d8cfc2..91a107ea0d 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -8615,6 +8615,13 @@ \item a \keyword{reinterpret_cast}\iref{expr.reinterpret.cast}; +\item +pointer arithmetic\iref{expr.add} where +one (possibly converted) operand +points to the first element of an array of unknown bound and +the other (possibly converted) operand +is of integral type with non-zero value; + \item a modification of an object\iref{expr.assign,expr.post.incr,expr.pre.incr} unless it is applied to a non-volatile lvalue of literal type From f55bea98696bc7059f02aa2b8c997132f3b8d065 Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 12:53:19 +0100 Subject: [PATCH 10/46] CWG3008 Missing Annex C entry for void object declarations --- source/compatibility.tex | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/source/compatibility.tex b/source/compatibility.tex index 65f268e21b..f89950bdb4 100644 --- a/source/compatibility.tex +++ b/source/compatibility.tex @@ -3192,6 +3192,24 @@ \rSec2[diff.dcl]{\ref{dcl}: declarations} +\diffref{dcl.pre} +\change +In \Cpp{}, no declaration of a variable can have \cv{} \tcode{void} type. +In C, this is allowed, unless the declaration is a definition. +\begin{example} +\begin{codeblock} +extern void x; // valid C, invalid in \Cpp{} +\end{codeblock} +\end{example} +\rationale +Stricter type checking in \Cpp{}. +\effect +Deletion of semantically well-defined feature. +\difficulty +Syntactic transformation. +\howwide +Seldom. + \diffref{dcl.stc} \change In \Cpp{}, the \keyword{static} or \keyword{extern} specifiers can only be applied to names of objects or functions.\\ From b265dd32d58281e6324a0f996e94d7120669881b Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 13:01:21 +0100 Subject: [PATCH 11/46] CWG3011 Parenthesized aggregate initialization for new-expressions --- source/expressions.tex | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/source/expressions.tex b/source/expressions.tex index 91a107ea0d..70da493b4c 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -5954,7 +5954,8 @@ \impldef{maximum size of an allocated object} limit\iref{implimits}; or \item -the \grammarterm{new-initializer} is a \grammarterm{braced-init-list} and the +the \grammarterm{new-initializer} is a \grammarterm{braced-init-list} +or a parenthesized \grammarterm{expression-list} and the number of array elements for which initializers are provided (including the terminating \tcode{'\textbackslash 0'} in a \grammarterm{string-literal}\iref{lex.string}) exceeds the number of elements to initialize. @@ -5984,17 +5985,24 @@ \pnum If the allocated type is an array, -the \grammarterm{new-initializer} is a \grammarterm{braced-init-list}, and +the \grammarterm{new-initializer} is a \grammarterm{braced-init-list} +or a parenthesized \grammarterm{expression-list}, and the \grammarterm{expression} is potentially-evaluated and not a core constant expression, -the semantic constraints of copy-initializing a hypothetical element of -the array from an empty initializer list -are checked\iref{dcl.init.list}. +the semantic constraints of initializing a hypothetical element of +the array are checked as follows: +\begin{itemize} +\item +If the \grammarterm{new-initializer} is a \grammarterm{braced-init-list}, +the hypothetical element is copy-initialized +from an empty initializer list\iref{dcl.init.list}. +\item +Otherwise, the hypothetical element is value-initialized\iref{dcl.init.general}. +\end{itemize} \begin{note} The array can contain more elements than there are -elements in the \grammarterm{braced-init-list}, -requiring initialization of the remainder of the array elements from -an empty initializer list. +elements in the \grammarterm{new-initializer}, +requiring initialization of the remainder of the array elements as appropriate. \end{note} \pnum From 45b325b10bdd5091a6bc1a82b51555a9747cd0d0 Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 13:11:12 +0100 Subject: [PATCH 12/46] CWG3032 Template argument disambiguation Fixes NB CA 092 (C++26 CD). --- source/templates.tex | 40 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/source/templates.tex b/source/templates.tex index a4f4446043..b25336cc50 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -715,13 +715,18 @@ \begin{bnf} \nontermdef{template-argument}\br + template-argument-name\br constant-expression\br type-id\br - \opt{nested-name-specifier} template-name\br - nested-name-specifier \terminal{template} template-name\br braced-init-list \end{bnf} +\begin{bnf} +\nontermdef{template-argument-name}\br + \opt{nested-name-specifier} identifier\br + nested-name-specifier \terminal{template} identifier +\end{bnf} + \pnum \indextext{component name}% The component name of a @@ -889,6 +894,11 @@ \end{codeblock} \end{example} +\pnum +The component names of a \grammarterm{template-argument-name} are +those of its \grammarterm{nested-name-specifier} (if any) and +its \grammarterm{identifier}. + \pnum A \grammarterm{template-id} or \grammarterm{splice-specialization-specifier} is \defnx{valid}{\idxgram{template-id}!valid} if @@ -1052,6 +1062,32 @@ the $n^\text{th}$ template argument is a pack expansion whose pattern is the name of the template parameter pack. +\pnum +If a \grammarterm{template-argument} $A$ +matches the form \grammarterm{template-argument-name}, +it is interpreted as such; +the \grammarterm{identifier} is looked up +and its meaning is determined as follows: +\begin{itemize} +\item +If lookup finds an injected-class-name\iref{temp.local}, then: +\begin{itemize} +\item +When $A$ is for a type template template parameter, +$A$ denotes the corresponding class template. +\item +Otherwise, it denotes a \grammarterm{type-name}. +\end{itemize} +\item +Otherwise, if lookup finds a template, +$A$ denotes that template. +\item +Otherwise, if lookup finds a type alias or a type, +$A$ denotes the underlying type and is interpreted as a \grammarterm{type-id}. +\item +Otherwise, $A$ is interpreted as an expression. +\end{itemize} + \pnum In a \grammarterm{template-argument}, From e1e198f4afc5a41ad444b90fca0d816a8b1cfb90 Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 13:19:32 +0100 Subject: [PATCH 13/46] CWG3055 Misleading body for surrogate call function --- source/overloading.tex | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/overloading.tex b/source/overloading.tex index 2340f35644..329cbc8312 100644 --- a/source/overloading.tex +++ b/source/overloading.tex @@ -602,12 +602,16 @@ ``reference to function of ($\tcode{P}_1, \dotsc, \tcode{P}_n$) returning \tcode{R}'', a \defn{surrogate call function} with the unique name \placeholder{call-function} -and having the form +and having a declaration of the form \begin{ncbnf} \terminal{R} \placeholder{call-function} \terminal{(} conversion-type-id \ % -\terminal{F, P$_1$ a$_1$, $\dotsc$, P$_n$ a$_n$)} \terminal{\{} \keyword{return} \terminal{F (a$_1$, $\dotsc$, a$_n$); \}} +\terminal{F, P$_1$ a$_1$, $\dotsc$, P$_n$ a$_n$);} \end{ncbnf} is also considered as a candidate function. +\begin{note} +If a surrogate call function is selected by overload resolution, +the behavior is as described in~\ref{over.call}. +\end{note} Similarly, surrogate call functions are added to the set of candidate functions for each non-explicit conversion function declared in a base class of From 7a1e977f1b212cf949f42eb27b9b061a82078df9 Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 13:20:38 +0100 Subject: [PATCH 14/46] CWG3056 Missing semicolons in grammar for type-requirement --- source/expressions.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/expressions.tex b/source/expressions.tex index 70da493b4c..15ed9445a1 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -3355,8 +3355,8 @@ \begin{bnf} \nontermdef{type-requirement}\br \keyword{typename} \opt{nested-name-specifier} type-name \terminal{;}\br - \keyword{typename} splice-specifier\br - \keyword{typename} splice-specialization-specifier + \keyword{typename} splice-specifier \terminal{;}\br + \keyword{typename} splice-specialization-specifier \terminal{;} \end{bnf} \pnum From 81ed76bc4ccdf21661669d50469feb540c90e05d Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 13:23:57 +0100 Subject: [PATCH 15/46] CWG3057 Ranking of derived-to-base conversions should ignore reference binding --- source/overloading.tex | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/source/overloading.tex b/source/overloading.tex index 329cbc8312..f0aa5b1778 100644 --- a/source/overloading.tex +++ b/source/overloading.tex @@ -2401,10 +2401,10 @@ 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, +If the argument expression has a type \tcode{D} that +is a derived class of \tcode{T}, the implicit conversion sequence is a derived-to-base -conversion\iref{over.best.ics}. +conversion from \tcode{D} to \tcode{T}\iref{over.best.ics}. \item Otherwise, @@ -3083,15 +3083,6 @@ \end{codeblock} \end{example} -\item -binding of an expression of type -\tcode{C} -to a reference to type -\tcode{B} -is better than binding an expression of type -\tcode{C} -to a reference to type -\tcode{A}, \item conversion of \tcode{A::*} @@ -3120,16 +3111,6 @@ to \tcode{A*}, \item -binding of an expression of type -\tcode{B} -to a reference to type -\tcode{A} -is better than binding an expression of type -\tcode{C} -to a -reference to type -\tcode{A}, -\item conversion of \tcode{B::*} to From a6489fbb3d6c684fc518f8210b0624ae0f063436 Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 13:26:15 +0100 Subject: [PATCH 16/46] CWG3059 throw; in constant expressions --- source/expressions.tex | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source/expressions.tex b/source/expressions.tex index 15ed9445a1..1c68a56a57 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -8688,6 +8688,11 @@ \tcode{std::current_exception} or \tcode{std::rethrow_exception}\iref{propagation} are destroyed within the evaluation of $E$; +\item +a \grammarterm{throw-expression}\iref{expr.throw} with no operand, +unless there is a currently handled exception +whose exception object was constructed within the evaluation of $E$; + \item an \grammarterm{await-expression}\iref{expr.await}; From abfffd14047743ad32d5bf636d781ef2226b8eca Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 13:29:35 +0100 Subject: [PATCH 17/46] CWG3060 Change in behavior for noexcept main --- source/basic.tex | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/source/basic.tex b/source/basic.tex index 48d8ac0760..394fca9040 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -7177,8 +7177,13 @@ \indextext{\idxcode{main} function!implementation-defined parameters to}% An implementation shall allow both \begin{itemize} -\item a function of \tcode{()} returning \keyword{int} and -\item a function of \tcode{(\keyword{int}}, pointer to pointer to \tcode{\keyword{char})} returning \keyword{int} +\item +an ``optionally \tcode{noexcept} function of +\tcode{()} returning \keyword{int}'' and +\item +an ``optionally \tcode{noexcept} function of +\tcode{(\keyword{int}}, pointer to pointer to \tcode{\keyword{char})} +returning \keyword{int}'' \end{itemize} \indextext{\idxcode{argc}}% \indextext{\idxcode{argv}}% From f5b56ae93c71a9d106ba2a6983c03fdb7753079d Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 13:54:57 +0100 Subject: [PATCH 18/46] CWG3062 Overlapping specification of default template arguments --- source/declarations.tex | 17 ++++++----------- source/templates.tex | 5 ++--- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/source/declarations.tex b/source/declarations.tex index b6555fac46..64de1a8496 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -4264,10 +4264,10 @@ \indextext{declaration!default argument|(} \pnum -If an \grammarterm{initializer-clause}{} is specified in a -\grammarterm{parameter-declaration}{} this -\grammarterm{initializer-clause}{} -is used as a default argument. +If an \grammarterm{initializer-clause} is specified in a +\grammarterm{parameter-declaration} that is not a +\grammarterm{template-parameter}\iref{temp.param}, +this \grammarterm{initializer-clause} is used as a default argument. \begin{note} Default arguments will be used in calls where trailing arguments are missing\iref{expr.call}. @@ -4298,15 +4298,10 @@ A default argument shall be specified only in the \grammarterm{parameter-declaration-clause} of a function declaration -or \grammarterm{lambda-declarator} -or in a -\grammarterm{template-parameter}\iref{temp.param}. +or \grammarterm{lambda-declarator}. A default argument shall not be specified for -a template parameter pack or a function parameter pack. -If it is specified in a -\grammarterm{parameter-declaration-clause}, -it shall not occur within a +A default argument shall not occur within a \grammarterm{declarator} or \grammarterm{abstract-declarator} diff --git a/source/templates.tex b/source/templates.tex index b25336cc50..e33a10e81d 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -572,9 +572,8 @@ A \defnadj{default}{template argument} is a template argument\iref{temp.arg} specified after \tcode{=} in a \grammarterm{template-parameter}. -A default template argument may be specified for -any kind of template parameter -that is not a template parameter pack\iref{temp.variadic}. +A default template argument shall not be specified for +a template parameter pack\iref{temp.variadic}. A default template argument may be specified in a template declaration. A default template argument shall not be specified in the \grammarterm{template-parameter-list}{s} From 16201fa982a359f6ab35101e9bb9f8bdb42e447f Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 13:57:28 +0100 Subject: [PATCH 19/46] CWG3066 Declarative nested-name-specifier in explicit instantiation --- source/expressions.tex | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/source/expressions.tex b/source/expressions.tex index 1c68a56a57..c14c85987a 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -1878,12 +1878,16 @@ A \grammarterm{nested-name-specifier} is \defn{declarative} if it is part of \begin{itemize} \item -a \grammarterm{class-head-name}, +a \grammarterm{class-head-name}\iref{class.pre}, \item -an \grammarterm{enum-head-name}, +an \grammarterm{enum-head-name}\iref{dcl.enum}, \item a \grammarterm{qualified-id} -that is the \grammarterm{id-expression} of a \grammarterm{declarator-id}, or +that is the \grammarterm{id-expression} +of a \grammarterm{declarator-id}\iref{dcl.decl.general}, +\item +an \grammarterm{elaborated-type-specifier} +of an explicit instantiation\iref{temp.explicit}, or \item a declarative \grammarterm{nested-name-specifier}. \end{itemize} From a7d160199aacaffbcc3e9b6b12a53e235597404b Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 14:00:06 +0100 Subject: [PATCH 20/46] CWG3067 Array-to-pointer conversion with object type mismatch --- source/expressions.tex | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/source/expressions.tex b/source/expressions.tex index c14c85987a..64062583ef 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -714,11 +714,15 @@ \indextext{conversion!array-to-pointer}% \indextext{decay!array|see{conversion, array-to-pointer}}% \indextext{decay!function|see{conversion, function-to-pointer}}% -An lvalue or rvalue of type ``array of \tcode{N} \tcode{T}'' or ``array +An expression $E$ of type ``array of \tcode{N} \tcode{T}'' or ``array of unknown bound of \tcode{T}'' can be converted to a prvalue of type ``pointer to \tcode{T}''. -The temporary materialization conversion\iref{conv.rval} is applied. -The result is a pointer to the first element of the array. +If $E$ is a prvalue, +the temporary materialization conversion\iref{conv.rval} is applied. +If the result of $E$ (possibly converted) is an object +whose type is similar to the type of $E$, +the result is a pointer to the first element of the array; +otherwise, the behavior is undefined. \rSec2[conv.func]{Function-to-pointer conversion} From 77b9c7faf3dd9aaff069b0ccf01e9a76217c5a6f Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 14:03:16 +0100 Subject: [PATCH 21/46] CWG3070 Trivial assignment can skip member subobjects --- source/classes.tex | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/classes.tex b/source/classes.tex index 6f1e64c940..4940b5acfd 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -1704,7 +1704,8 @@ and no virtual base classes\iref{class.mi}, and \item -the constructor selected to copy/move each direct base class subobject is trivial, and +the constructor selected to copy/move each direct base class subobject +is a direct member of that base class and is trivial, and \item for each non-static data member of @@ -1986,7 +1987,7 @@ and no virtual base classes\iref{class.mi}, and \item the assignment operator selected to copy/move each direct -base class subobject is trivial, and +base class subobject is a direct member of that base class and is trivial, and \item for each non-static data member of From 3c11d7e7f3cc2b9329af8948c58b66f5f701a4fa Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 14:04:53 +0100 Subject: [PATCH 22/46] CWG3071 Negative tuple_size in structured bindings --- source/declarations.tex | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source/declarations.tex b/source/declarations.tex index 64de1a8496..0e0deb0c10 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -7710,9 +7710,8 @@ names a complete class type with a member named \tcode{value}, the expression \tcode{std::tuple_size::value} shall be a well-formed integral constant expression -and -the structured binding size of \tcode{E} is equal to the value of that -expression. +whose value is non-negative; +the structured binding size of \tcode{E} is equal to that value. Let \tcode{i} be an index prvalue of type \tcode{std::size_t} corresponding to $\tcode{v}_i$. If a search for the name \tcode{get} From 41c5c55cb0c5fbff6cd2866f87c293fe3637f3ac Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 14:06:41 +0100 Subject: [PATCH 23/46] CWG3072 Incorrect examples for lambda SFINAE --- source/templates.tex | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/templates.tex b/source/templates.tex index e33a10e81d..4a9996c568 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -8032,17 +8032,17 @@ template auto h(T) -> decltype([x = T::invalid]() { }); void h(...); -h(0); // error: invalid expression not part of the immediate context +h(0); // OK, calls \tcode{h(...)} template auto i(T) -> decltype([]() -> typename T::invalid { }); void i(...); -i(0); // error: invalid expression not part of the immediate context +i(0); // OK, calls \tcode{i(...)} template - auto j(T t) -> decltype([](auto x) -> decltype(x.invalid) { } (t)); // \#1 -void j(...); // \#2 -j(0); // deduction fails on \#1, calls \#2 + auto j(T t) -> decltype([](auto x) -> decltype(x.invalid) { } (t)); +void j(...); +j(0); // OK, calls \tcode{j(...)} \end{codeblock} \end{example} \end{note} From 68c66352f186956cf9dfa94c272608cc249788a3 Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 14:11:34 +0100 Subject: [PATCH 24/46] CWG3073 Dependence of R on T2 is unclear --- source/overloading.tex | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/source/overloading.tex b/source/overloading.tex index f0aa5b1778..6e571586cd 100644 --- a/source/overloading.tex +++ b/source/overloading.tex @@ -1160,23 +1160,23 @@ the candidate functions are selected as follows: \begin{itemize} \item -Let $R$ be a set of types including +Let $R$ be the set of all \begin{itemize} \item -``lvalue reference to \cvqual{cv2} \tcode{T2}'' +lvalue reference types (when converting to an lvalue) and \item -``\cvqual{cv2} \tcode{T2}'' -and ``rvalue reference to \cvqual{cv2} \tcode{T2}'' -(when converting to an rvalue or an lvalue of function type) +non-reference types and rvalue reference types +(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 the members of $R$ +having the form ``\cv{}~\tcode{T2}'' or ``reference to \cvqual{cv2}~\tcode{T2}'' where ``\cvqual{cv1} \tcode{T}'' is reference-compatible\iref{dcl.init.ref} with ``\cvqual{cv2} \tcode{T2}''. For direct-initialization, the permissible types for explicit conversion functions are the members of $R$ +having the form ``\cv{}~\tcode{T2}'' or ``reference to \cvqual{cv2}~\tcode{T2}'' where \tcode{T2} can be converted to type \tcode{T} with a (possibly trivial) qualification conversion\iref{conv.qual}; otherwise there are none. From 3243d8e7de9dee9d9184a6cade1b36988e50274d Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 14:13:56 +0100 Subject: [PATCH 25/46] CWG3075 Unclear matching of import directive --- source/preprocessor.tex | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/source/preprocessor.tex b/source/preprocessor.tex index 240a4b7fd1..bcfb932ff0 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -1305,9 +1305,10 @@ first two forms of \grammarterm{pp-import} is immediately after the \grammarterm{new-line} terminating the \grammarterm{pp-import}. -The last form of \grammarterm{pp-import} is only considered -if the first two forms did not match, and -does not have a point of macro import. +The last form of \grammarterm{pp-import} +does not have a point of macro import, and +is only considered if, after macro replacement, +the first two forms did not match. \pnum If a \grammarterm{pp-import} is produced by source file inclusion From 4fc39031cc4fd12bf997f6218d3d666fdb07d095 Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 14:19:43 +0100 Subject: [PATCH 26/46] CWG3076 Remove unnecessary IFNDR for malformed header-name-tokens --- source/lex.tex | 7 ++++++- source/preprocessor.tex | 3 +++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/source/lex.tex b/source/lex.tex index 289bbaf073..a48f5433c7 100644 --- a/source/lex.tex +++ b/source/lex.tex @@ -1795,10 +1795,15 @@ \indextext{literal!string}% \begin{bnf} \nontermdef{string-literal}\br - \opt{encoding-prefix} \terminal{"} \opt{s-char-sequence} \terminal{"}\br + \opt{encoding-prefix} plain-string-literal\br \opt{encoding-prefix} \terminal{R} raw-string \end{bnf} +\begin{bnf} +\nontermdef{plain-string-literal}\br + \terminal{"} \opt{s-char-sequence} \terminal{"} +\end{bnf} + \begin{bnf} \nontermdef{s-char-sequence}\br s-char \opt{s-char-sequence} diff --git a/source/preprocessor.tex b/source/preprocessor.tex index bcfb932ff0..712c333113 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -757,6 +757,9 @@ in the directive are processed just as in normal text (i.e., each identifier currently defined as a macro name is replaced by its replacement list of preprocessing tokens). +After replacement, +if the first preprocessing token is a \grammarterm{string-literal}, +it shall be a \grammarterm{plain-string-literal}. Then, an attempt is made to form a \grammarterm{header-name} preprocessing token\iref{lex.header} from the whitespace and the characters of the spellings of the resulting sequence of preprocessing tokens; From a4bc63f27883fbdc57f8ade5a886e404675017a5 Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 14:20:58 +0100 Subject: [PATCH 27/46] CWG3077 Undesirable formation of import directive with string-literal --- source/preprocessor.tex | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/preprocessor.tex b/source/preprocessor.tex index 712c333113..2427067a52 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -204,8 +204,7 @@ immediately followed on the same logical source line by a \grammarterm{header-name}, \tcode{<}, -\grammarterm{identifier}, -\grammarterm{string-literal}, or +\grammarterm{identifier}, or \tcode{:} preprocessing token, or From 3140e5f668e341d72ed926b6b3a50d8e48b20d8a Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 14:25:37 +0100 Subject: [PATCH 28/46] CWG3078 Different treatment of #include pp-tokens and header-name-tokens --- source/lex.tex | 10 +++++----- source/preprocessor.tex | 13 +++++++------ 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/source/lex.tex b/source/lex.tex index a48f5433c7..4330268461 100644 --- a/source/lex.tex +++ b/source/lex.tex @@ -831,11 +831,11 @@ \pnum In all respects of the language, each alternative token behaves the same, respectively, as its primary token, except for its spelling. -\begin{footnote} -Thus the ``stringized'' values\iref{cpp.stringize} of -\tcode{[} and \tcode{<:} will be different, maintaining the source -spelling, but the tokens can otherwise be freely interchanged. -\end{footnote} +\begin{note} +The ``stringized'' values\iref{cpp.stringize} of +\tcode{[} and \tcode{<:} are different, +maintaining the source spelling. +\end{note} The set of alternative tokens is defined in \tref{lex.digraph}. diff --git a/source/preprocessor.tex b/source/preprocessor.tex index 2427067a52..a9f09027aa 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -353,7 +353,7 @@ \begin{bnf} \nontermdef{header-name-tokens}\br - string-literal\br + plain-string-literal\br \terminal{<} h-pp-tokens \terminal{>} \end{bnf} @@ -756,12 +756,13 @@ in the directive are processed just as in normal text (i.e., each identifier currently defined as a macro name is replaced by its replacement list of preprocessing tokens). -After replacement, -if the first preprocessing token is a \grammarterm{string-literal}, -it shall be a \grammarterm{plain-string-literal}. -Then, an attempt is made to form a \grammarterm{header-name} +The resulting sequence of preprocessing tokens shall be of the form +\begin{ncsimplebnf} +header-name-tokens +\end{ncsimplebnf} +An attempt is then made to form a \grammarterm{header-name} preprocessing token\iref{lex.header} from the whitespace and the characters -of the spellings of the resulting sequence of preprocessing tokens; +of the spellings of the \grammarterm{header-name-tokens}; the treatment of whitespace is \impldef{treatment of whitespace when processing a \tcode{\#include} directive}. If the attempt succeeds, the directive with the so-formed \grammarterm{header-name} From 5b61c71ed3875c27507064f37e77a7f8232aceb9 Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 14:26:58 +0100 Subject: [PATCH 29/46] CWG3079 Allow empty-declarations in anonymous unions --- source/classes.tex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/classes.tex b/source/classes.tex index 4940b5acfd..f19d1da01d 100644 --- a/source/classes.tex +++ b/source/classes.tex @@ -3357,7 +3357,8 @@ \indextext{access control!anonymous \tcode{union}}% \indextext{restriction!anonymous \tcode{union}}% Each \grammarterm{member-declaration} in the \grammarterm{member-specification} -of an anonymous union shall either define one or more public non-static data members or +of an anonymous union shall define one or more public non-static data members, +be an \grammarterm{empty-declaration}, or be a \grammarterm{static_assert-declaration}. Nested types, anonymous unions, and functions shall not be declared within an anonymous union. From ae227c765b42304593dff419a2077a1e112f958d Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 14:29:37 +0100 Subject: [PATCH 30/46] CWG3080 Clarify kinds of permitted template template arguments --- source/templates.tex | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/source/templates.tex b/source/templates.tex index 4a9996c568..a6c909e6a9 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -1465,11 +1465,14 @@ template parameter shall be the name of a template. For a \grammarterm{type-tt-parameter}, -the name shall denote a class template or alias template. +the name shall denote a class template, alias template, or +type template template parameter. For a \grammarterm{variable-tt-parameter}, -the name shall denote a variable template. +the name shall denote a variable template or +variable template template parameter. For a \grammarterm{concept-tt-parameter}, -the name shall denote a concept. +the name shall denote a concept or +concept template parameter. Only primary templates are considered when matching the template template argument with the corresponding parameter; partial specializations are not considered even if their parameter lists match that of the template template From 73dcbe247123194e48283385ef1d6c4be702467b Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 14:33:01 +0100 Subject: [PATCH 31/46] CWG3081 Require glvalue when splicing direct base class relationship Fixes NB US 29-062 (C++26 CD). --- source/basic.tex | 4 +++- source/expressions.tex | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/source/basic.tex b/source/basic.tex index 394fca9040..5ecef1c768 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -4810,7 +4810,9 @@ \item a class member access\iref{expr.ref} using the \tcode{.} operator where the left operand is one of these expressions and - the right operand designates a non-static data member of non-reference type, + the right operand designates + a non-static data member\iref{class.mem.general} of non-reference type or + a direct base class relationship\iref{class.derived.general}, \item a pointer-to-member operation\iref{expr.mptr.oper} using the \tcode{.*} operator where the left operand is one of these expressions and diff --git a/source/expressions.tex b/source/expressions.tex index 64062583ef..231ca32e0d 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -4173,7 +4173,9 @@ For a dot that is followed by an expression that designates a static member or an enumerator, the first expression is a discarded-value expression\iref{expr.context}; -if the expression after the dot designates a non-static data member, +if the expression after the dot designates a +non-static data member\iref{class.mem.general} or +a direct base class relationship\iref{class.derived.general}, the first expression shall be a glvalue. A postfix expression that is followed by an arrow shall be a prvalue having pointer type. From c41620c489ad84e09488d9611793492c2d99725d Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 15:20:01 +0100 Subject: [PATCH 32/46] CWG3083 Remove redundant restrictions on class and enum definitions Fixes NB US 35-066 (C++26 CD). --- source/statements.tex | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/statements.tex b/source/statements.tex index 34018bd618..adfe291adc 100644 --- a/source/statements.tex +++ b/source/statements.tex @@ -154,8 +154,6 @@ each \grammarterm{decl-specifier} shall be either a \grammarterm{type-specifier} or \keyword{constexpr}. -The \grammarterm{decl-specifier-seq} of a \grammarterm{for-range-declaration} -shall not define a class or enumeration. \rSec1[stmt.label]{Label}% \indextext{statement!labeled} From fb6d393822a3a31fc76a290a8384528a4bc6ecdb Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 15:21:35 +0100 Subject: [PATCH 33/46] CWG3085 Apply restriction inside for-range-declaration Fixes NB US 34-067 (C++26 CD). --- source/statements.tex | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/source/statements.tex b/source/statements.tex index adfe291adc..ad36a30051 100644 --- a/source/statements.tex +++ b/source/statements.tex @@ -147,10 +147,9 @@ it is interpreted as the latter. \pnum -In the \grammarterm{decl-specifier-seq} of a \grammarterm{condition} -or of a \grammarterm{for-range-declaration}, -including that of any \grammarterm{structured-binding-declaration} of -the \grammarterm{condition}, +Let $D$ be any \grammarterm{condition} or \grammarterm{for-range-declaration}. +In the \grammarterm{decl-specifier-seq} of $D$, +including that of any \grammarterm{structured-binding-declaration} of $D$, each \grammarterm{decl-specifier} shall be either a \grammarterm{type-specifier} or \keyword{constexpr}. From 5850cd597ea6f66d04c2643cae5e4524f1dc44ea Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 15:24:04 +0100 Subject: [PATCH 34/46] CWG3086 Destringizing should consider all sorts of encoding-prefixes Fixes NB US 60-110 (C++26 CD). --- source/preprocessor.tex | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/preprocessor.tex b/source/preprocessor.tex index a9f09027aa..bf72a88706 100644 --- a/source/preprocessor.tex +++ b/source/preprocessor.tex @@ -2481,12 +2481,12 @@ \indextext{operator!pragma|see{macro, pragma operator}} \pnum -A unary operator expression of the form: +A unary operator expression of the form \begin{ncbnf} \terminal{_Pragma} \terminal{(} string-literal \terminal{)} \end{ncbnf} is processed as follows: The \grammarterm{string-literal} is \defnx{destringized}{destringization} -by deleting the \tcode{L} prefix, if present, deleting the leading and trailing +by deleting any \grammarterm{encoding-prefix}, deleting the leading and trailing double-quotes, replacing each escape sequence \tcode{\textbackslash"} by a double-quote, and replacing each escape sequence \tcode{\textbackslash\textbackslash} by a single backslash. The resulting sequence of characters is processed through translation phase 3 From 2c581e92bdc9ccc9fc11f2d3ea0235a4d0e1e7e8 Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 15:25:52 +0100 Subject: [PATCH 35/46] CWG3090 Internal linkage from header units Fixes NB US 43-080 (C++26 CD). --- source/modules.tex | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/modules.tex b/source/modules.tex index 90c0d8bc16..551e1ecc62 100644 --- a/source/modules.tex +++ b/source/modules.tex @@ -334,8 +334,9 @@ \pnum \begin{note} -Names introduced by exported declarations -have either external linkage or no linkage; see \ref{basic.link}. +Names introduced by exported declarations never have module linkage. +They have external linkage, no linkage, or +(in the case of header units) internal linkage; see \ref{basic.link}. Namespace-scope declarations exported by a module can be found by name lookup in any translation unit importing that module\iref{basic.lookup}. Class and enumeration member names can be found by name lookup in any From aa9f28528fc813055e0819073dda6a3fb9feb7ff Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 15:28:36 +0100 Subject: [PATCH 36/46] CWG3091 Linking of translation units as sequences of tokens Fixes NB US 15-032 (C++26 CD). --- source/basic.tex | 4 ++-- source/lex.tex | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/basic.tex b/source/basic.tex index 5ecef1c768..d93a18fed8 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -2887,8 +2887,8 @@ \indextext{program}% \indextext{linking}% A \defn{program} consists of one or more translation units\iref{lex.phases} -linked together. A translation unit consists -of a sequence of declarations. +that are translated and linked together. +A translation unit consists of a sequence of declarations. \begin{bnf} \nontermdef{translation-unit}\br diff --git a/source/lex.tex b/source/lex.tex index 4330268461..17e3cd61b1 100644 --- a/source/lex.tex +++ b/source/lex.tex @@ -283,7 +283,7 @@ \item \indextext{linking}% Translated translation units are combined, and -all external entity references are resolved. Library +all external entity references are resolved\iref{basic.link}. Library components are linked to satisfy external references to entities not defined in the current translation. All such translator output is collected into a program image which contains information From 19684185a7d5c7366a10778a67a95d33e14d4cdf Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 15:29:59 +0100 Subject: [PATCH 37/46] CWG3096 Value-dependence of size of structured binding pack with non-dependent initializer Fixes NB AT 4-099 (C++26 CD). --- source/templates.tex | 2 -- 1 file changed, 2 deletions(-) diff --git a/source/templates.tex b/source/templates.tex index a6c909e6a9..ae4f80757e 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -5975,8 +5975,6 @@ \keyword{sizeof} \terminal{...} \terminal{(} identifier \terminal{)}\br fold-expression \end{ncsimplebnf} -unless the \grammarterm{identifier} is a structured binding pack -whose initializer is not dependent. \pnum A \grammarterm{noexcept-expression}\iref{expr.unary.noexcept} From dc9b1357113205133a6f6af5368e7cb46d060939 Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 15:31:08 +0100 Subject: [PATCH 38/46] CWG3097 Lambda expression introduces a scope Fixes NB AT 4-099 (C++26 CD). --- source/basic.tex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/basic.tex b/source/basic.tex index d93a18fed8..320c2d6247 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -954,7 +954,8 @@ declaration, \grammarterm{parameter-declaration-clause}, \grammarterm{statement}, -\grammarterm{handler}, or +\grammarterm{handler}, +\grammarterm{lambda-expression}, or contract assertion (as described in the following subclauses of \ref{basic.scope}) appearing in another scope, which thereby contains $S$. From 441eeba08bb56e7396ea3ae8e9a5ddcb47e26951 Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 15:44:07 +0100 Subject: [PATCH 39/46] CWG3100 Destruction order for objects with static storage duration Fixes NB CA 045 (C++26 CD). --- source/basic.tex | 53 ++++++++++++++++++++++++++++++----------- source/declarations.tex | 9 +++++-- 2 files changed, 46 insertions(+), 16 deletions(-) diff --git a/source/basic.tex b/source/basic.tex index 320c2d6247..52573f69c1 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -7542,21 +7542,45 @@ apply only to complete objects not having constant destruction. \pnum -If the completion of the constructor or dynamic initialization of an object with static -storage duration strongly happens before that of another, the completion of the destructor -of the second is sequenced before the initiation of the destructor of the first. -If the completion of the constructor or dynamic initialization of an object with thread -storage duration is sequenced before that of another, the completion of the destructor -of the second is sequenced before the initiation of the destructor of the first. +If the deemed construction\iref{dcl.init.general} of a complete object with static +storage duration strongly happens before that of another, the completion of the destruction +of the second is sequenced before the initiation of the destruction of the first. +If the deemed construction of a complete object with thread +storage duration is sequenced before that of another, the completion of the destruction +of the second is sequenced before the initiation of the destruction of the first. If an object is initialized statically, the object is destroyed in the same order as if -the object was dynamically initialized. For an object of array or class -type, all subobjects of that object are destroyed before any block -variable with static storage duration initialized during the construction -of the subobjects is destroyed. +the object was dynamically initialized. If the destruction of an object with static or thread storage duration exits via an exception, the function \tcode{std::terminate} is called\iref{except.terminate}. +\begin{example} +In the following program, +the elements of \tcode{a} are destroyed, +followed by \tcode{dt}, and +finally by the two \tcode{Btemp} objects: +\begin{codeblock} +struct DTemp { ~DTemp(); }; +struct Temp { + ~Temp() { + static DTemp dt; + } +}; +struct BTemp { + ~BTemp(); +}; +struct A { + const BTemp &tb; + ~A(); +}; +A a[] = { (Temp(), BTemp()), BTemp() }; + +int main() {} +\end{codeblock} +If the array \tcode{a} were an object with automatic storage duration, +the \tcode{Btemp} temporaries would be destroyed +as each element of the array is destroyed\iref{class.temporary}. +\end{example} \pnum If a function contains a block variable of static or thread storage duration that has been @@ -7572,12 +7596,13 @@ \pnum \indextext{\idxcode{atexit}}% \indexlibraryglobal{atexit}% -If the completion of the initialization of an object with static storage +If the deemed construction of a complete object with static storage duration strongly happens before a call to \tcode{std::atexit}~(see \libheader{cstdlib}, \ref{support.start.term}), the call to the function passed to -\tcode{std::atexit} is sequenced before the call to the destructor for the object. If a -call to \tcode{std::atexit} strongly happens before the completion of the initialization of -an object with static storage duration, the call to the destructor for the +\tcode{std::atexit} is sequenced before the initiation of the destruction of the object. +If a call to \tcode{std::atexit} strongly happens before the deemed construction of +a complete object with static storage duration, +the completion of the destruction of the object is sequenced before the call to the function passed to \tcode{std::atexit}. If a call to \tcode{std::atexit} strongly happens before another call to \tcode{std::atexit}, the call to the function passed to the second \tcode{std::atexit} call is sequenced before diff --git a/source/declarations.tex b/source/declarations.tex index 0e0deb0c10..c0747f03b4 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -5437,8 +5437,13 @@ \grammarterm{designated-initializer-list}. \pnum -An object whose initialization has completed -is deemed to be constructed, +The \defnadj{deemed}{construction} of an object occurs when +its initialization completes; +for the purposes of~\ref{basic.start.term}, +if the initialization is a full-expression, +deemed construction occurs when +the evaluation of that full-expression completes. +The object is deemed to be constructed, even if the object is of non-class type or no constructor of the object's class is invoked for the initialization. From fa5bfc7e67fbf42b3f2c69e04ba08d3cb7372116 Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 15:47:55 +0100 Subject: [PATCH 40/46] CWG3102 Update list of void contexts Editorial note: * Changed "requires expression" to \grammarterm{requires-expression}. Only the latter form seems to be in use. --- source/basic.tex | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source/basic.tex b/source/basic.tex index 52573f69c1..f9f6c6cd27 100644 --- a/source/basic.tex +++ b/source/basic.tex @@ -5602,13 +5602,15 @@ is an incomplete type that cannot be completed; such a type has an empty set of values. It is used as the return type for functions that do not return a value. -An expression of type \cv{}~\keyword{void} shall -be used only as +\begin{note} +An expression of type \cv{}~\keyword{void} can be used as \begin{itemize} \item an expression statement\iref{stmt.expr}, \item the expression in a \keyword{return} statement\iref{stmt.return} for a function with the return type \cv{}~\keyword{void}, \item an operand of a comma expression\iref{expr.comma}, +\item the operand of a parenthesized expression\iref{expr.prim.paren}, +\item a requirement in a \grammarterm{requires-expression}\iref{expr.prim.req.general}, \item the second or third operand of \tcode{?:}\iref{expr.cond}, \item the operand of a \keyword{typeid} expression\iref{expr.typeid}, \item the operand of a \keyword{noexcept} operator\iref{expr.unary.noexcept}, @@ -5616,6 +5618,7 @@ \item the operand of an explicit conversion to type \cv{}~\keyword{void}\iref{expr.type.conv,expr.static.cast,expr.cast}. \end{itemize} +\end{note} \pnum The types denoted by \cv~\tcode{std::nullptr_t} are distinct types. From fa0e5639c991d9808bc85ae16fd8487a1ae8f278 Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 16:00:22 +0100 Subject: [PATCH 41/46] CWG3105 Consteval destructor through immediate escalation --- source/expressions.tex | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/source/expressions.tex b/source/expressions.tex index 231ca32e0d..a37db1639e 100644 --- a/source/expressions.tex +++ b/source/expressions.tex @@ -9173,7 +9173,8 @@ a defaulted special member function that is not declared with the \keyword{consteval} specifier, or \item -a function that results from the instantiation +a function that is not a prospective destructor and +that results from the instantiation of a templated entity defined with the \keyword{constexpr} specifier. \end{itemize} An immediate-escalating expression shall appear only From 0312df943d42dc259cbcdf94a55d5f9d0c8a8127 Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 16:01:55 +0100 Subject: [PATCH 42/46] CWG3106 Redundant exclusion of (non-existent) UCNs in r-char-sequences --- source/lex.tex | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/source/lex.tex b/source/lex.tex index 17e3cd61b1..eac2a4299c 100644 --- a/source/lex.tex +++ b/source/lex.tex @@ -468,9 +468,8 @@ The \grammarterm{universal-character-name} construct provides a way to name any element in the translation character set using just the basic character set. If a \grammarterm{universal-character-name} outside -the \grammarterm{c-char-sequence}, \grammarterm{s-char-sequence}, or -\grammarterm{r-char-sequence} of a \grammarterm{character-literal} or -\grammarterm{string-literal} +the \grammarterm{c-char-sequence} or \grammarterm{s-char-sequence} +of a \grammarterm{character-literal} or \grammarterm{string-literal} (in either case, including within a \grammarterm{user-defined-literal}) corresponds to a control character or to a character in the basic character set, the program is ill-formed. From 38008512fc3543e78b79dda400b96043d76d31ba Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 16:03:06 +0100 Subject: [PATCH 43/46] CWG3107 Misleading note "An alias template name is never deduced." --- source/templates.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/templates.tex b/source/templates.tex index ae4f80757e..0c35d898d9 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -4664,7 +4664,7 @@ that names a specialization of an alias template is a \grammarterm{typedef-name} for a type alias. \begin{note} -An alias template name is never deduced. +The alias template name is not deduced from such a type\iref{temp.deduct.type}. \end{note} \begin{example} \begin{codeblock} From a64ab84f2952f5c593c34bb41913dff5e994ac43 Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 16:10:09 +0100 Subject: [PATCH 44/46] CWG3111 Template parameter objects of array type --- source/meta.tex | 4 ++++ source/templates.tex | 14 ++++++++++---- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/source/meta.tex b/source/meta.tex index f0bd37f53d..01e0cf2df6 100644 --- a/source/meta.tex +++ b/source/meta.tex @@ -4124,6 +4124,10 @@ \begin{codeblock} if constexpr (is_annotation(@$R$@)) { return @$C$@; +} else if constexpr (is_array_type(type_of(@$R$@))) { + return reflect_constant_array([: @$R$@ :]); +} else if constexpr (is_function_type(type_of(@$R$@))) { + return reflect_function([: @$R$@ :]); } else { return reflect_constant([: @$R$@ :]); } diff --git a/source/templates.tex b/source/templates.tex index 0c35d898d9..ab322238a4 100644 --- a/source/templates.tex +++ b/source/templates.tex @@ -496,15 +496,21 @@ \end{itemize} \pnum +Certain constructs refer to template parameter objects, +which are distinct objects with static storage duration and non-volatile const type. +No two such objects have template-argument-equivalent values\iref{temp.type}. An \grammarterm{id-expression} naming a constant template parameter of class type \tcode{T} -denotes a static storage duration object of type \tcode{const T}, -known as a \defn{template parameter object}, -which is template-argument-equivalent\iref{temp.type} to +denotes the template parameter object of type \tcode{const T}, +which is template-argument-equivalent to the corresponding template argument after it has been converted to the type of the template parameter\iref{temp.arg.nontype}. -No two template parameter objects are template-argument-equivalent. +\begin{note} +There can be template parameter objects of array type\iref{meta.define.static}, +but such an object is never denoted by an \grammarterm{id-expression} +that names a constant template parameter. +\end{note} \begin{note} If an \grammarterm{id-expression} names a non-reference constant template parameter, From ee16c7fc37022671f859098d91fe4c742c21aa6e Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 16:13:15 +0100 Subject: [PATCH 45/46] CWG3112 Introduce a term for C-style variadic functions Fixes NB FR 155 (C++26 CD). --- source/declarations.tex | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/declarations.tex b/source/declarations.tex index c0747f03b4..0a1c007d57 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -3874,6 +3874,10 @@ \end{codeblock} \end{example} +\pnum +A function with a parameter-type-list that has an ellipsis +is termed a \defnadj{vararg}{function}. + \pnum An \defn{explicit-object-parameter-declaration} is a \grammarterm{parameter-declaration} with a \keyword{this} specifier. From 5bfe79076f094705c4b561aaf86f7a32c8e47cd9 Mon Sep 17 00:00:00 2001 From: Eisenwave Date: Sun, 9 Nov 2025 16:16:35 +0100 Subject: [PATCH 46/46] CWG3116 First element of an array --- source/declarations.tex | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/declarations.tex b/source/declarations.tex index 0a1c007d57..78c46e5f7d 100644 --- a/source/declarations.tex +++ b/source/declarations.tex @@ -3549,6 +3549,8 @@ of \tcode{N} subobjects of type \tcode{U}, known as the \defnx{elements}{array!element} of the array, and numbered \tcode{0} to \tcode{N-1}. +The element numbered \tcode{0} is termed +the \defnx{first element}{array!first element} of the array. \pnum In addition to declarations in which an incomplete object type is allowed,