<HTML>
<HEAD>
<META http-equiv="Content-Type" content="text/html; charset=us-ascii">
<TITLE>
    Core "ready" Issues
   </TITLE>
</HEAD>
<BODY>
<TABLE ALIGN="RIGHT" CELLSPACING="0" CELLPADDING="0">
<TR>
<TD ALIGN="RIGHT">
      Document number:
     </TD>
<TD>
       &#160;P2386R0</TD>
</TR>
<TR>
<TD ALIGN="RIGHT">
      Date:
     </TD>
<TD>
      &#160;2021-05-30</TD>
</TR>
<TR>
<TD ALIGN="RIGHT">
      Project:
     </TD>
<TD>
      &#160;Programming Language C++
     </TD>
</TR>
<TR>
<TD ALIGN="RIGHT">
      Reference:
     </TD>
<TD>
      &#160;ISO/IEC IS 14882:2020
     </TD>
</TR>
<TR>
<TD ALIGN="RIGHT">
      Reply to:
     </TD>
<TD>
      &#160;William M. Miller
     </TD>
</TR>
<TR>
<TD></TD>
<TD>
      &#160;Edison Design Group, Inc.
     </TD>
</TR>
<TR>
<TD></TD>
<TD>
      &#160;<A HREF="mailto://wmm@edg.com">wmm@edg.com</A></TD>
</TR>
</TABLE><BR CLEAR="ALL"><BR><CENTER>
<H2>
     Core Language Working Group "ready" Issues
     for the
     June, 2021 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/2020/n4878.pdf">WG21 N4878</A>.
   </P>
<HR><A NAME="2397"></A><H4>2397.
  
<TT>auto</TT> specifier for pointers and references to arrays
</H4><B>Section: </B>9.3.4.5&#160; [dcl.array]
 &#160;&#160;&#160;

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

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

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


<P>According to 9.3.4.5 [dcl.array] paragraph 1,</P>

<BLOCKQUOTE>

<P>In a declaration <TT>T D</TT> where <TT>D</TT> has the
form</P>

<UL><TT>D1 [</TT> <I>constant-expression<SUB>opt</SUB></I> <TT>]</TT> <I>attribute-specifier-seq<SUB>opt</SUB></I></UL>

<P>and the type of the identifier in the declaration <TT>T
D1</TT> is
&#8220;<I>derived-declarator-type-list</I> <TT>T</TT>&#8221;,
then the type of the identifier of <TT>D</TT> is an array
type; if the type of the identifier of <TT>D</TT> contains
the <TT>auto</TT> <I>type-specifier</I>, the program is
ill-formed.</P>

</BLOCKQUOTE>

<P>This formulation forbids useful constructs like</P>

<PRE>
  int a[3];
  auto (*p)[3] = &amp;a;
</PRE>

<P>(accepted by current implementations) and should be
relaxed to accommodate such cases.</P>

<P><B>Notes from the February, 2019 meeting:</B></P>

<P>CWG agreed that the example should be accepted.</P>

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

<P>It was observed that CWG rejected the same example as
being "not a defect" in considering issue 1222. However, the use of <TT>auto</TT> has
significantly expanded since that time and the prohibition
of such declarations now seems inconsistent.</P>

<P><B>Proposed resolution, May, 2021:</B></P>

<OL><LI><P>Change 9.3.4.5 [dcl.array] paragraph 4 as
follows:</P></LI>

<BLOCKQUOTE>

<TT>U</TT> is called the array element type; this type shall
not be <SPAN style="text-decoration:line-through;background-color:#FFA0A0">a placeholder type
(9.2.9.6 [dcl.spec.auto]),</SPAN> a reference type, a
function type, an array of unknown bound,
or <I>cv</I> <TT>void</TT>.

</BLOCKQUOTE>

<LI><P>Change 9.3.4.6 [dcl.fct] paragraph 11 as follows:</P></LI>

<BLOCKQUOTE>

The return type shall be a non-array object type, a
reference type, or <I>cv</I> <TT>void</TT>. <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I>
An array of placeholder type is considered an array type.
&#8212;<I>end note</I>]</SPAN>

</BLOCKQUOTE>

<LI><P>Change 9.2.9.6.2 [dcl.type.auto.deduct] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

<P>A type <TT>T</TT>
containing a placeholder type, and a corresponding
initializer <I>E</I>, are determined as follows:</P>

<UL><LI><P>for a non-discarded <TT>return</TT> statement
that occurs in a function declared with a return type that
contains a placeholder type, <TT>T</TT> is the declared
return type and <I>E</I> is the operand of
the <TT>return</TT> statement. If the <TT>return</TT>
statement has no operand, then <I>E</I>
is <TT>void()</TT>;</P></LI>

<LI><P>for a variable declared with a type that contains a
placeholder type, <TT>T</TT> is the declared type of the
variable and <I>E</I> is the initializer. If the
initialization is direct-list-initialization, the
initializer shall be a <I>braced-init-list</I> containing
only a single <I>assignment-expression</I> and <I>E</I> is
the <I>assignment-expression</I>;</P></LI>

<LI><P>for a non-type template parameter declared with a
type that contains a placeholder type, <TT>T</TT> is the
declared type of the non-type template parameter
and <I>E</I> is the corresponding template
argument.</P></LI>

</UL>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>T</TT> shall not be an array type.</SPAN> In the
case of a <TT>return</TT> statement with no operand...</P>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="2448"></A><H4>2448.
  
Cv-qualification of arithmetic types and deprecation of volatile
</H4><B>Section: </B>6.8.2&#160; [basic.fundamental]
 &#160;&#160;&#160;

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

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

 <B>Date: </B>2020-03-23


