<HTML>
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<TITLE>
    Core "ready" Issues
   </TITLE>
<STYLE TYPE="text/css">
  INS { text-decoration:none; font-weight:bold; background-color:#A0FFA0 }
  .INS { text-decoration:none; background-color:#D0FFD0 }
  DEL { text-decoration:line-through; background-color:#FFA0A0 }
  SPAN.cmnt { font-family:Times; font-style:italic }
</STYLE>
</HEAD>
<BODY>
<TABLE ALIGN="RIGHT" CELLSPACING="0" CELLPADDING="0">
<TR>
<TD ALIGN="RIGHT">
      Document number:
     </TD>
<TD>
       &#160;P2709R0</TD>
</TR>
<TR>
<TD ALIGN="RIGHT">
      Date:
     </TD>
<TD>
      &#160;2022-11-11</TD>
</TR>
<TR>
<TD ALIGN="RIGHT">
      Project:
     </TD>
<TD>
      &#160;Programming Language C++
     </TD>
</TR>
<TR>
<TD ALIGN="RIGHT">
      Reference:
     </TD>
<TD>
      &#160;ISO/IEC IS 14882:2020
     </TD>
</TR>
<TR>
<TD ALIGN="RIGHT">
      Reply to:
     </TD>
<TD>
      &#160;Jens Maurer
     </TD>
</TR>
<TR>
<TD></TD>
<TD>
      &#160;<A HREF="mailto://jens.maurer@gmx.net">jens.maurer@gmx.net</A>
</TD>
</TR>
</TABLE>
<BR CLEAR="ALL"><BR><CENTER><H2>
     Core Language Working Group "ready" Issues
     for the
     November, 2022 meeting
    </H2></CENTER>
<BR><P>
    References in this document reflect the section and paragraph
    numbering of document
    <A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/n4917.pdf">WG21 N4917</A>.
   </P>
<HR>
<A NAME="2392"></A><H4>2392.
  
<I>new-expression</I> size check and constant evaluation
</H4>
<B>Section: </B>7.7&#160; [<A href="https://wg21.link/expr.const">expr.const</A>]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>Tam S. B
 &#160;&#160;&#160;

 <B>Date: </B>2018-12-05


<P>According to 7.6.2.8 [<A href="https://wg21.link/expr.new#8">expr.new</A>] paragraph 8, if the
<I>expression</I> in a <I>noptr-new-declarator</I> is a core constant
expression, the program is ill-formed if the <I>expression</I> is
erroneous, e.g., negative. However, consider the following example:</P>

<PRE>
  template&lt;class T = void&gt; constexpr int f() { T t; return 1; }
  using _ = decltype(new int[f()]);
</PRE>

<P>
<TT>f()</TT> is a core constant expression, so it must be evaluated to
determine its value. However, because the expression appears in an
unevaluated operand, it is not &#8220;potentially constant evaluated&#8221;
and thus <TT>f</TT> is not &#8220;needed for constant evaluation&#8221;, so
the template is not instantiated (13.9.2 [<A href="https://wg21.link/temp.inst#7">temp.inst</A>] paragraph 7).
There is implementation divergence on the handling of this example.</P>

<P><B>CWG telecon 2022-09-09:</B></P>

<P>The example should be well-formed, because <TT>f</TT> is not
instantiated.</P>

<P>A similar situation arises for narrowing conversions, except that
in the latter case, determining the value at compile-time empowers to
allow additional cases, whereas the <I>new-expression</I> case uses a
compile-time value to prohibit additional cases.</P>

<P><B>Proposed resolution (approved by CWG 2022-09-23):</B></P>

<P>Change in 7.6.2.8 [<A href="https://wg21.link/expr.new#8">expr.new</A>] paragraph 8 as follows:</P>

<BLOCKQUOTE>

If the expression is erroneous after converting to <TT>std::size_t</TT>:
<UL>

<LI>if the expression is a <INS>potentially-evaluated</INS> core
constant expression, the program is ill-formed;</LI>

<LI>otherwise, an allocation function is not called; instead...</LI>

</UL>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2407"></A><H4>2407.
  
Missing entry in Annex C for defaulted comparison operators
</H4>
<B>Section: </B>Clause Annex C&#160; [<A href="https://wg21.link/diff">diff</A>]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>Tomasz Kaminski
 &#160;&#160;&#160;

 <B>Date: </B>2019-02-26




<P>The changes from
<A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1185r2.html">P1185R2</A>
need an entry in Annex C, because they affect the interpretation
of existing well-formed code. For example, given:</P>

<PRE>
  struct A {
    operator int() const { return 10; }
  };

  bool operator==(A, int); //<SPAN CLASS="cmnt"> #1</SPAN>
  //<SPAN CLASS="cmnt">built-in: </SPAN>bool operator==(int, int);<SPAN CLASS="cmnt"> // #2</SPAN>

  A a, b;
</PRE>

<P>The expression <TT>10 == a</TT> resolves to #2 in C++17
but now to #1. In addition, <TT>a == b</TT> is now ambiguous,
because #1 has a user-defined conversion on the second
argument, while the reversed order has it on the first
argument. Similarly for <TT>operator!=.</TT>
</P>

<P><B>Notes from the March, 2019 teleconference:</B></P>

<P>The ambiguity in <TT>10 == a</TT> arises from the consideration
of the reverse ordering of the operands.</P>

<P>CWG found this breakage surprising and asked for EWG's opinion
before updating Annex C.</P>

<P><B>Proposed resolution (April, 2019) [SUPERSEDED]</B></P>

<P>Add the following as a new subclause in C.2 [<A href="https://wg21.link/diff.cpp17">diff.cpp17</A>]:</P>

<BLOCKQUOTE>

<P><INS>C.5.6 Clause 12: Overloading</INS></P>

<P><INS>Affected subclause: 12.2.2.3 [<A href="https://wg21.link/over.match.oper">over.match.oper</A>]<BR>
Change: Overload resolution may change for equality operators
7.6.10 [<A href="https://wg21.link/expr.eq">expr.eq</A>].<BR>
Rationale: Support calling <TT>operator==</TT> with reversed order
of arguments.<BR>
Effect on original feature: Valid C++ 2017 code that uses
equality operators with conversion functions may be ill-formed
or have different semantics in this International Standard.</INS></P>

<PRE>
<INS>  struct A {
    operator int() const { return 10; }
  };

  bool operator==(A, int);               //<SPAN CLASS="cmnt"> #1</SPAN>
  //<SPAN CLASS="cmnt"> built-in: </SPAN>bool operator==(int, int);  //<SPAN CLASS="cmnt"> #2</SPAN>
  bool b = 10 == A();                   //<SPAN CLASS="cmnt"> uses #1 with reversed order of arguments; previously used #2</SPAN></INS>
</PRE>

</BLOCKQUOTE>

<P><B>Proposed resolution:</B></P>

<P>Add the following as a new subclause in C.2 [<A href="https://wg21.link/diff.cpp17">diff.cpp17</A>]:</P>

<BLOCKQUOTE class="ins">

<P>C.5.6 Clause 12: Overloading</P>

<P>Affected subclause: 12.2.2.3 [<A href="https://wg21.link/over.match.oper">over.match.oper</A>]<BR>
Change: Overload resolution may change for equality operators
7.6.10 [<A href="https://wg21.link/expr.eq">expr.eq</A>].<BR>
Rationale: Support calling <TT>operator==</TT> with reversed order
of arguments.<BR>
Effect on original feature: Valid C++ 2017 code that uses
equality operators with conversion functions may be ill-formed
or have different semantics in this International Standard.</P>

<PRE>
  struct A {
    operator int() const { return 10; }
  };

  bool operator==(A, int);               //<SPAN CLASS="cmnt"> #1</SPAN>
  //<SPAN CLASS="cmnt"> built-in: </SPAN>bool operator==(int, int);   //<SPAN CLASS="cmnt"> #2</SPAN>
  bool b = 10 == A();                   //<SPAN CLASS="cmnt"> uses #1 with reversed order of arguments; previously used #2</SPAN>

  struct B {
    bool operator==(const B&amp;);          //<SPAN CLASS="cmnt"> member function with no cv-qualifier</SPAN>
  };
  B b1;
  bool eq = (b1 == b1);                   //<SPAN CLASS="cmnt"> ambiguous; previously well-formed</SPAN>
</PRE>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2410"></A><H4>2410.
  
Implicit calls of immediate functions
</H4>
<B>Section: </B>9.2.6&#160; [<A href="https://wg21.link/dcl.constexpr">dcl.constexpr</A>]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>John Spicer
 &#160;&#160;&#160;

 <B>Date: </B>2019-03-27


<P>The intent for immediate functions is that they can only be
called at compile time. That rule is enforced by the wording
of 7.5.4 [<A href="https://wg21.link/expr.prim.id#3">expr.prim.id</A>] paragraph 3:</P>

<BLOCKQUOTE>

An <I>id-expression</I> that denotes an immediate function
(9.2.6 [<A href="https://wg21.link/dcl.constexpr">dcl.constexpr</A>]) shall appear as a subexpression
of an immediate invocation or in an immediate function
context (7.7 [<A href="https://wg21.link/expr.const">expr.const</A>]).

</BLOCKQUOTE>

<P>However, this restriction does not apply to implicit
function calls such as constructor and operator
invocations.  Presumably some additional wording is needed
for such cases.</P>

<P><B>Additional note, July, 2019:</B></P>

<P>This issue would appear to be NAD because of the following
wording from 7.7 [<A href="https://wg21.link/expr.const#10">expr.const</A>] paragraph 10:</P>

<BLOCKQUOTE>

An expression or conversion is an immediate invocation if it
is an explicit or implicit invocation of an immediate
function and is not in an immediate function context. An
immediate invocation shall be a constant expression.

</BLOCKQUOTE>

<P><B>Proposed resolution (approved by CWG 2022-10-21):</B></P>

<P>Change in 7.7 [<A href="https://wg21.link/expr.const#10">expr.const</A>] paragraph 10 as follows:</P>

<BLOCKQUOTE>

An <DEL>expression or conversion</DEL> <INS>invocation</INS> is an
immediate invocation if it is an explicit or implicit invocation of an
immediate function and is not in an immediate function context. An
immediate invocation shall be a constant expression.

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2428"></A><H4>2428.
  
Deprecating a concept
</H4>
<B>Section: </B>13.7.9&#160; [<A href="https://wg21.link/temp.concept">temp.concept</A>]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>Eric Niebler
 &#160;&#160;&#160;

 <B>Date: </B>2018-12-10




<P>The grammar for a <I>concept-definition</I> does not include an
<I>attribute-specifier-seq<SUB>opt</SUB></I>, making it impossible
to deprecate an attribute. This seems like an oversight.</P>

<P><B>CWG telecon 2022-10-07:</B></P>

<P>Agreed.</P>

<P><B>Proposed resolution (approved by CWG 2022-10-21):</B></P>

<OL>
<LI>
<P>Change in 9.12.5 [<A href="https://wg21.link/dcl.attr.deprecated#2">dcl.attr.deprecated</A>] paragraph 2 as follows:</P>

<BLOCKQUOTE>

The attribute may be applied to the declaration of a class,
a <I>typedef-name</I>, a variable, a non-static data member, a
function, a namespace, an enumeration, an enumerator,
<INS>a concept,</INS> or a template specialization.

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 13.7.9 [<A href="https://wg21.link/temp.concept#1">temp.concept</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

A concept is a template that defines constraints on its template
arguments.

<PRE>
<I>concept-definition</I>:
    concept <I>concept-name</I> <INS><I>attribute-specifier-seq</I><SUB>opt</SUB></INS> = <I>constraint-expression</I> ;

<I>concept-name</I>:
    <I>identifier</I>
</PRE>

A <I>concept-definition</I> declares a concept. Its <I>identifier</I>
becomes a <I>concept-name</I> referring to that concept within its
scope. <INS>The optional <I>attribute-specifier-seq</I> appertains to
the concept.</INS>
</BLOCKQUOTE>
</LI>
</OL>

<BR><BR><HR>
<A NAME="2440"></A><H4>2440.
  
Allocation in core constant expressions
</H4>
<B>Section: </B>7.7&#160; [<A href="https://wg21.link/expr.const">expr.const</A>]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>Davis Herring
 &#160;&#160;&#160;

 <B>Date: </B>2019-08-28


<P>7.7 [<A href="https://wg21.link/expr.const#5">expr.const</A>] paragraph 5 attempts to describe
allowable allocation/deallocation calls in terms of what could
be called &#8220;core constant subexpressions,&#8221; but the
actual definition of a core constant expression in paragraph 4
is in terms of evaluation.</P>

<P><U>Suggested resolution [SUPERSEDED]:</U></P>

<P>Replace the entirety of 7.7 [<A href="https://wg21.link/expr.const#6">expr.const</A>] paragraph 6
with the following:</P>

<BLOCKQUOTE>

For the purposes of determining whether an expression <DEL>E</DEL> is
a core constant expression,
the evaluation of <DEL>a call
to</DEL> <INS>the body of</INS> a member function of
<TT>std::allocator&lt;T&gt;</TT> as defined in
20.2.10.2 [<A href="https://wg21.link/allocator.members">allocator.members</A>], where <TT>T</TT> is a literal
type, <DEL>does not disqualify E from being a core constant
expression, even if the actual evaluation of such a call would
otherwise fail the requirements for a core constant
expression</DEL> <INS>is ignored</INS>. Similarly, the evaluation
of <DEL>a call to</DEL> <INS>the body
of <TT>std::destroy_at</TT>, <TT>std::ranges::destroy_at</TT>, </INS>
<TT>std::construct_at</TT><INS>,</INS> or
<TT>std::ranges::construct_at</TT>
<DEL>(27.11.8 [<A href="https://wg21.link/specialized.construct">specialized.construct</A>]) does not disqualify E from being a
core constant expression unless the first argument, of type T*, does
not point to storage allocated with std::allocator&lt;T&gt; or to an
object whose lifetime began within the evaluation of E, or the
evaluation of</DEL> <INS>is considered to include only</INS> the
underlying constructor <DEL>call disqualifies E from being a core
constant expression</DEL> <INS>(for the
functions <TT>construct_at</TT>) or destructor (for the
functions <TT>destroy_at</TT>) call if the first argument (of
type <TT>T*</TT>) points to storage allocated
with <TT>std::allocator&lt;T&gt;</TT></INS>.

</BLOCKQUOTE>

<P><B>CWG telecon 2022-10-21:</B></P>

<P>The references to <TT>destroy_at</TT> were removed in an unrelated update
to the Working Draft. Also, restore the reference to local objects whose
lifetime began within E.</P>

<P><B>Proposed resolution (approved by CWG 2022-11-10):</B></P>

<P>Change in 7.7 [<A href="https://wg21.link/expr.const#6">expr.const</A>] paragraph 6 as follows:</P>

<BLOCKQUOTE>

For the purposes of determining whether an expression E is
a core constant expression,
the evaluation of <DEL>a call
to</DEL> <INS>the body of</INS> a member function of
<TT>std::allocator&lt;T&gt;</TT> as defined in
20.2.10.2 [<A href="https://wg21.link/allocator.members">allocator.members</A>], where <TT>T</TT> is a literal
type, <DEL>does not disqualify E from being a core constant
expression, even if the actual evaluation of such a call would
otherwise fail the requirements for a core constant
expression</DEL> <INS>is ignored</INS>. Similarly, the evaluation
of <DEL>a call to</DEL> <INS>the body of </INS>
<TT>std::construct_at</TT> or <TT>std::ranges::construct_at</TT>
<DEL>(27.11.8 [<A href="https://wg21.link/specialized.construct">specialized.construct</A>]) does not disqualify E from being a
core constant expression unless the first argument, of type T*, does
not point to storage allocated with std::allocator&lt;T&gt; or to an
object whose lifetime began within the evaluation of E, or the
evaluation of</DEL> <INS>is considered to include only</INS> the
underlying constructor <DEL>call disqualifies E from being a core
constant expression</DEL> <INS>call if the first argument (of
type <TT>T*</TT>) points to storage allocated
with <TT>std::allocator&lt;T&gt;</TT> or to an object whose lifetime
began within the evaluation of <I>E</I></INS>.

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2451"></A><H4>2451.
  
<I>promise</I><TT>.unhandled_exception()</TT> and final suspend point
</H4>
<B>Section: </B>9.5.4&#160; [<A href="https://wg21.link/dcl.fct.def.coroutine">dcl.fct.def.coroutine</A>]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>Lewis Baker
 &#160;&#160;&#160;

 <B>Date: </B>2020-02-14


<P>According to 9.5.4 [<A href="https://wg21.link/dcl.fct.def.coroutine#14">dcl.fct.def.coroutine</A>] paragraph 14,</P>

<BLOCKQUOTE>

If the evaluation of the expression
<I>promise</I><TT>.unhandled_exception()</TT> exits via an
exception, the coroutine is considered suspended at the
final suspend point.

</BLOCKQUOTE>

<P>However, the &#8220;final suspend point&#8221; is defined as
being &#8220;the <I>await-expression</I> containing the call to
<TT>final_suspend</TT>&#8221; (bullet 5.2), and it is not desired
to evaluate the <TT>final_suspend</TT> expression in this case.</P>

<P><U>Suggested resolution [SUPERSEDED]:</U></P>

<OL>
<LI><P>Change 9.5.4 [<A href="https://wg21.link/dcl.fct.def.coroutine#5">dcl.fct.def.coroutine</A>] paragraph 5 as follows:</P></LI>

<BLOCKQUOTE>

<P>...where</P>

<UL>
<LI><P>the <I>await-expression</I> containing the call
to <TT>initial_suspend</TT> is the <I>initial <DEL>suspend
point</DEL> <INS>await expression</INS></I>, and</P></LI>

<LI><P>the <I>await-expression</I> containing the call to
<TT>final_suspend</TT> is the <I>final <DEL>suspend point</DEL>
<INS>await expression</INS></I>, and</P></LI>

<LI><P>
<I>initial-await-resume-called</I> is
initially <TT>false</TT> and is set to <TT>true</TT>
immediately before the evaluation of the <I>await-resume</I>
expression (7.6.2.4 [<A href="https://wg21.link/expr.await">expr.await</A>]) of the initial
<DEL>suspend point</DEL> <INS>await expression</INS>, and</P></LI>

<LI><P>...</P></LI>

<LI><P>
<I>promise-constructor-arguments</I> is determined as
follows: overload resolution is performed on a promise
constructor call created by assembling an argument list with
lvalues <TT>p</TT><SUB>1</SUB> ...
<TT>p</TT><SUB><I>n</I></SUB>. If a viable constructor is
found (12.2.3 [<A href="https://wg21.link/over.match.viable">over.match.viable</A>]),
then <I>promise-constructor-arguments</I> is
<TT>(p</TT><SUB>1</SUB>, ..., <TT>p</TT><SUB><I>n</I></SUB><TT>)</TT>,
otherwise <I>promise-constructor-arguments</I> is
empty<DEL>.</DEL> <INS>, and</INS>
</P></LI>

<LI>
<P><INS>A coroutine is suspended at a <I>final suspend
point</I> if it is suspended</INS></P>

<UL>
<LI><P><INS>at a final await expression or</INS></P></LI>

<LI><P><INS>due to an exception exiting from
<TT>unhandled_exception()</TT></INS></P></LI>

</UL>
</LI>

</UL>

</BLOCKQUOTE>

<LI><P>Change bullet 3.2 of 7.6.2.4 [<A href="https://wg21.link/expr.await">expr.await</A>] as follows:</P></LI>

<BLOCKQUOTE>

<P>Evaluation of an <I>await-expression</I> involves the
following auxiliary types, expressions, and objects:</P>

<UL>
<LI><P>...</P></LI>

<LI>

<P>
<I>a</I> is the <I>cast-expression</I> if
the <I>await-expression</I> was implicitly produced by
a <I>yield-expression</I> (7.6.17 [<A href="https://wg21.link/expr.yield">expr.yield</A>]), an
initial <DEL>suspend point</DEL> <INS>await expression</INS>,
or a final <DEL>suspend point</DEL> <INS>await expression</INS>
(9.5.4 [<A href="https://wg21.link/dcl.fct.def.coroutine">dcl.fct.def.coroutine</A>]). Otherwise</P>
</LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

<LI><P>If needed, change 9.5.4 [<A href="https://wg21.link/dcl.fct.def.coroutine#14">dcl.fct.def.coroutine</A>] paragraph 14 as
follows:</P></LI>

<BLOCKQUOTE>

If the evaluation of the expression
<I>promise</I><TT>.unhandled_exception()</TT> exits via an
exception, the coroutine is considered suspended at the
final suspend point <INS>and the exception propagates to the
caller or resumer</INS>.

</BLOCKQUOTE>

</OL>

<P><B>Notes from the August, 2020 teleconference [SUPERSEDED]:</B></P>

<P>CWG expressed some concern about the lack of a precise definition
of &#8220;suspend point&#8221;. Gor Nishanov suggests the following
change, in 7.6.2.4 [<A href="https://wg21.link/expr.await#5.1">expr.await</A>] bullet 5.1:</P>

<BLOCKQUOTE>

<UL>
<LI><P>If the evaluation of <I>await-suspend</I> exits
via an exception, the exception is caught, the coroutine is
resumed, and the exception is immediately re-thrown
(14.2 [<A href="https://wg21.link/except.throw">except.throw</A>]). Otherwise, control flow returns
to the current coroutine caller or resumer
(9.5.4 [<A href="https://wg21.link/dcl.fct.def.coroutine">dcl.fct.def.coroutine</A>]) without exiting any scopes
(8.7 [<A href="https://wg21.link/stmt.jump">stmt.jump</A>]). <INS>The point in the coroutine
immediately prior to control returning to its caller or
resumer is a coroutine <I>suspend point</I>.</INS>
</P></LI>

</UL>

</BLOCKQUOTE>

<P><B>Proposed resolution (approved by CWG 2022-11-10):</B></P>

<OL>

<LI>
<P>Change in 7.6.2.4 [<A href="https://wg21.link/expr.await#3.2">expr.await</A>] bullet 3.2 as follows:</P>

<BLOCKQUOTE>

<P>Evaluation of an <I>await-expression</I> involves the
following auxiliary types, expressions, and objects:</P>

<UL>
<LI><P>...</P></LI>

<LI>

<P>
<I>a</I> is the <I>cast-expression</I> if
the <I>await-expression</I> was implicitly produced by
a <I>yield-expression</I> (7.6.17 [<A href="https://wg21.link/expr.yield">expr.yield</A>]), an
initial <DEL>suspend point</DEL> <INS>await expression</INS>,
or a final <DEL>suspend point</DEL> <INS>await expression</INS>
(9.5.4 [<A href="https://wg21.link/dcl.fct.def.coroutine">dcl.fct.def.coroutine</A>]). Otherwise</P>
</LI>

<LI><P>...</P></LI>

</UL>

</BLOCKQUOTE>

</LI>

<LI>

<P>Change in 7.6.2.4 [<A href="https://wg21.link/expr.await#5.1">expr.await</A>] bullet 5.1 as follows:</P>

<BLOCKQUOTE>

<UL>
<LI>
<P>If the evaluation of <I>await-suspend</I> exits
via an exception, the exception is caught, the coroutine is
resumed, and the exception is immediately re-thrown
(14.2 [<A href="https://wg21.link/except.throw">except.throw</A>]). Otherwise, control flow returns
to the current coroutine caller or resumer
(9.5.4 [<A href="https://wg21.link/dcl.fct.def.coroutine">dcl.fct.def.coroutine</A>]) without exiting any scopes
(8.7 [<A href="https://wg21.link/stmt.jump">stmt.jump</A>]). <INS>The point in the coroutine
immediately prior to control returning to its caller or
resumer is a coroutine <I>suspend point</I>.</INS>
</P>
</LI>
</UL>

</BLOCKQUOTE>

</LI>

<LI>
<P>Change in 9.5.4 [<A href="https://wg21.link/dcl.fct.def.coroutine#5">dcl.fct.def.coroutine</A>] paragraph 5 as follows:</P>

<BLOCKQUOTE>

<P>...where</P>

<UL>
<LI><P>the <I>await-expression</I> containing the call
to <TT>initial_suspend</TT> is the <I>initial <DEL>suspend
point</DEL> <INS>await expression</INS></I>, and</P></LI>

<LI><P>the <I>await-expression</I> containing the call to
<TT>final_suspend</TT> is the <I>final <DEL>suspend point</DEL>
<INS>await expression</INS></I>, and</P></LI>

<LI><P>
<I>initial-await-resume-called</I> is
initially <TT>false</TT> and is set to <TT>true</TT>
immediately before the evaluation of the <I>await-resume</I>
expression (7.6.2.4 [<A href="https://wg21.link/expr.await">expr.await</A>]) of the initial
<DEL>suspend point</DEL> <INS>await expression</INS>, and</P></LI>

<LI><P>...</P></LI>

<LI><P>
<I>promise-constructor-arguments</I> is determined as
follows: overload resolution is performed on a promise
constructor call created by assembling an argument list with
lvalues <TT>p</TT><SUB>1</SUB> ...
<TT>p</TT><SUB><I>n</I></SUB>. If a viable constructor is
found (12.2.3 [<A href="https://wg21.link/over.match.viable">over.match.viable</A>]),
then <I>promise-constructor-arguments</I> is
<TT>(p</TT><SUB>1</SUB>, ..., <TT>p</TT><SUB><I>n</I></SUB><TT>)</TT>,
otherwise <I>promise-constructor-arguments</I> is
empty<DEL>.</DEL> <INS>, and</INS>
</P></LI>

<LI><INS>a coroutine is suspended at the <I>initial suspend point</I> if it is suspended at the initial await expression, and</INS></LI>

<LI>
<P><INS>a coroutine is suspended at a <I>final suspend
point</I> if it is suspended</INS></P>

<UL>
<LI><P><INS>at a final await expression or</INS></P></LI>

<LI><P><INS>due to an exception exiting from
<TT>unhandled_exception()</TT></INS></P></LI>

</UL>
</LI>

</UL>

</BLOCKQUOTE>

</LI>

<LI>
<P>Change 9.5.4 [<A href="https://wg21.link/dcl.fct.def.coroutine#14">dcl.fct.def.coroutine</A>] paragraph 14 as
follows:</P>

<BLOCKQUOTE>

If the evaluation of the expression
<I>promise</I><TT>.unhandled_exception()</TT> exits via an
exception, the coroutine is considered suspended at the
final suspend point <INS>and the exception propagates to the
caller or resumer</INS>.

</BLOCKQUOTE>

</LI>

</OL>

<BR><BR><HR>
<A NAME="2508"></A><H4>2508.
  
Restrictions on uses of template parameter names
</H4>
<B>Section: </B>13.8.2&#160; [<A href="https://wg21.link/temp.local">temp.local</A>]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>Daveed Vandevoorde
 &#160;&#160;&#160;

 <B>Date: </B>2021-11-01


<P>The status of an example like the following is unclear:</P>

<PRE>
  template&lt;typename T&gt; T T(T) {}
</PRE>

<P>According to 13.8.2 [<A href="https://wg21.link/temp.local#6">temp.local</A>] paragraph 6,</P>

<BLOCKQUOTE>

<P>The name of a <I>template-parameter</I> shall not be bound
to any following declaration contained by the scope to which
the <I>template-parameter</I> belongs.  [<I>Example 5</I>:</P>

<PRE>
  ...
  template&lt;class X&gt; class X; //<SPAN CLASS="cmnt"> error: hidden by template-parameter</SPAN>
</PRE>

<P>&#8212;<I>end example</I>]</P>

</BLOCKQUOTE>

<P>The intent would appear to be that the function template
could not have the same name as the template parameter.
However, according to 6.4.9 [<A href="https://wg21.link/basic.scope.temp#2">basic.scope.temp</A>] paragraph 2,</P>

<BLOCKQUOTE>

Each <I>template-declaration</I> <TT>D</TT> introduces a
template parameter scope that extends from the beginning of
its <I>template-parameter-list</I> to the end of
the <I>template-declaration</I>. Any declaration outside
the <I>template-parameter-list</I> that would inhabit that
scope instead inhabits the same scope as <TT>D</TT>.

</BLOCKQUOTE>

<P>This would indicate that the function template inhabits
the namespace scope, not the template parameter scope, so
the prohibition against use of the template parameter name
would not apply.</P>

<P>To reject both the function and class template examples,
13.8.2 [<A href="https://wg21.link/temp.local#6">temp.local</A>] paragraph 6 could be changed to
read:</P>

<BLOCKQUOTE>

The name of a <I>template-parameter</I> shall not be bound
to any following declaration <INS>whose locus is</INS>
contained by the scope to which
the <I>template-parameter</I> belongs.

</BLOCKQUOTE>

<P>To accept both examples, the change could be:</P>

<BLOCKQUOTE>

The name of a <I>template-parameter</I> shall not be bound
to any following declaration <INS>that inhabits a scope</INS>
contained by the scope to which
the <I>template-parameter</I> belongs.

</BLOCKQUOTE>

<P><B>Notes from the December, 2021 teleconference:</B></P>

<P>The consensus of CWG was to reject both examples, i.e.,
the first option.</P>

<P><B>Additional note (December, 2021):</B></P>

<P>It was observed that this issue is, strictly speaking,
not a defect: the word &#8220;contains&#8221; is used in
6.4.1 [<A href="https://wg21.link/basic.scope.scope#1">basic.scope.scope</A>] paragraph 1 in its usual English
sense to refer to the lexical nesting of scopes, so the
template parameter scope of <TT>T</TT>
&#8220;contains&#8221; the declaration of the
function <TT>T</TT>. However, the use of the term
&#8220;locus&#8221; would make the intent clearer.</P>

<P><B>Proposed resolution (December, 2021):</B></P>

<P>Change 13.8.2 [<A href="https://wg21.link/temp.local#6">temp.local</A>] paragraph 6 as follows:</P>

<BLOCKQUOTE>

The name of a <I>template-parameter</I> shall not be bound
to any following declaration <INS>whose locus is</INS>
contained by the scope to which
the <I>template-parameter</I> belongs.

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2583"></A><H4>2583.
  
Common initial sequence should consider over-alignment
</H4>
<B>Section: </B>11.4.1&#160; [<A href="https://wg21.link/class.mem.general">class.mem.general</A>]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>Brian Bi
 &#160;&#160;&#160;

 <B>Date: </B>2022-05-03


<P>Consider:</P>

<PRE>
  struct A {
    int i;
    char c;
  };

  struct B {
    int i;
    alignas(8) char c;
  };

  union U { A a; B b; };
</PRE>

<P>On a lot of platforms, <TT>A</TT> and <TT>B</TT> do not have the
same layout, yet 11.4.1 [<A href="https://wg21.link/class.mem.general#23">class.mem.general</A>] paragraph 23 does not
consider differences in alignment in the rules for "common initial
sequence":</P>

<BLOCKQUOTE>

The common initial sequence of two standard-layout struct
(11.2 [<A href="https://wg21.link/class.prop">class.prop</A>]) types is the longest sequence of
non-static data members and bit-fields in declaration order, starting
with the first such entity in each of the structs, such that
corresponding entities have layout-compatible types
(6.8 [<A href="https://wg21.link/basic.types">basic.types</A>]), either both entities are declared with the
<TT>no_unique_address</TT> attribute (9.12.11 [<A href="https://wg21.link/dcl.attr.nouniqueaddr">dcl.attr.nouniqueaddr</A>]) or
neither is, and either both entities are bit-fields with the same
width or neither is a bit-field.

</BLOCKQUOTE>

<P>In the following example,</P>

<PRE>
  struct S0 {
    alignas(16) char x[128];
    int i;
  };
  struct alignas(16) S1 {
    char x[128];
    int i;
  };
</PRE>

<P>
<TT>S0</TT> and <TT>S1</TT> have the same alignment, yet per the
suggested rules below, they will not be layout-compatible.</P>

<P><U>Suggested resolution [SUPERSEDED]:</U></P>

<P>Change in 11.4.1 [<A href="https://wg21.link/class.mem.general">class.mem.general</A>] paragraphs 23-25 as follows (also
add bullets):</P>

<BLOCKQUOTE>

The common initial sequence of two standard-layout struct
(11.2 [<A href="https://wg21.link/class.prop">class.prop</A>]) types is the longest sequence of
non-static data members and bit-fields in declaration order, starting
with the first such entity in each of the structs, such that

<UL>
<LI>corresponding entities have layout-compatible types
(6.8 [<A href="https://wg21.link/basic.types">basic.types</A>]),
</LI>

<LI>
<INS>either both entities have <I>alignment-specifier</I>s that
specify equivalent alignment or neither entity has
an <I>alignment-specifier</I> (9.12.2 [<A href="https://wg21.link/dcl.align">dcl.align</A>]),</INS>
</LI>

<LI>either both entities are declared with the
<TT>no_unique_address</TT> attribute (9.12.11 [<A href="https://wg21.link/dcl.attr.nouniqueaddr">dcl.attr.nouniqueaddr</A>]) or
neither is, and
</LI>

<LI>either both entities are bit-fields with the same width or neither
is a bit-field.
</LI>

</UL>

<P>[...]</P>

<P>Two standard-layout struct (11.2 [<A href="https://wg21.link/class.prop">class.prop</A>]) types are
layout-compatible classes if their common initial sequence comprises
all members and bit-fields of both classes (6.8 [<A href="https://wg21.link/basic.types">basic.types</A>])
<INS>and either both types are declared with
<I>alignment-specifier</I>s that specify equivalent alignment or
neither type has an <I>alignment-specifier</I></INS>.</P>

<P>Two standard-layout unions are layout-compatible if they have the
same number of non-static data members and

corresponding non-static
data members (in any order)

<UL>
<LI>have layout-compatible types (6.8.1 [<A href="https://wg21.link/basic.types.general">basic.types.general</A>])
<INS>and</INS>
</LI>

<LI>
<INS>either both
have <I>alignment-specifier</I>s that specify equivalent alignment or
neither has an <I>alignment-specifier</I></INS>.</LI>

</UL>
</P>

</BLOCKQUOTE>

<P><B>Proposed resolution (approved by CWG telecon 2022-08-26):</B></P>

<P>Change in 11.4.1 [<A href="https://wg21.link/class.mem.general">class.mem.general</A>] paragraphs 23-25 as follows (also
add bullets):</P>

<BLOCKQUOTE>

The common initial sequence of two standard-layout struct
(11.2 [<A href="https://wg21.link/class.prop">class.prop</A>]) types is the longest sequence of
non-static data members and bit-fields in declaration order, starting
with the first such entity in each of the structs, such that

<UL>
<LI>corresponding entities have layout-compatible types
(6.8 [<A href="https://wg21.link/basic.types">basic.types</A>]),
</LI>

<LI>
<INS>corresponding entities have the same alignment requirements (6.7.6 [<A href="https://wg21.link/basic.align">basic.align</A>]),</INS>
</LI>

<LI>either both entities are declared with the
<TT>no_unique_address</TT> attribute (9.12.11 [<A href="https://wg21.link/dcl.attr.nouniqueaddr">dcl.attr.nouniqueaddr</A>]) or
neither is, and
</LI>

<LI>either both entities are bit-fields with the same width or neither
is a bit-field.
</LI>

</UL>

<P>[...]</P>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2590"></A><H4>2590.
  
Underlying type should determine size and alignment requirements of an enum
</H4>
<B>Section: </B>9.7.1&#160; [<A href="https://wg21.link/dcl.enum">dcl.enum</A>]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>Brian Bi
 &#160;&#160;&#160;

 <B>Date: </B>2022-05-15


<P>Subclause 9.7.1 [<A href="https://wg21.link/dcl.enum">dcl.enum</A>] specifies how the underlying
type of an enumeration is determined, and, for enumerations whose
underlying type is fixed, specifies that the enumeration has the same
set of values as the underlying type.  However, the specification does
not relate the size and alignment requirements of the enumeration to
those of the underlying type.  Those ought to be the same.</P>

<P><U>Suggested resolution [SUPERSEDED]:</U></P>

<P>Add a new paragraph after 9.7.1 [<A href="https://wg21.link/dcl.enum#8">dcl.enum</A>] paragraph 8:</P>

<BLOCKQUOTE>

<P>For an enumeration whose underlying type is fixed, ...</P>

<P><INS>An enumeration has the same size, value representation, and alignment
requirements (6.7.6 [<A href="https://wg21.link/basic.align">basic.align</A>]) as its underlying
type. Furthermore, each value of an enumeration has the same
representation as the same value of the underlying type.</INS></P>

<P>Two enumeration types are <I>layout-compatible enumerations</I> if ...</P>

</BLOCKQUOTE>

<P><B>Proposed resolution (approved by CWG 2022-08-26):</B></P>

<P>Add a new paragraph after 9.7.1 [<A href="https://wg21.link/dcl.enum#8">dcl.enum</A>] paragraph 8:</P>

<BLOCKQUOTE>

<P>For an enumeration whose underlying type is fixed, ...</P>

<P><INS>An enumeration has the same size, value representation, and alignment
requirements (6.7.6 [<A href="https://wg21.link/basic.align">basic.align</A>]) as its underlying
type. Furthermore, each value of an enumeration has the same
representation as the corresponding value of the underlying type.</INS></P>

<P>Two enumeration types are <I>layout-compatible enumerations</I> if ...</P>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2598"></A><H4>2598.
  
Unions should not require a non-static data member of literal type
</H4>
<B>Section: </B>6.8.1&#160; [<A href="https://wg21.link/basic.types.general">basic.types.general</A>]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2022-06-18


<P>According to 6.8.1 [<A href="https://wg21.link/basic.types.general#10">basic.types.general</A>] paragraph 10, a type is a
literal type only if it satisfies the following:</P>

<BLOCKQUOTE>

A type is a <I>literal type</I> if it is:

<UL>
<LI>...</LI>

<LI>a possibly cv-qualified class type (Clause 11 [<A href="https://wg21.link/class">class</A>])
that has all of the following properties:
<UL>

<LI>it has a constexpr
destructor (9.2.6 [<A href="https://wg21.link/dcl.constexpr">dcl.constexpr</A>]),</LI>

<LI>it is either a
closure type (7.5.5.2 [<A href="https://wg21.link/expr.prim.lambda.closure">expr.prim.lambda.closure</A>]), an aggregate type
(9.4.2 [<A href="https://wg21.link/dcl.init.aggr">dcl.init.aggr</A>]), or has at least one constexpr
constructor or constructor template (possibly inherited
(9.9 [<A href="https://wg21.link/namespace.udecl">namespace.udecl</A>]) from a base class) that is not a copy or
move constructor,</LI>

<LI>if it is a union, at least one of its
non-static data members is of non-volatile literal type, and
</LI>

<LI>
if it is not a union, all of its non-static data members and base
classes are of non-volatile literal types.</LI>
</UL>
</LI>
</UL>

[<I>Note 4:</I> A literal type is one for which it might be possible
to create an object within a constant expression. ... &#8212;<I>end
note</I>]

</BLOCKQUOTE>

<P>However, the normative rule disagrees with the note. Consider:</P>

<PRE>
  struct A { A(); };
  union U {
    A a;
    constexpr U() {}
    constexpr ~U() {}
  };
</PRE>

<P>It is certainly possible to create an object of type <TT>U</TT> in
a constant expression, even though <TT>U</TT> is not a literal
type.</P>

<P>In the suggested resolution, the aggregate type rule is intended to
capture the fact that it is not possible for aggregate initialization
of a non-empty union to leave no active member (and similarly for each
anonymous union member in a non-union union-like class).</P>

<P><U>Suggested resolution [SUPERSEDED]:</U></P>

<P>Change in 6.8.1 [<A href="https://wg21.link/basic.types.general#10">basic.types.general</A>] paragraph 10 as follows:</P>

<BLOCKQUOTE>

A type is a <I>literal type</I> if it is:

<UL>
<LI>...</LI>

<LI>a possibly cv-qualified class type (Clause 11 [<A href="https://wg21.link/class">class</A>])
that has all of the following properties:
<UL>

<LI>it has a constexpr
destructor (9.2.6 [<A href="https://wg21.link/dcl.constexpr">dcl.constexpr</A>]),</LI>

<LI>it <DEL>is</DEL> either

<UL>
<LI>
<INS>is</INS> a closure type (7.5.5.2 [<A href="https://wg21.link/expr.prim.lambda.closure">expr.prim.lambda.closure</A>]),</LI>

<LI>
<INS>is</INS> an aggregate type
(9.4.2 [<A href="https://wg21.link/dcl.init.aggr">dcl.init.aggr</A>]) <INS>for which that type (if it is a
union) or each of its anonymous union members (otherwise) either has
at least one variant member of non-volatile literal type or has no
variant members,</INS> or</LI>

<LI>has at least one constexpr
constructor or constructor template (possibly inherited
(9.9 [<A href="https://wg21.link/namespace.udecl">namespace.udecl</A>]) from a base class) that is not a copy or
move constructor, <INS>and</INS>
</LI>

</UL>
</LI>

<LI>
<DEL>if it is a union, at least one of its
non-static data members is of non-volatile literal type, and</DEL>
</LI>

<LI>
<DEL>if it is not a union,</DEL> all of its
non-static <INS>non-variant</INS> data members and base classes are of
non-volatile literal types.</LI>
</UL>
</LI>
</UL>

</BLOCKQUOTE>

<P><B>Proposed resolution (CWG telecon 2022-08-12) [SUPERSEDED]:</B></P>

<P>Change in 6.8.1 [<A href="https://wg21.link/basic.types.general#10">basic.types.general</A>] paragraph 10 as follows:</P>

<BLOCKQUOTE>

A type is a <I>literal type</I> if it is:

<UL>
<LI>...</LI>

<LI>a possibly cv-qualified class type (Clause 11 [<A href="https://wg21.link/class">class</A>])
that has all of the following properties:
<UL>

<LI>it has a constexpr
destructor (9.2.6 [<A href="https://wg21.link/dcl.constexpr">dcl.constexpr</A>]),</LI>

<LI>
<INS>all of its non-static non-variant data members and base classes
are of non-volatile literal types, and</INS>
</LI>

<LI>it <DEL>is</DEL> either

<UL>
<LI>
<INS>is</INS> a closure type (7.5.5.2 [<A href="https://wg21.link/expr.prim.lambda.closure">expr.prim.lambda.closure</A>]),</LI>

<LI>
<INS>is</INS> an aggregate type
(9.4.2 [<A href="https://wg21.link/dcl.init.aggr">dcl.init.aggr</A>]) <INS>for which that type (if it is a
union) or each of its anonymous union members (otherwise) either has
at least one variant member of non-volatile literal type or has no
variant members,</INS> or</LI>

<LI>has at least one constexpr
constructor or constructor template (possibly inherited
(9.9 [<A href="https://wg21.link/namespace.udecl">namespace.udecl</A>]) from a base class) that is not a copy or
move constructor<DEL>,</DEL> <INS>.</INS>
</LI>

</UL>
</LI>

<LI>
<DEL>if it is a union, at least one of its
non-static data members is of non-volatile literal type, and</DEL>
</LI>

<LI>
<DEL>if it is not a union, all of its non-static data members and base
classes are of non-volatile literal types.</DEL>
</LI>
</UL>
</LI>
</UL>

</BLOCKQUOTE>

<P><B>Proposed resolution (approved by CWG 2022-11-09):</B></P>

<P>Change 6.8.1 [<A href="https://wg21.link/basic.types.general">basic.types.general</A>] paragraph 10 as follows:</P>

<BLOCKQUOTE>

<P>A type is a <I>literal type</I> if it is:</P>

<UL>
<LI><P>...</P></LI>

<LI><P> a possibly cv-qualified class type
 (Clause 11 [<A href="https://wg21.link/class">class</A>]) that has all of the
 following properties:</P></LI>

<UL>
<LI><P>it has a constexpr destructor
(9.2.6 [<A href="https://wg21.link/dcl.constexpr">dcl.constexpr</A>]),</P></LI>

<LI><P><INS>all of its non-static non-variant data members
and base classes are of non-volatile literal types,
and</INS></P></LI>

<LI><P>it <DEL>is either</DEL>
</P></LI>

<UL>
<LI><P>
<INS>is</INS> a closure type
(7.5.5.2 [<A href="https://wg21.link/expr.prim.lambda.closure">expr.prim.lambda.closure</A>]),</P></LI>

<LI><P><DEL>an aggregate type
(9.4.2 [<A href="https://wg21.link/dcl.init.aggr">dcl.init.aggr</A>]),</DEL></P></LI>

<LI><P><INS>is an aggregate union type that has either no
variant members or at least one variant member of
non-volatile literal type,</INS></P></LI>

<LI><P><INS>is a non-union aggregate type for which each
of its anonymous union members satisfies the above requirements
for an aggregate union type, or</INS></P></LI>

<LI><P>has at least one constexpr constructor or constructor
template (possibly inherited (9.9 [<A href="https://wg21.link/namespace.udecl">namespace.udecl</A>]) from
a base class) that is not a copy or move
constructor<DEL>,</DEL><INS>.</INS>
</P></LI>

</UL>

<LI><P><DEL>if it is a union, at least one of its non-static
data members is of non-volatile literal type,
and</DEL></P></LI>

<LI><P><DEL>if it is not a union, all of its non-static data
members and base classes are of non-volatile literal
types.</DEL></P></LI>

</UL>

</UL>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2599"></A><H4>2599.
  
What does initializing a parameter include?
</H4>
<B>Section: </B>7.6.1.3&#160; [<A href="https://wg21.link/expr.call">expr.call</A>]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>Davis Herring
 &#160;&#160;&#160;

 <B>Date: </B>2022-06-18


<P>Subclause 7.6.1.3 [<A href="https://wg21.link/expr.call#8">expr.call</A>] paragraph 8 specifies:</P>

<BLOCKQUOTE>

The <I>postfix-expression</I> is sequenced before each expression in
the <I>expression-list</I> and any default argument. The
initialization of a parameter, including every associated value
computation and side effect, is indeterminately sequenced with respect
to that of any other parameter.  [<I>Note 8:</I> All side effects of
argument evaluations are sequenced before the function is entered (see
6.9.1 [<A href="https://wg21.link/intro.execution">intro.execution</A>]). &#8212;<I>end note</I>]

</BLOCKQUOTE>

<P>Consider:</P>

<PRE>
  f(std::unique_ptr&lt;int&gt;(new int),std::unique_ptr&lt;int&gt;(new int));
</PRE>

<P>It is not clear from the phrasing whether the evaluation of
each <TT>new int</TT> is part of the "initialization of [its]
parameter" or whether only the initialization of <TT>f</TT>'s parameters from
the completed <TT>std::unique_ptr&lt;int&gt;</TT> objects is
included. The note does not help, since it can be read as
distinguishing argument evaluations from initialization.</P>

<P><U>Suggested resolution [SUPERSEDED]:</U></P>

<P>Insert before 9.4.1 [<A href="https://wg21.link/dcl.init.general#18">dcl.init.general</A>] paragraph 18 as follows:</P>

<BLOCKQUOTE>

<P>An <I>initializer-clause</I> followed by an ellipsis is a pack
expansion (13.7.4 [<A href="https://wg21.link/temp.variadic">temp.variadic</A>]).</P>

<P><INS>Initialization includes the evaluation of all subexpressions
of each <I>initializer-clause</I> of the initializer (possibly nested
within <I>braced-init-list</I>s).</INS></P>

<P>If the initializer is a parenthesized <I>expression-list</I>, the
expressions are evaluated in the order specified for function calls
(7.6.1.3 [<A href="https://wg21.link/expr.call">expr.call</A>]).</P>

</BLOCKQUOTE>

<P><B>Proposed resolution (approved by CWG 2022-08-26):</B></P>

<P>Insert before 9.4.1 [<A href="https://wg21.link/dcl.init.general#18">dcl.init.general</A>] paragraph 18 as follows:</P>

<BLOCKQUOTE>

<P>An <I>initializer-clause</I> followed by an ellipsis is a pack
expansion (13.7.4 [<A href="https://wg21.link/temp.variadic">temp.variadic</A>]).</P>

<P><INS>Initialization includes the evaluation of all subexpressions
of each <I>initializer-clause</I> of the initializer (possibly nested
within <I>braced-init-list</I>s) and the creation of any temporary
objects for function arguments or return values
(6.7.7 [<A href="https://wg21.link/class.temporary">class.temporary</A>]).</INS></P>

<P>If the initializer is a parenthesized <I>expression-list</I>, the
expressions are evaluated in the order specified for function calls
(7.6.1.3 [<A href="https://wg21.link/expr.call">expr.call</A>]).</P>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2601"></A><H4>2601.
  
Tracking of created and destroyed subobjects
</H4>
<B>Section: </B>14.3&#160; [<A href="https://wg21.link/except.ctor">except.ctor</A>]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2022-06-16


<P>Subclause 14.3 [<A href="https://wg21.link/except.ctor#3">except.ctor</A>] paragraph 3 specifies:</P>

<BLOCKQUOTE>

If the initialization or destruction of an object other than by
delegating constructor is terminated by an exception, the destructor
is invoked for each of the object's direct subobjects and, for a
complete object, virtual base class subobjects, whose initialization
has completed (9.4 [<A href="https://wg21.link/dcl.init">dcl.init</A>]) and whose destructor has not
yet begun execution, except that in the case of destruction, the
variant members of a union-like class are not destroyed.

</BLOCKQUOTE>

<P>A traditional implementation has no way of knowing which subobjects
are in the state that their initialization has completed but their
destructor has not yet begun execution.  For example, the program
might call the destructor explicitly, and the implementation does not
track whether that has happened. The intent here is that it only
matters whether the implied destructor call generated implicitly as
part of the class object's destructor has begun yet, but it does not
say that, and the reference to variant members reinforces the
interpretation that the set of subobjects that are destroyed is
determined dynamically based on which objects are within their
lifetimes. Also, combining construction and destruction rules here
confuses the matter further -- in "whose initialization has completed
and whose destructor has not yet begun" we care exclusively about the
first part in constructors and exclusively about the second part in
destructors.</P>

<P>The set of things that we actually want to destroy here is the
things that were initialized by the initialization (constructor or
aggregate initializer) itself, not the things that have been
constructed and not destroyed by evaluations that the initialization
happens to perform. For example:</P>

<PRE>
  struct A {
    union { T x; U y; };
    A() { throw "does not destroy x"; }
    A(int) : x() { throw "does destroy x"; }
    A(float) : x() { x.~T(); throw "still destroys x, oops"; }
    A(double) : x() {
      x.~T();
      new(&amp;y) U();
      throw "destroys x, does not destroy y";
    }
  };
</PRE>

<P>and similarly for aggregate initialization:</P>

<PRE>
  struct B {
    union { T x; U y; };
    int a;
  };
  B b = { .x = {}, .a = (b.x.~T(), new (&amp;b.y) U(), throw "destroys x not y")};
</PRE>

<P>Destruction is completely different: we just want to destroy all
the things that the destructor was going to destroy anyway and hasn't
already started destroying.</P>

<P><U>Suggested resolution [SUPERSEDED]:</U></P>

<P>Change in 14.3 [<A href="https://wg21.link/except.ctor#3">except.ctor</A>] paragraph 3 as follows:</P>

<BLOCKQUOTE>

<P>If the initialization <DEL>or destruction</DEL> of an object other than by
delegating constructor is terminated by an exception, the destructor
is invoked for each of the object's <DEL>direct subobjects and, for a
complete object, virtual base class</DEL> subobjects
<INS>that were directly initialized by the object's initialization and</INS>
<DEL>,</DEL> whose initialization has completed
(9.4 [<A href="https://wg21.link/dcl.init">dcl.init</A>]) <DEL>and whose destructor has not yet begun
execution, except that in the case of destruction, the variant members
of a union-like class are not destroyed</DEL>.
<INS> A subobject is directly initialized if its initialization is
specified in 11.9.3 [<A href="https://wg21.link/class.base.init">class.base.init</A>] for initialization by
constructor, in 11.9.4 [<A href="https://wg21.link/class.inhctor.init">class.inhctor.init</A>] for initialization by
inherited constructor, in 9.4.2 [<A href="https://wg21.link/dcl.init.aggr">dcl.init.aggr</A>] for aggregate
initialization, or in 9.4.1 [<A href="https://wg21.link/dcl.init.general">dcl.init.general</A>] for
default-initialization, value-initialization, or direct-initialization
of an array. [<I>Note</I>: This includes virtual base class subobjects if the
initialization is for a complete object, and can include variant
members that were nominated explicitly by a <I>mem-initializer</I> or
<I>designated-initializer-clause</I> or that have a default member
initializer. -- end note]</INS>
</P>

<P><INS>If the destructor of an object is terminated by an exception,
each destructor invocation that would be performed after executing the
body of the destructor (11.4.7 [<A href="https://wg21.link/class.dtor">class.dtor</A>]) and that has not
yet begun execution is performed. [<I>Note</I>: This includes virtual
base class subobjects if the destructor was invoked for a complete
object. -- end note ]</INS></P>

</BLOCKQUOTE>

<P><B>Proposed resolution (CWG telecon 2022-08-12) [SUPERSEDED]:</B></P>

<P>Change in 14.3 [<A href="https://wg21.link/except.ctor#3">except.ctor</A>] paragraph 3 as follows:</P>

<BLOCKQUOTE>

<P>If the initialization <DEL>or destruction</DEL> of an object other than by
delegating constructor is terminated by an exception, the destructor
is invoked for each of the object's <DEL>direct subobjects and, for a
complete object, virtual base class</DEL> subobjects
<INS>that were known to be initialized by the object's initialization and</INS>
<DEL>,</DEL> whose initialization has completed
(9.4 [<A href="https://wg21.link/dcl.init">dcl.init</A>]) <DEL>and whose destructor has not yet begun
execution, except that in the case of destruction, the variant members
of a union-like class are not destroyed</DEL>.
<INS>A subobject is <em>known to be initialized</em> if its initialization is
specified in 11.9.3 [<A href="https://wg21.link/class.base.init">class.base.init</A>] for initialization by
constructor, in 11.9.4 [<A href="https://wg21.link/class.inhctor.init">class.inhctor.init</A>] for initialization by
inherited constructor, in 9.4.2 [<A href="https://wg21.link/dcl.init.aggr">dcl.init.aggr</A>] for aggregate
initialization, or in 9.4.1 [<A href="https://wg21.link/dcl.init.general">dcl.init.general</A>] for
default-initialization, value-initialization, or direct-initialization
of an array. [<I>Note</I>: This includes virtual base class subobjects if the
initialization is for a complete object, and can include variant
members that were nominated explicitly by a <I>mem-initializer</I> or
<I>designated-initializer-clause</I> or that have a default member
initializer. -- end note]</INS>
</P>

<P><INS>If the destructor of an object is terminated by an exception,
each destructor invocation that would be performed after executing the
body of the destructor (11.4.7 [<A href="https://wg21.link/class.dtor">class.dtor</A>]) and that has not
yet begun execution is performed. [<I>Note</I>: This includes virtual
base class subobjects if the destructor was invoked for a complete
object. -- end note ]</INS></P>

</BLOCKQUOTE>

<P><B>Additional notes (August, 2022):</B></P>

<P>The proposed resolution above does not handle the situation where
the initialization of a closure object is terminated by an exception
during the evaluation of a lambda expression.  It also does not handle
11.4.5.3 [<A href="https://wg21.link/class.copy.ctor#14.1">class.copy.ctor</A>] bullet 14.1 (array copies in defaulted
constructors).</P>

<P><B>Proposed resolution (approved by CWG telecon 2022-09-09):</B></P>

<P>Change in 14.3 [<A href="https://wg21.link/except.ctor#3">except.ctor</A>] paragraph 3 as follows:</P>

<BLOCKQUOTE>

<P>If the initialization <DEL>or destruction</DEL> of an object other than by
delegating constructor is terminated by an exception, the destructor
is invoked for each of the object's <DEL>direct subobjects and, for a
complete object, virtual base class</DEL> subobjects
<INS>that were known to be initialized by the object's initialization and</INS>
<DEL>,</DEL> whose initialization has completed
(9.4 [<A href="https://wg21.link/dcl.init">dcl.init</A>]) <DEL>and whose destructor has not yet begun
execution, except that in the case of destruction, the variant members
of a union-like class are not destroyed</DEL>.

[<I>Note:</I> If such an object has a reference member that extends
the lifetime of a temporary object, this ends the lifetime of the
reference member, so the lifetime of the temporary object is
effectively not extended. &#8212;<I>end note</I>]

<INS>A subobject is <em>known to be initialized</em> if its initialization is
specified</INS>
<UL class="ins">
<LI><INS>in 11.9.3 [<A href="https://wg21.link/class.base.init">class.base.init</A>] for initialization by
constructor,</INS></LI>
<LI><INS>in 11.4.5.3 [<A href="https://wg21.link/class.copy.ctor">class.copy.ctor</A>] for initialization by
defaulted copy/move constructor,</INS></LI>
<LI><INS>in 11.9.4 [<A href="https://wg21.link/class.inhctor.init">class.inhctor.init</A>] for initialization by
inherited constructor,</INS></LI>
<LI><INS>in 9.4.2 [<A href="https://wg21.link/dcl.init.aggr">dcl.init.aggr</A>] for aggregate
initialization,</INS></LI>
<LI><INS>in 7.5.5.3 [<A href="https://wg21.link/expr.prim.lambda.capture">expr.prim.lambda.capture</A>] for the initialization of the
closure object when evaluating a <I>lambda-expression</I>,</INS></LI>
<LI><INS>in 9.4.1 [<A href="https://wg21.link/dcl.init.general">dcl.init.general</A>] for
default-initialization, value-initialization, or direct-initialization
of an array.</INS></LI>
</UL>
<INS>[<I>Note</I>: This includes virtual base class subobjects if the
initialization is for a complete object, and can include variant
members that were nominated explicitly by a <I>mem-initializer</I> or
<I>designated-initializer-clause</I> or that have a default member
initializer. &#8212;<I>end note</I>]</INS>
</P>

<P><INS>If the destructor of an object is terminated by an exception,
each destructor invocation that would be performed after executing the
body of the destructor (11.4.7 [<A href="https://wg21.link/class.dtor">class.dtor</A>]) and that has not
yet begun execution is performed. [<I>Note</I>: This includes virtual
base class subobjects if the destructor was invoked for a complete
object. &#8212;<I>end note</I>]</INS></P>

<P>The subobjects are
destroyed in the reverse order of the completion of their
construction. Such destruction is sequenced before entering a handler
of the <I>function-try-block</I> of the constructor or destructor, if
any.</P>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2602"></A><H4>2602.
  
consteval defaulted functions
</H4>
<B>Section: </B>9.2.6&#160; [<A href="https://wg21.link/dcl.constexpr">dcl.constexpr</A>]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>Aaron Ballman
 &#160;&#160;&#160;

 <B>Date: </B>2022-06-16




<P>It is not clear whether a defaulted consteval function is still an
immediate function even if it is not a valid constexpr function. For
example:</P>

<PRE>
  template &lt;typename Ty&gt;
  struct A {
    Ty n;
    consteval A() {}
  };

  template &lt;typename Ty&gt;
  struct B {
    Ty n;
    consteval B() = default;
  };

  A&lt;int&gt; a;
  B&lt;int&gt; b;
</PRE>

<P>The declarations of <TT>a</TT> and <TT>b</TT> should both fail due
to an uninitialized member <TT>n</TT> in each of <TT>A</TT>
and <TT>B</TT>. The <TT>= default</TT>; should not make a
difference. However, there is implementation divergence. We should be
able to lean on 7.7 [<A href="https://wg21.link/expr.const#5.5">expr.const</A>] bullet 5.5 to handle this
when the immediate invocation is required.</P>

<P><U>Possible resolution:</U></P>

<P>Change in 9.2.6 [<A href="https://wg21.link/dcl.constexpr#7">dcl.constexpr</A>] paragraph 7 as follows:</P>

<BLOCKQUOTE>

If the instantiated template specialization of a
constexpr <INS>templated</INS> function <DEL>template or member
function of a class template</DEL> would fail to satisfy the
requirements for a constexpr function, that specialization is still a
constexpr function, even though a call to such a function cannot
appear in a constant expression.
<INS>Similarly, if the instantiated template specialization of a
consteval <INS>templated</INS> function would fail to satisfy the
requirements for a consteval function, that specialization is still an
immediate function, even though an immediate invocation would be
ill-formed.</INS> If no specialization of the template would satisfy
the requirements for a constexpr <INS>or consteval</INS> function when
considered as a non-template function, the template is ill-formed, no
diagnostic required.

</BLOCKQUOTE>

<P><B>Proposed resolution (August, 2022):</B></P>

<P>Change in 9.2.6 [<A href="https://wg21.link/dcl.constexpr#4">dcl.constexpr</A>] paragraph 4 as follows:</P>

<BLOCKQUOTE>

If the instantiated template specialization of a
constexpr <INS>templated</INS> function <DEL>template or member
function of a class template</DEL> would fail to satisfy the
requirements for a constexpr function, that specialization is still a
constexpr function, even though a call to such a function cannot
appear in a constant expression.
<INS>Similarly, if the instantiated template specialization of a
consteval <INS>templated</INS> function would fail to satisfy the
requirements for a consteval function, that specialization is still an
immediate function, even though an immediate invocation would be
ill-formed.</INS>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2603"></A><H4>2603.
  
Holistic functional equivalence for function templates
</H4>
<B>Section: </B>13.7.7.2&#160; [<A href="https://wg21.link/temp.over.link">temp.over.link</A>]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>Davis Herring
 &#160;&#160;&#160;

 <B>Date: </B>2022-06-20


<P>In C++20, 13.7.7.2 [<A href="https://wg21.link/temp.over.link#7">temp.over.link</A>] paragraph 7 defined
equivalence for function templates in terms of equivalence of several
of its components; functional equivalence for them was similar in that
it was defined recursively for their "return types and parameter
lists", but differed with regard to constraints in that it required
that they "accept and are satisfied by the same set of template
argument lists". P1787R6 simplified the treatment by relying entirely
on the "depends on whether two constructs are equivalent, and they are
functionally equivalent but not equivalent" rule to make the
correspondence check between the function templates ill-formed, no
diagnostic required.</P>

<P>This created a situation where moving a constraint between
a <I>template-head</I> and a <I>requires-clause</I> makes a function
template truly different (because there is no reasonable way to read
6.4.1 [<A href="https://wg21.link/basic.scope.scope#4.3.2">basic.scope.scope</A>] bullet 4.3.2's "equivalent
[...], <I>template-head</I>s, and <I>trailing requires-clause</I>s (if
any)" as requiring a <I>joint</I> check for functional equivalence),
even if overload resolution would never be able to distinguish
them.</P>

<P><U>Suggested resolution [SUPERSEDED]:</U></P>

<P>Change in 13.7.7.2 [<A href="https://wg21.link/temp.over.link#7">temp.over.link</A>] paragraph 7 as follows:</P>

<BLOCKQUOTE>

If the validity or meaning of the program depends on whether two
constructs are equivalent, and they are functionally equivalent but
not equivalent, the program is ill-formed, no diagnostic
required. <INS>Furthermore, if two function templates do not
correspond, but accept and are satisfied by the same set of template
argument lists, the program is ill-formed, no diagnostic
required.</INS>

</BLOCKQUOTE>

<P><U>Suggested resolution (August, 2022) [SUPERSEDED]:</U></P>

<OL>

<LI>

<P>Append to 6.4.1 [<A href="https://wg21.link/basic.scope.scope#3">basic.scope.scope</A>] paragraph 3 as follows:</P>

<P>
<UL>
<LI>...</LI>
<LI>the types of their object parameters are equivalent.</LI>
</UL>
<INS>Two function templates have <I>corresponding signatures</I> if
their <I>template-parameter-list</I>s have the same length,
corresponding <I>template-parameter</I>s are equivalent, they have
equivalent non-object-parameter-type-lists and return types (if any),
and, if both are non-static members, they have corresponding object
parameters.</INS>
</P>

</LI>

<LI>
<P>Change in 6.4.1 [<A href="https://wg21.link/basic.scope.scope#4">basic.scope.scope</A>] paragraph 4 as follows:</P>

<UL>
<LI>...</LI>
<LI>
<UL>
<LI>...</LI>
<LI>both declare function templates with <INS>corresponding signatures
and</INS> equivalent <DEL>non-object-parameter-type-lists, return
types (if any),</DEL> <I>template-head</I>s<DEL>,</DEL> and trailing
<I>requires-clause</I>s (if any)<DEL>, and, if both are non-static members,
they have corresponding object parameters</DEL>.
</LI>
</UL>
</LI>
</UL>

</LI>

<LI>

<P>Change in 13.7.7.2 [<A href="https://wg21.link/temp.over.link#7">temp.over.link</A>] paragraph 7 as follows:</P>

<BLOCKQUOTE>

If the validity or meaning of the program depends on whether two
constructs are equivalent, and they are functionally equivalent but
not equivalent, the program is ill-formed, no diagnostic
required. <INS>Furthermore, if two function templates with
corresponding signatures do not correspond, but accept and are
satisfied by the same set of template argument lists, the program is
ill-formed, no diagnostic required.</INS>

</BLOCKQUOTE>

</LI>

</OL>

<P><B>Proposed resolution (approved by CWG 2022-09-09):</B></P>

<OL>

<LI>

<P>Append to 6.4.1 [<A href="https://wg21.link/basic.scope.scope#3">basic.scope.scope</A>] paragraph 3 as follows:</P>

<P>
<UL>
<LI>...</LI>
<LI>the types of their object parameters are equivalent.</LI>
</UL>
<INS>Two function templates have <I>corresponding signatures</I> if
their <I>template-parameter-list</I>s have the same length,
corresponding <I>template-parameter</I>s are equivalent, they have
equivalent non-object-parameter-type-lists and return types (if any),
and, if both are non-static members, they have corresponding object
parameters.</INS>
</P>

</LI>

<LI>
<P>Change in 6.4.1 [<A href="https://wg21.link/basic.scope.scope#4">basic.scope.scope</A>] paragraph 4 as follows:</P>

<UL>
<LI>...</LI>
<LI>
<UL>
<LI>...</LI>
<LI>both declare function templates with <INS>corresponding signatures
and</INS> equivalent <DEL>non-object-parameter-type-lists, return
types (if any),</DEL> <I>template-head</I>s<DEL>,</DEL> and trailing
<I>requires-clause</I>s (if any)<DEL>, and, if both are non-static members,
they have corresponding object parameters</DEL>.
</LI>
</UL>
</LI>
</UL>

</LI>

<LI>

<P>Change in 13.7.7.2 [<A href="https://wg21.link/temp.over.link#7">temp.over.link</A>] paragraph 7 as follows:</P>

<BLOCKQUOTE>

If the validity or meaning of the program depends on whether two
constructs are equivalent, and they are functionally equivalent but
not equivalent, the program is ill-formed, no diagnostic
required.
<INS>Furthermore, if two function templates that do not correspond</INS>

<UL>
<LI><INS>have the same name,</INS></LI>
<LI><INS>have corresponding signatures (6.4.1 [<A href="https://wg21.link/basic.scope.scope">basic.scope.scope</A>]),</INS></LI>
<LI><INS>would declare the same entity
(6.6 [<A href="https://wg21.link/basic.link">basic.link</A>]) considering them to correspond, and</INS></LI>
<LI><INS>accept and are satisfied by the same set of template argument lists,</INS></LI>
</UL>
<INS>the program is ill-formed, no diagnostic required.</INS>

</BLOCKQUOTE>

</LI>

</OL>

<BR><BR><HR>
<A NAME="2604"></A><H4>2604.
  
Attributes for an explicit specialization
</H4>
<B>Section: </B>13.9.4&#160; [<A href="https://wg21.link/temp.expl.spec">temp.expl.spec</A>]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>Aaron Ballman
 &#160;&#160;&#160;

 <B>Date: </B>2022-06-23




<P>It is unclear whether an explicit template specialization
"inherits" the attributes written on the primary template, or whether
the specialization has to repeat the attributes. For example:</P>

<PRE>
  template &lt;typename Ty&gt;
  [[noreturn]] void func(Ty);

  template &lt;&gt;
  void func&lt;int&gt;(int) {
    //<SPAN CLASS="cmnt"> Warning about returning from a noreturn function or not?</SPAN>
  }
</PRE>

<P>A similar question arises for attributes written on the parameters
of the primary function template. For example:</P>

<PRE>
  template &lt;typename Ty&gt;
  void func([[maybe_unused]] int i);

  template &lt;&gt;
  void func&lt;int&gt;(int i) {
   //<SPAN CLASS="cmnt"> i is not used, should it be warned on or not?</SPAN>
  }
</PRE>

<P>There is implementation divergence for the example.</P>

<P><U>Suggested resolution [SUPERSEDED]:</U></P>

<P>Change in 13.9.4 [<A href="https://wg21.link/temp.expl.spec#13">temp.expl.spec</A>] paragraph 13 as follows:</P>

<BLOCKQUOTE>

<INS>Any attributes applying to any part of the declaration of an explicit specialization of a function or variable template, as well as </INS>
<DEL>Whether</DEL> <INS>whether such</INS> an explicit
specialization <DEL>of a function or variable template</DEL> is
inline, constexpr, or an immediate function<INS>,</INS> is determined
by the explicit specialization and is independent of those properties
of the template.
<INS>[ Note: Attributes that would affect the association of the
declaration of an explicit specialization with the declaration of the
primary template need to match. -- end note ]</INS>

</BLOCKQUOTE>

<P><B>Proposed resolution (approved by CWG 2022-11-09):</B></P>

<P>Change 13.9.4 [<A href="https://wg21.link/temp.expl.spec">temp.expl.spec</A>] paragraph 13 as follows:</P>

<BLOCKQUOTE>

Whether an explicit specialization of a function or variable
template is inline, constexpr, or an immediate function is
determined by the explicit specialization and is independent
of those properties of the template. <INS>Similarly, attributes
appearing in the declaration of a template have no effect on an
explicit specialization of that template.</INS> [<I>Example 7:</I>

<PRE>
  template&lt;class T&gt; void f(T) { /* ... */ }
  template&lt;class T&gt; inline T g(T) { /* ... */ }

  template&lt;&gt; inline void f&lt;&gt;(int) { /* ... */ } //<SPAN CLASS="cmnt"> OK, inline</SPAN>
  template&lt;&gt; int g&lt;&gt;(int) { /* ... */ }         //<SPAN CLASS="cmnt"> OK, not inline</SPAN>

<INS>  template&lt;typename&gt; [[noreturn]] void h([[maybe_unused]] int i);
  template&lt;&gt; void h&lt;int&gt;(int i) {
    //<SPAN CLASS="cmnt"> Implementations are expected not to warn that the function returns but can</SPAN>
    //<SPAN CLASS="cmnt"> warn about the unused parameter.</SPAN>
  }</INS>
</PRE>

<P>&#8212;<I>end example</I>]</P>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2605"></A><H4>2605.
  
Implicit-lifetime aggregates
</H4>
<B>Section: </B>11.2&#160; [<A href="https://wg21.link/class.prop">class.prop</A>]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>Davis Herring
 &#160;&#160;&#160;

 <B>Date: </B>2022-06-27


<P>Subclause 11.2 [<A href="https://wg21.link/class.prop#9">class.prop</A>] paragraph 9 specifies:</P>

<BLOCKQUOTE>

A class S is an <I>implicit-lifetime class</I> if
<UL>
<LI>it is an aggregate or</LI>
<LI>it has at least one trivial eligible constructor and a trivial,
non-deleted destructor.</LI>
</UL>

</BLOCKQUOTE>

<P>However, an aggregate may have a non-deleted non-trivial destructor:</P>

<PRE>
  struct X {
    Y i;
    ~X();
  };
</PRE>

<P>This class is an aggregate, but destroying X itself (ignoring the
subobjects) does not satisfy "destroying an instance of the type runs
no code"; see P0593R6 "Implicit creation of objects for low-level
object manipulation" section 3.1.</P>

<P><B>Additional notes (September, 2022):</B></P>

<P>From a thread starting
<A HREF="http://lists.isocpp.org/core/2022/09/13217.php">here</A>:
What if <TT>X</TT> had a deleted destructor (either explicitly or
implicitly)?</P>

<P><B>CWG 2022-11-09:</B></P>

<P>A deleted destructor does not prevent an aggregate from being an
implicit-lifetime class.</P>

<P><B>Proposed resolution (approved by CWG 2022-11-09):</B></P>

<P>Change in 11.2 [<A href="https://wg21.link/class.prop#9">class.prop</A>] paragraph 9 as follows:</P>

<BLOCKQUOTE>

A class S is an <I>implicit-lifetime class</I> if
<UL>
<LI>it is an aggregate <INS>whose destructor is not user-provided</INS> or</LI>
<LI>it has at least one trivial eligible constructor and a trivial,
non-deleted destructor.</LI>
</UL>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2610"></A><H4>2610.
  
Indirect private base classes in aggregates
</H4>
<B>Section: </B>9.4.2&#160; [<A href="https://wg21.link/dcl.init.aggr">dcl.init.aggr</A>]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>Chris Bowler
 &#160;&#160;&#160;

 <B>Date: </B>2022-07-21




<P>The wording appears to prohibit aggregates from having indirect
private base classes.  That does not match existing practice and is an
unnecessary restriction. For example:</P>

<PRE>
#include &lt;type_traits&gt;

struct B1 {};
struct B2 : private B1 {};
struct S : public B2 {};

void f() {
  static_assert(std::is_aggregate&lt;S&gt;::value);
}
</PRE>

<P><B>Proposed resolution (approved by CWG 2022-08-26):</B></P>

<P>Change in 9.4.2 [<A href="https://wg21.link/dcl.init.aggr">dcl.init.aggr</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

An aggregate is an array or a class (Clause 11 [<A href="https://wg21.link/class">class</A>]) with

<UL>
<LI>no user-declared or inherited constructors
(11.4.5 [<A href="https://wg21.link/class.ctor">class.ctor</A>]),</LI>

<LI>no private or protected direct non-static data members
(11.8 [<A href="https://wg21.link/class.access">class.access</A>]),</LI>

<LI><INS>no private or protected direct base classes
(11.8.3 [<A href="https://wg21.link/class.access.base">class.access.base</A>]), and</INS></LI>

<LI>no virtual functions (11.7.3 [<A href="https://wg21.link/class.virtual">class.virtual</A>])
<INS>or virtual base classes
(11.7.2 [<A href="https://wg21.link/class.mi">class.mi</A>]).</INS><DEL>, and</DEL>
</LI>

<LI><DEL>no virtual, private, or protected base classes
(11.7.2 [<A href="https://wg21.link/class.mi">class.mi</A>]).</DEL></LI>
</UL>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2611"></A><H4>2611.
  
Missing parentheses in expansion of fold-expression could cause syntactic reinterpretation
</H4>
<B>Section: </B>13.7.4&#160; [<A href="https://wg21.link/temp.variadic">temp.variadic</A>]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>Richard Smith
 &#160;&#160;&#160;

 <B>Date: </B>2022-08-05


<P>
13.7.4 [<A href="https://wg21.link/temp.variadic#10">temp.variadic</A>] paragraph 10 expands
a <I>fold-expression</I> (including its enclosing parentheses) to an
unparenthesized expression. If interpreted literally, this could
result in reassociation and misinterpretation of the expression. For
example, given:</P>

<PRE>
template&lt;int ...N&gt; int k = 2 * (... + N);
</PRE>

<P>
... <TT>k&lt;1, 2, 3&gt;</TT> is specified as expanding to <TT>int
k&lt;1, 2, 3&gt; = 2 * 1 + (2 + 3);</TT> resulting in a value of 7
rather than the intended value of 12.
</P>

<P>Further, there is implementation divergence for the following example:</P>

<PRE>
#include &lt;type_traits&gt;
template&lt;class ...TT&gt;
void f(TT ...tt) {
  static_assert(std::is_same_v&lt;decltype((tt, ...)), int&amp;&gt;);
}
template void f(int /*,int*/);
</PRE>

<P>gcc and MSVC apply the general <I>expression</I> interpretation
of <code>decltype</code>, whereas clang and icc apply
the <I>identifier</I> special case.</P>

<P><B>Proposed resolution (approved by CWG 2022-08-26):</B></P>

Change in 13.7.4 [<A href="https://wg21.link/temp.variadic#10">temp.variadic</A>] paragraph 10 as follows:

<BLOCKQUOTE>

The instantiation of a <I>fold-expression</I>
(7.5.6 [<A href="https://wg21.link/expr.prim.fold">expr.prim.fold</A>]) produces:

<UL>
<LI>
<TT><INS>(</INS> ((E<SUB>1</SUB> <I>op</I> E<SUB>2</SUB> ) <I>op</I> . . . ) <I>op</I> E<SUB>N</SUB> <INS>)</INS></TT> for a unary left fold,</LI>
<LI>
<TT><INS>(</INS> E<SUB>1</SUB> <I>op</I> (. . . <I>op</I> (E<SUB>N-1</SUB> <I>op</I> E<SUB>N</SUB> )) <INS>)</INS></TT> for a unary right fold,</LI>
<LI>
<TT><INS>(</INS> (((E <I>op</I> E<SUB>1</SUB> ) <I>op</I> E<SUB>2</SUB> ) <I>op</I> . . . ) <I>op</I> E<SUB>N</SUB> <INS>)</INS></TT> for a binary left fold, and</LI>
<LI>
<TT><INS>(</INS> E<SUB>1</SUB> <I>op</I> (. . . <I>op</I> (E<SUB>N-1</SUB> <I>op</I> (E<SUB>N</SUB> <I>op</I> E))) <INS>)</INS></TT> for a binary right fold.</LI>
</UL>
...

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2612"></A><H4>2612.
  
Incorrect comment in example
</H4>
<B>Section: </B>9.4.1&#160; [<A href="https://wg21.link/dcl.init.general">dcl.init.general</A>]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>Jiang An
 &#160;&#160;&#160;

 <B>Date: </B>2022-05-24


<P>Subclause 9.4.1 [<A href="https://wg21.link/dcl.init.general#16.6.1">dcl.init.general</A>] bullet 16.6.1 says:</P>

<BLOCKQUOTE>

[<I>Example 2:</I> <TT>T x = T(T(T()));</TT> calls the <TT>T</TT>
default constructor to initialize <TT>x</TT>. &#8212;<I>end example</I>]

</BLOCKQUOTE>

<P>This is incorrect; in some situations, the default constructor is
not invoked (see 9.4.1 [<A href="https://wg21.link/dcl.init.general#9">dcl.init.general</A>] paragraph 9).</P>

<P><B>Proposed resolution (approved by CWG 2022-08-26):</B></P>

<P>Change in 9.4.1 [<A href="https://wg21.link/dcl.init.general#16.6.1">dcl.init.general</A>] bullet 16.6.1 as follows:</P>

<BLOCKQUOTE>

[<I>Example 2:</I> <TT>T x = T(T(T()));</TT> <DEL>calls the <TT>T</TT>
default constructor to initialize</DEL>
<INS>value-initializes</INS> <TT>x</TT>.  &#8212;<I>end example</I>]

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2613"></A><H4>2613.
  
Incomplete definition of resumer
</H4>
<B>Section: </B>9.5.4&#160; [<A href="https://wg21.link/dcl.fct.def.coroutine">dcl.fct.def.coroutine</A>]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>Jim X
 &#160;&#160;&#160;

 <B>Date: </B>2022-02-15


<P>Subclause 9.5.4 [<A href="https://wg21.link/dcl.fct.def.coroutine#8">dcl.fct.def.coroutine</A>] paragraph 8 specifies:</P>

<BLOCKQUOTE>

A suspended coroutine can be resumed to continue execution by invoking
a resumption member function (17.12.4.6 [<A href="https://wg21.link/coroutine.handle.resumption">coroutine.handle.resumption</A>]) of a
coroutine handle (17.12.4 [<A href="https://wg21.link/coroutine.handle">coroutine.handle</A>]) that refers to the
coroutine. The function that invoked a resumption member function is
called the <I>resumer</I>.

</BLOCKQUOTE>

<P>However, non-functions can also resume a coroutine, for example:</P>

<PRE>
Task task() {
  std::cout &lt;&lt; "in task\n";
  int r = co_await Line();
  std::cout &lt;&lt; "resumed\n";
  co_return r;
}
auto r = task();
auto c = (r.coro_.resume(), 0); //<SPAN CLASS="cmnt"> #1</SPAN>
</PRE>

<P><B>Proposed resolution (approved by CWG 2022-08-26):</B></P>

<P>Change in 9.5.4 [<A href="https://wg21.link/dcl.fct.def.coroutine#8">dcl.fct.def.coroutine</A>] paragraph 8 as follows:</P>

<BLOCKQUOTE>

A suspended coroutine can be resumed to continue execution by invoking
a resumption member function (17.12.4.6 [<A href="https://wg21.link/coroutine.handle.resumption">coroutine.handle.resumption</A>]) of a
coroutine handle (17.12.4 [<A href="https://wg21.link/coroutine.handle">coroutine.handle</A>]) that refers to the
coroutine. The <DEL>function</DEL> <INS>evaluation</INS> that invoked a
resumption member function is called the <I>resumer</I>.

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2614"></A><H4>2614.
  
Unspecified results for class member access
</H4>
<B>Section: </B>7.6.1.5&#160; [<A href="https://wg21.link/expr.ref">expr.ref</A>]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>Andrey Erokhin
 &#160;&#160;&#160;

 <B>Date: </B>2021-10-27


<P>Subclause 7.6.1.5 [<A href="https://wg21.link/expr.ref#6">expr.ref</A>] paragraph 6 specifies:</P>

<BLOCKQUOTE>

If <TT>E2</TT> is declared to have type &#8220;reference
to <TT>T</TT>&#8221;, then <TT>E1.E2</TT> is an lvalue; the type
of <TT>E1.E2</TT> is <TT>T</TT>. Otherwise, ...

</BLOCKQUOTE>

<P>This does not specifiy which object or functiom the resulting
lvalue designates.  A similar problem exists with member enumerators:</P>

<BLOCKQUOTE>

If <TT>E2</TT> is a member enumerator and the type of <TT>E2</TT>
is <TT>T</TT>, the expression <TT>E1.E2</TT> is a prvalue. The type
of <TT>E1.E2</TT> is <TT>T</TT>.

</BLOCKQUOTE>

<P><B>Proposed resolution (approved by CWG 2022-09-23):</B></P>

<OL>
<LI>
<P>Split and change in 7.6.1.5 [<A href="https://wg21.link/expr.ref#6">expr.ref</A>] paragraph 6 as follows:</P>

<BLOCKQUOTE>

<P>
If <TT>E2</TT> is declared to have type &#8220;reference
to <TT>T</TT>&#8221;, then <TT>E1.E2</TT> is an lvalue<DEL>; the</DEL> <INS>of</INS> type
<DEL>of <TT>E1.E2</TT> is</DEL> <TT>T</TT>. <INS>If <TT>E2</TT> is a
static data member, <TT>E1.E2</TT> designates the object or function
to which the reference is bound, otherwise <TT>E1.E2</TT> designates
the object or function to which the corresponding reference member
of <TT>E1</TT> is bound.</INS>
</P>

<P>Otherwise, ...</P>

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 7.6.1.5 [<A href="https://wg21.link/expr.ref#6.5">expr.ref</A>] bullet 6.5 as follows:</P>

<BLOCKQUOTE>

If <TT>E2</TT> is a member enumerator and the type of <TT>E2</TT>
is <TT>T</TT>, the expression <TT>E1.E2</TT> is a
prvalue<DEL>. The</DEL> <INS>of</INS> type <DEL>of <TT>E1.E2</TT>
is</DEL> <TT>T</TT> <INS>whose value is the value of the
enumerator</INS>.

</BLOCKQUOTE>

</LI>
</OL>

<BR><BR><HR>
<A NAME="2616"></A><H4>2616.
  
Imprecise restrictions on <TT>break</TT> and <TT>continue</TT>
</H4>
<B>Section: </B>Clause 8&#160; [<A href="https://wg21.link/stmt.stmt">stmt.stmt</A>]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>Jim X
 &#160;&#160;&#160;

 <B>Date: </B>2022-08-24


<P>Consider:</P>

<PRE>
for (int i = 0; i&lt; 10; ++i){
  auto f = [](){
    break; //<SPAN CLASS="cmnt"> #1</SPAN>
  };
}
</PRE>

<P>Subclause 8.7.2 [<A href="https://wg21.link/stmt.break#1">stmt.break</A>] paragraph 1 specifies:</P>

<BLOCKQUOTE>

The <TT>break</TT> statement shall occur only in
an <I>iteration-statement</I> or a <TT>switch</TT> statement and
causes termination of the smallest
enclosing <I>iteration-statement</I> or <TT>switch</TT> statement;
control passes to the statement following the terminated statement, if
any.

</BLOCKQUOTE>

<P>Does the <TT>break</TT> at #1 "occur" in the <TT>for</TT> loop?</P>

<P><B>Proposed resolution (approved by CWG 2022-08-26):</B></P>

<OL>

<LI>
<P>Append to 8.1 [<A href="https://wg21.link/stmt.pre#3">stmt.pre</A>] paragraph 3 as follows:</P>

<BLOCKQUOTE>
<P>... <INS>A statement S1 is <I>enclosed by</I> a statement S2 if S2
encloses S1.</INS>
</P>

<P>The rules for conditions apply both...</P>
</BLOCKQUOTE>

</LI>

<LI>
<P>Change in 8.2 [<A href="https://wg21.link/stmt.label#2">stmt.label</A>] paragraph 2 as follows:</P>

<BLOCKQUOTE>

<DEL>Case labels and default labels shall occur only
in <TT>switch</TT> statements</DEL>
<INS>A <I>labeled-statement</I> whose <I>label</I> is a case or
default label shall be enclosed by (8.1 [<A href="https://wg21.link/stmt.pre">stmt.pre</A>])
a <TT>switch</TT> statement (8.5.3 [<A href="https://wg21.link/stmt.switch">stmt.switch</A>]).</INS>.

</BLOCKQUOTE>

</LI>

<LI>

<P>Change in 8.7.2 [<A href="https://wg21.link/stmt.break#1">stmt.break</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

<DEL>The</DEL> <INS>A</INS> <TT>break</TT> statement shall <DEL>occur
only in</DEL> <INS>be enclosed by (8.1 [<A href="https://wg21.link/stmt.pre">stmt.pre</A>])</INS>
an <I>iteration-statement</I> <INS>(8.6 [<A href="https://wg21.link/stmt.iter">stmt.iter</A>])</INS> or
a <TT>switch</TT>
statement <DEL>and</DEL> <INS>(8.5.3 [<A href="https://wg21.link/stmt.switch">stmt.switch</A>]). The <TT>break</TT>
statement</INS> causes termination of the smallest
<INS>such</INS> enclosing
<DEL><I>iteration-statement</I> or <TT>switch</TT></DEL> statement;
control passes to the statement following the terminated statement, if
any.

</BLOCKQUOTE>

</LI>

<LI>

<P>Change in 8.7.3 [<A href="https://wg21.link/stmt.cont#1">stmt.cont</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

<DEL>The</DEL> <INS>A</INS> <TT>continue</TT> statement
shall <DEL>occur only in</DEL> <INS>be enclosed by
(8.1 [<A href="https://wg21.link/stmt.pre">stmt.pre</A>])</INS> an <I>iteration-statement</I>
<INS>(8.6 [<A href="https://wg21.link/stmt.iter">stmt.iter</A>])</INS>
<DEL>and</DEL><INS>. The <TT>continue</TT> statement</INS> causes
control to pass to the loop-continuation portion of the smallest
<INS>such</INS> enclosing
<DEL><I>iteration-statement</I></DEL> <INS>statement</INS>,
that is, to the end of the loop. ...

</BLOCKQUOTE>

</LI>

</OL>

<BR><BR><HR>
<A NAME="2618"></A><H4>2618.
  
Substitution during deduction should exclude exception specifications
</H4>
<B>Section: </B>13.10.3.1&#160; [<A href="https://wg21.link/temp.deduct.general">temp.deduct.general</A>]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>Christof Meerwald
 &#160;&#160;&#160;

 <B>Date: </B>2021-11-27


<P>Subclause 13.10.3.1 [<A href="https://wg21.link/temp.deduct.general#7">temp.deduct.general</A>] paragraph 7 specifies:</P>

<BLOCKQUOTE>

<P>
The substitution occurs in all types and expressions that are used in
the function type and in template parameter declarations. The
expressions include not only constant expressions such as those that
appear in array bounds or as nontype template arguments but also
general expressions (i.e., non-constant expressions) inside sizeof,
decltype, and other contexts that allow non-constant expressions. The
substitution proceeds in lexical order and stops when a condition that
causes deduction to fail is encountered. If substitution into
different declarations of the same function template would cause
template instantiations to occur in a different order or not at all,
the program is ill-formed; no diagnostic required.
</P>
<P>[<I>Note 4:</I> The equivalent substitution in exception
specifications is done only when the <I>noexcept-specifier</I> is
instantiated, at which point a program is ill-formed if the
substitution results in an invalid type or expression. &#8212;<I>end
note</I>]
</P>

</BLOCKQUOTE>

<P>The note says that substitution into the <I>noexcept-specifier</I>
occurs late, but the normative text does not support that, because the
exception specification is part of the function type.</P>

<P>Subclause 13.10.3.1 [<A href="https://wg21.link/temp.deduct.general#8">temp.deduct.general</A>] paragraph 8 specifies:</P>

<BLOCKQUOTE>

Only invalid types and expressions in the immediate context of the
function type, its template parameter types, and
its <I>explicit-specifier</I> can result in a deduction failure.

</BLOCKQUOTE>

<P>However, paragraph 7 does not mention the <I>explicit-specifier</I>
when describing the substitution.</P>

<P><B>Proposed resolution (approved by CWG 2022-09-09):</B></P>

<P>Change in 13.10.3.1 [<A href="https://wg21.link/temp.deduct.general#7">temp.deduct.general</A>] paragraph 7 as follows:</P>

<BLOCKQUOTE>

<P>
<INS>The <I>deduction substitution loci</I> are</INS>
<UL>
<LI><INS>the function type outside of the <I>noexcept-specifier</I>,</INS></LI>
<LI><INS>the <I>explicit-specifier</I>, and</INS></LI>
<LI>
<INS>the template parameter declarations</INS>.</LI>
</UL>
The substitution occurs in all types and expressions that are used in
the <DEL>function type and in template parameter declarations</DEL>
<INS>deduction substitution loci</INS>. ...
</P>

</BLOCKQUOTE>

<P>Change in 13.10.3.1 [<A href="https://wg21.link/temp.deduct.general#8">temp.deduct.general</A>] paragraph 8 as follows:</P>

<BLOCKQUOTE>
...
<DEL>Only invalid</DEL> <INS>Invalid</INS> types and
expressions <INS>can result in a deduction failure only</INS> in the
immediate context of the <DEL>function type, its template parameter
types, and its <I>explicit-specifier</I></DEL>
<INS>deduction substitution loci</INS> <DEL>can result in a deduction
failure</DEL>.

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2619"></A><H4>2619.
  
Kind of initialization for a <I>designated-initializer-list</I>
</H4>
<B>Section: </B>9.4.2&#160; [<A href="https://wg21.link/dcl.init.aggr">dcl.init.aggr</A>]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>Jim X
 &#160;&#160;&#160;

 <B>Date: </B>2022-07-13


<P>Consider:</P>

<PRE>
struct S {
  explicit S(int){}
};
struct A {
  S s;
};
struct B {
  union {
    S s;
  };
};
int main() {
  A a1 = {.s{0}};  //<SPAN CLASS="cmnt"> #1</SPAN>
  A a2{.s{0}};     //<SPAN CLASS="cmnt"> #2</SPAN>
  B b1 = {.s{0}};  //<SPAN CLASS="cmnt"> #3</SPAN>
  B b2{.s{0}};     //<SPAN CLASS="cmnt"> #4</SPAN>
}
</PRE>

<P>Subclause 9.4.2 [<A href="https://wg21.link/dcl.init.aggr#4.2">dcl.init.aggr</A>] bullet 4.2 specifies:</P>

<BLOCKQUOTE>

Otherwise, the element is copy-initialized from the
corresponding <I>initializer-clause</I> or is initialized with
the <I>brace-or-equal-initializer</I> of the
corresponding <I>designated-initializer-clause</I>.

</BLOCKQUOTE>

<P>It is unclear what kind of initialization is performed for "is
initialized".  For example, one could imagine that the top-level kind
of initialization is inherited.  On the other hand,
9.4.1 [<A href="https://wg21.link/dcl.init.general#14">dcl.init.general</A>] paragraph 14 specifies:</P>

<BLOCKQUOTE>

The initialization that occurs in the = form of
a <I>brace-or-equal-initializer</I> or condition
(8.5 [<A href="https://wg21.link/stmt.select">stmt.select</A>]), as well as in argument passing, function
return, throwing an exception (14.2 [<A href="https://wg21.link/except.throw">except.throw</A>]), handling an
exception (14.4 [<A href="https://wg21.link/except.handle">except.handle</A>]), and aggregate member
initialization (9.4.2 [<A href="https://wg21.link/dcl.init.aggr">dcl.init.aggr</A>]), is
called <I>copy-initialization</I>.

</BLOCKQUOTE>

<P>There is implementation divergence: gcc and icc reject the example; clang and
MSVC accept.</P>

<P><U>Suggested resolution [SUPERSEDED]:</U></P>

<OL>
<LI>
<P>Change in 9.4.2 [<A href="https://wg21.link/dcl.init.aggr#4.1">dcl.init.aggr</A>] bullet 4.1 as follows:</P>

<BLOCKQUOTE>

If the element is an anonymous union member and the initializer list
is a brace-enclosed <I>designated-initializer-list</I>, the element is
initialized by the <DEL><I>designated-initializer-list</I></DEL>
<INS><I>braced-init-list</I></INS> <TT>{ D }</TT>, where <TT>D</TT> is
the <I>designated-initializer-clause</I> naming a member of the
anonymous union member.

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 9.4.2 [<A href="https://wg21.link/dcl.init.aggr#4.2">dcl.init.aggr</A>] bullet 4.2 as follows:</P>

<BLOCKQUOTE>

Otherwise, the element is copy-initialized from the
corresponding <I>initializer-clause</I> or
is <DEL>initialized</DEL> <INS>copy-initialized or
direct-initialized</INS> with the <I>brace-or-equal-initializer</I> of
the corresponding <I>designated-initializer-clause</I><INS>, according
to the form of the <I>brace-or-equal-initializer</I>
(9.4.1 [<A href="https://wg21.link/dcl.init.general">dcl.init.general</A>])</INS>. ...

</BLOCKQUOTE>
</LI>
</OL>

<P><B>CWG telecon 2022-09-09:</B></P>

<P>The examples #1 to #4 should all be valid, direct-initializing
the <TT>s</TT> member.</P>

<P><B>Proposed resolution (approved by CWG 2022-09-23):</B></P>

<OL>

<LI>
<P>Change in 9.4.1 [<A href="https://wg21.link/dcl.init.general#14">dcl.init.general</A>] paragraph 14 as follows:</P>

<BLOCKQUOTE>

The initialization that occurs in the = form of
a <I>brace-or-equal-initializer</I> or condition
(8.5 [<A href="https://wg21.link/stmt.select">stmt.select</A>]), as well as in argument passing, function
return, throwing an exception (14.2 [<A href="https://wg21.link/except.throw">except.throw</A>]), handling an
exception (14.4 [<A href="https://wg21.link/except.handle">except.handle</A>]), and aggregate member
initialization <INS>other than by
a <I>designated-initializer-clause</I></INS>
(9.4.2 [<A href="https://wg21.link/dcl.init.aggr">dcl.init.aggr</A>]), is called <I>copy-initialization</I>.

</BLOCKQUOTE>

</LI>

<LI>
<P>Change in 9.4.2 [<A href="https://wg21.link/dcl.init.aggr#4.1">dcl.init.aggr</A>] bullet 4.1 as follows:</P>

<BLOCKQUOTE>

If the element is an anonymous union member and the initializer list
is a brace-enclosed <I>designated-initializer-list</I>, the element is
initialized by the <DEL><I>designated-initializer-list</I></DEL>
<INS><I>braced-init-list</I></INS> <TT>{ D }</TT>, where <TT>D</TT> is
the <I>designated-initializer-clause</I> naming a member of the
anonymous union member.

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 9.4.2 [<A href="https://wg21.link/dcl.init.aggr#4.2">dcl.init.aggr</A>] bullet 4.2 as follows:</P>

<BLOCKQUOTE>

Otherwise, the element is copy-initialized from the
corresponding <I>initializer-clause</I> or
is initialized with the <I>brace-or-equal-initializer</I> of
the corresponding <I>designated-initializer-clause</I>.
If that initializer is of the form <I>assignment-expression</I> or
= <I>assignment-expression</I> and a narrowing conversion
(9.4.5 [<A href="https://wg21.link/dcl.init.list">dcl.init.list</A>]) is required to convert the expression,
the program is ill-formed.
<INS>[ Note: If the initialization is
by <I>designated-initializer-clause</I>, its form determines whether
copy-initialization or direct-initialization is performed.-- end
note]</INS>
</BLOCKQUOTE>
</LI>
</OL>

<BR><BR><HR>
<A NAME="2620"></A><H4>2620.
  
Nonsensical disambiguation rule
</H4>
<B>Section: </B>9.3.3&#160; [<A href="https://wg21.link/dcl.ambig.res">dcl.ambig.res</A>]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>Krystian Stasiowski
 &#160;&#160;&#160;

 <B>Date: </B>2019-04-18


<P>Subclause 9.3.3 [<A href="https://wg21.link/dcl.ambig.res#1">dcl.ambig.res</A>] paragraph 1 specifies:</P>

<BLOCKQUOTE>

The ambiguity arising from the similarity between a function-style
cast and a declaration mentioned in 8.9 [<A href="https://wg21.link/stmt.ambig">stmt.ambig</A>] can also
occur in the context of a declaration. In that context, the choice is
between a function declaration with a redundant set of parentheses
around a parameter name and an object declaration with a
function-style cast as the initializer. Just as for the ambiguities
mentioned in 8.9 [<A href="https://wg21.link/stmt.ambig">stmt.ambig</A>], the resolution is to consider
any construct that could possibly be a declaration a declaration.

</BLOCKQUOTE>

<P>The specification correctly describes an ambiguity between a
function declaration and an object declaration, but resolves the
ambiguity to a "declaration", which does not offer any insight.</P>

<P><B>Proposed resolution (2022-09-09) [SUPERSEDED]:</B></P>

<P>Change in 9.3.3 [<A href="https://wg21.link/dcl.ambig.res#1">dcl.ambig.res</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

... <DEL>Just as for the ambiguities mentioned in
8.9 [<A href="https://wg21.link/stmt.ambig">stmt.ambig</A>], the</DEL> <INS>The</INS> resolution is to
consider any construct that could possibly be a <INS>function</INS>
declaration a <INS>function</INS> declaration.

</BLOCKQUOTE>

<P><B>Proposed resolution (approved by CWG 2022-09-23):</B></P>

<P>Change in 9.3.3 [<A href="https://wg21.link/dcl.ambig.res#1">dcl.ambig.res</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

The ambiguity arising from the similarity between a function-style
cast and a declaration mentioned in 8.9 [<A href="https://wg21.link/stmt.ambig">stmt.ambig</A>] can also
occur in the context of a declaration. In that context, the choice is
between
<DEL>a function declaration with a redundant set of parentheses around
a parameter name and</DEL> an object declaration with a function-style
cast as the initializer
<INS>and a declaration involving a function declarator with a
redundant set of parentheses around a parameter name</INS>.  Just as
for the ambiguities mentioned in 8.9 [<A href="https://wg21.link/stmt.ambig">stmt.ambig</A>], the
resolution is to consider any construct<INS>, such as the potential
parameter declaration,</INS> that could possibly be a
declaration <INS>to be</INS> a declaration.

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2622"></A><H4>2622.
  
Compounding types from function and pointer-to-member types
</H4>
<B>Section: </B>Clause Annex B&#160; [<A href="https://wg21.link/implimits">implimits</A>]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>Jim X
 &#160;&#160;&#160;

 <B>Date: </B>2022-09-02


<P>Clause Annex B [<A href="https://wg21.link/implimits#2.3">implimits</A>] bullet 2.3 specifies:</P>

<BLOCKQUOTE>

<UL>
<LI>
Pointer (9.3.4.2 [<A href="https://wg21.link/dcl.ptr">dcl.ptr</A>]), array
(9.3.4.5 [<A href="https://wg21.link/dcl.array">dcl.array</A>]), and function
(9.3.4.6 [<A href="https://wg21.link/dcl.fct">dcl.fct</A>]) declarators (in any combination)
modifying a class, arithmetic, or incomplete type in a declaration
[256].
</LI>
</UL>

</BLOCKQUOTE>

<P>This omits function types as the to-be-modified type, and ignores
pointer-to-member declarators.</P>

<P><B>Proposed resolution (approved by CWG 2022-09-23):</B></P>

<P>Change in Clause Annex B [<A href="https://wg21.link/implimits#2.3">implimits</A>] bullet 2.3 as follows:</P>

<BLOCKQUOTE>

<UL>
<LI>
Pointer (9.3.4.2 [<A href="https://wg21.link/dcl.ptr">dcl.ptr</A>]),
<INS>pointer-to-member (9.3.4.4 [<A href="https://wg21.link/dcl.mptr">dcl.mptr</A>]),</INS> array
(9.3.4.5 [<A href="https://wg21.link/dcl.array">dcl.array</A>]), and function
(9.3.4.6 [<A href="https://wg21.link/dcl.fct">dcl.fct</A>]) declarators (in any combination)
modifying a <DEL>class, arithmetic, or incomplete</DEL> type in a
declaration [256].
</LI>
</UL>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2624"></A><H4>2624.
  
Array delete expression with no array cookie
</H4>
<B>Section: </B>7.6.2.9&#160; [<A href="https://wg21.link/expr.delete">expr.delete</A>]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>Blacktea Hamburger
 &#160;&#160;&#160;

 <B>Date: </B>2022-08-22


<P>Consider:</P>

<PRE>
char *p = static_cast&lt;char*&gt;(operator new[](2));
p = new (p) char[2];  // #1
delete[] p;           // #2
</PRE>

<P>Subclause 7.6.2.8 [<A href="https://wg21.link/expr.new#16">expr.new</A>] paragraph 16 specifies:</P>

<BLOCKQUOTE>

... When a <I>new-expression</I> calls an allocation function and that
allocation has not been extended, the <I>new-expression</I> passes the
amount of space requested to the allocation function as the first
argument of type std::size_t. That argument shall be no less than the
size of the object being created; it may be greater than the size of
the object being created only if the object is an array and the
allocation function is not a non-allocating form
(17.6.3.4 [<A href="https://wg21.link/new.delete.placement">new.delete.placement</A>]). ...

</BLOCKQUOTE>

<P>Subclause 7.6.2.9 [<A href="https://wg21.link/expr.delete#2">expr.delete</A>] paragraph 2 specifies:</P>

<BLOCKQUOTE>

... In an array delete expression, the value of the operand
of <TT>delete</TT> may be a null pointer value or a pointer value that
resulted from a previous array <I>new-expression</I>. [ Footnote:
... ]  If not, the behavior is undefined.

</BLOCKQUOTE>

<P>The non-allocating form of the <I>new-expression</I> at #1 is
constrained not to place an array cookie at the start of the array.
Yet, the array delete appears to be expected to divine that fact.</P>

<P><B>Proposed resolution (approved by CWG 2022-10-07):</B></P>

<P>Change in 7.6.2.9 [<A href="https://wg21.link/expr.delete#2">expr.delete</A>] paragraph 2 as follows:</P>

<BLOCKQUOTE>

... In an array delete expression, the value of the operand
of <TT>delete</TT> may be a null pointer value or a pointer value that
resulted from a previous array <I>new-expression</I> <INS>whose
allocation function was not a non-allocating form
(17.6.3.4 [<A href="https://wg21.link/new.delete.placement">new.delete.placement</A>])</INS>. [ Footnote: ... ]  If not, the
behavior is undefined.

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2625"></A><H4>2625.
  
Deletion of pointer to out-of-lifetime object
</H4>
<B>Section: </B>6.7.3&#160; [<A href="https://wg21.link/basic.life">basic.life</A>]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>Blacktea Hamburger
 &#160;&#160;&#160;

 <B>Date: </B>2022-08-27


<P>Consider:</P>

<PRE>
struct S {};

int main() {
  S* p = new S;
  p-&gt;~S();
  delete p;
}
</PRE>

<P>This code appears to be allowed per 6.7.3 [<A href="https://wg21.link/basic.life#6.1">basic.life</A>] bullet 6.1:</P>

<BLOCKQUOTE>

The program has undefined behavior if:

<UL>
<LI>the object will be or was of a class type with a non-trivial
destructor and the pointer is used as the operand of
a <I>delete-expression</I>,</LI>

<LI>...</LI>
</UL>

</BLOCKQUOTE>

<P>However, this calls the (trivial) destructor on <TT>*p</TT> twice.
Invoking a non-static member function of an out-of-lifetime object is
generally undefined behavior per 6.7.3 [<A href="https://wg21.link/basic.life#6.2">basic.life</A>] bullet 6.2 and 6.7.3 [<A href="https://wg21.link/basic.life#7.2">basic.life</A>] bullet 7.2.  The rules
ought to be consistent.</P>

<P><B>Proposed resolution (approved by CWG 2022-10-07):</B></P>

<P>Change in 6.7.3 [<A href="https://wg21.link/basic.life#6.1">basic.life</A>] bullet 6.1 as follows:</P>

<BLOCKQUOTE>

The program has undefined behavior if:

<UL>
<LI>
<DEL>the object will be or was of a class type with a non-trivial
destructor and</DEL> the pointer is used as the operand of
a <I>delete-expression</I>,</LI>

<LI>...</LI>
</UL>

</BLOCKQUOTE>


<BR><BR><HR>
<A NAME="2626"></A><H4>2626.
  
Rephrase ones' complement using base-2 representation
</H4>
<B>Section: </B>7.6.2.2&#160; [<A href="https://wg21.link/expr.unary.op">expr.unary.op</A>]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>Jim X
 &#160;&#160;&#160;

 <B>Date: </B>2022-09-10


<P>Subclause 7.6.2.2 [<A href="https://wg21.link/expr.unary.op#10">expr.unary.op</A>] paragraph 10 specifies:</P>

<BLOCKQUOTE>

The operand of ~ shall have integral or unscoped enumeration type; the
result is the ones' complement of its operand. Integral promotions are
performed. The type of the result is the type of the promoted operand.
There is an ambiguity in the grammar...

</BLOCKQUOTE>

<P>This should be phrased in terms of the base-2 representation
similar to bitwise-AND, instead of alluding to some bit representation
by using the term "ones' complement".</P>

<P><B>Proposed resolution (approved by CWG 2022-10-07):</B></P>

<P>Subclause 7.6.2.2 [<A href="https://wg21.link/expr.unary.op#10">expr.unary.op</A>] paragraph 10 specifies:</P>

<BLOCKQUOTE>

The operand of ~ shall have integral or unscoped enumeration
type<DEL>; the result is the ones' complement of its
operand</DEL>. Integral promotions are performed. The type of the
result is the type of the promoted operand.
<INS>Given the coefficients <TT>x<SUB>i</SUB></TT> of the base-2
representation (6.8.2 [<A href="https://wg21.link/basic.fundamental">basic.fundamental</A>]) of the promoted
operand <TT>x</TT>, the coefficient <TT>r<SUB>i</SUB></TT> of the
base-2 representation of the result <TT>r</TT> is 1
if <TT>x<SUB>i</SUB></TT> is 0, and 0 otherwise.</INS>

There is an ambiguity in the grammar...

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2627"></A><H4>2627.
  
Bit-fields and narrowing conversions
</H4>
<B>Section: </B>9.4.5&#160; [<A href="https://wg21.link/dcl.init.list">dcl.init.list</A>]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>Tim Song
 &#160;&#160;&#160;

 <B>Date: </B>2021-08-13




<P>Consider:</P>

<PRE>
struct C {
  long long i : 8;
};

void f() {
  C x{1}, y{2};
  x.i &lt;=&gt; y.i; //<SPAN CLASS="cmnt"> error: narrowing conversion required (7.6.8 [<A href="https://wg21.link/expr.spaceship#4.1">expr.spaceship</A>] bullet 4.1)</SPAN>
}
</PRE>

<P>The rules for narrowing conversions in 9.4.5 [<A href="https://wg21.link/dcl.init.list#7">dcl.init.list</A>] paragraph 7 consider only the source type, even though integral
promotions can change the type of a bit-field to a smaller integer
type without loss of value range according to 7.3.7 [<A href="https://wg21.link/conv.prom#5">conv.prom</A>] paragraph 5:</P>

<BLOCKQUOTE>

A prvalue for an integral bit-field (11.4.10 [<A href="https://wg21.link/class.bit">class.bit</A>]) can
be converted to a prvalue of type <TT>int</TT> if <TT>int</TT> can
represent all the values of the bit-field; otherwise, it can be
converted to <TT>unsigned int</TT> if <TT>unsigned int</TT> can
represent all the values of the bit-field. If the bit-field is larger
yet, no integral promotion applies to it. If the bit-field has
enumeration type, it is treated as any other value of that type for
promotion purposes.

</BLOCKQUOTE>

<P>There is implementation divergence in the handling of this example.</P>

<P><B>Proposed resolution (approved by CWG 2022-10-07):</B></P>

<P>Change in 9.4.5 [<A href="https://wg21.link/dcl.init.list#7.4">dcl.init.list</A>] bullet 7.4 as follows:</P>

<BLOCKQUOTE>

<P>A narrowing conversion is an implicit conversion</P>

<UL>
<LI>...</LI>

<LI>from an integer type or unscoped enumeration type to an integer
type that cannot represent all the values of the original type, except
where

<UL>
<LI><INS>the source is a bit-field whose width <I>w</I> is less than
that of its type (or, for an enumeration type, its underlying type)
and the target type can represent all the values of a hypothetical
extended integer type with width <I>w</I> and with the same signedness
as the original type or</INS></LI>
<LI>the source is a constant expression whose value after integral
promotions will fit into the target type, or
</LI>
</UL>

</LI>

<LI>...</LI>
</UL>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2629"></A><H4>2629.
  
Variables of floating-point type as <TT>switch</TT> conditions
</H4>
<B>Section: </B>8.5.3&#160; [<A href="https://wg21.link/stmt.switch">stmt.switch</A>]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>Jim X
 &#160;&#160;&#160;

 <B>Date: </B>2022-09-07


<P>Consider:</P>

<PRE>
switch(float v = 0) {
  case 0: ;
}
</PRE>

<P>Subclause 8.1 [<A href="https://wg21.link/stmt.pre#5">stmt.pre</A>] paragraph 5 specifies:</P>

<BLOCKQUOTE>

... The value of a <I>condition</I> that is an initialized declaration in a
<TT>switch</TT> statement is the value of the declared variable if it has
integral or enumeration type, or of that variable implicitly converted
to integral or enumeration type otherwise. ...

</BLOCKQUOTE>

<P>That appears to permit variables of floating-point type, whose
value can be converted to integral type.  In
contrast, <I>expression</I>s of floating-point type are prohibited by
8.5.3 [<A href="https://wg21.link/stmt.switch#2">stmt.switch</A>] paragraph 2:</P>

<BLOCKQUOTE>

The condition shall be of integral type, enumeration type, or class type. ...

</BLOCKQUOTE>

<P><U>Possible resolution [SUPERSEDED]:</U></P>

<P>Change in 8.1 [<A href="https://wg21.link/stmt.pre#5">stmt.pre</A>] paragraph 5 as follows:</P>

<BLOCKQUOTE>

... The value of a <I>condition</I> that is an initialized declaration in a
<TT>switch</TT> statement is the value of the declared variable if it
has integral or enumeration type, or of that variable implicitly
converted to integral or enumeration type <INS>if it has class
type;</INS> otherwise <INS>the program is ill-formed</INS>. ...

</BLOCKQUOTE>

<P><B>CWG telecon 2022-10-21:</B></P>

<P>Rewording is needed.</P>

<P><B>Proposed resolution (approved by CWG 2022-11-09):</B></P>

<OL>

<LI>

<P>Change in 8.1 [<A href="https://wg21.link/stmt.pre#5">stmt.pre</A>] paragraph 5 as follows:</P>

<BLOCKQUOTE>

... <DEL>The value of a <I>condition</I> that is an initialized declaration in a
<TT>switch</TT> statement is the value of the declared variable if it
has integral or enumeration type, or of that variable implicitly
converted to integral or enumeration type otherwise.</DEL> ...

</BLOCKQUOTE>

</LI>

<LI>

<P>Change in 8.5.3 [<A href="https://wg21.link/stmt.switch#2">stmt.switch</A>] paragraph 2 as follows:</P>

<BLOCKQUOTE>

<INS>The value of a <I>condition</I> that is an initialized
declaration is the value of the declared variable, or the value of
the <I>expression</I> otherwise.</INS> The <INS>value of the</INS>
condition shall be of integral type, enumeration type, or class
type. If of class type, the condition is contextually implicitly
converted (7.3 [<A href="https://wg21.link/conv">conv</A>]) to an integral or enumeration
type. If the (possibly converted) type is subject to integral
promotions (7.3.7 [<A href="https://wg21.link/conv.prom">conv.prom</A>]), the condition is converted to
the promoted type. ...

</BLOCKQUOTE>

</LI>

</OL>

<BR><BR><HR>
<A NAME="2630"></A><H4>2630.
  
Syntactic specification of class completeness
</H4>
<B>Section: </B>11.4.1&#160; [<A href="https://wg21.link/class.mem.general">class.mem.general</A>]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>Jim X
 &#160;&#160;&#160;

 <B>Date: </B>2022-07-04


<P>Consider:</P>

<PRE>
//<SPAN CLASS="cmnt"> translation unit 1</SPAN>
export module A;
export class X {};

//<SPAN CLASS="cmnt"> translation unit 2</SPAN>
import A;
X x; //<SPAN CLASS="cmnt"> is </SPAN><TT>X</TT><SPAN CLASS="cmnt"> complete at this point?</SPAN>
</PRE>

<P>Subclause 11.4.1 [<A href="https://wg21.link/class.mem.general#8">class.mem.general</A>] paragraph 8 specifies:</P>

<BLOCKQUOTE>

A class is considered a completely-defined object type
(6.8.1 [<A href="https://wg21.link/basic.types.general">basic.types.general</A>]) (or complete type) at the
closing <TT>}</TT> of the <I>class-specifier</I>. ...

</BLOCKQUOTE>

<P>The syntactic (even lexical) reference to the closing <TT>}</TT>
does not address the question when a different translation unit
regards a class as complete.  However, it seems this provision is
entirely redundant given 6.3 [<A href="https://wg21.link/basic.def.odr#13">basic.def.odr</A>] paragraph 13:</P>

<BLOCKQUOTE>

A definition of a class shall be reachable in every context in which
the class is used in a way that requires the class type to be
complete.

</BLOCKQUOTE>

<P>The standard never asks the question: "Is class X complete?"; it
always specifies "X shall be complete" (otherwise the program is
ill-formed).</P>

<P><U>Possible resolution [SUPERSEDED]:</U></P>

<P>Change in 11.4.1 [<A href="https://wg21.link/class.mem.general#8">class.mem.general</A>] paragraph 8 as follows:</P>

<BLOCKQUOTE>

<DEL>A class is considered a completely-defined object type
(6.8.1 [<A href="https://wg21.link/basic.types.general">basic.types.general</A>]) (or complete type) at the
closing <TT>}</TT> of the <I>class-specifier</I>.
The</DEL> <INS>A</INS> class is regarded as complete within its
complete-class contexts; otherwise it is regarded as incomplete within
its own class <I>member-specification</I>.

</BLOCKQUOTE>

<P><B>CWG telecon 2022-10-21:</B></P>

<P>Explicitly refer to reachable definitions.</P>

<P><B>Proposed resolution (approved by CWG 2022-11-09):</B></P>

<P>Change in 11.4.1 [<A href="https://wg21.link/class.mem.general#8">class.mem.general</A>] paragraph 8 as follows:</P>

<BLOCKQUOTE>

<DEL>A class is considered a completely-defined object type
(6.8.1 [<A href="https://wg21.link/basic.types.general">basic.types.general</A>]) (or complete type) at the
closing <TT>}</TT> of the <I>class-specifier</I>.
The</DEL> <INS>A</INS> class is regarded as complete <INS>where its
definition is reachable and</INS> within its complete-class contexts;
otherwise it is regarded as incomplete within its own
class <I>member-specification</I>.

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2635"></A><H4>2635.
  
Constrained structured bindings
</H4>
<B>Section: </B>9.1&#160; [<A href="https://wg21.link/dcl.pre">dcl.pre</A>]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>Corentin Jabot
 &#160;&#160;&#160;

 <B>Date: </B>2022-10-20




<P>Consider:</P>

<PRE>
template&lt;class T&gt; concept C = true;
C auto [x, y] = std::pair{1, 2}; //<SPAN CLASS="cmnt"> ok?</SPAN>
</PRE>

<P>Subclause 9.1 [<A href="https://wg21.link/dcl.pre#6">dcl.pre</A>] paragraph 6 specifies:</P>

<BLOCKQUOTE>

A <I>simple-declaration</I> with an <I>identifier-list</I> is called a
<I>structured binding declaration</I> (9.6 [<A href="https://wg21.link/dcl.struct.bind">dcl.struct.bind</A>]). If
the <I>decl-specifier-seq</I> contains any <I>decl-specifier</I> other
than static, thread_local, auto (9.2.9.6 [<A href="https://wg21.link/dcl.spec.auto">dcl.spec.auto</A>]),
or <I>cv-qualifier</I> s, the program is ill-formed.

</BLOCKQUOTE>

<P>Use of the word "contains" leads to an interpretation that
any <I>placeholder-type-specifier</I>
(9.2.9.6.1 [<A href="https://wg21.link/dcl.spec.auto.general">dcl.spec.auto.general</A>]), possibly including
a <I>type-constraint</I>, is valid here, since
a <I>placeholder-type-specifier</I> is a <I>decl-specifier</I> and
"contains" <TT>auto</TT>.</P>

<P>However, paper P1141R2 (Yet another approach for constrained
declarations), applied in November 2018, expressly excludes structured
bindings from constrained <TT>auto</TT>:</P>

<BLOCKQUOTE>

Structured bindings do deduce auto in some cases; however, the auto is
deduced from the whole (and not from the individual components). It is
somewhat doubtful that applying the constraint to the whole, as
opposed to (for example) applying separately to each component, is the
correct semantic. Therefore, we propose to defer enabling the
application of constraints to structured bindings to separate papers.

</BLOCKQUOTE>

<P>Notwithstanding, clang, gcc, and MSVC accept the example.</P>

<P><B>Proposed resolution (approved by CWG 2022-10-21):</B></P>

<P>Change in 9.1 [<A href="https://wg21.link/dcl.pre#6">dcl.pre</A>] paragraph 6 specifies:</P>

<BLOCKQUOTE>

A <I>simple-declaration</I> with an <I>identifier-list</I> is called a
<I>structured binding declaration</I> (9.6 [<A href="https://wg21.link/dcl.struct.bind">dcl.struct.bind</A>]).
<DEL>If the <I>decl-specifier-seq</I> contains
any <I>decl-specifier</I> other than static, thread_local, auto
(9.2.9.6 [<A href="https://wg21.link/dcl.spec.auto">dcl.spec.auto</A>]), or <I>cv-qualifier</I>s, the program
is ill-formed.</DEL>
<INS>Each <I>decl-specifier</I> in the <I>decl-specifier-seq</I> shall
be <TT>static</TT>, <TT>thread_local</TT>, <TT>auto</TT>
(9.2.9.6 [<A href="https://wg21.link/dcl.spec.auto">dcl.spec.auto</A>]), or a <I>cv-qualifier</I>.</INS>

<INS>[ Example:</INS>

<PRE class="ins">
template&lt;class T&gt; concept C = true;
C auto [x, y] = std::pair{1, 2}; //<SPAN CLASS="cmnt"> error: constrained placeholder-type-specifier not permitted for structured bindings</SPAN>
</PRE>

<INS> -- end example ]</INS>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2641"></A><H4>2641.
  
Redundant specification of value category of literals
</H4>
<B>Section: </B>5.13&#160; [<A href="https://wg21.link/lex.literal">lex.literal</A>]
 &#160;&#160;&#160;

 <B>Status: </B>ready
 &#160;&#160;&#160;

 <B>Submitter: </B>Andrey Erokhin
 &#160;&#160;&#160;

 <B>Date: </B>2022-11-07




<P>Subclause 7.5.1 [<A href="https://wg21.link/expr.prim.literal#1">expr.prim.literal</A>] paragraph 1 specifies:</P>

<BLOCKQUOTE>

... A <I>string-literal</I> is an lvalue designating a corresponding
string literal object (5.13.5 [<A href="https://wg21.link/lex.string">lex.string</A>]),
a <I>user-defined-literal</I> has the same value category as the
corresponding operator call expression described in
5.13.8 [<A href="https://wg21.link/lex.ext">lex.ext</A>], and any other literal is a prvalue.

</BLOCKQUOTE>

<P>Yet, there is redundant specification in 5.13.2 [<A href="https://wg21.link/lex.icon#3">lex.icon</A>] paragraph 3:</P>

<BLOCKQUOTE>

The type of an <I>integer-literal</I> is the first type in the list in
Table 9 corresponding to its optional <I>integer-suffix</I> in which
its value can be represented. An <I>integer-literal</I> is a prvalue.

</BLOCKQUOTE>

<P>And in 5.13.6 [<A href="https://wg21.link/lex.bool#1">lex.bool</A>] paragraph 1:</P>

<BLOCKQUOTE>

The Boolean literals are the keywords <TT>false</TT> and
<TT>true</TT>. Such literals are prvalues and have type <TT>bool</TT>.

</BLOCKQUOTE>

<P>And in 5.13.7 [<A href="https://wg21.link/lex.nullptr#1">lex.nullptr</A>] paragraph 1:</P>

<BLOCKQUOTE>

The pointer literal is the keyword <TT>nullptr</TT>. It is a prvalue
of type <TT>std::nullptr_t</TT>.

</BLOCKQUOTE>

<P><B>Proposed resolution (approved by CWG 2022-11-10):</B></P>

<OL>

<LI>

<P>Change in 5.13.1 [<A href="https://wg21.link/lex.literal.kinds#1">lex.literal.kinds</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

There are several kinds of literals. [ Footnote: ... ]

<PRE>
<I>literal:
    integer-literal
    character-literal
    floating-point-literal
    string-literal
    boolean-literal
    pointer-literal
    user-defined-literal</I>
</PRE>

<INS>[ Note: When appearing as an <I>expression</I>, a literal has a
type and a value category (7.5.1 [<A href="https://wg21.link/expr.prim.literal">expr.prim.literal</A>]). -- end note
]</INS>

</BLOCKQUOTE>

</LI>

<LI>
<P>Change in 5.13.2 [<A href="https://wg21.link/lex.icon#3">lex.icon</A>] paragraph 3 as follows:</P>

<BLOCKQUOTE>

The type of an <I>integer-literal</I> is the first type in the list in
Table 9 corresponding to its optional <I>integer-suffix</I> in which
its value can be represented. <DEL>An <I>integer-literal</I> is a
prvalue.</DEL>

</BLOCKQUOTE>

</LI>

<LI>

<P>Change in 5.13.6 [<A href="https://wg21.link/lex.bool#1">lex.bool</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

The Boolean literals are the keywords <TT>false</TT> and
<TT>true</TT>. Such literals <DEL>are prvalues and</DEL> have
type <TT>bool</TT>.

</BLOCKQUOTE>
</LI>

<LI>

<P>Change in 5.13.7 [<A href="https://wg21.link/lex.nullptr#1">lex.nullptr</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

The pointer literal is the keyword <TT>nullptr</TT>. It <DEL>is a
prvalue of</DEL> <INS>has</INS> type <TT>std::nullptr_t</TT>.

</BLOCKQUOTE>

</LI>

</OL>

<BR><BR>
</BODY>
</HTML>
