This is an unofficial snapshot of the ISO/IEC JTC1 SC22 WG21 Core Issues List revision 115d. See http://www.open-std.org/jtc1/sc22/wg21/ for the official list.
2024-10-26
[Accepted as a DR at the March, 2024 meeting.]
Consider:
struct A{
int a;
void show(){
int* r = &a; // #1
}
};
According to 11.4.3 [class.mfct.non.static] paragraph 2, the transformation to class member access does not happen for the id-expression a, because it is the unparenthesized operand of &:
When an id-expression (7.5.5 [expr.prim.id]) that is neither part of a class member access syntax (7.6.1.5 [expr.ref]) nor the un-parenthesized operand of the unary & operator (7.6.2.2 [expr.unary.op]) is used where the current class is X (7.5.3 [expr.prim.this]), if name lookup (6.5 [basic.lookup]) resolves the name in the id-expression to a non-static non-type member of some class C, and if either the id-expression is potentially evaluated or C is X or a base class of X, the id-expression is transformed into a class member access expression (7.6.1.5 [expr.ref]) using (*this) as the postfix-expression to the left of the . operator. [Note 1: If C is not X or a base class of X, the class member access expression is ill-formed. —end note] This transformation does not apply in the template definition context (13.8.3.2 [temp.dep.type]).
Proposed resolution (approved by CWG 2024-03-20):
This resolution moves the transformation to 7.5.5.1 [expr.prim.id.general], where the similar transformation for anonymous unions is already described.
Change in 6.3 [basic.def.odr] paragraph 7 as follows:
*this is odr-used if this appears as a potentially-evaluated expression (including as the result oftheany implicit transformationin the body of a non-static member functionto a class member access expression (11.4.3 [class.mfct.non.static]7.5.5.1 [expr.prim.id.general])).
Add a new paragraph before 7.5.5.1 [expr.prim.id.general] paragraph 2:
If an id-expression E denotes a non-static non-type member of some class C at a point where the current class (7.5.3 [expr.prim.this]) is X and
the id-expression is transformed into a class member access expression using (*this) as the object expression. [Note 1: If C is not X or a base class of X, the class member access expression is ill-formed. Also, if the id-expression occurs within a static or explicit object member function, the class member access is ill-formed. —end note] This transformation does not apply in the template definition context (13.8.3.2 [temp.dep.type]).
- E is potentially evaluated or C is X or a base class of X, and
- E is not the id-expression of a class member access expression (7.6.1.5 [expr.ref]), and
- if E is a qualified-id, E is not the un-parenthesized operand of the unary & operator (7.6.2.2 [expr.unary.op]),
If an id-expression E denotes a member M of an anonymous union (11.5.2 [class.union.anon]) U:
- If U is a non-static data member, E refers to M as a member of the lookup context of the terminal name of E (after any implicit transformation to a class member access expression
(11.4.3 [class.mfct.non.static])).- ...
Change in 7.5.5.1 [expr.prim.id.general] paragraph 3 as follows:
An id-expression that denotes a non-static data member or implicit object member function of a class can only be used:
- as part of a class member access (
7.6.1.5 [expr.ref]after any implicit transformation (see above)) in which the object expression refers to the member's class[ Footnote: This also applies when the object expression is an implicit (*this) (11.4.3 [class.mfct.non.static]).]or a class derived from that class, or- ...
Change in 7.5.5.2 [expr.prim.id.unqual] paragraph 1 as follows:
... [ Note: ...Within the definition of a non-static member function, an identifier that names a non-static member is transformed to a class member access expression (11.4.3 [class.mfct.non.static]).—end note]
Remove 11.4.3 [class.mfct.non.static] paragraph 2, including the example:
When an id-expression (7.5.5 [expr.prim.id]) that is neither part of a class member access syntax (7.6.1.5 [expr.ref]) nor the un-parenthesized operand of the unary & operator (7.6.2.2 [expr.unary.op]) is used where the current class is X (7.5.3 [expr.prim.this]), if name lookup (6.5 [basic.lookup]) resolves the name in the id-expression to a non-static non-type member of some class C, and if either the id-expression is potentially evaluated or C is X or a base class of X, the id-expression is transformed into a class member access expression (7.6.1.5 [expr.ref]) using (*this) as the postfix-expression to the left of the . operator. [Note 1: If C is not X or a base class of X, the class member access expression is ill-formed. —end note] This transformation does not apply in the template definition context (13.8.3.2 [temp.dep.type]). [ Example: ... ]
Change in 13.8.3.2 [temp.dep.type] paragraph 6 as follows:
[ Example: ...template int C<B>::g(); // OK, transformation to class member access syntax // does not occur in the template definition context; see-- end example ]11.4.3 [class.mfct.non.static]7.5.5.1 [expr.prim.id.general]