<P>According to the definitions in 6.8.2 [basic.fundamental],
the arithmetic types include only the non-cv-qualified versions.
In the taxonomy of fundamental types, the first mention of
&#8220;cv-qualified versions of these types&#8221; is for
scalar types (6.8 [basic.types] paragraph 9). However,
7.6.1.6 [expr.post.incr] paragraph 1 and
7.6.2.3 [expr.pre.incr] paragraph 1 both say:</P>

<BLOCKQUOTE>

The type of the operand shall be an arithmetic type other
than <I>cv</I> <TT>bool</TT>, or...

</BLOCKQUOTE>

<P>which is a contradiction, since cv-qualified <TT>bool</TT>
is not an arithmetic type. Similarly, 7.6.19 [expr.ass]
paragraph 6 requires an arithmetic type for <TT>+=</TT>
and <TT>-=</TT>. D.6 [depr.volatile.type] deprecates
the increment and decrement operators when applied to
volatile-qualified arithmetic types, but the wording already
made those ill-formed (since the normative wording requires
an arithmetic type and not a possibly cv-qualified version
thereof).</P>

<P>A related question is whether 12.5 [over.built],
which explicitly allows for cv-qualified arithmetic types,
should also note the deprecation.</P>

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

<P><B>Notes from the July, 2020 teleconference:</B></P>

<P>CWG felt that no changes should be made to
12.5 [over.built].</P>

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

<OL><LI><P>Change 6.8.2 [basic.fundamental] paragraphs 11 and 12 as follows,
splitting paragraph 12 as indicated:</P></LI>

<BLOCKQUOTE>

