cplusplus / CWG

Core Working Group
23 stars 7 forks source link

[expr.prim.id] No normative wording that makes the program ill-formed but only a note exists #568

Open ranaanoop opened 1 week ago

ranaanoop commented 1 week ago

Full name of submitter: Anoop Rana

Reference: [expr.prim.id]

Link to reflector thread (if any): https://stackoverflow.com/questions/78707693/msvc-rejects-program-with-member-function-call-while-gcc-and-clang-accept

Issue description:

While answering a question I noticed that currently there is no normative wording that makes the below modified program ill-formed. In fact, we see compiler divergence for the modified program. Note that the below given program is different from the question in that here g is a static member function.

struct C  
{
  void f(this C self);  
  static void g() 
  {
       C::f();      //#1: gcc accepts but clang and msvc rejects
    // (C::f)();    //#2: all three compilers rejects

  }
};
int main()
{ 

}

Gcc accepts #1 while clang and msvc rejects it. OTOH, all three compilers reject #2. I think the intention is to make both 1# and #2 ill-formed as can be seen from non-normative note in expr.prim.id saying:

[Note 2: 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]

As we can see the note intend to make #1 and #2 ill-formed afaik. So this note should be made normative by changing it from a note to a bullet point in [expr.prim.id].

Suggested Resolution

Make the note normative by changing it to a bullet etc point.

frederick-vs-ja commented 1 week ago

The sentence was added by CWG2771.

I guess the suggestion would be normatively redundant and it's better to keep the sentence in a note. Given [expr.prim.id.general] p2.3 reads

if E is a qualified-id, E is not the un-parenthesized operand of the unary & operator ([expr.unary.op]),

C::f needs to be transformed into (*this).C::f in #1, which is clearly ill-formed in a static or explicit object member function.

This is already reported as the bug of GCC (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=113388). The standard wording and other compilers (Godbolt link) are fine here.

t3nsor commented 1 week ago

The "missing" normative wording is [expr.prim.this]/3, which makes it illegal to mention this in a static member function.

Also note that CWG2902 may make the wording easier to read for this case. It attempts to reorganize the specification so that it either directly tells you that the program is ill-formed, or tells you where to look (via cross-reference).