<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 }
  .DEL { text-decoration:line-through; background-color: #FFD0D0 }
  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;P3524R0</TD>
</TR>
<TR>
<TD ALIGN="RIGHT">
      Date:
     </TD>
<TD>
      &#160;2024-11-22</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 14882:2024
     </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, 2024 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/2024/n4993.pdf">WG21 N4993</A>.
   </P>
<HR>
<A NAME="1953"></A><H4>1953.
  
Data races and common initial sequence
</H4>
<B>Section: </B>6.7.1&#160; [<A href="https://wg21.link/intro.memory">intro.memory</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Faisal Vali
 &#160;&#160;&#160;

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




<P>According to 6.7.1 [<A href="https://wg21.link/intro.memory#3">intro.memory</A>] paragraph 3,</P>

<BLOCKQUOTE>

A <I>memory location</I> is either an object of scalar type or a
maximal sequence of adjacent bit-fields all having non-zero
width. [<I>Note:</I> Various features of the language, such
as references and virtual functions, might involve
additional memory locations that are not accessible to
programs but are managed by the
implementation. &#8212;<I>end note</I>] Two or more threads
of execution (6.9.2 [<A href="https://wg21.link/intro.multithread">intro.multithread</A>]) can update and
access separate memory locations without interfering with
each other.

</BLOCKQUOTE>

<P>It is not clear how this relates to the permission
granted in 11.4 [<A href="https://wg21.link/class.mem#18">class.mem</A>] paragraph 18 to inspect
the common initial sequence of standard-layout structs that
are members of a standard-layout union.  If one thread is
writing to the common initial sequence and another is
reading from it via a different struct, that should
constitute a data race, but the current wording does not
clearly state that.</P>

<P><B>Additional notes (October, 2024)</B></P>

<P>(From submission
<A HREF="https://github.com/cplusplus/CWG/issues/621">#621</A>.)
</P>

<P>A similar concern arises for the following example:</P>

<PRE>
  union U { int x, y; } u;
  (u.x = 1, 0) + (u.y = 2, 0);
</PRE>

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

<P>Change in 6.7.1 [<A href="https://wg21.link/intro.memory#3">intro.memory</A>] paragraph 3 as follows:</P>

<BLOCKQUOTE>

A <I>memory location</I> is <INS>the storage occupied by the object
representation of</INS> either an object of scalar type that is not a
bit-field or a maximal sequence of adjacent bit-fields all having
nonzero width. ...

</BLOCKQUOTE>

<P><B>CWG 2024-10-25</B></P>

<P>Subclause 6.9.1 [<A href="https://wg21.link/intro.execution#10">intro.execution</A>] paragraph 10 does not cover
unsequenced object creation that does not change any bits of storage,
such as a placement new invoking a trivial default constructor.  The
original concern in this issue was addressed by P0137R1, adding the
following in 11.4.2 [<A href="https://wg21.link/class.mfct#28">class.mfct</A>] paragraph 28:

<BLOCKQUOTE>

In a standard-layout union with an active member
(11.5 [<A href="https://wg21.link/class.union">class.union</A>]) of struct type T1, it is permitted to read
a non-static data member m of another union member of struct type T2
provided m is part of the common initial sequence of T1 and T2; the
behavior is as if the corresponding member of T1 were nominated.

</BLOCKQUOTE>
</P>

<P><B>Proposed resolution (approved by CWG 2024-11-08):</B></P>

<OL>
<LI>
<P>Change in 6.7.1 [<A href="https://wg21.link/intro.memory#3">intro.memory</A>] paragraph 3 as follows:</P>

<BLOCKQUOTE>

A <I>memory location</I> is <INS>the storage occupied by the object
representation of</INS> either an object of scalar type that is not a
bit-field or a maximal sequence of adjacent bit-fields all having
nonzero width. ...

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 6.9.1 [<A href="https://wg21.link/intro.execution#10">intro.execution</A>] paragraph 10 and add bullets as
follows:</P>

<BLOCKQUOTE>

... The value computations of the operands of an operator are
sequenced before the value computation of the result of the
operator. <DEL>If</DEL> <INS>The behavior is undefined if</INS>
<UL>
<LI>a side effect on a memory location
(6.7.1 [<A href="https://wg21.link/intro.memory">intro.memory</A>]) <INS>or</INS>
</LI>
<LI class="ins">starting or ending the lifetime of an object in a memory location</LI>
</UL>
is unsequenced relative to <DEL>either</DEL>
<UL>
<LI>another side effect on the same memory location<INS>,</INS>
</LI>
<LI>
<INS>starting or ending the lifetime of an object occupying
storage that overlaps with the memory location,</INS> or</LI>
<LI>a value computation using the value of any object in the
same memory location,</LI>
</UL>
and <DEL>they</DEL> <INS>the two evaluations</INS> are not potentially
concurrent (6.9.2 [<A href="https://wg21.link/intro.multithread">intro.multithread</A>])
<DEL>, the behavior is undefined</DEL>.
<INS>[ Note: Starting the lifetime of an object in a memory location
can end the lifetime of objects in other memory locations
(6.7.3 [<A href="https://wg21.link/basic.life">basic.life</A>]). -- end note ]</INS>

<P>[ Note: ... ]</P>

<P>[ Example:</P>
<PRE>
  void g(int i) {
    i = 7, i++, i++;     //<SPAN CLASS="cmnt"> i becomes 9</SPAN>
    i = i++ + 1;   //<SPAN CLASS="cmnt"> the value of i is incremented</SPAN>
    i = i++ + i;   //<SPAN CLASS="cmnt"> undefined behavior</SPAN>
    i = i + 1;     //<SPAN CLASS="cmnt"> the value of i is incremented</SPAN>
<INS>    union U { int x, y; } u;
    (u.x = 1, 0) + (u.y = 2, 0);   //<SPAN CLASS="cmnt"> undefined behavior</SPAN></INS>
  }
</PRE>
<P>-- end example ]</P>
</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 6.9.2.2 [<A href="https://wg21.link/intro.races#2">intro.races</A>] paragraph 2 as follows, adding
bullets:</P>

<BLOCKQUOTE>

Two expression evaluations <I>conflict</I> if one of them
<UL>
<LI>modifies (3.1 [<A href="https://wg21.link/defns.access">defns.access</A>]) a memory location
(6.7.1 [<A href="https://wg21.link/intro.memory">intro.memory</A>]) <INS>or</INS>
</LI>
<LI class="ins">starts or ends the lifetime of an object in a memory
location</LI>
</UL>
and the other one
<UL>
<LI>reads or modifies the same memory location <INS>or</INS>
</LI>
<LI>
<INS>starts or ends the lifetime of an object occupying storage
that overlaps with the memory location</INS>.</LI>
</UL>
[<I>Note 2:</I> A modification can still conflict even if it does not
alter the value of any bits. &#8212;<I>end note</I>]

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

<BR><BR><HR>
<A NAME="1965"></A><H4>1965.
  
Explicit casts to reference types
</H4>
<B>Section: </B>7.6.1.7&#160; [<A href="https://wg21.link/expr.dynamic.cast">expr.dynamic.cast</A>]
 &#160;&#160;&#160;

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

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

 <B>Date: </B>2014-07-07




<P>The specification of <TT>dynamic_cast</TT> in
7.6.1.7 [<A href="https://wg21.link/expr.dynamic.cast#2">expr.dynamic.cast</A>] paragraph 2 (and <TT>const_cast</TT>
in 7.6.1.11 [<A href="https://wg21.link/expr.const.cast">expr.const.cast</A>] is the same) says that the operand
of a cast to an lvalue reference type must be an lvalue, so that</P>

<PRE>
  struct A { virtual ~A(); }; A &amp;&amp;make_a();

  A &amp;&amp;a = dynamic_cast&lt;A&amp;&amp;&gt;(make_a());   //<SPAN CLASS="cmnt"> ok</SPAN>
  const A &amp;b = dynamic_cast&lt;const A&amp;&gt;(make_a()); //<SPAN CLASS="cmnt"> ill-formed</SPAN>
</PRE>

<P>The behavior of <TT>static_cast</TT> is an odd hybrid:</P>

<PRE>
  struct B : A { }; B &amp;&amp;make_b();
  A &amp;&amp;c = static_cast&lt;A&amp;&amp;&gt;(make_b()); //<SPAN CLASS="cmnt"> ok</SPAN>
  const A &amp;d = static_cast&lt;const A&amp;&gt;(make_b()); //<SPAN CLASS="cmnt"> ok</SPAN>
  const B &amp;e = static_cast&lt;const B&amp;&gt;(make_a()); //<SPAN CLASS="cmnt"> ill-formed</SPAN>
</PRE>

<P>(Binding a const lvalue reference to an rvalue is permitted by
7.6.1.9 [<A href="https://wg21.link/expr.static.cast#4">expr.static.cast</A>] paragraph 4 but not by paragraphs 2 and
3.)</P>

<P>There is implementation divergence on the treatment of these examples.</P>

<P>Also, <TT>const_cast</TT> permits binding an rvalue reference to a
class prvalue but not to any other kind of prvalue, which seems like an
unnecessary restriction.</P>

<P>Finally, 7.6.1.9 [<A href="https://wg21.link/expr.static.cast#3">expr.static.cast</A>] paragraph 3 allows binding an
rvalue reference to a class or array prvalue, but not to other kinds of
prvalues; those are covered in paragraph 4.  This would be less confusing
if paragraph 3 only dealt with binding rvalue references to glvalues and
left all discussion of prvalues to paragraph 4, which adequately handles
the class and array cases as well.</P>

<P><B>Notes from the May, 2015 meeting:</B></P>

<P>CWG reaffirmed the status quo for <TT>dynamic_cast</TT> but felt
that <TT>const_cast</TT> should be changed to permit binding an
rvalue reference to types that have associated memory (class and
array types).</P>

<P><B>CWG 2024-11-19</B></P>

<P>Resolved by the resolution of issue 2879.</P>

<BR><BR><HR>
<A NAME="2283"></A><H4>2283.
  
Missing complete type requirements
</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>Richard Smith
 &#160;&#160;&#160;

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




<P>
<A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0135r1.html">P0135R1</A>
(Wording for guaranteed copy elision through simplified value
categories) removes complete type requirements from
7.6.1.3 [<A href="https://wg21.link/expr.call">expr.call</A>] (under the assumption that subclause
9.4 [<A href="https://wg21.link/dcl.init">dcl.init</A>] has them; apparently it does not) and from
7.6.1.8 [<A href="https://wg21.link/expr.typeid#3">expr.typeid</A>] paragraph 3.  These both appear to be bad
changes and should presumably be reverted.
</P>

<P><B>Additional notes (October, 2024)</B></P>

<P>An almost-editorial change (approved by CWG 2021-08-24) restored a
consistent complete-type requirement for <TT>typeid</TT>; see
<A HREF="https://github.com/cplusplus/draft/pull/4827">cplusplus/draft#4827</A>.</P>

<P><B>Proposed resolution (approved by CWG 2024-10-25):</B></P>

<P>Change in 7.6.1.3 [<A href="https://wg21.link/expr.call#13">expr.call</A>] paragraph 13 as follows:</P>

<BLOCKQUOTE>

A function call is an lvalue if the result type is an lvalue reference
type or an rvalue reference to function type, an xvalue if the result
type is an rvalue reference to object type, and a prvalue otherwise.
<INS>If it is a non-<TT>void</TT> prvalue, the type of the function
call expression shall be complete, except as specified in
9.2.9.6 [<A href="https://wg21.link/dcl.type.decltype">dcl.type.decltype</A>].</INS>

</BLOCKQUOTE>
<BR><BR><HR>
<A NAME="2815"></A><H4>2815.
  
Overload resolution for references/pointers to <TT>noexcept</TT> functions
</H4>
<B>Section: </B>12.2.4.3&#160; [<A href="https://wg21.link/over.ics.rank">over.ics.rank</A>]
 &#160;&#160;&#160;

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

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

 <B>Date: </B>2023-10-05




<P>Consider:</P>

<PRE>
  void f() noexcept {}

  void g(void (*)() noexcept) {}
  void g(void (&amp;)()) {}

  int main() {
    g(f);     // <SPAN CLASS="cmnt">error: ambiguous</SPAN>
  }
</PRE>

<P>In contrast:</P>

<PRE>
  void f() noexcept {}

  void g(void (*)()) {} 
  void g(void (&amp;)()) {}      // <SPAN CLASS="cmnt">#1</SPAN>

  int main() {
    g(f);    // <SPAN CLASS="cmnt">OK, calls #1</SPAN>
  }
</PRE>

<P>In both cases, binding <TT>void(&amp;)()</TT> to <TT>void()
noexcept</TT> is considered an identity conversion, without further
disambiguation by 12.2.4.3 [<A href="https://wg21.link/over.ics.rank">over.ics.rank</A>].</P>

<P><B>CWG 2024-06-26</B></P>

<P>Binding a reference to a function should not be considered an
identity conversion if it strips a non-throwing exception
specification.  This amendment removes the ambiguity for the first
example and makes the second example ambiguous, which is
desirable.</P>

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

<OL>
<LI>
<P>Change in 12.2.4.2.5 [<A href="https://wg21.link/over.ics.ref#1">over.ics.ref</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

When a parameter of type &#8220;reference to cvT&#8221; binds directly
(9.4.4 [<A href="https://wg21.link/dcl.init.ref">dcl.init.ref</A>]) to an argument expression:
<UL>
<LI>If the argument expression has a type that is a derived class of
the parameter type, the implicit conversion sequence is a
derived-to-base conversion (12.2.4.2 [<A href="https://wg21.link/over.best.ics">over.best.ics</A>]).</LI>
<LI>Otherwise, <DEL>if T is a function type, or</DEL> if the type of
the argument is possibly cv-qualified T, or if T is an array type of
unknown bound with element type U and the argument has an array type
of known bound whose element type is possibly cv-qualified U, the
implicit conversion sequence is the identity
conversion.  <DEL>[<I>Note 1:</I> When T is a function type, the type
of the argument can differ only by the presence of noexcept.
&#8212;<I>end note</I>]</DEL>
</LI>
<LI class="ins">Otherwise, if T is a function type, the implicit
conversion sequence is a function pointer conversion.</LI>
<LI>Otherwise, the implicit conversion
sequence is a qualification conversion.
</LI>
</UL>

[<I>Example 1:</I>
<PRE>
  struct A {};
  struct B : public A {} b;
  int f(A&amp;);
  int f(B&amp;);
  int i = f(b);    //<SPAN CLASS="cmnt"> calls f(B&amp;), an exact match, rather than f(A&amp;), a conversion</SPAN>
</PRE>
<PRE class="ins">
   void g() noexcept;
   int h(void (&amp;)() noexcept); //<SPAN CLASS="cmnt"> #1</SPAN>
   int h(void (&amp;)());          //<SPAN CLASS="cmnt"> #2</SPAN>
   int j = h(g);               //<SPAN CLASS="cmnt"> calls #1, an exact match, rather than #2, a function pointer conversion</SPAN>
</PRE>
&#8212;<I>end example</I>]

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 12.2.4.3 [<A href="https://wg21.link/over.ics.rank#3.2.6">over.ics.rank</A>] bullet 3.2.6 as follows:</P>

<BLOCKQUOTE>
<PRE>
  int f(const int &amp;);
  int f(int &amp;);
  int g(const int &amp;);
  int g(int);
  int i;
  int j = f(i);   //<SPAN CLASS="cmnt"> calls </SPAN>f(int &amp;)
  int k = g(i);   //<SPAN CLASS="cmnt"> ambiguous</SPAN>

  struct X {
    void f() const;
    void f();
  };
  void g(const X&amp; a, X b) {
    a.f();     //<SPAN CLASS="cmnt"> calls </SPAN>X::f() const
    b.f();     //<SPAN CLASS="cmnt"> calls </SPAN>X::f()
  }

  int h1(int (&amp;)[]);
  int h1(int (&amp;)[1]);
<DEL>  int h2(void (&amp;)());
  int h2(void (&amp;)() noexcept);</DEL>
  void g2() {
    int a[1];
    h1(a);
<DEL>    extern void f2() noexcept;
    h2(f2);</DEL>
  }
</PRE>
</BLOCKQUOTE>
</LI>
</OL>

<BR><BR><HR>
<A NAME="2879"></A><H4>2879.
  
Undesired outcomes with <TT>const_cast</TT>
</H4>
<B>Section: </B>7.6.1.11&#160; [<A href="https://wg21.link/expr.const.cast">expr.const.cast</A>]
 &#160;&#160;&#160;

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

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

 <B>Date: </B>2024-04-15


<P>(From submissions
<A HREF="https://github.com/cplusplus/CWG/issues/526">#526</A>,
<A HREF="https://github.com/cplusplus/CWG/issues/232">#232</A>, and
<A HREF="https://github.com/cplusplus/CWG/issues/342">#342</A>.)</P>

<P>The resolution of issue 891 intended to
make <TT>const_cast&lt;int&amp;&amp;&gt;(2)</TT> ill-formed.  However,
combined with the temporary materialization conversion turning
prvalues into glvalues (7.1 [<A href="https://wg21.link/expr.pre#7">expr.pre</A>] paragraph 7, this is now
well-formed.</P>

<P>Also, the current rules regrettably allow
<TT>const_cast&lt;int&gt;(0)</TT> and const_casts involving function
pointers and pointers to member functions. The latter is
non-normatively considered disallowed by the note in
7.6.1.11 [<A href="https://wg21.link/expr.const.cast#9">expr.const.cast</A>] paragraph 9.</P>

<P>Major implementations except MSVC agree with the proposed direction
of this issue.</P>

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

<OL>
<LI>
<P>Change in 7.6.1.11 [<A href="https://wg21.link/expr.const.cast#3">expr.const.cast</A>] paragraph 3 as follows:</P>

<BLOCKQUOTE>

<P class="del">For two similar types T1 and T2 (7.3.6 [<A href="https://wg21.link/conv.qual">conv.qual</A>]), a
prvalue of type T1 may be explicitly converted to the type T2 using a
const_cast if, considering the qualification-decompositions of both
types, each Pi1 is the same as Pi2 for all i. The result of a
const_cast refers to the original entity.</P>

<P class="ins">
If <TT>T</TT> is an object pointer type or pointer to data member
type, the type of <TT>v</TT> shall be similar to <TT>T</TT> and the
corresponding P<SUB>i</SUB> components of the qualification
decompositions of <TT>T</TT> and the type of <TT>v</TT> shall be the same
(7.3.6 [<A href="https://wg21.link/conv.qual">conv.qual</A>]).
If <TT>v</TT> is a null pointer or null member pointer, the
result is a null pointer or null member pointer,
respectively. Otherwise, the result points to or past the end of the
same object or member, respectively, as <TT>v</TT>.
</P>

<P>[ Example: ... ]</P>

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 7.6.1.11 [<A href="https://wg21.link/expr.const.cast#4">expr.const.cast</A>] paragraph 4 as follows:</P>

<BLOCKQUOTE>

<P class="del">
For two object types T1 and T2, if a pointer to T1 can be explicitly
converted to the type &#8220;pointer to T2&#8221; using a const_cast,
then the following conversions can also be made:</P>
<UL class="del">
<LI>an lvalue of type T1 can be explicitly converted to an lvalue of
type T2 using the cast const_cast&lt;T2&amp;&gt;;</LI>
<LI>a glvalue of type T1 can be
explicitly converted to an xvalue of type T2 using the cast
const_cast&lt;T2&amp;&amp;&gt;; and</LI>
<LI>if T1 is a class type, a prvalue of type T1 can be explicitly
converted to an xvalue of type T2 using the cast
const_cast&lt;T2&amp;&amp;&gt;.</LI>
</UL>
<P class="del">The result of a reference const_cast refers to the
original object if the operand is a glvalue and to the result of
applying the temporary materialization conversion
(7.3.5 [<A href="https://wg21.link/conv.rval">conv.rval</A>]) otherwise.
</P>

<P class="ins">
Otherwise, T shall be a reference type. Let T1 be the type of v and T2
be the type referred to by T. A const_cast from "pointer to T1" to
"pointer to T2" shall be valid. If T is an lvalue reference type, v
shall be an lvalue. Otherwise, if T2 is a class type and v is a
prvalue, the temporary materialization conversion
(7.3.5 [<A href="https://wg21.link/conv.rval">conv.rval</A>]) is applied. Otherwise, the temporary
materialization conversion is not applied and v shall be a
glvalue. The result refers to the same object as the (possibly
converted) operand.
</P>

</BLOCKQUOTE>
</LI>

<LI>
<P>Remove 7.6.1.11 [<A href="https://wg21.link/expr.const.cast#5">expr.const.cast</A>] paragraph 5:</P>

<BLOCKQUOTE class="del">

A null pointer value (6.8.4 [<A href="https://wg21.link/basic.compound">basic.compound</A>]) is converted to the
null pointer value of the destination type. The null member pointer
value (7.3.13 [<A href="https://wg21.link/conv.mem">conv.mem</A>]) is converted to the null member
pointer value of the destination type.

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

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

<OL>
<LI>
<P>Change in 7.6.1.11 [<A href="https://wg21.link/expr.const.cast#1">expr.const.cast</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

The result of the expression const_cast&lt;T&gt;(v) is of type T. If T
is an lvalue reference to object type, the result is an lvalue; if T
is an rvalue reference to object type, the result is an xvalue;
otherwise, the result is a prvalue and the lvalue-to-rvalue
(7.3.2 [<A href="https://wg21.link/conv.lval">conv.lval</A>]), array-to-pointer
(7.3.3 [<A href="https://wg21.link/conv.array">conv.array</A>]), and function-to-pointer
(7.3.4 [<A href="https://wg21.link/conv.func">conv.func</A>]) standard conversions are performed on the
expression v. <INS>The temporary materialization conversion
(7.3.5 [<A href="https://wg21.link/conv.rval">conv.rval</A>]) is not performed on <TT>v</TT>, other
than as specified below.</INS> Conversions that can be performed
explicitly using const_cast are listed below. No other conversion
shall be performed explicitly using const_cast.

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 7.6.1.11 [<A href="https://wg21.link/expr.const.cast#3">expr.const.cast</A>] paragraph 3 as follows:</P>

<BLOCKQUOTE>

For two similar <INS>object pointer or pointer to data member</INS>
types T1 and T2 (7.3.6 [<A href="https://wg21.link/conv.qual">conv.qual</A>]), a prvalue of type
T1 <DEL>may</DEL> <INS>can</INS> be explicitly converted to the type
T2 using a const_cast if, considering the qualification-decompositions
of both types, each Pi1 is the same as Pi2 for all i. <DEL>The result of a
const_cast refers to the original entity.</DEL>
<INS>If <TT>v</TT> is a null pointer or null member pointer, the
result is a null pointer or null member pointer,
respectively. Otherwise, the result points to or past the end of the
same object, or points to the same member, respectively,
as <TT>v</TT>.</INS>

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 7.6.1.11 [<A href="https://wg21.link/expr.const.cast#4">expr.const.cast</A>] paragraph 4 as follows:</P>

<BLOCKQUOTE>

For two object types T1 and T2, if a pointer to T1 can be explicitly
converted to the type &#8220;pointer to T2&#8221; using a const_cast,
then the following conversions can also be made:
<UL>
<LI>an lvalue of type T1 can be explicitly converted to an lvalue of
type T2 using the cast const_cast&lt;T2&amp;&gt;;</LI>
<LI>a glvalue of type T1 can be
explicitly converted to an xvalue of type T2 using the cast
const_cast&lt;T2&amp;&amp;&gt;; and</LI>
<LI>if T1 is a class type, a prvalue of type T1 can be explicitly
converted to an xvalue of type T2 using the cast
const_cast&lt;T2&amp;&amp;&gt;. <INS>The temporary materialization
conversion is performed on <TT>v</TT></INS>.</LI>
</UL>
The result <DEL>of a reference const_cast</DEL> refers to the
<DEL>original</DEL> <INS>same</INS> object <DEL>if</DEL> <INS>as</INS>
the <INS>(possibly converted)</INS> operand <DEL>is a glvalue and to
the result of applying the temporary materialization conversion
(7.3.5 [<A href="https://wg21.link/conv.rval">conv.rval</A>]) otherwise</DEL>.

</BLOCKQUOTE>
</LI>

<LI>
<P>Remove 7.6.1.11 [<A href="https://wg21.link/expr.const.cast#5">expr.const.cast</A>] paragraph 5:</P>

<BLOCKQUOTE class="del">

A null pointer value (6.8.4 [<A href="https://wg21.link/basic.compound">basic.compound</A>]) is converted to the
null pointer value of the destination type. The null member pointer
value (7.3.13 [<A href="https://wg21.link/conv.mem">conv.mem</A>]) is converted to the null member
pointer value of the destination type.

</BLOCKQUOTE>

</LI>
</OL>

<P><B>CWG 2024-05-31</B></P>

<P>The existing example in 7.6.1.11 [<A href="https://wg21.link/expr.const.cast#3">expr.const.cast</A>] paragraph 3
shows the temporary materialization conversion applied to an array
type.  The example would be made ill-formed by the suggested
resolution above.  More investigation is advised.</P>

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

<OL>
<LI>
<P>Change in 7.6.1.11 [<A href="https://wg21.link/expr.const.cast#1">expr.const.cast</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

The result of the expression const_cast&lt;T&gt;(v) is of type T. If T
is an lvalue reference to object type, the result is an lvalue; if T
is an rvalue reference to object type, the result is an xvalue;
otherwise, the result is a prvalue and the lvalue-to-rvalue
(7.3.2 [<A href="https://wg21.link/conv.lval">conv.lval</A>]), array-to-pointer
(7.3.3 [<A href="https://wg21.link/conv.array">conv.array</A>]), and function-to-pointer
(7.3.4 [<A href="https://wg21.link/conv.func">conv.func</A>]) standard conversions are performed on the
expression v. <INS>The temporary materialization conversion
(7.3.5 [<A href="https://wg21.link/conv.rval">conv.rval</A>]) is not performed on <TT>v</TT>, other
than as specified below.</INS> Conversions that can be performed
explicitly using const_cast are listed below. No other conversion
shall be performed explicitly using const_cast.

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 7.6.1.11 [<A href="https://wg21.link/expr.const.cast#3">expr.const.cast</A>] paragraph 3 as follows:</P>

<BLOCKQUOTE>

For two similar <INS>object pointer or pointer to data member</INS>
types T1 and T2 (7.3.6 [<A href="https://wg21.link/conv.qual">conv.qual</A>]), a prvalue of type
T1 <DEL>may</DEL> <INS>can</INS> be explicitly converted to the type
T2 using a const_cast if, considering the qualification-decompositions
of both types, each Pi1 is the same as Pi2 for all i. <DEL>The result of a
const_cast refers to the original entity.</DEL>
<INS>If <TT>v</TT> is a null pointer or null member pointer, the
result is a null pointer or null member pointer,
respectively. Otherwise, the result points to or past the end of the
same object, or points to the same member, respectively,
as <TT>v</TT>.</INS>

<DEL>[Example 1:</DEL>
<PRE class="del">
  typedef int *A[3];                //<SPAN CLASS="cmnt"> array of 3 pointer to int</SPAN>
  typedef const int *const CA[3];   //<SPAN CLASS="cmnt"> array of 3 const pointer to const int</SPAN>
  CA &amp;&amp;r = A{};        //<SPAN CLASS="cmnt"> OK, reference binds to temporary array object</SPAN>
                       //<SPAN CLASS="cmnt"> after qualification conversion to type CA</SPAN>
  A &amp;&amp;r1 = const_cast&lt;A&gt;(CA{});     //<SPAN CLASS="cmnt"> error: temporary array decayed to pointer</SPAN>

  A &amp;&amp;r2 = const_cast&lt;A&amp;&amp;&gt;(CA{});    //<SPAN CLASS="cmnt"> OK</SPAN>
</PRE>
<DEL>-- end example]</DEL>
</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 7.6.1.11 [<A href="https://wg21.link/expr.const.cast#4">expr.const.cast</A>] paragraph 4 as follows:</P>

<BLOCKQUOTE>

For two object types T1 and T2, if a pointer to T1 can be explicitly
converted to the type &#8220;pointer to T2&#8221; using a const_cast,
then the following conversions can also be made:
<UL>
<LI>an lvalue of type T1 can be explicitly converted to an lvalue of
type T2 using the cast const_cast&lt;T2&amp;&gt;;</LI>
<LI>a glvalue of type T1 can be
explicitly converted to an xvalue of type T2 using the cast
const_cast&lt;T2&amp;&amp;&gt;; and</LI>
<LI>if T1 is a class <INS>or array</INS> type, a prvalue of type T1 can be explicitly
converted to an xvalue of type T2 using the cast
const_cast&lt;T2&amp;&amp;&gt;. <INS>The temporary materialization
conversion is performed on <TT>v</TT></INS>.</LI>
</UL>
The result <DEL>of a reference const_cast</DEL> refers to the
<DEL>original</DEL> <INS>same</INS> object <DEL>if</DEL> <INS>as</INS>
the <INS>(possibly converted)</INS> operand <DEL>is a glvalue and to
the result of applying the temporary materialization conversion
(7.3.5 [<A href="https://wg21.link/conv.rval">conv.rval</A>]) otherwise</DEL>.

<P class="ins">[Example 2:</P>
<PRE class="ins">
  typedef int *A[3];                //<SPAN CLASS="cmnt"> array of 3 pointer to int</SPAN>
  typedef const int *const CA[3];   //<SPAN CLASS="cmnt"> array of 3 const pointer to const int</SPAN>

  auto &amp;&amp;r2 = const_cast&lt;A&amp;&amp;&gt;(CA{}); //<SPAN CLASS="cmnt"> OK, temporary materialization conversion is performed</SPAN>
</PRE>
<P class="ins">-- end example]</P>
</BLOCKQUOTE>
</LI>

<LI>
<P>Remove 7.6.1.11 [<A href="https://wg21.link/expr.const.cast#5">expr.const.cast</A>] paragraph 5:</P>

<BLOCKQUOTE class="del">

A null pointer value (6.8.4 [<A href="https://wg21.link/basic.compound">basic.compound</A>]) is converted to the
null pointer value of the destination type. The null member pointer
value (7.3.13 [<A href="https://wg21.link/conv.mem">conv.mem</A>]) is converted to the null member
pointer value of the destination type.

</BLOCKQUOTE>
</LI>

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

<BLOCKQUOTE>
[Example 5: ...
<PRE>
  constexpr int f() {
    const int &amp;x = 42;
    const_cast&lt;int &amp;&gt;(x) = 1;  //<SPAN CLASS="cmnt"> undefined behavior</SPAN>
    return x;
  }
  constexpr int z = f();          //<SPAN CLASS="cmnt"> error: not a constant expression</SPAN>
</PRE>
<PRE class="ins">
  typedef int *AP[3];        //<SPAN CLASS="cmnt"> array of 3 pointer to int</SPAN>
  typedef const int *const ACPC[3]; //<SPAN CLASS="cmnt"> array of 3 const pointer to const int</SPAN>
  ACPC &amp;&amp;r = AP{};          //<SPAN CLASS="cmnt"> binds directly</SPAN>
</PRE>
-- end example]
</BLOCKQUOTE>
</LI>
</OL>

<P>This resolution also resolve issue 1965.</P>

<P><B>CWG 2024-10-11</B></P>

<P>Subclause 7.2.1 [<A href="https://wg21.link/basic.lval#7">basic.lval</A>] paragraph 7 should be amended
with "unless otherwise specified" and cross-references to the exceptions.</P>

<P><B>Proposed resolution (approved by CWG 2024-10-25)</B></P>

<OL>
<LI>
<P>Change in 7.2.1 [<A href="https://wg21.link/basic.lval#7">basic.lval</A>] paragraph 7 as follows:</P>

<BLOCKQUOTE>

<DEL>Whenever</DEL> <INS>Unless otherwise specified
(7.6.1.11 [<A href="https://wg21.link/expr.const.cast">expr.const.cast</A>]), whenever</INS> a prvalue appears as
an operand of an operator that expects a glvalue for that operand, the
temporary materialization conversion (7.3.5 [<A href="https://wg21.link/conv.rval">conv.rval</A>]) is
applied to convert the expression to an xvalue.

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 7.6.1.11 [<A href="https://wg21.link/expr.const.cast#1">expr.const.cast</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

The result of the expression const_cast&lt;T&gt;(v) is of type T. If T
is an lvalue reference to object type, the result is an lvalue; if T
is an rvalue reference to object type, the result is an xvalue;
otherwise, the result is a prvalue and the lvalue-to-rvalue
(7.3.2 [<A href="https://wg21.link/conv.lval">conv.lval</A>]), array-to-pointer
(7.3.3 [<A href="https://wg21.link/conv.array">conv.array</A>]), and function-to-pointer
(7.3.4 [<A href="https://wg21.link/conv.func">conv.func</A>]) standard conversions are performed on the
expression v. <INS>The temporary materialization conversion
(7.3.5 [<A href="https://wg21.link/conv.rval">conv.rval</A>]) is not performed on <TT>v</TT>, other
than as specified below.</INS> Conversions that can be performed
explicitly using const_cast are listed below. No other conversion
shall be performed explicitly using const_cast.

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 7.6.1.11 [<A href="https://wg21.link/expr.const.cast#3">expr.const.cast</A>] paragraph 3 as follows:</P>

<BLOCKQUOTE>

For two similar <INS>object pointer or pointer to data member</INS>
types T1 and T2 (7.3.6 [<A href="https://wg21.link/conv.qual">conv.qual</A>]), a prvalue of type
T1 <DEL>may</DEL> <INS>can</INS> be explicitly converted to the type
T2 using a const_cast if, considering the qualification-decompositions
of both types, each Pi1 is the same as Pi2 for all i. <DEL>The result of a
const_cast refers to the original entity.</DEL>
<INS>If <TT>v</TT> is a null pointer or null member pointer, the
result is a null pointer or null member pointer,
respectively. Otherwise, the result points to or past the end of the
same object, or points to the same member, respectively,
as <TT>v</TT>.</INS>

<DEL>[Example 1:</DEL>
<PRE class="del">
  typedef int *A[3];                //<SPAN CLASS="cmnt"> array of 3 pointer to int</SPAN>
  typedef const int *const CA[3];   //<SPAN CLASS="cmnt"> array of 3 const pointer to const int</SPAN>
  CA &amp;&amp;r = A{};        //<SPAN CLASS="cmnt"> OK, reference binds to temporary array object</SPAN>
                       //<SPAN CLASS="cmnt"> after qualification conversion to type CA</SPAN>
  A &amp;&amp;r1 = const_cast&lt;A&gt;(CA{});     //<SPAN CLASS="cmnt"> error: temporary array decayed to pointer</SPAN>

  A &amp;&amp;r2 = const_cast&lt;A&amp;&amp;&gt;(CA{});    //<SPAN CLASS="cmnt"> OK</SPAN>
</PRE>
<DEL>-- end example]</DEL>
</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 7.6.1.11 [<A href="https://wg21.link/expr.const.cast#4">expr.const.cast</A>] paragraph 4 as follows:</P>

<BLOCKQUOTE>

For two object types T1 and T2, if a pointer to T1 can be explicitly
converted to the type &#8220;pointer to T2&#8221; using a const_cast,
then the following conversions can also be made:
<UL>
<LI>an lvalue of type T1 can be explicitly converted to an lvalue of
type T2 using the cast const_cast&lt;T2&amp;&gt;;</LI>
<LI>a glvalue of type T1 can be
explicitly converted to an xvalue of type T2 using the cast
const_cast&lt;T2&amp;&amp;&gt;; and</LI>
<LI>if T1 is a class <INS>or array</INS> type, a prvalue of type T1 can be explicitly
converted to an xvalue of type T2 using the cast
const_cast&lt;T2&amp;&amp;&gt;. <INS>The temporary materialization
conversion is performed on <TT>v</TT></INS>.</LI>
</UL>
The result <DEL>of a reference const_cast</DEL> refers to the
<DEL>original</DEL> <INS>same</INS> object <DEL>if</DEL> <INS>as</INS>
the <INS>(possibly converted)</INS> operand <DEL>is a glvalue and to
the result of applying the temporary materialization conversion
(7.3.5 [<A href="https://wg21.link/conv.rval">conv.rval</A>]) otherwise</DEL>.

<P class="ins">[Example 2:</P>
<PRE class="ins">
  typedef int *A[3];                //<SPAN CLASS="cmnt"> array of 3 pointer to int</SPAN>
  typedef const int *const CA[3];   //<SPAN CLASS="cmnt"> array of 3 const pointer to const int</SPAN>

  auto &amp;&amp;r2 = const_cast&lt;A&amp;&amp;&gt;(CA{}); //<SPAN CLASS="cmnt"> OK, temporary materialization conversion is performed</SPAN>
</PRE>
<P class="ins">-- end example]</P>
</BLOCKQUOTE>
</LI>

<LI>
<P>Remove 7.6.1.11 [<A href="https://wg21.link/expr.const.cast#5">expr.const.cast</A>] paragraph 5:</P>

<BLOCKQUOTE class="del">

A null pointer value (6.8.4 [<A href="https://wg21.link/basic.compound">basic.compound</A>]) is converted to the
null pointer value of the destination type. The null member pointer
value (7.3.13 [<A href="https://wg21.link/conv.mem">conv.mem</A>]) is converted to the null member
pointer value of the destination type.

</BLOCKQUOTE>
</LI>

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

<BLOCKQUOTE>
[Example 5: ...
<PRE>
  constexpr int f() {
    const int &amp;x = 42;
    const_cast&lt;int &amp;&gt;(x) = 1;  //<SPAN CLASS="cmnt"> undefined behavior</SPAN>
    return x;
  }
  constexpr int z = f();          //<SPAN CLASS="cmnt"> error: not a constant expression</SPAN>
</PRE>
<PRE class="ins">
  typedef int *AP[3];        //<SPAN CLASS="cmnt"> array of 3 pointer to int</SPAN>
  typedef const int *const ACPC[3]; //<SPAN CLASS="cmnt"> array of 3 const pointer to const int</SPAN>
  ACPC &amp;&amp;r = AP{};          //<SPAN CLASS="cmnt"> binds directly</SPAN>
</PRE>
-- end example]
</BLOCKQUOTE>
</LI>
</OL>

<P>This resolution also resolve issue 1965.</P>

<BR><BR><HR>
<A NAME="2890"></A><H4>2890.
  
Defining members of local classes
</H4>
<B>Section: </B>11.6&#160; [<A href="https://wg21.link/class.local">class.local</A>]
 &#160;&#160;&#160;

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

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

 <B>Date: </B>2024-03-08




<P>Subclause 11.6 [<A href="https://wg21.link/class.local#3">class.local</A>] paragraph 3 establishes
restrictions on the definition of classes nested within local classes,
but it is unclear which restrictions exist for other members of local
classes.</P>

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

<P>Change in 11.6 [<A href="https://wg21.link/class.local#3">class.local</A>] paragraph 3 as follows:</P>

<BLOCKQUOTE>

<DEL>If class X is a local class, a nested class Y may be
declared in class X and later defined in the
definition of class X or be later defined in the same scope as the
definition of class X.</DEL> A class nested within a local class is a local
class.
<INS>A member of a local class X shall be declared only in the
definition of X or the nearest enclosing block scope of X.</INS>

</BLOCKQUOTE>

<P><B>CWG 2024-06-14</B></P>

<P>The implementation status quo is that no members of local classes
other than nested classes can be defined at block scope.</P>

<P><B>Proposed resolution (approved by CWG 2024-11-08):</B></P>

<P>Change in 11.6 [<A href="https://wg21.link/class.local#3">class.local</A>] paragraph 3 as follows:</P>

<BLOCKQUOTE>

<DEL>If class X is a local class, a nested class Y may be
declared in class X and later defined in the
definition of class X or be later defined in the same scope as the
definition of class X.</DEL> A class nested within a local class is a local
class.
<INS>A member of a local class X shall be declared only in the
definition of X or, if the member is a nested class, in the nearest
enclosing block scope of X.</INS>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2894"></A><H4>2894.
  
Functional casts create prvalues of reference type
</H4>
<B>Section: </B>7.6.1.4&#160; [<A href="https://wg21.link/expr.type.conv">expr.type.conv</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Jan Schultke
 &#160;&#160;&#160;

 <B>Date: </B>2024-05-14


<P>(From submission
<A HREF="https://github.com/cplusplus/CWG/issues/536">#536</A>.)</P>

<P>For <TT>T{...}</TT>, the rule in 7.6.1.4 [<A href="https://wg21.link/expr.type.conv#2">expr.type.conv</A>] paragraph 2 yields a prvalue of reference type if <TT>T</TT> is a
reference type:</P>

<BLOCKQUOTE>

... Otherwise, the expression is a prvalue of the specified type whose
result object is direct-initialized (9.4) with the initializer. ...

</BLOCKQUOTE>

<P>Also, it should be clarified that <TT>void(1, 2)</TT>
and <TT>void{1}</TT> are ill-formed.</P>

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

<P>Change in 7.6.1.4 [<A href="https://wg21.link/expr.type.conv#1">expr.type.conv</A>] paragraph 1 and 2 as follows:</P>

<BLOCKQUOTE>

<P>A <I>simple-type-specifier</I> (9.2.9.3 [<A href="https://wg21.link/dcl.type.simple">dcl.type.simple</A>])
or <I>typename-specifier</I> (13.8 [<A href="https://wg21.link/temp.res">temp.res</A>]) followed by a
parenthesized optional <I>expression-list</I> or by
a <I>braced-init-list</I> (the initializer) constructs a value of the
specified type given the initializer. If the type is a placeholder for
a deduced class type, it is replaced by the return type of the
function selected by overload resolution for class template deduction
(12.2.2.9 [<A href="https://wg21.link/over.match.class.deduct">over.match.class.deduct</A>]) for the remainder of this
subclause. Otherwise, if the type contains a placeholder type, it is
replaced by the type determined by placeholder type deduction
(9.2.9.7.2 [<A href="https://wg21.link/dcl.type.auto.deduct">dcl.type.auto.deduct</A>]). <INS>Let <TT>T</TT> denote the
resulting type.</INS> [ Example: ... ]
</P>

<P>
If the initializer is a parenthesized single expression, the type
conversion expression is equivalent to the corresponding cast
expression (7.6.3 [<A href="https://wg21.link/expr.cast">expr.cast</A>]). Otherwise, if <DEL>the type</DEL> <INS><TT>T</TT></INS> is <I>cv</I>
<TT>void</TT> <DEL>and</DEL> <INS>,</INS> the
initializer <DEL>is</DEL> <INS>shall be</INS> <TT>()</TT>
or <TT>{}</TT> (after pack expansion, if any), <INS>and</INS> the
expression is a prvalue of type void that performs no
initialization. Otherwise, the expression <DEL>is a prvalue of the
specified type whose result object is direct-initialized
(9.4 [<A href="https://wg21.link/dcl.init">dcl.init</A>]) with the initializer</DEL> <INS> has the
same effect as direct-initializing an invented variable <TT>t</TT> of
type <TT>T</TT> from the initializer and then using <TT>t</TT> as the
result of the expression. The result is an lvalue if <TT>T</TT> is an
lvalue reference type or an rvalue reference to function type, an
xvalue if <TT>T</TT> is an rvalue reference to object type, and a
prvalue otherwise</INS>.  If the initializer is a parenthesized
optional <I>expression-list</I>, <DEL>the specified
type</DEL> <INS><TT>T</TT></INS> shall not be an array type.
</P>

</BLOCKQUOTE>

<P><B>CWG 2024-06-14</B></P>

<P>The resolution above introduces an additional variable even for a
prvalue, which defeats mandatory copy elision.  Use the pattern from
7.6.1.9 [<A href="https://wg21.link/expr.static.cast#4">expr.static.cast</A>] paragraph 4 instead.</P>

<P><B>Proposed resolution (approved by CWG 2024-10-25):</B></P>

<P>Change in 7.6.1.4 [<A href="https://wg21.link/expr.type.conv#1">expr.type.conv</A>] paragraph 1 and 2 as follows, move the example to the bottom, and add bullets:</P>

<BLOCKQUOTE>

<P>A <I>simple-type-specifier</I> (9.2.9.3 [<A href="https://wg21.link/dcl.type.simple">dcl.type.simple</A>])
or <I>typename-specifier</I> (13.8 [<A href="https://wg21.link/temp.res">temp.res</A>]) followed by a
parenthesized optional <I>expression-list</I> or by
a <I>braced-init-list</I> (the initializer) constructs a value of the
specified type given the initializer. If the type is a placeholder for
a deduced class type, it is replaced by the return type of the
function selected by overload resolution for class template deduction
(12.2.2.9 [<A href="https://wg21.link/over.match.class.deduct">over.match.class.deduct</A>]) for the remainder of this
subclause. Otherwise, if the type contains a placeholder type, it is
replaced by the type determined by placeholder type deduction
(9.2.9.7.2 [<A href="https://wg21.link/dcl.type.auto.deduct">dcl.type.auto.deduct</A>]). <INS>Let <TT>T</TT> denote the
resulting type.</INS> <DEL>[ Example: ... ]</DEL>
</P>

<P>
<INS>Then:</INS>
<UL>
<LI>
If the initializer is a parenthesized single expression, the type
conversion expression is equivalent to the corresponding cast
expression (7.6.3 [<A href="https://wg21.link/expr.cast">expr.cast</A>]).
</LI>
<LI>Otherwise, if <DEL>the type</DEL> <INS><TT>T</TT></INS> is <I>cv</I>
<TT>void</TT> <DEL>and</DEL> <INS>,</INS> the
initializer <DEL>is</DEL> <INS>shall be</INS> <TT>()</TT>
or <TT>{}</TT> (after pack expansion, if any), <INS>and</INS> the
expression is a prvalue of type void that performs no
initialization. </LI>
<LI><INS>Otherwise, if <TT>T</TT> is a reference type, the expression has
the same effect as direct-initializing an invented variable <TT>t</TT>
of type <TT>T</TT> from the initializer and then using <TT>t</TT> as
the result of the expression; the result is an lvalue if <TT>T</TT> is
an lvalue reference type or an rvalue reference to function type and
an xvalue otherwise.</INS></LI>
<LI>Otherwise, the expression is a prvalue
of <DEL>the specified</DEL> type <INS><TT>T</TT></INS> whose
result object is direct-initialized (9.4 [<A href="https://wg21.link/dcl.init">dcl.init</A>]) with
the initializer.</LI>
</UL>
If the initializer is a parenthesized
optional <I>expression-list</I>, <DEL>the specified
type</DEL> <INS><TT>T</TT></INS> shall not be an array type.
</P>

<P><INS>[Example: ... ]</INS></P>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2899"></A><H4>2899.
  
Bad value representations should cause undefined behavior
</H4>
<B>Section: </B>7.3.2&#160; [<A href="https://wg21.link/conv.lval">conv.lval</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Jan Schultke
 &#160;&#160;&#160;

 <B>Date: </B>2024-06-05


<P>(From editorial issue
<A HREF="https://github.com/cplusplus/draft/issues/7051">#7051</A>.)</P>

<P>Consider:</P>

<PRE>
static_assert(sizeof(bool) == 1);  // <SPAN CLASS="cmnt">assumption for the example</SPAN>
bool f() {
  char c = 2;
  bool b = true;
  memcpy(&amp;b, &amp;c, 1);     // <SPAN CLASS="cmnt">#1</SPAN>
  return b;              // <SPAN CLASS="cmnt">#2</SPAN>
}
</PRE>

<P>Assuming that false and true are represented as 0 and 1, the value
representation of <TT>b</TT> now has a bad value.  This should, but
does not, result in undefined behavior during the lvalue-to-rvalue
conversion at #2.</P>

<P><B>Proposed resolution (approved by CWG 2024-08-16):</B></P>

<P>Change in 7.3.2 [<A href="https://wg21.link/conv.lval#3">conv.lval</A>] paragraph 3 as follows:</P>

<BLOCKQUOTE>

The result of the conversion is determined according to the following
rules:
<UL>
<LI>If T is cv std::nullptr_t, the result is a null pointer constant
(7.3.12 [<A href="https://wg21.link/conv.ptr">conv.ptr</A>]).  [<I>Note 1:</I> Since the conversion
does not access the object to which the glvalue refers, there is no
side effect even if T is volatile-qualified
(6.9.1 [<A href="https://wg21.link/intro.execution">intro.execution</A>]), and the glvalue can refer to an inactive
member of a union (11.5 [<A href="https://wg21.link/class.union">class.union</A>]). &#8212;<I>end note</I>]
</LI>
<LI>Otherwise, if T has a class type, the conversion copy-initializes
the result object from the glvalue.</LI>
<LI>Otherwise, if the object to which the glvalue refers contains an
invalid pointer value (6.7.5.5.3 [<A href="https://wg21.link/basic.stc.dynamic.deallocation">basic.stc.dynamic.deallocation</A>]), the behavior
is implementation-defined.</LI>
<LI class="ins">Otherwise, if the bits in the value representation of
the object to which the glvalue refers are not valid for the object's
type, the behavior is undefined.
[ Example:
<PRE>
bool f() {
  bool b = true;
  char c = 42;
  memcpy(&amp;b, &amp;c, 1);
  return b;           //<SPAN CLASS="cmnt"> undefined behavior if 42 is not a valid value representation for </SPAN>bool
}
</PRE>
-- end example ]
</LI>
<LI>Otherwise, the object indicated by the glvalue is read
(3.1 [<A href="https://wg21.link/defns.access">defns.access</A>]), and the value contained in the object is
the prvalue result. <DEL>If the result is an erroneous value
(6.7.4 [<A href="https://wg21.link/basic.indet">basic.indet</A>]) and the bits in the value representation
are not valid for the object's type, the behavior is
undefined.</DEL>
</LI>
</UL>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2901"></A><H4>2901.
  
Unclear semantics for near-match aliased access
</H4>
<B>Section: </B>7.2.1&#160; [<A href="https://wg21.link/basic.lval">basic.lval</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Jan Schultke
 &#160;&#160;&#160;

 <B>Date: </B>2024-06-14


<P>(From submission
<A HREF="https://github.com/cplusplus/CWG/issues/548">#548</A>.)</P>

<P>Subclause 7.2.1 [<A href="https://wg21.link/basic.lval#11">basic.lval</A>] paragraph 11 specifies:</P>

<BLOCKQUOTE>

... If a program attempts to access (3.1 [<A href="https://wg21.link/defns.access">defns.access</A>]) the stored
value of an object through a glvalue through which it is not
type-accessible, the behavior is undefined. ...

</BLOCKQUOTE>

<P>Thus, access (read or write) to an <TT>int</TT> object using an
lvalue of type <TT>unsigned int</TT> is valid.  However,
7.3.2 [<A href="https://wg21.link/conv.lval#3.4">conv.lval</A>] bullet 3.4 does not specify the resulting
value when, for example, the object contains the value -1:</P>

<BLOCKQUOTE>

<UL>
<LI>Otherwise, the object indicated by the glvalue is read
(3.1 [<A href="https://wg21.link/defns.access">defns.access</A>]), and the value contained in the object is
the prvalue result. ...</LI>
</UL>

</BLOCKQUOTE>

<P>Similarly, 7.6.19 [<A href="https://wg21.link/expr.ass#2">expr.ass</A>] paragraph 2 is silent for the
assignment case:</P>

<BLOCKQUOTE>

In simple assignment (=), the object referred to by the left operand
is modified (3.1 [<A href="https://wg21.link/defns.access">defns.access</A>]) by replacing its value with the
result of the right operand.

</BLOCKQUOTE>

<P>Any concerns about accesses to the object representation are handled in the context of
<A HREF="https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p1839r5.pdf">P1839</A>.</P>

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

<OL>
<LI>
<P>Change in 7.3.2 [<A href="https://wg21.link/conv.lval#3.4">conv.lval</A>] bullet 3.4 as follows:</P>

<BLOCKQUOTE>

<UL>
<LI>Otherwise, the object indicated by the glvalue is read
(3.1 [<A href="https://wg21.link/defns.access">defns.access</A>])<DEL>, and the value contained in the object
is the prvalue result</DEL>.<INS> Let <I>V</I> be the value contained
in the object.  If <TT>T</TT> is an integer type, the prvalue result
is the value of type <TT>T</TT> congruent (6.8.2 [<A href="https://wg21.link/basic.fundamental">basic.fundamental</A>])
to <I>V</I>, and <I>V</I> otherwise.</INS> ...</LI>
</UL>

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 7.6.1.6 [<A href="https://wg21.link/expr.post.incr#1">expr.post.incr</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

The value of a postfix ++ expression is the value <DEL>of</DEL>
<INS>obtained by applying the lvalue-to-rvalue conversion
(7.3.2 [<A href="https://wg21.link/conv.lval">conv.lval</A>]) to</INS> its operand.  [<I>Note 1:</I>
The value obtained is a copy of the original value. &#8212;<I>end
note</I>] ...

</BLOCKQUOTE>
</LI>

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

<BLOCKQUOTE>

In simple assignment (=), <INS>let <I>V</I> be the result of the right
operand;</INS> the object referred to by the left operand is modified
(3.1 [<A href="https://wg21.link/defns.access">defns.access</A>]) by replacing its value with <DEL>the result
of the right operand</DEL> <INS>V or, if the object is of integer
type, with the value congruent (6.8.2 [<A href="https://wg21.link/basic.fundamental">basic.fundamental</A>]) to
V</INS>.

</BLOCKQUOTE>

</LI>
</OL>

<BR><BR><HR>
<A NAME="2905"></A><H4>2905.
  
Value-dependence of <I>noexcept-expression</I>
</H4>
<B>Section: </B>13.8.3.4&#160; [<A href="https://wg21.link/temp.dep.constexpr">temp.dep.constexpr</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Mital Ashok
 &#160;&#160;&#160;

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


<P>(From submission
<A HREF="https://github.com/cplusplus/CWG/issues/554">#554</A>.)</P>

<P>The following examples of <I>noexcept-expression</I>s are not
specified to be value-dependent, but ought to be, because
value-initialization of <TT>T</TT> might throw an exception.</P>

<PRE>
  template&lt;typename T&gt;
  void f() {
    noexcept(static_cast&lt;int&gt;(T{}));
    noexcept(typeid(*T{}));
    noexcept(delete T{});
  }
</PRE>

<P><B>Proposed resolution (approved by CWG 2024-11-19):</B></P>

<OL>
<LI>
<P>Change in 13.8.3.4 [<A href="https://wg21.link/temp.dep.constexpr#2">temp.dep.constexpr</A>] paragraph 2 as follows:</P>

<BLOCKQUOTE>

Expressions of the following form are value-dependent if
the <I>unary-expression</I> or expression is <I>type-dependent</I> or
the <I>type-id</I> is dependent:
<PRE>
sizeof <I>unary-expression</I>
sizeof ( <I>type-id</I> )
typeid ( expression )
typeid ( <I>type-id</I> )
alignof ( <I>type-id</I> )
<DEL>noexcept ( <I>expression</I> )</DEL>
</PRE>

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 13.8.3.4 [<A href="https://wg21.link/temp.dep.constexpr#3">temp.dep.constexpr</A>] paragraph 3 as follows:</P>

<BLOCKQUOTE>

Expressions of the following form are value-dependent if either
the <I>type-id</I> <DEL>or</DEL> <INS>,</INS> <I>simple-type-specifier</I><INS>,
or <I>typename-specifier</I></INS> is dependent or the expression
or <I>cast-expression</I> is value-dependent <INS>or
any <I>expression</I> in the <I>expression-list</I> is value-dependent
or any <I>assignment-expression</I> in the <I>braced-init-list</I> is
value-dependent</INS>:
<PRE>
<I>simple-type-specifier</I> ( <I>expression-list<sub>opt</sub></I> )
<INS><I>typename-specifier</I> ( <I>expression-list</I><sub>opt</sub> )
<I>simple-type-specifier</I> <I>braced-init-list</I>
<I>typename-specifier</I> <I>braced-init-list</I></INS>
static_cast &lt; <I>type-id</I> &gt; ( <I>expression</I> )
const_cast &lt; <I>type-id</I> &gt; ( <I>expression</I> )
reinterpret_cast &lt; <I>type-id</I> &gt; ( <I>expression</I> )
<INS>dynamic_cast &lt; <I>type-id</I> &gt; ( <I>expression</I> )</INS>
( <I>type-id</I> ) <I>cast-expression</I>
</PRE>

</BLOCKQUOTE>
</LI>

<LI>
<P>Add a new paragraph before 13.8.3.4 [<A href="https://wg21.link/temp.dep.constexpr#5">temp.dep.constexpr</A>] paragraph 5 as follows:</P>

<BLOCKQUOTE>

<P class="ins">
A <I>noexcept-expression</I> (7.6.2.7 [<A href="https://wg21.link/expr.unary.noexcept">expr.unary.noexcept</A>]) is
value-dependent if its <I>expression</I> involves a template parameter.
</P>

<P>An expression of the form &amp;<I>qualified-id</I> where ...</P>

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

<BR><BR><HR>
<A NAME="2906"></A><H4>2906.
  
Lvalue-to-rvalue conversion of class types for conditional operator
</H4>
<B>Section: </B>7.6.16&#160; [<A href="https://wg21.link/expr.cond">expr.cond</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Jan Schultke
 &#160;&#160;&#160;

 <B>Date: </B>2024-06-08


<P>(From submission
<A HREF="https://github.com/cplusplus/CWG/issues/550">#550</A>.)</P>

<P>There are two known situations where the lvalue-to-rvalue
conversion is applied to class types, which can be non-constexpr even
if the resulting copy constructor invocation would be constexpr
(7.7 [<A href="https://wg21.link/expr.const#5.9">expr.const</A>] bullet 5.9).  The other such situation is
7.6.1.3 [<A href="https://wg21.link/expr.call#11">expr.call</A>] paragraph 11.  Here, the concern is with
7.6.16 [<A href="https://wg21.link/expr.cond#7">expr.cond</A>] paragraph 7, which can be invoked for class
types; for example:</P>

<PRE>
  struct S {};
  S a;
  constexpr S b = a;        //<SPAN CLASS="cmnt"> OK, call to implicitly-declared copy constructor</SPAN>
  constexpr S d = false ? S{} : a; //<SPAN CLASS="cmnt"> error: lvalue-to-rvalue conversion of 'a' is not a constant expression</SPAN>
</PRE>

<P>Major implementations disagree with the ill-formed outcome.</P>

<P><B>Proposed resolution (approved by CWG 2024-06-26):</B></P>

<P>Change in 7.6.16 [<A href="https://wg21.link/expr.cond#7">expr.cond</A>] paragraph 7 as follows:</P>

<BLOCKQUOTE>

<P>
Otherwise, the result is a prvalue. If the second and third operands
do not have the same type, ...
</P>

<P>
<DEL>Lvalue-to-rvalue (7.3.2 [<A href="https://wg21.link/conv.lval">conv.lval</A>]),
array-to-pointer</DEL>
<INS>Array-to-pointer</INS>
(7.3.3 [<A href="https://wg21.link/conv.array">conv.array</A>])<DEL>,</DEL> and function-to-pointer
(7.3.4 [<A href="https://wg21.link/conv.func">conv.func</A>]) standard conversions are performed on the
second and third operands. After those conversions, one of the
following shall hold:
<UL>
<LI>The second and third operands have the same type; the result is of
that type and the result <DEL>object</DEL>
is <DEL>initialized</DEL> <INS>copy-initialized</INS> using the
selected operand.
</LI>
<LI>The second and third operands have arithmetic or enumeration type;
the usual arithmetic conversions (7.4 [<A href="https://wg21.link/expr.arith.conv">expr.arith.conv</A>]) are
performed to bring them to a common type, and the result is of that
type.</LI>
<LI>One or both of the second and third operands have pointer type;
<INS>lvalue-to-rvalue (7.3.2 [<A href="https://wg21.link/conv.lval">conv.lval</A>]),</INS> pointer
<DEL>conversions</DEL> (7.3.12 [<A href="https://wg21.link/conv.ptr">conv.ptr</A>]), function pointer
<DEL>conversions</DEL> (7.3.14 [<A href="https://wg21.link/conv.fctptr">conv.fctptr</A>]), and qualification
conversions (7.3.6 [<A href="https://wg21.link/conv.qual">conv.qual</A>]) are performed to bring them
to their composite pointer type (7.2.2 [<A href="https://wg21.link/expr.type">expr.type</A>]). The
result is of the composite pointer type.</LI>
<LI>One or both of the second and third operands have
pointer-to-member type; <INS>lvalue-to-rvalue
(7.3.2 [<A href="https://wg21.link/conv.lval">conv.lval</A>]),</INS> pointer to
member <DEL>conversions</DEL> (7.3.13 [<A href="https://wg21.link/conv.mem">conv.mem</A>]), function
pointer <DEL>conversions</DEL> (7.3.14 [<A href="https://wg21.link/conv.fctptr">conv.fctptr</A>]), and
qualification conversions (7.3.6 [<A href="https://wg21.link/conv.qual">conv.qual</A>]) are performed
to bring them to their composite pointer type
(7.2.2 [<A href="https://wg21.link/expr.type">expr.type</A>]). The result is of the composite pointer
type.
</LI>
<LI>Both the second and third operands have type std::nullptr_t or one
has that type and the other is a null pointer constant. The result is
of type std::nullptr_t.
</LI>
</UL>
</P>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2907"></A><H4>2907.
  
Constant lvalue-to-rvalue conversion on uninitialized <TT>std::nullptr_t</TT>
</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>Jim X
 &#160;&#160;&#160;

 <B>Date: </B>2023-01-10


<P>(From submission
<A HREF="https://github.com/cplusplus/CWG/issues/215">#215</A>.)</P>

<P>Consider:</P>

<PRE>
  void f() {
    std::nullptr_t np;       //<SPAN CLASS="cmnt"> uninitialized, thus </SPAN>np<SPAN CLASS="cmnt"> contains an erroneous value</SPAN>
    constexpr void *p1 = np; //<SPAN CLASS="cmnt"> error: converted initializer is not a constant expression</SPAN>
  }
</PRE>

<P>The lvalue-to-rvalue conversion on <TT>np</TT> does not actually
read the value of <TT>np</TT> (7.3.2 [<A href="https://wg21.link/conv.lval#3.1">conv.lval</A>] bullet 3.1), yet the situation is made ill-formed by
7.7 [<A href="https://wg21.link/expr.const#5.9">expr.const</A>] bullet 5.9.</P>

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

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

<BLOCKQUOTE>

An expression E is a core constant expression unless the evaluation of
E, following the rules of the abstract machine
(6.9.1 [<A href="https://wg21.link/intro.execution">intro.execution</A>]), would evaluate one of the following:

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

<LI>an lvalue-to-rvalue conversion (7.3.2 [<A href="https://wg21.link/conv.lval">conv.lval</A>]) unless it
is applied to
<UL>
<LI class="ins">a glvalue of type <I>cv</I> <TT>std::nullptr_t</TT>,</LI>
<LI>a non-volatile glvalue that refers to an object
that is usable in constant expressions, or</LI>
<LI>a non-volatile
glvalue of literal type that refers to a non-volatile object whose
lifetime began within the evaluation of E;</LI>
</UL>
</LI>

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

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2908"></A><H4>2908.
  
Counting physical source lines for <TT>__LINE__</TT>
</H4>
<B>Section: </B>15.7&#160; [<A href="https://wg21.link/cpp.line">cpp.line</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Alisdair Meredith
 &#160;&#160;&#160;

 <B>Date: </B>2024-06-17




<P>Given the existing implementation divergence, it should be
clarified that <TT>__LINE__</TT> counts physical source lines, not
logical ones.</P>

<P><B>Proposed resolution (approved by CWG 2024-08-16):</B></P>

<P>Change in 15.7 [<A href="https://wg21.link/cpp.line#2">cpp.line</A>] paragraph 2 as follows:</P>
<BLOCKQUOTE>

The <I>line number</I> of the current source line is <INS>the line
number of the current physical source line, i.e. it is</INS> one
greater than the number of new-line characters read or introduced in
translation phase 1 (5.2 [<A href="https://wg21.link/lex.phases">lex.phases</A>]) while processing the
source file to the current token.

</BLOCKQUOTE>
<BR><BR><HR>
<A NAME="2909"></A><H4>2909.
  
Subtle difference between constant-initialized and constexpr
</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>CWG
 &#160;&#160;&#160;

 <B>Date: </B>2024-06-24


<P>Subclause 7.7 [<A href="https://wg21.link/expr.const#2">expr.const</A>] paragraph 2 defines
"constant-initialized" using the following rule:</P>

<BLOCKQUOTE>
A variable or temporary object o is <I>constant-initialized</I> if
<UL>
<LI>either it has an initializer or its default-initialization results in
some initialization being performed, and</LI>
<LI>...</LI>
</UL>

</BLOCKQUOTE>

<P>However, the rules for <TT>constexpr</TT> are slightly different,
per 9.2.6 [<A href="https://wg21.link/dcl.constexpr#6">dcl.constexpr</A>] paragraph 6:</P>

<BLOCKQUOTE>

A constexpr specifier used in an object declaration declares the
object as const. Such an object shall have literal type and shall be
initialized. ...

</BLOCKQUOTE>

<P>The difference manifests for an example such as:</P>

<PRE>
  struct S {};
  int main() {
    constexpr S s;       //<SPAN CLASS="cmnt"> OK</SPAN>
    constexpr S s2 = s;  //<SPAN CLASS="cmnt"> error: </SPAN>s<SPAN CLASS="cmnt"> is not constant-initialized</SPAN>
  }
</PRE>

<P>Is the difference intentional?</P>

<P><B>Proposed resolution (approved by CWG 2024-10-25):</B></P>

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

<BLOCKQUOTE>

A variable or temporary object o is constant-initialized if
<UL>
<LI>either it has an initializer or its <DEL>default-initialization
results in some initialization being performed</DEL> <INS>type is
const-default-constructible (9.4.1 [<A href="https://wg21.link/dcl.init.general">dcl.init.general</A>])</INS>,
and</LI>
<LI>...</LI>
</UL>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2910"></A><H4>2910.
  
Effect of <I>requirement-parameter-list</I>s on odr-usability
</H4>
<B>Section: </B>6.3&#160; [<A href="https://wg21.link/basic.def.odr">basic.def.odr</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Hubert Tong
 &#160;&#160;&#160;

 <B>Date: </B>2024-06-24


<P>(From submission
<A HREF="https://github.com/cplusplus/CWG/issues/561">#561</A>.)</P>

<P>Consider:</P>

<PRE>
  bool f() {
    constexpr int z = 42;
    return requires {
      sizeof(int [*&amp;z]);
    } &amp;&amp; requires (int x) {
      sizeof(int [*&amp;z]);
    };
  }
</PRE>

<P>The second <I>requires-expression</I> introduces a function
parameter scope according to 6.4.4 [<A href="https://wg21.link/basic.scope.param">basic.scope.param</A>].  This affects
odr-usability as specified in 6.3 [<A href="https://wg21.link/basic.def.odr#10">basic.def.odr</A>] paragraph 10, but
the two <I>requires-expression</I> in the example ought to actually
behave the same.</P>

<P><B>Proposed resolution (approved by CWG 2024-11-19):</B></P>

<P>Change in 6.3 [<A href="https://wg21.link/basic.def.odr#10.2.2">basic.def.odr</A>] bullet 10.2.2 as follows:</P>

<BLOCKQUOTE>

A local entity (6.1 [<A href="https://wg21.link/basic.pre">basic.pre</A>]) is odr-usable in a scope
(6.4.1 [<A href="https://wg21.link/basic.scope.scope">basic.scope.scope</A>]) if:

<UL>
<LI>...</LI>
<LI>
for each intervening scope (6.4.1 [<A href="https://wg21.link/basic.scope.scope">basic.scope.scope</A>]) between the
point at which the entity is introduced and the scope (where *this is
considered to be introduced within the innermost enclosing class or
non-lambda function definition scope), either:
<UL>
<LI>the intervening scope is a block scope, or</LI>
<LI>the intervening scope is the function parameter scope of a
<I>lambda-expression</I> <INS>or <I>requires-expression</I></INS>, or</LI>
<LI>the intervening scope is the lambda scope of
a <I>lambda-expression</I> that has a <I>simple-capture</I> naming the
entity or has a <I>capture-default</I>, and the block scope of
the <I>lambda-expression</I> is also an intervening scope.</LI>
</UL>
</LI>
</UL>
</BLOCKQUOTE>
<BR><BR><HR>
<A NAME="2911"></A><H4>2911.
  
Unclear meaning of expressions "appearing within" subexpressions
</H4>
<B>Section: </B>7.5.8.1&#160; [<A href="https://wg21.link/expr.prim.req.general">expr.prim.req.general</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Hubert Tong
 &#160;&#160;&#160;

 <B>Date: </B>2024-06-24


<P>(From submission
<A HREF="https://github.com/cplusplus/CWG/issues/562">#562</A>.)</P>

<P>Subclause 7.5.8.1 [<A href="https://wg21.link/expr.prim.req.general#2">expr.prim.req.general</A>] paragraph 2 specifies:</P>

<BLOCKQUOTE>

A <I>requires-expression</I> is a prvalue of type bool whose value is
described below. Expressions appearing within
a <I>requirement-body</I> are unevaluated operands
(7.2.3 [<A href="https://wg21.link/expr.context">expr.context</A>]).

</BLOCKQUOTE>

<P>A <I>constant-expression</I> used as a non-type template argument
"appearing within" the <I>requirement-body</I> should not be
considered an "unevaluated operand".  Similarly, bodies
of <I>lambda-expression</I>s should not be in focus of "appearing
within".</P>

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

<OL>

<LI>
<P>Change in 7.2.3 [<A href="https://wg21.link/expr.context#1">expr.context</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

In some contexts, unevaluated operands appear
(<DEL>7.5.8 [<A href="https://wg21.link/expr.prim.req">expr.prim.req</A>]</DEL> <INS>7.5.8.2 [<A href="https://wg21.link/expr.prim.req.simple">expr.prim.req.simple</A>],
7.5.8.4 [<A href="https://wg21.link/expr.prim.req.compound">expr.prim.req.compound</A>]</INS>, 7.6.1.8 [<A href="https://wg21.link/expr.typeid">expr.typeid</A>],
7.6.2.5 [<A href="https://wg21.link/expr.sizeof">expr.sizeof</A>], 7.6.2.7 [<A href="https://wg21.link/expr.unary.noexcept">expr.unary.noexcept</A>],
9.2.9.6 [<A href="https://wg21.link/dcl.type.decltype">dcl.type.decltype</A>], 13.1 [<A href="https://wg21.link/temp.pre">temp.pre</A>],
13.7.9 [<A href="https://wg21.link/temp.concept">temp.concept</A>]). An unevaluated operand is not evaluated.

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 7.5.8.1 [<A href="https://wg21.link/expr.prim.req.general#2">expr.prim.req.general</A>] paragraph 2 as follows:</P>

<BLOCKQUOTE>

A <I>requires-expression</I> is a prvalue of type bool whose value is
described below. <DEL>Expressions appearing within
a <I>requirement-body</I> are unevaluated operands
(7.2.3 [<A href="https://wg21.link/expr.context">expr.context</A>]).</DEL>

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 7.5.8.2 [<A href="https://wg21.link/expr.prim.req.simple#1">expr.prim.req.simple</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

A <I>simple-requirement</I> asserts the validity of an expression.
<INS>The <I>expression</I> is an unevaluated operand.</INS>
[<I>Note 1:</I> The enclosing <I>requires-expression</I> will evaluate
to false if substitution of template arguments into the expression
fails. <DEL>The expression is an unevaluated operand
(7.2.3 [<A href="https://wg21.link/expr.context">expr.context</A>]).</DEL> &#8212;<I>end note</I>] ...

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 7.5.8.4 [<A href="https://wg21.link/expr.prim.req.compound#1">expr.prim.req.compound</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

A <I>compound-requirement</I> asserts properties of the expression
E. <INS>The <I>expression</I> is an unevaluated operand.</INS>
Substitution of template arguments (if any) and verification of
semantic properties proceed in the following order:

</BLOCKQUOTE>
</LI>
</OL>
<BR><BR><HR>
<A NAME="2913"></A><H4>2913.
  
Grammar for <I>deduction-guide</I> has <I>requires-clause</I> in the wrong position
</H4>
<B>Section: </B>13.7.2.3&#160; [<A href="https://wg21.link/temp.deduct.guide">temp.deduct.guide</A>]
 &#160;&#160;&#160;

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

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

 <B>Date: </B>2024-07-17


<P>(From submission
<A HREF="https://github.com/cplusplus/CWG/issues/576">#576</A>.)</P>

<P>
Issue 2707 added the
missing <I>requires-clause</I> to the grammar
for <I>deduction-guide</I>, but the position is inconsistent with that
of function declarations.</P>

<P><B>Proposed resolution (approved by CWG 2024-08-16):</B></P>

<P>Change in 13.7.2.3 [<A href="https://wg21.link/temp.deduct.guide#1">temp.deduct.guide</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

<PRE>
<I>deduction-guide :
    explicit-specifier<SUB>opt</SUB> template-name</I> ( <I>parameter-declaration-clause</I> ) <I><DEL>requires-clause<SUB>opt</SUB></DEL> -&gt; simple-template-id <INS>requires-clause<SUB>opt</SUB></INS></I> ;
</PRE>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2915"></A><H4>2915.
  
Explicit object parameters of type <TT>void</TT>
</H4>
<B>Section: </B>9.3.4.6&#160; [<A href="https://wg21.link/dcl.fct">dcl.fct</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Anoop Rana
 &#160;&#160;&#160;

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


<P>(From submission
<A HREF="https://github.com/cplusplus/CWG/issues/578">#578</A>.)</P>



<P>Consider:</P>

<PRE>
  struct A {
    void f(this void);
  };
</PRE>

<P>This ought to be an ill-formed parameter of type <TT>void</TT>.</P>

<P><B>Proposed resolution (approved by CWG 2024-08-16):</B></P>

<P>Change in 9.3.4.6 [<A href="https://wg21.link/dcl.fct#3">dcl.fct</A>] paragraph 3 as follows:</P>

<BLOCKQUOTE>

If the <I>parameter-declaration-clause</I> is empty, the function
takes no arguments. A parameter list consisting of a single unnamed
<INS>non-object</INS> parameter of non-dependent type <TT>void</TT> is
equivalent to an empty parameter list. Except for this special case, a
parameter shall not have type <I>cv</I> <TT>void</TT>.

</BLOCKQUOTE>
<BR><BR><HR>
<A NAME="2918"></A><H4>2918.
  
Consideration of constraints for address of overloaded function
</H4>
<B>Section: </B>12.3&#160; [<A href="https://wg21.link/over.over">over.over</A>]
 &#160;&#160;&#160;

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

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

 <B>Date: </B>2024-06-26




<P>Consider:</P>

<PRE>
  template&lt;bool B&gt; struct X {
    void f(short) requires B;
    void f(long);
    template&lt;typename&gt; void g(short) requires B;
    template&lt;typename&gt; void g(long);
   };
   void test(X&lt;true&gt; x) {
    x.f(0);           //<SPAN CLASS="cmnt"> #1, ambiguous</SPAN>
    x.g&lt;int&gt;(0);      //<SPAN CLASS="cmnt"> #2, ambiguous</SPAN>
    &amp;X&lt;true&gt;::f;      //<SPAN CLASS="cmnt"> #3, OK!</SPAN>
    &amp;X&lt;true&gt;::g&lt;int&gt;; //<SPAN CLASS="cmnt"> #4, ambiguous</SPAN>
  }
</PRE>

<P>For the function call cases, 12.2.4.1 [<A href="https://wg21.link/over.match.best.general#2.6">over.match.best.general</A>] bullet 2.6 and 13.7.7.3 [<A href="https://wg21.link/temp.func.order#6">temp.func.order</A>] paragraph 6 specify that
constraints are only considered if the competing overloads are
otherwise basically the same.  There is no corresponding restriction
when taking the address of a function.</P>

<P>For a second issue, the treatment of placeholder type deduction is
unclear:</P>

<PRE>
  template&lt;bool B&gt; struct X {
    void f(short) requires B;
    void f(short);
    template&lt;typename&gt; void g(short) requires B;
    template&lt;typename&gt; void g(short);
  };
  void test(X&lt;true&gt; x) {
    auto r = &amp;X&lt;true&gt;::f;       //<SPAN CLASS="cmnt"> #5</SPAN>
    auto s = &amp;X&lt;true&gt;::g&lt;int&gt;;  //<SPAN CLASS="cmnt"> #6</SPAN>
  }
</PRE>

<P>When the address of the overload set is resolved, there is a
target, but the target type is <TT>auto</TT>, which is not properly
handled.</P>

<P>See also issue 2572.</P>

<P><B>Proposed resolution (September, 2024) [SUPERSEDED]:</B></P>

<OL>
<LI>
<P>Change in 12.2.4.1 [<A href="https://wg21.link/over.match.best.general#2.6">over.match.best.general</A>] bullet 2.6 as follows:</P>

<BLOCKQUOTE>

<UL>
<LI>F1 and F2 are non-template functions and <INS>F1 is more
partial-ordering-constrained than F2
(13.5.5 [<A href="https://wg21.link/temp.constr.order">temp.constr.order</A>])</INS>
<UL class="del">
<LI>they have the same non-object-parameter-type-lists
(9.3.4.6 [<A href="https://wg21.link/dcl.fct">dcl.fct</A>]), and</LI>
<LI>if they are member
functions, both are direct members of the same class, and</LI>
<LI>if
both are non-static member functions, they have the same types for
their object parameters, and</LI>
<LI>F1 is more constrained than F2
according to the partial ordering of constraints described in
13.5.5 [<A href="https://wg21.link/temp.constr.order">temp.constr.order</A>],</LI>
</UL>
or if not that,
</LI>
</UL>

</BLOCKQUOTE>
</LI>

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

<BLOCKQUOTE>

... The target can be
<UL>
<LI>an object or reference being initialized
(9.4 [<A href="https://wg21.link/dcl.init">dcl.init</A>], 9.4.4 [<A href="https://wg21.link/dcl.init.ref">dcl.init.ref</A>],
9.4.5 [<A href="https://wg21.link/dcl.init.list">dcl.init.list</A>]),</LI>
<LI>the left side of an assignment (7.6.19 [<A href="https://wg21.link/expr.ass">expr.ass</A>]),</LI>
<LI>a parameter of a function (7.6.1.3 [<A href="https://wg21.link/expr.call">expr.call</A>]),</LI>
<LI>a parameter of a user-defined operator
(12.4 [<A href="https://wg21.link/over.oper">over.oper</A>]),</LI>
<LI>the return value of a function,
operator function, or conversion (8.7.4 [<A href="https://wg21.link/stmt.return">stmt.return</A>]),</LI>
<LI>an explicit type conversion (7.6.1.4 [<A href="https://wg21.link/expr.type.conv">expr.type.conv</A>],
7.6.1.9 [<A href="https://wg21.link/expr.static.cast">expr.static.cast</A>], 7.6.3 [<A href="https://wg21.link/expr.cast">expr.cast</A>]), or</LI>
<LI>a
non-type <I>template-parameter</I> (13.4.3 [<A href="https://wg21.link/temp.arg.nontype">temp.arg.nontype</A>]).</LI>
</UL>

<INS>If the target type contains a placeholder type, placeholder type
deduction is performed (9.2.9.7.2 [<A href="https://wg21.link/dcl.type.auto.deduct">dcl.type.auto.deduct</A>]), and the
remainder of this subclause uses the target type so deduced.
</INS>

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 12.3 [<A href="https://wg21.link/over.over#5">over.over</A>] paragraph 5 as follows:</P>

<BLOCKQUOTE>

All functions with associated constraints that are not satisfied
(13.5.3 [<A href="https://wg21.link/temp.constr.decl">temp.constr.decl</A>]) are eliminated from the set of selected
functions. If more than one function in the set remains, all function
template specializations in the set are eliminated if the set also
contains a function that is not a function template
specialization. Any given non-template function F0 is eliminated if
the set contains a second non-template function that is more
<DEL>constrained</DEL> <INS>partial-ordering-constrained</INS> than F0
<DEL>according to the partial ordering rules of</DEL>
<INS>(</INS>13.5.5 [<A href="https://wg21.link/temp.constr.order">temp.constr.order</A>]<INS>)</INS>. Any given
function template specialization F1 is eliminated if the set contains
a second function template specialization whose function template is
more specialized than the function template of F1 according to the
partial ordering rules of 13.7.7.3 [<A href="https://wg21.link/temp.func.order">temp.func.order</A>]. After such
eliminations, if any, there shall remain exactly one selected
function.

</BLOCKQUOTE>
</LI>

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

<BLOCKQUOTE>
<P>[Example 1: ...</P>

<P>The initialization of pfe is ill-formed because no f() with type
int(...) has been declared, and not because of any ambiguity. <DEL>For
another example,</DEL> <INS>-- end example]</INS>
</P>

<P class="ins">[Example:</P>

<P>...</P>

<P>-- end example]</P>

<P class="ins">[Example:</P>

<PRE class="ins">
  template&lt;bool B&gt; struct X {
    void f(short) requires B;
    void f(long);
    template&lt;typename&gt; void g(short) requires B;
    template&lt;typename&gt; void g(long);
  };
  void test() {
    &amp;X&lt;true&gt;::f;      //<SPAN CLASS="cmnt"> error: ambiguous; constraints are not considered</SPAN>
    &amp;X&lt;true&gt;::g&lt;int&gt;; //<SPAN CLASS="cmnt"> error: ambiguous; constraints are not considered</SPAN>
  }
</PRE>

<P class="ins">-- end example]</P>
</BLOCKQUOTE>
</LI>

<LI>
<P>Add a paragraph at the end of 13.5.5 [<A href="https://wg21.link/temp.constr.order">temp.constr.order</A>]:</P>

<BLOCKQUOTE>

<P>A declaration D1 is more constrained than another declaration D2 when
D1 is at least as constrained as D2, and D2 is not at least as
constrained as D1. [ Example: ... ]</P>

<P class="ins">
A non-template function F1 is more <I>partial-ordering-constrained</I>
than a non-template function F2 if
<UL class="ins">
<LI>they have the same non-object-parameter-type-lists
(9.3.4.6 [<A href="https://wg21.link/dcl.fct">dcl.fct</A>], and</LI>
<LI>if they are member functions, both are direct members of the same class, and</LI>
<LI>if both are non-static member functions, they have the same types for their object parameters, and</LI>
<LI>the declaration of F1 is more constrained than the declaration of F2.</LI>
</UL>
</P>

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 13.10.3.2 [<A href="https://wg21.link/temp.deduct.call#6">temp.deduct.call</A>] paragraph 6 as follows:</P>

<BLOCKQUOTE>

When P is a function type, function pointer type, or
pointer-to-member-function type:
<UL>
<LI>If the argument is an overload set containing one or more function
templates, the parameter is treated as a non-deduced context.</LI>
<LI>If the argument is an overload set (not containing function
templates), trial argument deduction is attempted using each of the
members of the set. <DEL>If deduction succeeds for only one of the
overload set members, that member is used as the argument value for
the deduction. If deduction succeeds for more than one member of the
overload set</DEL>
<INS>If all successful deductions yield the same deduced A, that
deduced A is the result of deduction; otherwise,</INS> the parameter
is treated as a non-deduced context.
</LI>
</UL>

</BLOCKQUOTE>
</LI>

<LI>
<P>Add a new paragraph at the end of 13.10.3.2 [<A href="https://wg21.link/temp.deduct.call">temp.deduct.call</A>] as follows:</P>

<BLOCKQUOTE class="ins">
[ Example:
<PRE>
  // <SPAN CLASS="cmnt">All arguments for placeholder type deduction (9.2.9.7.2 [<A href="https://wg21.link/dcl.type.auto.deduct">dcl.type.auto.deduct</A>]) yield the same deduced type.</SPAN>
  template&lt;bool B&gt; struct X {
    void f(short) requires B;   // #1
    void f(short);              // #2
  };
  void test() {
    auto x = &amp;X&lt;true&gt;::f;       //<SPAN CLASS="cmnt"> OK, deduces </SPAN>void(*)(short)<SPAN CLASS="cmnt">, selects #1</SPAN>
    auto y = &amp;X&lt;false&gt;::f;       //<SPAN CLASS="cmnt"> OK, deduces </SPAN>void(*)(short)<SPAN CLASS="cmnt">, selects #2</SPAN>
  }
</PRE>
-- end example]
</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 13.10.3.6 [<A href="https://wg21.link/temp.deduct.type#5.6">temp.deduct.type</A>] bullet 5.6 as follows:</P>

<BLOCKQUOTE>

<UL>
<LI>A function parameter for which the associated argument is an overload
set <DEL>(12.3 [<A href="https://wg21.link/over.over">over.over</A>])</DEL>, and one or more of the following
apply:
<UL>
<LI>
<DEL>more than one function matches</DEL> <INS>functions that do
not all have the same function type match</INS> the function parameter
type (resulting in an ambiguous deduction), or</LI>
<LI>no function matches the function parameter type, or</LI>
<LI>the overload set supplied as an argument contains one or more
function templates.
</LI>
</UL>
</LI>
</UL>

</BLOCKQUOTE>

</LI>

<LI>
<P>Add a section to C.1.4 [<A href="https://wg21.link/diff.cpp23.temp">diff.cpp23.temp</A>]:</P>

<BLOCKQUOTE class="ins">
<P>
Affected subclause: 13.10.3.2 [<A href="https://wg21.link/temp.deduct.call">temp.deduct.call</A>]<BR>
Change: Template argument deduction from overload sets succeeds in more cases.<BR>
Rationale: Allow consideration of constraints to disambiguate overload sets used as parameters in function calls.<BR>
Effect on original feature: Valid C++ 2023 code may become ill-formed.<BR>
[Example 1:
</P>
<PRE>
  template &lt;typename T&gt;
  void f(T &amp;&amp;, void (*)(T &amp;&amp;));

  void g(int &amp;);
  inline namespace A {
    void g(short &amp;&amp;);
  }
  inline namespace B {
    void g(short &amp;&amp;);
  }

  void q() {
    int x;
    f(x, g);         //<SPAN CLASS="cmnt"> ill-formed; previously well-formed, deducing </SPAN>T=int&amp;
  }
</PRE>
-- end example]
</BLOCKQUOTE>
</LI>
</OL>

<P><B>CWG 2024-09-27</B></P>

<P>Functions whose constraints are not satisfied should be excluded
from the overload set before attempting deduction.  Also, clarify that
12.3 [<A href="https://wg21.link/over.over">over.over</A>] applies after deduction is complete.</P>

<P><B>Proposed resolution (approved by CWG 2024-11-19):</B></P>

<OL>
<LI>
<P>Change in 12.2.4.1 [<A href="https://wg21.link/over.match.best.general#2.6">over.match.best.general</A>] bullet 2.6 as follows:</P>

<BLOCKQUOTE>

<UL>
<LI>F1 and F2 are non-template functions and <INS>F1 is more
partial-ordering-constrained than F2
(13.5.5 [<A href="https://wg21.link/temp.constr.order">temp.constr.order</A>])</INS>
<UL class="del">
<LI>they have the same non-object-parameter-type-lists
(9.3.4.6 [<A href="https://wg21.link/dcl.fct">dcl.fct</A>]), and</LI>
<LI>if they are member
functions, both are direct members of the same class, and</LI>
<LI>if
both are non-static member functions, they have the same types for
their object parameters, and</LI>
<LI>F1 is more constrained than F2
according to the partial ordering of constraints described in
13.5.5 [<A href="https://wg21.link/temp.constr.order">temp.constr.order</A>],</LI>
</UL>
or if not that,
</LI>
</UL>

</BLOCKQUOTE>
</LI>

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

<BLOCKQUOTE>

... The target can be
<UL>
<LI>an object or reference being initialized
(9.4 [<A href="https://wg21.link/dcl.init">dcl.init</A>], 9.4.4 [<A href="https://wg21.link/dcl.init.ref">dcl.init.ref</A>],
9.4.5 [<A href="https://wg21.link/dcl.init.list">dcl.init.list</A>]),</LI>
<LI>the left side of an assignment (7.6.19 [<A href="https://wg21.link/expr.ass">expr.ass</A>]),</LI>
<LI>a parameter of a function (7.6.1.3 [<A href="https://wg21.link/expr.call">expr.call</A>]),</LI>
<LI>a parameter of a user-defined operator
(12.4 [<A href="https://wg21.link/over.oper">over.oper</A>]),</LI>
<LI>the return value of a function,
operator function, or conversion (8.7.4 [<A href="https://wg21.link/stmt.return">stmt.return</A>]),</LI>
<LI>an explicit type conversion (7.6.1.4 [<A href="https://wg21.link/expr.type.conv">expr.type.conv</A>],
7.6.1.9 [<A href="https://wg21.link/expr.static.cast">expr.static.cast</A>], 7.6.3 [<A href="https://wg21.link/expr.cast">expr.cast</A>]), or</LI>
<LI>a
non-type <I>template-parameter</I> (13.4.3 [<A href="https://wg21.link/temp.arg.nontype">temp.arg.nontype</A>]).</LI>
</UL>

<INS>If the target type contains a placeholder type, placeholder type
deduction is performed (9.2.9.7.2 [<A href="https://wg21.link/dcl.type.auto.deduct">dcl.type.auto.deduct</A>]), and the
remainder of this subclause uses the target type so deduced.
</INS>

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 12.3 [<A href="https://wg21.link/over.over#5">over.over</A>] paragraph 5 as follows:</P>

<BLOCKQUOTE>

All functions with associated constraints that are not satisfied
(13.5.3 [<A href="https://wg21.link/temp.constr.decl">temp.constr.decl</A>]) are eliminated from the set of selected
functions. If more than one function in the set remains, all function
template specializations in the set are eliminated if the set also
contains a function that is not a function template
specialization. Any given non-template function F0 is eliminated if
the set contains a second non-template function that is more
<DEL>constrained</DEL> <INS>partial-ordering-constrained</INS> than F0
<DEL>according to the partial ordering rules of</DEL>
<INS>(</INS>13.5.5 [<A href="https://wg21.link/temp.constr.order">temp.constr.order</A>]<INS>)</INS>. Any given
function template specialization F1 is eliminated if the set contains
a second function template specialization whose function template is
more specialized than the function template of F1 according to the
partial ordering rules of 13.7.7.3 [<A href="https://wg21.link/temp.func.order">temp.func.order</A>]. After such
eliminations, if any, there shall remain exactly one selected
function.

</BLOCKQUOTE>
</LI>

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

<BLOCKQUOTE>
<P>[Example 1: ...</P>

<P>The initialization of pfe is ill-formed because no f() with type
int(...) has been declared, and not because of any ambiguity. <DEL>For
another example,</DEL> <INS>-- end example]</INS>
</P>

<P class="ins">[Example:</P>

<P>...</P>

<P>-- end example]</P>

<P class="ins">[Example:</P>

<PRE class="ins">
  template&lt;bool B&gt; struct X {
    void f(short) requires B;
    void f(long);
    template&lt;typename&gt; void g(short) requires B;
    template&lt;typename&gt; void g(long);
  };
  void test() {
    &amp;X&lt;true&gt;::f;      //<SPAN CLASS="cmnt"> error: ambiguous; constraints are not considered</SPAN>
    &amp;X&lt;true&gt;::g&lt;int&gt;; //<SPAN CLASS="cmnt"> error: ambiguous; constraints are not considered</SPAN>
  }
</PRE>

<P class="ins">-- end example]</P>
</BLOCKQUOTE>
</LI>

<LI>
<P>Add a paragraph at the end of 13.5.5 [<A href="https://wg21.link/temp.constr.order">temp.constr.order</A>]:</P>

<BLOCKQUOTE>

<P>A declaration D1 is more constrained than another declaration D2 when
D1 is at least as constrained as D2, and D2 is not at least as
constrained as D1. [ Example: ... ]</P>

<P class="ins">
A non-template function F1 is <I>more partial-ordering-constrained</I>
than a non-template function F2 if
<UL class="ins">
<LI>they have the same non-object-parameter-type-lists
(9.3.4.6 [<A href="https://wg21.link/dcl.fct">dcl.fct</A>], and</LI>
<LI>if they are member functions, both are direct members of the same class, and</LI>
<LI>if both are non-static member functions, they have the same types for their object parameters, and</LI>
<LI>the declaration of F1 is more constrained than the declaration of F2.</LI>
</UL>
</P>

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 13.10.3.2 [<A href="https://wg21.link/temp.deduct.call#6">temp.deduct.call</A>] paragraph 6 as follows:</P>

<BLOCKQUOTE>

When P is a function type, function pointer type, or
pointer-to-member-function type:
<UL>
<LI>If the argument is an overload set containing one or more function
templates, the parameter is treated as a non-deduced context.</LI>
<LI>If the argument is an overload set (not containing function
templates), trial argument deduction is attempted using each of the
members of the set <INS>whose associated constraints
(13.5.2 [<A href="https://wg21.link/temp.constr.constr">temp.constr.constr</A>]) are satisfied</INS>.
<DEL>If deduction succeeds for only one of the
overload set members, that member is used as the argument value for
the deduction. If deduction succeeds for more than one member of the
overload set</DEL>
<INS>If all successful deductions yield the same deduced A, that
deduced A is the result of deduction; otherwise,</INS> the parameter
is treated as a non-deduced context.
</LI>
</UL>

</BLOCKQUOTE>
</LI>

<LI>
<P>Add a new paragraph at the end of 13.10.3.2 [<A href="https://wg21.link/temp.deduct.call">temp.deduct.call</A>] as follows:</P>

<BLOCKQUOTE class="ins">
[ Example:
<PRE>
  // <SPAN CLASS="cmnt">All arguments for placeholder type deduction (9.2.9.7.2 [<A href="https://wg21.link/dcl.type.auto.deduct">dcl.type.auto.deduct</A>]) yield the same deduced type.</SPAN>
  template&lt;bool B&gt; struct X {
    static void f(short) requires B;   // #1
    static void f(short);              // #2
  };
  void test() {
    auto x = &amp;X&lt;true&gt;::f;       //<SPAN CLASS="cmnt"> OK, deduces </SPAN>void(*)(short)<SPAN CLASS="cmnt">, selects #1</SPAN>
    auto y = &amp;X&lt;false&gt;::f;       //<SPAN CLASS="cmnt"> OK, deduces </SPAN>void(*)(short)<SPAN CLASS="cmnt">, selects #2</SPAN>
  }
</PRE>
-- end example]
</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 13.10.3.6 [<A href="https://wg21.link/temp.deduct.type#5.6">temp.deduct.type</A>] bullet 5.6 as follows:</P>

<BLOCKQUOTE>

<UL>
<LI>A function parameter for which the associated argument is an
overload set <DEL>(12.3 [<A href="https://wg21.link/over.over">over.over</A>]), and</DEL> <INS>such
that</INS> one or more of the following apply:
<UL>
<LI>
<DEL>more than one function matches</DEL> <INS>functions whose
associated constraints are satisfied and that do not all have the same
function type match</INS> the function parameter type (resulting in an
ambiguous deduction), or</LI>
<LI>no function <INS>whose associated constraints are satisfied</INS>
matches the function parameter type, or</LI>
<LI>the overload set supplied as an argument contains one or more
function templates.
</LI>
</UL>
<INS>[ Note: A particular function from the overload set is selected
(12.3 [<A href="https://wg21.link/over.over">over.over</A>]) after template argument deduction has
succeeded (13.10.4 [<A href="https://wg21.link/temp.over">temp.over</A>]). -- end note ]</INS>
</LI>
</UL>

</BLOCKQUOTE>

</LI>

<LI>
<P>Add a section to C.1.4 [<A href="https://wg21.link/diff.cpp23.temp">diff.cpp23.temp</A>]:</P>

<BLOCKQUOTE class="ins">
<P>
Affected subclause: 13.10.3.2 [<A href="https://wg21.link/temp.deduct.call">temp.deduct.call</A>]<BR>
Change: Template argument deduction from overload sets succeeds in more cases.<BR>
Rationale: Allow consideration of constraints to disambiguate overload sets used as parameters in function calls.<BR>
Effect on original feature: Valid C++ 2023 code may become ill-formed.<BR>
[Example 1:
</P>
<PRE>
  template &lt;typename T&gt;
  void f(T &amp;&amp;, void (*)(T &amp;&amp;));

  void g(int &amp;);              // <SPAN CLASS="cmnt">#1</SPAN>
  inline namespace A {
    void g(short &amp;&amp;);         // <SPAN CLASS="cmnt">#2</SPAN>
  }
  inline namespace B {
    void g(short &amp;&amp;);         // <SPAN CLASS="cmnt">#3</SPAN>
  }

  void q() {
    int x;
    f(x, g);         //<SPAN CLASS="cmnt"> ill-formed; previously well-formed, deducing </SPAN>T=int&amp;
  }
</PRE>
There is no change to the applicable deduction rules for the
individual <TT>g</TT> candidates: Type deduction from #1 does not
succeed; type deductions from #2 and #3 both succeed.  -- end
example]
</BLOCKQUOTE>
</LI>
</OL>

<BR><BR><HR>
<A NAME="2919"></A><H4>2919.
  
Conversion function candidates for initialization of const lvalue reference
</H4>
<B>Section: </B>12.2.2.7&#160; [<A href="https://wg21.link/over.match.ref">over.match.ref</A>]
 &#160;&#160;&#160;

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

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

 <B>Date: </B>2024-07-18




<P>There is implementation divergence handling the following example:</P>

<PRE>
  struct A {
    A(const A&amp;) = delete;
  };
  struct B {
    operator A&amp;&amp;();
  };
  const A&amp; r = B();
</PRE>

<P>Conversion to an lvalue pursuant to 9.4.4 [<A href="https://wg21.link/dcl.init.ref#5.1">dcl.init.ref</A>] bullet 5.1 fails due to the attempt to invoke a deleted function,
but conversion to an rvalue according to 9.4.4 [<A href="https://wg21.link/dcl.init.ref#5.3">dcl.init.ref</A>] bullet 5.3 would succeed, except that 12.2.2.7 [<A href="https://wg21.link/over.match.ref#1.1">over.match.ref</A>] bullet 1.1 hinges on the target type of the initialization, not
the target type of the conversion.</P>

<P><B>Proposed resolution (approved by CWG 2024-08-16):</B></P>

<P>Change in 12.2.2.7 [<A href="https://wg21.link/over.match.ref#1.1">over.match.ref</A>] bullet 1.1 as follows:</P>

<BLOCKQUOTE>

Let R be a set of types including
<UL>
<LI>&#8220;lvalue reference to cv2 T2&#8221;
(when <DEL>initializing</DEL> <INS>converting to</INS> an
lvalue <DEL>reference or an rvalue reference to function</DEL>)
and</LI>
<LI>&#8220;cv2 T2&#8221; and &#8220;rvalue reference to cv2 T2&#8221;
(when <DEL>initializing</DEL> <INS>converting to</INS> an
rvalue <DEL>reference</DEL> or an lvalue <DEL>reference
to</DEL> <INS>of</INS> function <INS>type</INS>)</LI>
</UL>
for any T2.

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2921"></A><H4>2921.
  
Exporting redeclarations of entities not attached to a named module
</H4>
<B>Section: </B>10.2&#160; [<A href="https://wg21.link/module.interface">module.interface</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Tomasz Kami&#324;ski
 &#160;&#160;&#160;

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




<P>Consider:</P>

<PRE>
  export module mod;
  extern "C++" void func();
  export extern "C++" {
    void func();
  }
</PRE>

<P>Per 10.2 [<A href="https://wg21.link/module.interface#6">module.interface</A>] paragraph 6, this is currently
ill-formed, but implementation treatment varies and there seems to be
little rationale why this should be ill-formed for entities not
attached to a named module.</P>

<P>The rule also makes the following example ill-formed, which was
intended to be well-formed:</P>

<PRE>
  export module M;
  namespace N { //<SPAN CLASS="cmnt"> external linkage, attached to global module, not exported</SPAN>
    void f();
  }
  namespace N { //<SPAN CLASS="cmnt"> error: exported namespace, redeclares non-exported namespace</SPAN>
    export void g();
  }
</PRE>

<P>The mental model here is that for an entity not attached to a named
module, exportedness is not a meaningful property of that entity.</P>

<P><B>Proposed resolution (approved by CWG 2024-08-16):</B></P>

<P>Change in 10.2 [<A href="https://wg21.link/module.interface#6">module.interface</A>] paragraph 6 as follows:</P>

<BLOCKQUOTE>

A redeclaration of an entity X is implicitly exported if X was
introduced by an exported declaration; otherwise it shall not be
exported <INS>if it is attached to a named module</INS>.

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2922"></A><H4>2922.
  
constexpr placement-new is too permissive
</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>Brian Bi
 &#160;&#160;&#160;

 <B>Date: </B>2024-07-10




<P>constexpr placement new requires (just) pointer-interconvertibility
for the argument pointer, whereas <TT>static_cast</TT>
from <TT>void*</TT> to <TT>T*</TT> requires similarity.  Requiring
pointer-interconvertibility would not allow to differentiate two
members of some union of the same type; such differentiation is
required diagnose access to inactive union members.</P>

<P><B>Proposed resolution (approved by CWG 2024-08-16):</B></P>

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

<BLOCKQUOTE>

<UL>
<LI>
the selected allocation function is a non-allocating form
(17.6.3.4 [<A href="https://wg21.link/new.delete.placement">new.delete.placement</A>]) with an allocated type T, where
<UL>
<LI>the placement argument to the <I>new-expression</I> points to an
object <DEL>that is pointer-interconvertible with an object
of</DEL> <INS>whose</INS> type <INS>is similar to</INS>
T <INS>(7.3.6 [<A href="https://wg21.link/conv.qual">conv.qual</A>])</INS> or, if T is an array
type, <DEL>with</DEL> <INS>to</INS> the first element of an object
of <INS>a</INS> type <INS>similar to</INS> T, and</LI>
<LI>the placement argument points to storage whose
duration began within the evaluation of E;</LI>
</UL>
</LI>
</UL>

</BLOCKQUOTE>

<P><B>CWG 2024-11-19</B></P>

<P>The proposed resolution does not address the ambiguity with
different union members of the same type, but is a good fix to
increase consistency with <TT>static_cast</TT> regardless.</P>

<BR><BR><HR>
<A NAME="2924"></A><H4>2924.
  
Undefined behavior during constant evaluation
</H4>
<B>Section: </B>3.63&#160; [<A href="https://wg21.link/defns.undefined">defns.undefined</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Jan Schultke
 &#160;&#160;&#160;

 <B>Date: </B>2024-06-04


<P>(From editorial issue
<A HREF="https://github.com/cplusplus/draft/issues/7042">#7042</A>
and submission
<A HREF="https://github.com/cplusplus/CWG/issues/595">#595</A>.)</P>

<P>Subclause 3.63 [<A href="https://wg21.link/defns.undefined">defns.undefined</A>] states:</P>

<BLOCKQUOTE>

[Note 1 to entry: ... Evaluation of a constant expression
(7.7 [<A href="https://wg21.link/expr.const">expr.const</A>]) never exhibits behavior explicitly
specified as undefined in Clause 4 [<A href="https://wg21.link/intro">intro</A>] through
Clause 15 [<A href="https://wg21.link/cpp">cpp</A>]. &#8212;<I>end note</I>]

</BLOCKQUOTE>

<P>However, 7.7 [<A href="https://wg21.link/expr.const#5.8">expr.const</A>] bullet 5.8
excludes <TT>[[noreturn]]</TT> and <TT>[[assume]]</TT>; see also
7.7 [<A href="https://wg21.link/expr.const#6">expr.const</A>] paragraph 6.</P>

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

<P>Change in 3.63 [<A href="https://wg21.link/defns.undefined">defns.undefined</A>] as follows:</P>

<BLOCKQUOTE>

[Note 1 to entry: ... Evaluation of a constant expression
(7.7 [<A href="https://wg21.link/expr.const">expr.const</A>]) never exhibits behavior explicitly
specified as undefined in Clause 4 [<A href="https://wg21.link/intro">intro</A>] through
Clause 15 [<A href="https://wg21.link/cpp">cpp</A>]<INS>, excluding
9.12 [<A href="https://wg21.link/dcl.attr">dcl.attr</A>]</INS>. &#8212;<I>end note</I>]

</BLOCKQUOTE>

<P><B>CWG 2024-09-13</B></P>

<P>Admitting unbounded core-language undefined behavior in constant
expressions is to be avoided.  The quoted note is correct; the
semantics of <TT>[[noreturn]]</TT> and <TT>[[assume]]</TT> need to be
clarified.</P>

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

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

<BLOCKQUOTE>

... The expression is not evaluated. If the converted expression would
evaluate to true at the point where the assumption appears <INS>or if
the assumption is evaluated in a context that is manifestly
constant-evaluated</INS>, the assumption has no effect.  Otherwise,
the behavior is undefined.

</BLOCKQUOTE>
</LI>

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

<BLOCKQUOTE>

If a function <TT>f</TT> is called where <TT>f</TT> was previously
declared with the <TT>noreturn</TT> attribute<INS>, the function call
is evaluated in a context that is not manifestly constant-evaluated
(7.7 [<A href="https://wg21.link/expr.const">expr.const</A>]),</INS> and <TT>f</TT> eventually
returns, the behavior is undefined.

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

<P><B>CWG 2024-09-27</B></P>

<P>The suggested resolution is circular with the rules in
7.7 [<A href="https://wg21.link/expr.const#6">expr.const</A>] paragraph 6.</P>

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

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

<BLOCKQUOTE>

... The expression is not evaluated. If the converted expression would
evaluate to true at the point where the assumption appears, the
assumption has no effect.  Otherwise, <INS>outside of an evaluation to
determine whether an expression is a core constant expression
(7.7 [<A href="https://wg21.link/expr.const">expr.const</A>]),</INS> the behavior is undefined.

</BLOCKQUOTE>
</LI>

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

<BLOCKQUOTE>

If a function <TT>f</TT> is called where <TT>f</TT> was previously
declared with the <TT>noreturn</TT> attribute<INS>, the function call
is evaluated outside of an evaluation to determine whether an
expression is a core constant expression
(7.7 [<A href="https://wg21.link/expr.const">expr.const</A>]),</INS> and <TT>f</TT> eventually returns,
the behavior is undefined.

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

<P><B>CWG 2024-10-11</B></P>

<P>Implementations have two options: Either a violation of an
attribute causes an expressions not to be a constant expression,
leading to runtime undefined behavior, or the attribute has no effect
during constant evaluation.</P>

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

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

<BLOCKQUOTE>

<P class="ins">It is implementation-defined whether <I>E</I> is a core
constant expression in the situations specified in
9.12.3 [<A href="https://wg21.link/dcl.attr.assume">dcl.attr.assume</A>] and 9.12.11 [<A href="https://wg21.link/dcl.attr.noreturn">dcl.attr.noreturn</A>].
</P>

<P>It is unspecified whether E is a core constant expression if E
satisfies the constraints of a core constant expression, but
evaluation of E would evaluate</P>
<UL>
<LI>an operation that has undefined behavior as specified in
Clause 16 [<A href="https://wg21.link/library">library</A>] through Clause 34 [<A href="https://wg21.link/exec">exec</A>]<DEL>,</DEL>
<INS>or</INS>
</LI>
<LI>an invocation of the va_start macro
(17.13.2 [<A href="https://wg21.link/cstdarg.syn">cstdarg.syn</A>])<DEL>,</DEL><INS>.</INS>
</LI>
<LI class="del">a call to a function that was previously declared with
the noreturn attribute (9.12.11 [<A href="https://wg21.link/dcl.attr.noreturn">dcl.attr.noreturn</A>]) and that call
returns to its caller, or</LI>
<LI class="del">a statement with an assumption (9.12.3 [<A href="https://wg21.link/dcl.attr.assume">dcl.attr.assume</A>]) whose
converted <I>conditional-expression</I>, if evaluated where the
assumption appears, would not disqualify E from being a core constant
expression and would not evaluate to true.  [<I>Note 5:</I> E is not
disqualified from being a core constant expression if the hypothetical
evaluation of the converted <I>conditional-expression</I> would
disqualify E from being a core constant expression. &#8212;<I>end
note</I>]</LI>
</UL>

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 9.12.3 [<A href="https://wg21.link/dcl.attr.assume#1">dcl.attr.assume</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

... The expression is not evaluated.
<UL>
<LI>If the converted expression would evaluate to true at the point
where the assumption appears, the assumption has no effect.</LI>
<LI class="ins">Otherwise, if the statement with the assumption would
be evaluated as part of an evaluation of an expression <I>E</I> that
satisfies the constraints of a core constant expression
(7.7 [<A href="https://wg21.link/expr.const">expr.const</A>]):
<UL>
<LI>If the converted expression, evaluated at the point where the
assumption appears, would disqualify <I>E</I> from being a core
constant expression, the assumption is ignored.</LI>
<LI>Otherwise, it is implementation-defined whether <I>E</I> is a core
constant expression; if <I>E</I> is evaluated as a core constant
expression, the assumption has no effect.</LI>
</UL>
</LI>
<LI>Otherwise, the behavior is undefined.</LI>
</UL>

</BLOCKQUOTE>
</LI>

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

<BLOCKQUOTE>

If a function <TT>f</TT> is called where <TT>f</TT> was previously
declared with the <TT>noreturn</TT> attribute and <TT>f</TT>
eventually returns<INS>:</INS>
<UL>
<LI class="ins">If the function call would be part of an evaluation of
an expression <I>E</I> that satisfies the constraints of a core
constant expression (7.7 [<A href="https://wg21.link/expr.const">expr.const</A>]), it is
implementation-defined whether <I>E</I> is a core constant expression;
if <I>E</I> is evaluated as a core constant expression, the attribute
has no effect.</LI>
<LI>
<INS>Otherwise</INS>, the behavior is undefined.</LI>
</UL>

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

<P><B>CWG 2024-10-25</B></P>

<P>CWG prefers an approach suggested by Richard Smith that defines a
new term "runtime undefined behavior".</P>

<P><B>Proposed resolution (approved by CWG 2024-11-08):</B></P>

<OL>
<LI>
<P>Add to Clause 3 [<A href="https://wg21.link/intro.defs">intro.defs</A>]:</P>

<BLOCKQUOTE class="ins">

<P>
<B>constant evaluation</B> [defns.const.eval]</P>
<P>evaluation that is performed as part of evaluating an expression as a core constant expression (7.7 [<A href="https://wg21.link/expr.const">expr.const</A>])</P>

<P>
<B>runtime-undefined behavior</B> [defns.undefined.runtime]</P>
<P>behavior that is undefined except when it occurs during constant evaluation</P>
<P>[Note 1 to entry: During constant evaluation,
<UL>
<LI>it is
implementation-defined whether runtime-undefined behavior results in
the expression being deemed non-constant (as specified in
7.7 [<A href="https://wg21.link/expr.const">expr.const</A>]) and</LI>
<LI>runtime-undefined behavior has
no other effect.]</LI>
</UL>
</P>

</BLOCKQUOTE>
</LI>

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

<BLOCKQUOTE>

<UL>
<LI>an operation that would have undefined or erroneous behavior as
specified in Clause 4 [<A href="https://wg21.link/intro">intro</A>] through
Clause 15 [<A href="https://wg21.link/cpp">cpp</A>]<DEL>, excluding 9.12.3 [<A href="https://wg21.link/dcl.attr.assume">dcl.attr.assume</A>]
and 9.12.11 [<A href="https://wg21.link/dcl.attr.noreturn">dcl.attr.noreturn</A>]</DEL>;
</LI>
</UL>

</BLOCKQUOTE>
</LI>

<LI>
<P>Add a paragraph after 7.7 [<A href="https://wg21.link/expr.const#5">expr.const</A>] paragraph 5 as follows:</P>

<BLOCKQUOTE class="ins">

It is implementation-defined whether <I>E</I> is a core constant expression
if <I>E</I> satisfies the constraints of a core constant expression, but
evaluation of <I>E</I> has runtime-undefined behavior.

</BLOCKQUOTE>
</LI>

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

<BLOCKQUOTE>

<P>It is unspecified whether E is a core constant expression if E
satisfies the constraints of a core constant expression, but
evaluation of E would evaluate</P>
<UL>
<LI>an operation that has undefined behavior as specified in
Clause 16 [<A href="https://wg21.link/library">library</A>] through Clause 34 [<A href="https://wg21.link/exec">exec</A>]<DEL>,</DEL>
<INS>or</INS>
</LI>
<LI>an invocation of the va_start macro
(17.13.2 [<A href="https://wg21.link/cstdarg.syn">cstdarg.syn</A>])<DEL>,</DEL><INS>.</INS>
</LI>
<LI class="del">a call to a function that was previously declared with
the noreturn attribute (9.12.11 [<A href="https://wg21.link/dcl.attr.noreturn">dcl.attr.noreturn</A>]) and that call
returns to its caller, or</LI>
<LI class="del">a statement with an assumption (9.12.3 [<A href="https://wg21.link/dcl.attr.assume">dcl.attr.assume</A>]) whose
converted <I>conditional-expression</I>, if evaluated where the
assumption appears, would not disqualify E from being a core constant
expression and would not evaluate to true.  [<I>Note 5:</I> E is not
disqualified from being a core constant expression if the hypothetical
evaluation of the converted <I>conditional-expression</I> would
disqualify E from being a core constant expression. &#8212;<I>end
note</I>]</LI>
</UL>

</BLOCKQUOTE>
</LI>


<LI>
<P>Change in 9.12.3 [<A href="https://wg21.link/dcl.attr.assume#1">dcl.attr.assume</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

... If the converted expression would evaluate to true at the point
where the assumption appears, the assumption has no
effect. Otherwise, <DEL>the behavior is
undefined</DEL> <INS>evaluation of the assumption has
runtime-undefined behavior</INS>.

</BLOCKQUOTE>
</LI>

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

<BLOCKQUOTE>

If a function f is <DEL>called</DEL> <INS>invoked</INS> where f was
previously declared with the noreturn attribute
and <DEL>f</DEL> <INS>that invocation</INS> eventually returns, the
behavior is <INS>runtime-</INS>undefined.

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

<BR><BR><HR>
<A NAME="2927"></A><H4>2927.
  
Unclear status of translation unit with <TT>module</TT> keyword
</H4>
<B>Section: </B>15.1&#160; [<A href="https://wg21.link/cpp.pre">cpp.pre</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Chuanqi Xu
 &#160;&#160;&#160;

 <B>Date: </B>2024-08-15




<P>Consider:</P>

<PRE>
  using module = int;
  module i;
  int foo() {
    return i;
  }
</PRE>

<P>Is this a valid translation unit?</P>

<P>It is not a valid <I>module-file</I>, because the translation unit
does not start with <TT>module</TT> or <TT>export module</TT>
(15.4 [<A href="https://wg21.link/cpp.module">cpp.module</A>]).  It is also not a valid
traditional <I>preprocessing-file</I> (15.1 [<A href="https://wg21.link/cpp.pre">cpp.pre</A>]),
because <TT>module i</TT> is considered a preprocessing directive
(15.1 [<A href="https://wg21.link/cpp.pre#1.3">cpp.pre</A>] bullet 1.3, which is never
a <I>text-line</I> (15.1 [<A href="https://wg21.link/cpp.pre#2">cpp.pre</A>] paragraph 2):
</P>

<BLOCKQUOTE>

A sequence of preprocessing tokens is only a <I>text-line</I> if it
does not begin with a directive-introducing token. ...

</BLOCKQUOTE>

<P>A clarifying note would be appreciated.</P>

<P><U>Possible resolution (August, 2024):</U></P>

<P>Change in 15.1 [<A href="https://wg21.link/cpp.pre#2">cpp.pre</A>] paragraph 2 as follows:</P>

<BLOCKQUOTE>

<P>
A sequence of preprocessing tokens is only a <I>text-line</I> if it
does not begin with a directive-introducing token.
<INS>[ Note: A source line starting
with <TT>module</TT> <I>identifier</I> is always interpreted as a
preprocessing directive, not as a
<I>text-line</I>, even if parsing the source file as a
<I>preprocessing-file</I> subsequently fails.  -- end note ]</INS>
</P>

<P>A sequence of preprocessing tokens is only a
<I>conditionally-supported-directive</I> if ...</P>

</BLOCKQUOTE>

<P><B>CWG 2024-09-13</B></P>

<P>A source line starting with <TT>module</TT> <I>identifier</I>
appearing in a macro argument may or may not be interpreted as a
preprocessing directive (15.6.2 [<A href="https://wg21.link/cpp.subst#13">cpp.subst</A>] paragraph 13), thus
the note as written is incorrect.</P>

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

<P>Change in 15.1 [<A href="https://wg21.link/cpp.pre#2">cpp.pre</A>] paragraph 2 as follows:</P>

<BLOCKQUOTE>

<P>
A sequence of preprocessing tokens is only a <I>text-line</I> if it
does not begin with a directive-introducing token.
<INS>[ Example:</INS>
</P>

<PRE class="ins">
  using module = int;
  module i;       // <SPAN CLASS="cmnt">not a <I>text-line</I> and not a <I>control-line</I></SPAN>
  int foo() {
    return i;
  }
</PRE>

<INS>The example is not a valid <I>preprocessing-file</I>. -- end example]</INS>
</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2930"></A><H4>2930.
  
Unclear term "copy/move operation" in specification of copy elision
</H4>
<B>Section: </B>11.9.6&#160; [<A href="https://wg21.link/class.copy.elision">class.copy.elision</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Gabriel Dos Reis
 &#160;&#160;&#160;

 <B>Date: </B>2024-08-16




<P>The specification of copy elision in 11.9.6 [<A href="https://wg21.link/class.copy.elision">class.copy.elision</A>]
uses the undefined term "copy/move operation", even though the
constructor actually selected might not be a copy or move constructor
as specified in 11.4.5.3 [<A href="https://wg21.link/class.copy.ctor">class.copy.ctor</A>].  It is thus unclear
whether copy elision can be applied even in the case a non-copy/move
constructor is selected.</P>

<P><B>Proposed resolution (approved by CWG 2024-11-22):</B></P>

<P>Change in 11.9.6 [<A href="https://wg21.link/class.copy.elision#1">class.copy.elision</A>] paragraph 1 through 3 as follows:</P>

<BLOCKQUOTE>

When certain criteria are met, an implementation is allowed to omit
the <DEL>copy/move construction of</DEL> <INS>creation of</INS> a
class object <INS>from a source object of the same type (ignoring
cv-qualification)</INS>, even if the <INS>selected</INS> constructor
<DEL>selected for the copy/move operation</DEL> and/or the destructor
for the object have side effects. In such cases, the implementation
treats the source and target of the omitted <DEL>copy/move
operation</DEL> <INS>initialization</INS> as simply two different ways
of referring to the same object. If the first parameter of the
selected constructor is an rvalue reference to the object's type, the
destruction of that object occurs when the target would have been
destroyed; otherwise, the destruction occurs at the later of the times
when the two objects would have been destroyed without the
optimization.  [ <DEL>Footnote:</DEL> <INS>Note:</INS> Because only one object is destroyed instead
of two, and <DEL>one copy/move constructor is not executed</DEL>
<INS>the creation of one object is omitted</INS>, there is still one object destroyed
for each one constructed. -- end <DEL>footnote</DEL> <INS>note</INS> ] This elision
of <DEL>copy/move operations</DEL> <INS>object creation</INS>,
called <I>copy elision</I>, is permitted in the following
circumstances (which may be combined to eliminate multiple copies):
<UL>
<LI>in a <TT>return</TT>
statement <INS>(8.7.4 [<A href="https://wg21.link/stmt.return">stmt.return</A>])</INS> in a function with a
class return type, when the <I>expression</I> is the name of a
non-volatile object <INS><I>o</I></INS> with automatic storage
duration (other than a function parameter or a variable introduced by
the <I>exception-declaration</I> of a <I>handler</I>
(14.4 [<A href="https://wg21.link/except.handle">except.handle</A>])) <DEL>with the same type (ignoring
cv-qualification) as the function return type</DEL>, the
<DEL>copy/move operation</DEL> <INS>copy-initialization of the result
object</INS> can be omitted by constructing <DEL>the
object</DEL> <INS><I>o</I></INS> directly into the function call's
<DEL>return</DEL> <INS>result</INS> object<INS>;</INS>
</LI>
<LI>
in a <I>throw-expression</I> (7.6.18 [<A href="https://wg21.link/expr.throw">expr.throw</A>]), when the
operand is the name of a non-volatile object <INS><I>o</I></INS> with
automatic storage duration (other than a function <DEL>or
catch-clause</DEL> parameter <INS>or a variable introduced by
the <I>exception-declaration</I> of a <I>handler</I></INS>) that
belongs to a scope that does not contain the innermost
enclosing <I>compound-statement</I> associated with a <I>try-block</I>
(if there is one), the <DEL>copy/move
operation</DEL> <INS>copy-initialization of the exception object</INS>
can be omitted by constructing <DEL>the object</DEL>
<INS><I>o</I></INS> directly into the exception object<INS>;</INS>
</LI>
<LI>in a coroutine (9.5.4 [<A href="https://wg21.link/dcl.fct.def.coroutine">dcl.fct.def.coroutine</A>]), a copy of a coroutine
parameter can be omitted and references to that copy replaced with
references to the corresponding parameter if the meaning of the
program will be unchanged except for the execution of a constructor
and destructor for the parameter copy object<INS>;</INS>
</LI>
<LI>when the <I>exception-declaration</I> of a handler
(14.4 [<A href="https://wg21.link/except.handle">except.handle</A>]) declares an object <INS><I>o</I></INS> <DEL>of
the same type (except for cv-qualification) as the exception object
(14.2 [<A href="https://wg21.link/except.throw">except.throw</A>])</DEL>, the <DEL>copy operation</DEL>
<INS>copy-initialization of <I>o</I></INS> can be
omitted by treating the <I>exception-declaration</I> as an alias for
the exception object if the meaning of the program will be unchanged
except for the execution of constructors and destructors for the
object declared by the <I>exception-declaration</I>.  [<I>Note 1:</I>
There cannot be a move from the exception object because it is always
an lvalue. &#8212;<I>end note</I>]
</LI>
</UL>

</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2931"></A><H4>2931.
  
Restrictions on operator functions that are explicit object member functions
</H4>
<B>Section: </B>12.4.1&#160; [<A href="https://wg21.link/over.oper.general">over.oper.general</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Barry Revzin
 &#160;&#160;&#160;

 <B>Date: </B>2024-08-26


<P>(From submission
<A HREF="https://github.com/cplusplus/CWG/issues/600">#600</A>.)</P>

<P>With the introduction of explicit object member functions, the
restrictions on operator functions became inconsistent.  Subclause
12.4.1 [<A href="https://wg21.link/over.oper.general#7">over.oper.general</A>] paragraph 7 specifies:</P>

<BLOCKQUOTE>

An operator function shall either
<UL>
<LI>be a member function or</LI>
<LI>be a non-member function that has at least one non-object
parameter whose type is a class, a reference to a class, an
enumeration, or a reference to an enumeration.</LI>
</UL>

</BLOCKQUOTE>

<P>Talking about non-object parameters in a bullet discussing
non-member functions makes no sense.  The following example ought to
be prohibited, for consistency with <TT>operator==(int, int)</TT>:</P>

<PRE>
  struct B {
    bool operator==(this int, int);
    operator int() const;
  };
</PRE>

<P><B>Proposed resolution (approved by CWG 2024-11-22):</B></P>

<P>Change in 12.4.1 [<A href="https://wg21.link/over.oper.general#7">over.oper.general</A>] paragraph 7 as follows, removing
the bullets:</P>

<BLOCKQUOTE>

An operator function shall <DEL>either</DEL>
<UL>
<LI><DEL>be a member function or</DEL></LI>
<LI>
<DEL>be a non-member function that has</DEL> <INS>have</INS> at
least one <DEL>non-object</DEL> <INS>function</INS> parameter <INS>or
implicit object parameter</INS> whose type is a class, a reference to
a class, an enumeration, or a reference to an enumeration.</LI>
</UL>

</BLOCKQUOTE>
<BR><BR><HR>
<A NAME="2933"></A><H4>2933.
  
Dangling references
</H4>
<B>Section: </B>7.2.2&#160; [<A href="https://wg21.link/expr.type">expr.type</A>]
 &#160;&#160;&#160;

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

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

 <B>Date: </B>2024-09-04




<P>Issue 453 clarified that there are no
empty lvalues, and undefined behavior ensues when trying to create
one.  However, the wording now does not specify the behavior of
dangling references, where the storage of the referenced object has
gone away.</P>

<P><B>Proposed resolution (approved by CWG 2024-11-08):</B></P>

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

<BLOCKQUOTE>

A pointer value P is valid in the context of an evaluation E if P
is <INS>a pointer to function or</INS> a null pointer value, or if it
is a pointer to or past the end of an object O and E happens before
the end of the duration of the region of storage for O. If a pointer
value P is used in an evaluation E and P is not valid in the context
of E, then ...

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 7.2.2 [<A href="https://wg21.link/expr.type#1">expr.type</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

If an expression initially has the type &#8220;reference to T&#8221;
(9.3.4.3 [<A href="https://wg21.link/dcl.ref">dcl.ref</A>], 9.4.4 [<A href="https://wg21.link/dcl.init.ref">dcl.init.ref</A>]), the type
is adjusted to T prior to any further analysis<INS>; the value
category of the expression is not altered</INS>.
<DEL>The expression designates</DEL>
<INS>Let <I>X</I> be</INS> the object or function denoted by the
reference<DEL>, and the expression is an lvalue or an xvalue,
depending on the expression</DEL>.  <INS>If a pointer to <I>X</I>
would be valid in the context of the evalution of the expression
(6.8.2 [<A href="https://wg21.link/basic.fundamental">basic.fundamental</A>]), the result designates <I>X</I>;
otherwise, the behavior is undefined.</INS>

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

<BR><BR><HR>
<A NAME="2936"></A><H4>2936.
  
Local classes of templated functions should be part of the current instantiation
</H4>
<B>Section: </B>13.8.3.2&#160; [<A href="https://wg21.link/temp.dep.type">temp.dep.type</A>]
 &#160;&#160;&#160;

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

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

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




<P>Consider:</P>

<PRE>
  template&lt;class T&gt;
  void f()
  {
    struct Y {
      using type = int;
    };
    Y::type y;  //<SPAN CLASS="cmnt"> error; missing typename</SPAN>
  }
</PRE>

<P>Since lookup of <TT>Y</TT> always finds the local class, regardless
of <TT>T</TT>, the requirement to apply <TT>typename</TT> is too
strict.</P>

<P><B>Proposed resolution (approved by CWG 2024-11-08):</B></P>

<P>Change in 13.8.3.2 [<A href="https://wg21.link/temp.dep.type#1">temp.dep.type</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

A name or <I>template-id</I> refers to the current instantiation if it
is

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

<LI>in the definition of a nested class of a class template, the name
of the nested class referenced as a member of the current
instantiation, <DEL>or</DEL>
</LI>

<LI>in the definition of a class template partial specialization or a
member of a class template partial specialization, the name of the
class template followed by a template argument list equivalent to that
of the partial specialization (13.7.6 [<A href="https://wg21.link/temp.spec.partial">temp.spec.partial</A>]) enclosed
in &lt;&gt; (or an equivalent template alias specialization)<DEL>.</DEL><INS>, or</INS>
</LI>

<LI class="ins">in the definition of a templated function, the name of
a local class (11.6 [<A href="https://wg21.link/class.local">class.local</A>].</LI>

</UL>
</BLOCKQUOTE>

<BR><BR><HR>
<A NAME="2937"></A><H4>2937.
  
Grammar for <I>preprocessing-file</I> has no normative effect
</H4>
<B>Section: </B>5.2&#160; [<A href="https://wg21.link/lex.phases">lex.phases</A>]
 &#160;&#160;&#160;

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

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

 <B>Date: </B>2024-09-27


<P>(From submission
<A HREF="https://github.com/cplusplus/CWG/issues/615">#615</A>.)
</P>

<P>Subclause 15.1 [<A href="https://wg21.link/cpp.pre">cpp.pre</A>] defines the grammar
production <I>preprocessing-file</I>, but nothing in the standard
specifies that a translation unit is ill-formed if it fails to match
that grammar.  Similarly, <I>translation-unit</I> has no effect.</P>

<P><B>Proposed resolution (approved by CWG 2024-11-08):</B></P>

<OL>
<LI>
<P>Change in 5.2 [<A href="https://wg21.link/lex.phases#1.4">lex.phases</A>] bullet 1.4 as follows:</P>

<BLOCKQUOTE>

<UL>
<LI>...</LI>
<LI>
<INS>The source file is analyzed as a <I>preprocessing-file</I>
(15.1 [<A href="https://wg21.link/cpp.pre">cpp.pre</A>]).</INS> Preprocessing directives are executed,
macro invocations are expanded, and _Pragma unary operator expressions
are executed. A #include preprocessing directive causes the named
header or source file to be processed from phase 1 through phase 4,
recursively. All preprocessing directives are then deleted.
</LI>
<LI>...</LI>
</UL>

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 5.2 [<A href="https://wg21.link/lex.phases#1.7">lex.phases</A>] bullet 1.7 as follows:</P>


<BLOCKQUOTE>

Whitespace characters separating tokens are no longer
significant. Each preprocessing token is converted into a token
(5.6 [<A href="https://wg21.link/lex.token">lex.token</A>]). The resulting tokens constitute a
<I>translation unit</I> and are syntactically and semantically
analyzed <INS>as a <I>translation-unit</I>
(6.6 [<A href="https://wg21.link/basic.link">basic.link</A>])</INS> and translated.

</BLOCKQUOTE>
</LI>
</OL>
<BR><BR><HR>
<A NAME="2939"></A><H4>2939.
  
Do not allow <TT>reinterpret_cast</TT> from prvalue to rvalue reference
</H4>
<B>Section: </B>7.6.1.10&#160; [<A href="https://wg21.link/expr.reinterpret.cast">expr.reinterpret.cast</A>]
 &#160;&#160;&#160;

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

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

 <B>Date: </B>2024-10-01


<P>(From submission
<A HREF="https://github.com/cplusplus/CWG/issues/617">#617</A>.)
</P>

<P>In 7.6.1.10 [<A href="https://wg21.link/expr.reinterpret.cast#11">expr.reinterpret.cast</A>] paragraph 11, there is an issue
similar to the one described in issue 2879:
The operand for a cast to reference type can be a "glvalue of type
T1", which implies that a prvalue is also acceptable, because it is
materialized per 7.2.1 [<A href="https://wg21.link/basic.lval#7">basic.lval</A>] paragraph 7.  However, no
implementation accepts
<TT>reinterpret_cast&lt;double&amp;&amp;&gt;(0)</TT>.</P>

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

<OL>
<LI>
<P>Change in 7.6.1.10 [<A href="https://wg21.link/expr.reinterpret.cast#1">expr.reinterpret.cast</A>] paragraph 1 as follows:</P>

<BLOCKQUOTE>

The result of the expression reinterpret_cast&lt;T&gt;(v) is the
result of converting the expression v to type T. If T is an lvalue
reference type or an rvalue reference to function type, the result is
an lvalue; if T is an rvalue reference to object type, the result is
an xvalue; otherwise, the result is a prvalue and the lvalue-to-rvalue
(7.3.2 [<A href="https://wg21.link/conv.lval">conv.lval</A>]), array-to-pointer
(7.3.3 [<A href="https://wg21.link/conv.array">conv.array</A>]), and function-to-pointer
(7.3.4 [<A href="https://wg21.link/conv.func">conv.func</A>]) standard conversions are performed on the
expression v. <INS>The temporary materialization conversion
(7.3.5 [<A href="https://wg21.link/conv.rval">conv.rval</A>]) is not performed on v.</INS> Conversions
that can be performed explicitly using reinterpret_cast are listed
below. No other conversion can be performed explicitly using
reinterpret_cast.

</BLOCKQUOTE>
</LI>

<LI>
<P>Remove 7.6.1.10 [<A href="https://wg21.link/expr.reinterpret.cast#3">expr.reinterpret.cast</A>] paragraph 3:</P>

<BLOCKQUOTE class="del">

[<I>Note 1:</I> The mapping performed by reinterpret_cast might, or
might not, produce a representation different from the original
value. &#8212;<I>end note</I>]

</BLOCKQUOTE>
</LI>

<LI>
<P>Remove from 7.6.1.10 [<A href="https://wg21.link/expr.reinterpret.cast#6">expr.reinterpret.cast</A>] paragraph 6 as follows:</P>

<BLOCKQUOTE>

... <DEL>[<I>Note 5:</I> See also 7.3.12 [<A href="https://wg21.link/conv.ptr">conv.ptr</A>] for more
details of pointer conversions. &#8212;<I>end note</I>]</DEL>

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 7.6.1.10 [<A href="https://wg21.link/expr.reinterpret.cast#11">expr.reinterpret.cast</A>] paragraph 11 as follows:</P>

<BLOCKQUOTE>

A glvalue of type T1, designating an object or function x, can be cast
to the type &#8220;reference to T2&#8221; if an expression of type
&#8220;pointer to T1&#8221; can be explicitly converted to the type
&#8220;pointer to T2&#8221; using a reinterpret_cast. The result is
that of *reinterpret_cast&lt;T2 *&gt;(p) where p is a pointer to x of
type &#8220;pointer to T1&#8221;. <INS>[ Note:</INS> No temporary is
created, no copy is made, and no constructors
(11.4.5 [<A href="https://wg21.link/class.ctor">class.ctor</A>]) or conversion functions
(11.4.8 [<A href="https://wg21.link/class.conv">class.conv</A>]) are called [ Footnote: ... ]. <INS>--
end note ]</INS>

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

<P><B>CWG 2024-10-11</B></P>

<P>The note in 7.6.1.10 [<A href="https://wg21.link/expr.reinterpret.cast#3">expr.reinterpret.cast</A>] paragraph 3 should be kept,
and the list of exceptions in 7.2.1 [<A href="https://wg21.link/basic.lval#7">basic.lval</A>] paragraph 7
established by issue 2879 should be amended
with a cross-reference to 7.6.1.10 [<A href="https://wg21.link/expr.reinterpret.cast">expr.reinterpret.cast</A>].</P>

<P><B>Proposed resolution (approved by CWG 2024-11-22):</B></P>

<OL>
<LI>
<P>Change in 7.2.1 [<A href="https://wg21.link/basic.lval#7">basic.lval</A>] paragraph 7 as follows:</P>

<BLOCKQUOTE>

Unless otherwise specified (<INS>7.6.1.10 [<A href="https://wg21.link/expr.reinterpret.cast">expr.reinterpret.cast</A>],</INS>
7.6.1.11 [<A href="https://wg21.link/expr.const.cast">expr.const.cast</A>]), whenever a prvalue appears as an
operand of an operator that expects a glvalue for that operand, the
temporary materialization conversion (7.3.5 [<A href="https://wg21.link/conv.rval">conv.rval</A>]) is
applied to convert the expression to an xvalue.

</BLOCKQUOTE>
</LI>

<LI>
<P>Remove from 7.6.1.10 [<A href="https://wg21.link/expr.reinterpret.cast#6">expr.reinterpret.cast</A>] paragraph 6 as follows:</P>

<BLOCKQUOTE>

... <DEL>[<I>Note 5:</I> See also 7.3.12 [<A href="https://wg21.link/conv.ptr">conv.ptr</A>] for more
details of pointer conversions. &#8212;<I>end note</I>]</DEL>

</BLOCKQUOTE>
</LI>

<LI>
<P>Change in 7.6.1.10 [<A href="https://wg21.link/expr.reinterpret.cast#11">expr.reinterpret.cast</A>] paragraph 11 as follows:</P>

<BLOCKQUOTE>

<DEL>A</DEL> <INS>If v is a</INS> glvalue of type T1, designating an
object or function x, <INS>it</INS> can be cast to the type &#8220;reference to
T2&#8221; if an expression of type &#8220;pointer to T1&#8221; can be
explicitly converted to the type &#8220;pointer to T2&#8221; using a
reinterpret_cast. The result is that of *reinterpret_cast&lt;T2
*&gt;(p) where p is a pointer to x of type &#8220;pointer to
T1&#8221;. <INS>[ Note:</INS> No temporary is <INS>materialized
(7.3.5 [<A href="https://wg21.link/conv.rval">conv.rval</A>]) or</INS> created, no copy is made, and no
constructors (11.4.5 [<A href="https://wg21.link/class.ctor">class.ctor</A>]) or conversion functions
(11.4.8 [<A href="https://wg21.link/class.conv">class.conv</A>]) are called [ Footnote: ... ]. <INS>--
end note ]</INS>

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

<BR><BR><HR>
<A NAME="2944"></A><H4>2944.
  
Unsequenced <I>throw-expression</I>s
</H4>
<B>Section: </B>7.6.18&#160; [<A href="https://wg21.link/expr.throw">expr.throw</A>]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Jan Schultke
 &#160;&#160;&#160;

 <B>Date: </B>2024-10-23


<P>(From submission
<A HREF="https://github.com/cplusplus/CWG/issues/626">#626</A>.)
</P>

<P>The semantics of unsequenced <I>throw-expression</I>s is unclear.
For example:</P>

<PRE>
  (throw /* ... */, 0) + (throw /* ... */, 0);
</PRE>

<P>This appears to cause two unsequenced transfers of control, which
makes little sense.  In contrast, a <TT>co_await</TT> expression is
indivisible (6.9.1 [<A href="https://wg21.link/intro.execution#11">intro.execution</A>] paragraph 11) per
issue 2466.</P>

<P><B>Proposed resolution (approved by CWG 2024-11-08):</B></P>

<P>Change in 6.9.1 [<A href="https://wg21.link/intro.execution#11">intro.execution</A>] paragraph 11 as follows, adding
bullets:</P>

<BLOCKQUOTE>

When invoking a function (whether or not the function is inline),
every argument expression and the postfix expression designating the
called function are sequenced before every expression or statement in
the body of the called function. For each
<UL>
<LI>function invocation<INS>,</INS>
</LI>
<LI>evaluation of an <I>await-expression</I><INS>
(7.6.2.4 [<A href="https://wg21.link/expr.await">expr.await</A>]), or</INS>
</LI>
<LI class="ins">evaluation of a <I>throw-expression</I>
(7.6.18 [<A href="https://wg21.link/expr.throw">expr.throw</A>])</LI>
</UL>
F, each evaluation that does
not occur within F but is evaluated on the same thread and as part of
the same signal handler (if any) is either sequenced before all
evaluations that occur within F or sequenced after all evaluations
that occur within F; [ Foonote: ... ] if F invokes or resumes a
coroutine (7.6.2.4 [<A href="https://wg21.link/expr.await">expr.await</A>]), only evaluations subsequent
to the previous suspension (if any) and prior to the next suspension
(if any) are considered to occur within F.

</BLOCKQUOTE>

<P><B>CWG 2024-11-08</B></P>

<P>Check with implementers (in particular MSVC) that the proposed
resolution is acceptable.</P>

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