<P>Types <TT>bool</TT>, <TT>char</TT>, <TT>wchar_t</TT>,
<TT>char8_t</TT>, <TT>char16_t</TT>, <TT>char32_t</TT>, and
the signed and unsigned integer types<SPAN style="font-weight:bold;background-color:#A0FFA0">, and cv-qualified
versions (6.8.4 [basic.type.qualifier]) thereof,</SPAN> are
collectively <SPAN style="text-decoration:line-through;background-color:#FFA0A0">called</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">termed</SPAN>
<I>integral types</I>. A synonym for integral type
is <I>integer type</I>.  [<I>Note 8:</I> Enumerations
(9.7.1 [dcl.enum]) are not integral; however,
unscoped enumerations can be promoted to integral types as
specified in 7.3.7 [conv.prom]. &#8212;<I>end
note</I>]</P>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">There are <I>three floating-point types</I>:</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">The three distinct types</SPAN> <TT>float</TT>,
<TT>double</TT>, and <TT>long double</TT> <SPAN style="font-weight:bold;background-color:#A0FFA0">can represent
floating-point numbers</SPAN>. The type <TT>double</TT>
provides at least as much precision as <TT>float</TT>, and the type
<TT>long double</TT> provides at least as much precision as
<TT>double</TT>. The set of values of the
type <TT>float</TT> is a subset of the set of values of the
type <TT>double</TT>; the set of values of the
type <TT>double</TT> is a subset of the set of values of the
type <TT>long double</TT>. <SPAN style="font-weight:bold;background-color:#A0FFA0">The types <TT>float</TT>,
<TT>double</TT>, and <TT>long double</TT>, and cv-qualified
versions (6.8.4 [basic.type.qualifier]) thereof, are
collectively termed <I>floating-point types</I>.</SPAN> The
value representation of floating-point types is
implementation-defined.  <I>[Note 9:</I> This document
imposes no requirements on the accuracy of floating-point
operations; see also
17.3 [support.limits]. &#8212;<I>end note</I>]</P>

<P>Integral and floating-point types are
collectively <SPAN style="text-decoration:line-through;background-color:#FFA0A0">called</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">termed</SPAN>
<I>arithmetic types</I>. Specializations of the standard
library template <TT>std::numeric_limits</TT>
(17.3 [support.limits]) shall specify the maximum and
minimum values of each arithmetic type for an
implementation.</P>

</BLOCKQUOTE>

<LI><P>Change 6.8.4 [basic.type.qualifier] paragraph 1 as follows,
splitting the paragraph as indicated:</P></LI>

<BLOCKQUOTE>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">A type mentioned in 6.8.2 [basic.fundamental] and
6.8.3 [basic.compound] is a <I>cv-unqualified</I>
type.</SPAN> Each type <SPAN style="text-decoration:line-through;background-color:#FFA0A0">which is a cv-unqualified object type
or is <TT>void</TT> (6.8 [basic.types]) has three
corresponding cv-qualified versions of its type</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">other than a function or reference type is part of a
group of four distinct, but related,
types</SPAN>: <SPAN style="font-weight:bold;background-color:#A0FFA0">a <I>cv-unqualified</I> version,</SPAN>
a <I>const-qualified</I> version,
a <I>volatile-qualified</I> version, and
a <I>const-volatile-qualified</I> version. 
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">The type of an object (6.7.2 [intro.object])
includes the <I>cv-qualifier</I>s specified in
the <I>decl-specifier-seq</I> (9.2 [dcl.spec]),
<I>declarator</I> (9.3 [dcl.decl]), <I>type-id</I>
(9.3.2 [dcl.name]), or <I>new-type-id</I>
(7.6.2.8 [expr.new]) when the object is
created.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">The types in each such group shall have
the same representation and alignment requirements
(6.7.6 [basic.align]).  [<I>Footnote:</I> The same
representation and alignment requirements are meant to imply
interchangeability as arguments to functions, return values
from functions, and non-static data members of
unions. &#8212;<I>end footnote</I>] A function or reference
type is always cv-unqualified.</SPAN></P>

<UL><LI><P>A <I>const object</I> is an object of
type <TT>const T</TT> or a non-mutable subobject of a const
object.</P></LI>

<LI><P>A <I>volatile object</I> is an object of
type <TT>volatile T</TT> or a subobject of a volatile
object.</P></LI>

<LI><P>A <I>const volatile object</I> is an object of
type <TT>const volatile T</TT>, a non-mutable subobject of a
const volatile object, a const subobject of a volatile
object, or a non-mutable volatile subobject of a const
object.</P></LI>

</UL>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">The cv-qualified or cv-unqualified versions of a
type are distinct types; however, they shall have the same
representation and alignment requirements
(6.7.6 [basic.align]).<SUP>40</SUP></SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">[<I>Note:</I>
The type of an object (6.7.2 [intro.object]) includes
the <I>cv-qualifier</I>s specified in the
<I>decl-specifier-seq</I> (9.2 [dcl.spec]),
<I>declarator</I> (9.3 [dcl.decl]), <I>type-id</I>
(9.3.2 [dcl.name]), or <I>new-type-id</I>
(7.6.2.8 [expr.new]) when the object is created.
&#8212;<I>end note</I>]</SPAN></P>

</BLOCKQUOTE>

<LI><P>Change 12.5 [over.built] paragraphs 2-10 as follows:</P></LI>

<BLOCKQUOTE>

<P>In this subclause, the term <I>promoted integral type</I>
is used to refer to those <SPAN style="font-weight:bold;background-color:#A0FFA0">cv-unqualified</SPAN> integral
types which are preserved by integral promotion
(7.3.7 [conv.prom]) (including e.g. <TT>int</TT>
and <TT>long</TT> but excluding e.g. <TT>char</TT>
). [<I>Note 2:</I> In all cases where a promoted integral
type is required, an operand of unscoped enumeration type
will be acceptable by way of the integral
promotions. &#8212;<I>end note</I>]</P>

<P>In the remainder of this subclause, <I>vq</I>
represents either <TT>volatile</TT> or no cv-qualifier.</P>

<P>For every pair (<I>T, vq</I>), where <I>T</I> is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">an</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">a cv-unqualified</SPAN> arithmetic type other
than <TT>bool</TT> <SPAN style="font-weight:bold;background-color:#A0FFA0">or a cv-unqualified pointer to
(possibly cv-qualified) object type</SPAN>, there exist
candidate operator functions of the form</P>

<UL><I>vq T</I><TT>&amp; operator++(</TT><I>vq T</I><TT>&amp;);</TT><BR>
<I>T</I> <TT>operator++(</TT><I>vq T</I><TT>&amp;, int);</TT>
</UL>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">For every pair (<I>T, vq</I>), where <I>T</I> is an
arithmetic type other than <TT>bool</TT>, there exist
candidate operator functions of the form</SPAN></P>

<UL><I>vq T</I><TT>&amp; operator--(</TT><I>vq T</I><TT>&amp;);</TT><BR>
<I>T</I> <TT>operator--(</TT><I>vq T</I><TT>&amp;, int);</TT>
</UL>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">For every pair (<I>T, vq</I>), where <I>T</I> is a
cv-qualified or cv-unqualified object type, there exist
candidate operator functions of the form</SPAN></P>

<UL><SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>T*vq</I><TT>&amp; operator++(</TT><I>T*vq</I><TT>&amp;);</TT><BR>
<I>T*vq</I><TT>&amp; operator--(</TT><I>T*vq</I><TT>&amp;);</TT><BR>
<I>T*</I><TT>&#160;&#160;&#160;&#160;operator++(</TT><I>T*vq</I><TT>&amp;, int);</TT><BR>
<I>T*</I><TT>&#160;&#160;&#160;&#160;operator--(</TT><I>T*vq</I><TT>&amp;, int);</TT></SPAN>
</UL>

<P>For every <SPAN style="text-decoration:line-through;background-color:#FFA0A0">cv-qualified or cv-unqualified</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">(possibly cv-qualified)</SPAN> object type <I>T</I>
<SPAN style="font-weight:bold;background-color:#A0FFA0">and for every function type <I>T</I> that has neither
cv-qualifiers nor a <I>ref-qualifier</I></SPAN>,
there exist candidate operator functions of the form</P>

<UL><I>T</I><TT>&amp; operator*(</TT><I>T</I><TT>*);</TT>
</UL>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">For every function type <I>T</I> that does not have
cv-qualifiers or a ref-qualifier, there exist candidate
operator functions of the form</SPAN></P>

<UL><SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>T</I><TT>&amp; operator*(</TT><I>T</I><TT>*);</TT></SPAN>
</UL>

<P>For every type <I>T</I> there exist candidate operator
functions of the form</P>

<UL><I>T</I><TT>* operator+(</TT><I>T</I><TT>*);</TT>
</UL>

<P>For every <SPAN style="font-weight:bold;background-color:#A0FFA0">cv-unqualified</SPAN> floating-point or
promoted integral type <I>T</I>, there exist candidate
operator functions of the form</P>

<UL><I>T</I><TT> operator+(</TT><I>T</I><TT>);</TT><BR>
<I>T</I><TT>l operator-(</TT><I>T</I><TT>);</TT>
</UL>

</BLOCKQUOTE>

</OL>

<P><I>[Drafting note: 20.15 [meta] regarding
type traits appropriately handles cv-qualified and
cv-unqualified types and does not require revision.]</I></P>

<BR><BR><HR><A NAME="2458"></A><H4>2458.
  
Value category of expressions denoting non-static member functions
</H4><B>Section: </B>7.6.1.5&#160; [expr.ref]
 &#160;&#160;&#160;

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

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

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




<P>Expressions denoting non-static member functions are currently
classified as prvalues (7.5.4.3 [expr.prim.id.qual] paragraph 2;
7.6.1.5 [expr.ref] bullet 6.3.2; and
7.6.4 [expr.mptr.oper] paragraph 6). It would simplify the
specification if such expressions were categorized as lvalues.
(See also <A HREF="https://github.com/cplusplus/draft/pull/3262">
this pull request</A>.)</P>

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

<P>CWG preferred that the unbound case (i.e., <TT>&amp;X::f</TT>)
should be an lvalue, while the bound case should be a prvalue.</P>

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

<OL><LI><P>Change 7.5.4.3 [expr.prim.id.qual] paragraph 5, converting
the running text into a bulleted list, as follows:</P></LI>

<BLOCKQUOTE>

<P>The result of a <I>qualified-id</I> <SPAN style="font-weight:bold;background-color:#A0FFA0"><I>Q</I></SPAN>
is the entity it denotes (6.5.5 [basic.lookup.qual]). The
type of the expression is the type of the result.  The
result is an lvalue if the member is</P>

<UL><LI><P>a function <SPAN style="font-weight:bold;background-color:#A0FFA0">other than a non-static member
function</SPAN>,</P></LI>

<LI><P><SPAN style="font-weight:bold;background-color:#A0FFA0">a non-static member function if <I>Q</I> is the operand
of a unary <TT>&amp;</TT> operator,</SPAN></P></LI>

<LI><P>a variable,</P></LI>

<LI><P>a structured binding
(9.6 [dcl.struct.bind]), <SPAN style="font-weight:bold;background-color:#A0FFA0">or</SPAN></P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">a static member function, or</SPAN></P></LI>

<LI><P>a data member,</P></LI>

</UL>

<P>and a prvalue otherwise.</P>

</BLOCKQUOTE>

<LI><P>Change 7.6.2.2 [expr.unary.op] paragraph 3 as follows:</P></LI>

<BLOCKQUOTE>

<P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">The result of the</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">The operand of
the</SPAN> unary<TT> &amp;</TT> operator <SPAN style="font-weight:bold;background-color:#A0FFA0">shall be an
lvalue of some type <TT>T</TT>. The result</SPAN> is a
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">pointer to its operand</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">prvalue</SPAN>.</P>

<UL><LI><P>If the operand is a <I>qualified-id</I> naming a
non-static or variant member <TT>m</TT> of some
class <TT>C</TT> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">with type <TT>T</TT></SPAN>, the result
has type &#8220;pointer to member of class <TT>C</TT> of
type <TT>T</TT>&#8221; and <SPAN style="text-decoration:line-through;background-color:#FFA0A0">is a prvalue
designating</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">designates</SPAN>
<TT>C::m</TT>.</P></LI>

<LI><P>Otherwise, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">if the operand is an lvalue of
type <TT>T</TT>,</SPAN> the <SPAN style="text-decoration:line-through;background-color:#FFA0A0">resulting expression is a
prvalue of</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">result has</SPAN> type &#8220;pointer
to <TT>T</TT>&#8221; <SPAN style="text-decoration:line-through;background-color:#FFA0A0">whose result is a pointer</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">and points</SPAN> to the designated object
(6.7.1 [intro.memory]) or
function <SPAN style="font-weight:bold;background-color:#A0FFA0">(6.8.3 [basic.compound])</SPAN>. [<I>Note
2:</I> In particular, taking the address of a variable of
type &#8220;<I>cv</I> <TT>T</TT>&#8221; yields a pointer of
type &#8220;pointer to <I>cv</I> <TT>T</TT>&#8221;.
&#8212;<I>end note</I>]</P></LI>

<LI><P><SPAN style="text-decoration:line-through;background-color:#FFA0A0">Otherwise, the program is ill-formed.</SPAN></P></LI>

</UL>

</BLOCKQUOTE>

</OL>

<P><I>[Drafting note: neither 7.6.1.5 [expr.ref]
bullet 6.3.2,</I></P>

<BLOCKQUOTE>

<UL><LI><P>Otherwise (when <TT>E2</TT> refers to a
non-static member function), <TT>E1.E2</TT> is a
prvalue. The expression can be used only as the left-hand
operand of a member function call
(11.4.2 [class.mfct]).  [<I>Note 5:</I> Any
redundant set of parentheses surrounding the expression is
ignored (7.5.3 [expr.prim.paren]). &#8212;<I>end
note</I>]</P></LI></UL>

</BLOCKQUOTE>

<P><I>nor 7.6.4 [expr.mptr.oper] paragraph 6,</I></P>

<BLOCKQUOTE>

...The result of a <TT>.*</TT> expression whose second operand
is a pointer to a member function is a prvalue...

</BLOCKQUOTE>

<P><I>requires any change.]</I></P>

<BR><BR><HR><A NAME="2465"></A><H4>2465.
  
Coroutine parameters passed to a promise constructor
</H4><B>Section: </B>9.5.4&#160; [dcl.fct.def.coroutine]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Gor Nishanov
 &#160;&#160;&#160;

 <B>Date: </B>2020-10-19


<P>The resolution of issue 2436
(in <A HREF="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2107r0.html">P2107R0</A>)
deleted the sentence</P>

<BLOCKQUOTE>

A reference to a parameter in the <I>function-body</I> of
the coroutine and in the call to the coroutine promise
constructor is replaced by a reference to its copy.

</BLOCKQUOTE>

<P>replacing it with new wording in 7.5.4.2 [expr.prim.id.unqual]
paragraph 1:</P>

<BLOCKQUOTE>

An <I>identifier</I> that names a coroutine parameter refers
to the copy of the parameter (9.5.4 [dcl.fct.def.coroutine]).

</BLOCKQUOTE>

<P>This new approach no longer covers coroutine parameters
passed to a promise constructor, since the constructor call
is implicit, as described in 7.5.4.2 [expr.prim.id.unqual]
paragraph 5.</P>

<P><U>Suggested resolution:</U></P>

<OL><LI><P>Change 7.5.4.2 [expr.prim.id.unqual] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

In the following, <TT>p</TT><SUB><I>i</I></SUB> is an lvalue
of type <TT>P</TT><SUB><I>i</I></SUB>,
where <TT>p</TT><SUB>1</SUB> denotes <TT>*this</TT>
and <TT>p</TT><SUB><I>i</I>+1</SUB> denotes
the <I>i</I><SUP>th</SUP> function parameter for a
non-static member function,
and <TT>p</TT><SUB><I>i</I></SUB> denotes
the <I>i</I><SUP>th</SUP> function parameter otherwise.
<SPAN style="font-weight:bold;background-color:#A0FFA0">Let <TT>q</TT><SUB><I>i</I></SUB> be the corresponding
parameter copy, as described below.</SPAN>

</BLOCKQUOTE>

<LI><P>Change 7.5.4.2 [expr.prim.id.unqual] bullet 5.7 as follows:</P></LI>

<BLOCKQUOTE>

<P>A coroutine behaves as if its <I>function-body</I> were
replaced by...</P>

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

<LI><P><I>promise-constructor-arguments</I> is determined as
follows: overload resolution is performed on a promise
constructor call created by assembling an argument list with
lvalues <TT><SPAN style="text-decoration:line-through;background-color:#FFA0A0">p</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">q</SPAN></TT><SUB>1</SUB>
... <TT><SPAN style="text-decoration:line-through;background-color:#FFA0A0">p</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">q</SPAN></TT><SUB><I>n</I></SUB>.
If a viable constructor is found
(12.2.3 [over.match.viable]),
then <I>promise-constructor-arguments</I>
is <TT>(<SPAN style="text-decoration:line-through;background-color:#FFA0A0">p</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">q</SPAN></TT><SUB>1</SUB><TT>, ... ,
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">p</SPAN><SPAN style="font-weight:bold;background-color:#A0FFA0">q</SPAN></TT><SUB><I>n</I></SUB><TT>)</TT>,
otherwise <I>promise-constructor-arguments</I> is
empty.</P></LI>

</UL>

</BLOCKQUOTE>

</OL>

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

<OL><LI><P>Change 9.5.4 [dcl.fct.def.coroutine] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

In the following, <TT>p</TT><SUB><I>i</I></SUB> is an lvalue
of type <TT>P</TT><SUB><I>i</I></SUB>,
where <TT>p</TT><SUB>1</SUB> denotes <TT>*this</TT>
and <TT>p</TT><SUB><I>i</I>+1</SUB> denotes
the <I>i</I><SUP>th</SUP> function parameter for a
non-static member function,
and <TT>p</TT><SUB><I>i</I></SUB> denotes
the <I>i</I><SUP>th</SUP> function parameter otherwise.
<SPAN style="font-weight:bold;background-color:#A0FFA0">For a non-static member function,
<TT>q</TT><SUB>1</SUB> is an lvalue that denotes
<TT>*this</TT>; any other <TT>q</TT><SUB><I>i</I></SUB>
is an lvalue that denotes the parameter copy corresponding
to <TT>p</TT><SUB><I>i</I></SUB>, as described below.</SPAN>

</BLOCKQUOTE>

<LI><P>Change 9.5.4 [dcl.fct.def.coroutine] bullet 5.7 as follows:</P></LI>

<BLOCKQUOTE>

<P>A coroutine behaves as if its <I>function-body</I> were
replaced by: ... where</P>

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

<LI><P><I>promise-constructor-arguments</I> is determined as
follows: overload resolution is performed on a promise
constructor call created by assembling an argument list <SPAN style="text-decoration:line-through;background-color:#FFA0A0">with
lvalues <TT>p</TT><SUB>1</SUB>&#160;...&#160;<TT>p</TT><SUB><I>n</I></SUB></SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>q</TT><SUB>1</SUB>&#160;...&#160;<TT>q</TT><SUB><I>n</I></SUB></SPAN>.
If a viable constructor is found
(12.2.3 [over.match.viable]),
then <I>promise-constructor-arguments</I> is <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><TT>(p1, ... ,
p</TT><SUB><I>n</I></SUB><TT>)</TT></SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>(q</TT><SUB>1</SUB><TT>, ... ,
q</TT><SUB><I>n</I></SUB><TT>)</TT></SPAN>,
otherwise <I>promise-constructor-arguments</I> is
empty.</P></LI>

</UL>

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="2466"></A><H4>2466.
  
<TT>co_await</TT> should be a single evaluation
</H4><B>Section: </B>7.6.2.4&#160; [expr.await]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Gor Nishanov
 &#160;&#160;&#160;

 <B>Date: </B>2020-10-19


<P>The description of <TT>co_await</TT> should not permit
reordering the subexpressions constituting the evaluation of
a <TT>co_await</TT> expression.  For example, given </P>

<PRE>
  auto z = co_await coro + co_await coro;
</PRE>

<P>the result may be different from the expected</P>

<PRE>
  auto x = co_await coro;
  auto y = co_await coro;
  auto z = x + y;
</PRE>

<P><U>Suggested resolution:</U></P>

<P>Add the following as a new paragraph following
7.6.2.4 [expr.await] paragraph 5:</P>

<BLOCKQUOTE>

<P><SPAN style="font-weight:bold;background-color:#A0FFA0">With respect to an indeterminately-sequenced function
call, the operation of <TT>co_await</TT> is a single evaluation.
[<I>Note:</I> Therefore a function call cannot intervene between
the subexpressions constituting evaluation of a <TT>co_await</TT>
expression. &#8212;<I>end note</I>]</SPAN></P>

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

</BLOCKQUOTE>

<P><B>Proposed resolution, May, 2021:</B></P>

<OL><LI><P>Change 6.9.1 [intro.execution] paragraph 11 as
follows:</P></LI>

<BLOCKQUOTE>

When <SPAN style="text-decoration:line-through;background-color:#FFA0A0">calling</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">invoking</SPAN> a function
(whether or not the function is inline), every <SPAN style="text-decoration:line-through;background-color:#FFA0A0">value
computation and side effect associated with any</SPAN>
argument expression<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, or with</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">and</SPAN> the
postfix expression designating the called function<SPAN style="text-decoration:line-through;background-color:#FFA0A0">, is</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">are</SPAN> sequenced before <SPAN style="text-decoration:line-through;background-color:#FFA0A0">execution of</SPAN>
every expression or statement in the body of the called
function. For each function invocation <SPAN style="font-weight:bold;background-color:#A0FFA0">or evaluation of an
<I>await-expression</I></SPAN> <I>F</I>, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">for every</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">each</SPAN> evaluation <SPAN style="text-decoration:line-through;background-color:#FFA0A0"><I>A</I></SPAN>
that <SPAN style="text-decoration:line-through;background-color:#FFA0A0">occurs</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">does not occur</SPAN>
within <I>F</I> <SPAN style="text-decoration:line-through;background-color:#FFA0A0">and every evaluation <I>B</I> that does
not occur within <I>F</I></SPAN> but is evaluated on the same
thread and as part of the same signal handler (if any)<SPAN style="text-decoration:line-through;background-color:#FFA0A0">,
either <I>A</I> is sequenced before <I>B</I> or <I>B</I> is
sequenced before <I>A</I>.</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">is either sequenced
before all evaluations that occur within <I>F</I> or
sequenced after all evaluations that occur
within <I>F</I>;</SPAN> [<I>Footnote:</I> In other words,
function executions do not interleave with each
other. &#8212;<I>end footnote</I>] <SPAN style="font-weight:bold;background-color:#A0FFA0">if <I>F</I> invokes
or resumes a coroutine (7.6.2.4 [expr.await]), only
evaluations subsequent to the previous suspension (if any)
and prior to the next suspension (if any) are considered to
occur within <I>F</I>.</SPAN> [<I>Note 7:</I> If <I>A</I>
and <I>B</I> would not otherwise be sequenced then they are
indeterminately sequenced. &#8212;<I>end note</I>]

</BLOCKQUOTE>

<LI><P>Add the following note at the end of 7.6.2.4 [expr.await]
paragraph 5:</P></LI>

<BLOCKQUOTE>

<P>The <I>await-expression</I> evaluates the
(possibly-converted) <I>o</I> expression and
the <I>await-ready</I> expression, then:</P>

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

<P>[<I>Note:</I> With respect to sequencing, an
<I>await-expression</I> is indivisible
(6.9.1 [intro.execution]). &#8212;<I>end note</I>]</P>

</BLOCKQUOTE>

</OL>

<P>Drafting note: No change is needed in 6.9.1 [intro.execution]
paragraph 8:</P>

<BLOCKQUOTE>

...An expression <I>X</I> is said to be sequenced before an
expression <I>Y</I> if every value computation and every
side effect associated with the expression <I>X</I> is
sequenced before every value computation and every side
effect associated with the expression <I>Y</I>.

</BLOCKQUOTE>

<P><B>Additional note, May, 2021:</B></P>

<P>Note 7 in 6.9.1 [intro.execution] paragraph 11 refers
to evaluations <I>A</I> and <I>B</I>, even though the edit
to that paragraph above removes those names. This
discrepancy was noticed only after CWG approved the change
to the normative wording. Since it involves only the wording
of a non-normative note, the problem will be addressed
editorially. See <A HREF="https://github.com/cplusplus/draft/issues/4612">
editorial issue 4612</A>.</P>

<BR><BR><HR><A NAME="2474"></A><H4>2474.
  
Cv-qualification and deletion
</H4><B>Section: </B>7.6.2.9&#160; [expr.delete]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Unknown
 &#160;&#160;&#160;

 <B>Date: </B>2020-10-29


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

<P>According to 7.6.2.9 [expr.delete] paragraph 3,</P>

<BLOCKQUOTE>

In a single-object delete expression, if the static type of
the object to be deleted is different from its dynamic type
and the selected deallocation function (see below) is not a
destroying operator delete, the static type shall be a base
class of the dynamic type of the object to be deleted and
the static type shall have a virtual destructor or the
behavior is undefined. In an array delete expression, if the
dynamic type of the object to be deleted differs from its
static type, the behavior is undefined.

</BLOCKQUOTE>

<P>Both the static type and the dynamic type include
cv-qualification, and requiring agreement in qualification between
the two for deletion is not intended. Perhaps the restriction
should be to similar types instead of identical types?</P>

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

<P>&#8220;Similar types&#8221; raises issues with arrays of
unknown bounds, but a change to allow for differences in
cv-qualification is needed.</P>

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

<P>It was observed that current implementations store
the total number of class objects in a multi-dimensional
array in a &#8220;cookie&#8221; in the array allocation
overhead, rather than the number of top-level array
elements, and thus are able to invoke the destructors
correctly even if the type being deleted is an array of
unknown bound. Consequently, it was decided that use of
the &#8220;similar&#8221; criterion was appropriate.</P>

<P><B>Proposed resolution, May, 2021:</B></P>

<P>Change 7.6.2.9 [expr.delete] paragraph 3 as follows:</P>

<BLOCKQUOTE>

In a single-object delete expression, if the static type of
the object to be deleted is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">different from</SPAN>
<SPAN style="font-weight:bold;background-color:#A0FFA0">not similar (7.3.6 [conv.qual]) to</SPAN> its
dynamic type and the selected deallocation function (see
below) is not a destroying operator delete, the static type
shall be a base class of the dynamic type of the object to
be deleted and the static type shall have a virtual
destructor or the behavior is undefined. In an array delete
expression, if the dynamic type of the object to be deleted
<SPAN style="text-decoration:line-through;background-color:#FFA0A0">differs from</SPAN> <SPAN style="font-weight:bold;background-color:#A0FFA0">is not similar to</SPAN> its
static type, the behavior is undefined.

</BLOCKQUOTE>

<BR><BR><HR><A NAME="2477"></A><H4>2477.
  
Defaulted vs deleted copy constructors/assignment operators
</H4><B>Section: </B>11.4.5.3&#160; [class.copy.ctor]
 &#160;&#160;&#160;

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

 <B>Submitter: </B>Andrew Rogers
 &#160;&#160;&#160;

 <B>Date: </B>2021-02-04


<P>According to 11.4.5.3 [class.copy.ctor] paragraph 6,</P>

<BLOCKQUOTE>

If the class definition does not explicitly declare a copy
constructor, a non-explicit one is
declared <I>implicitly</I>.  If the class definition
declares a move constructor or move assignment operator, the
implicitly declared copy constructor is defined as deleted;
otherwise, it is defined as defaulted
(9.5 [dcl.fct.def]).

</BLOCKQUOTE>

<P>However, this rule is contradicted by paragraph 10, which
lists a number of other reasons why a defaulted copy
constructor will be defined as deleted, rather than being
&#8220;defined as defaulted,&#8221; as required by paragraph
6:</P>

<BLOCKQUOTE>

<P>A defaulted copy/move constructor for a class <TT>X</TT>
is defined as deleted (9.5.3 [dcl.fct.def.delete])
if <TT>X</TT> has:</P>

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

<P>A similar contradiction exists for copy assignment
operators in 11.4.6 [class.copy.assign] paragraphs 2
and 7.</P>

</BLOCKQUOTE>

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

<OL><LI><P>Change 11.4.5.3 [class.copy.ctor] paragraph 6 as
follows:</P></LI>

<BLOCKQUOTE>

If the class definition does not explicitly declare a copy
constructor, a non-explicit one is
declared <I>implicitly</I>.  If the class definition
declares a move constructor or move assignment operator, the
implicitly declared copy constructor is defined as deleted;
otherwise, it is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">defined as</SPAN> defaulted
(9.5 [dcl.fct.def]). The latter case is deprecated if
the class has a user-declared copy assignment operator or a
user-declared destructor (D.9 [depr.impldec]).

</BLOCKQUOTE>

<LI><P>Change 11.4.6 [class.copy.assign] paragraph 2 as follows:</P></LI>

<BLOCKQUOTE>

If the class definition does not explicitly declare a copy
assignment operator, one is declared <I>implicitly</I>.  If
the class definition declares a move constructor or move
assignment operator, the implicitly declared copy assignment
operator is defined as deleted; otherwise, it
is <SPAN style="text-decoration:line-through;background-color:#FFA0A0">defined as</SPAN> defaulted
(9.5 [dcl.fct.def]). The latter case is deprecated if
the class has a user-declared copy constructor or a
user-declared destructor (D.9). The implicitly-declared...

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="2479"></A><H4>2479.
  
Missing specifications for <TT>consteval</TT> and <TT>constinit</TT>
</H4><B>Section: </B>6.9.3.1&#160; [basic.start.main]
 &#160;&#160;&#160;

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

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

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


<P>There are several places where the <TT>consteval</TT>
and/or <TT>constinit</TT> keywords should be mentioned but
are not:</P>

<P>6.9.3.1 [basic.start.main] paragraph 3:</P>

<BLOCKQUOTE>

A program that defines <TT>main</TT>
as deleted or that declares <TT>main</TT>
to be <TT>inline</TT>, <TT>static</TT>, or <TT>constexpr</TT>
is ill-formed.

</BLOCKQUOTE>

<P>9.3.4.1 [dcl.meaning.general] paragraph 2:</P>

<BLOCKQUOTE>

A <TT>static</TT>, <TT>thread_local</TT>,
<TT>extern</TT>, <TT>mutable</TT>, <TT>friend</TT>,
<TT>inline</TT>, <TT>virtual</TT>, <TT>constexpr</TT>,
or <TT>typedef</TT> specifier or
an <I>explicit-specifier</I> applies directly to
each <I>declarator-id</I> in an <I>init-declarator-list</I>
or <I>member-declarator-list</I>...

</BLOCKQUOTE>

<P>11.4.5.1 [class.ctor.general] paragraph 1:</P>

<BLOCKQUOTE>

...In a constructor declaration, each <I>decl-specifier</I> in
the optional <I>decl-specifier-seq</I> shall be <TT>friend</TT>,
<TT>inline</TT>, <TT>constexpr</TT>, or an <I>explicit-specifier</I>.

</BLOCKQUOTE>

<P><B>Proposed resolution, May, 2021:</B></P>

<OL><LI><P>Change 6.9.3.1 [basic.start.main] paragraph 3
as follows:</P></LI>

<BLOCKQUOTE>

...A program that defines <TT>main</TT> as deleted or that
declares <TT>main</TT> to
be <TT>inline</TT>, <TT>static</TT>, <SPAN style="text-decoration:line-through;background-color:#FFA0A0">or</SPAN>
<TT>constexpr</TT><SPAN style="font-weight:bold;background-color:#A0FFA0">, or <TT>consteval</TT></SPAN>
is ill-formed...

</BLOCKQUOTE>

<LI><P>Change 9.3.4.1 [dcl.meaning.general] paragraph 4 as follows:</P></LI>

<BLOCKQUOTE>

A <TT>static</TT>, <TT>thread_local</TT>, <TT>extern</TT>,
<TT>mutable</TT>, <TT>friend</TT>, <TT>inline</TT>,
<TT>virtual</TT>, <TT>constexpr</TT>, <SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>consteval</TT>,
<TT>constinit</TT>,</SPAN> or <TT>typedef</TT> specifier or
an <I>explicit-specifier</I> applies directly to
each <I>declarator-id</I> in a declaration; the type
specified for each <I>declarator-id</I> depends on both
the <I>decl-specifier-seq</I> and its <I>declarator</I>.

</BLOCKQUOTE>

<LI><P>Change 11.4.5.1 [class.ctor.general] paragraph 5 as follows:</P></LI>

<BLOCKQUOTE>

...Constructors do not have names. In a constructor
declaration, each <I>decl-specifier</I> in the
optional <I>decl-specifier-seq</I> shall be <TT>friend</TT>,
<TT>inline</TT>, <TT>constexpr</TT>, <SPAN style="font-weight:bold;background-color:#A0FFA0"><TT>consteval</TT>,</SPAN>
or an <I>explicit-specifier</I>.

</BLOCKQUOTE>

</OL>

<BR><BR><HR><A NAME="2481"></A><H4>2481.
  
Cv-qualification of temporary to which a reference is bound
</H4><B>Section: </B>9.4.4&#160; [dcl.init.ref]
 &#160;&#160;&#160;

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

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

 <B>Date: </B>2021-03-20


<P>According to 9.4.4 [dcl.init.ref] bullet 5.4.2,
when a reference is initialized with a non-class value and
the referenced type is not reference-related to the type of
the initializer,</P>

<UL><LI><P>Otherwise, the initializer expression is implicitly
converted to a prvalue of type &#8220;<I>cv1</I>
<TT>T1</TT>&#8221;. The temporary materialization conversion
is applied and the reference is bound to the
result.</P></LI>

</UL>

<P>According to 7.2.2 [expr.type] paragraph 2, the
cv-qualification is discarded before invoking the temporary
materialization conversion:</P>

<BLOCKQUOTE>

If a prvalue initially has the type &#8220;<I>cv</I>
<TT>T</TT>&#8221;, where <TT>T</TT> is a cv-unqualified
non-class, non-array type, the type of the expression is
adjusted to <TT>T</TT> prior to any further analysis.

</BLOCKQUOTE>

<P>This results in a reference-to-const being bound to a
non-const object, meaning that a <TT>const_cast</TT> of
the reference to a reference-to-nonconst would allow a
well-defined modification of the value:</P>

<PRE>
  constexpr const int &amp;r = 42;
  const_cast&lt;int &amp;&gt;(r) = 23;  //<SPAN style="font-family:Times;font-style:italic"> Well-defined</SPAN>
  static_assert(r == 42);     //<SPAN style="font-family:Times;font-style:italic"> Ill-formed, non-constant expression</SPAN>
</PRE>

<P>This was different from the situation before the advent
of the temporary materialization conversion in C++17, when
the description of the reference binding created the
temporary explicitly with the cv-qualified type:</P>

<BLOCKQUOTE>

If <TT>T1</TT> is a non-class type, a temporary of type
&#8220;<I>cv1</I>
<TT>T1</TT>&#8221; is created and copy-initialized (8.5)
from the initializer expression. The reference is then bound
to the temporary.

</BLOCKQUOTE>

<P>Presumably this difference was unintentional and should
be reverted.</P>

<P><B>Proposed resolution, May, 2021:</B></P>

<P>Change 9.4.4 [dcl.init.ref] bullet 5.4.2 as follows:</P>

<BLOCKQUOTE>

<P>A reference to type &#8220;<I>cv1</I> <TT>T1</TT>&#8221; is
initialized by an expression of type &#8220;<I>cv2</I>
<TT>T2</TT>&#8221; as follows:</P>

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

<LI><P>Otherwise:</P></LI>

<UL><LI><P>If <TT>T1</TT> or <TT>T2</TT> is a class type and
<TT>T1</TT> is not reference-related to <TT>T2</TT>...</P></LI>

<LI><P>Otherwise, the initializer expression is implicitly
converted to a prvalue of type <SPAN style="text-decoration:line-through;background-color:#FFA0A0">&#8220;<I>cv1</I></SPAN>
<TT>T1</TT><SPAN style="text-decoration:line-through;background-color:#FFA0A0">&#8221;</SPAN>. The temporary materialization
conversion is applied<SPAN style="font-weight:bold;background-color:#A0FFA0">, considering the type of the
prvalue to be &#8220;<I>cv1</I> <TT>T1</TT>&#8221;,</SPAN>
and the reference is bound to the result.</P></LI>

</UL>

</UL>

</BLOCKQUOTE>

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