Title
Avoid circularity in specification of scope for friend class declarations
Status
drwp
Section
9.2.9.5 [dcl.type.elab]
Submitter
Jim X

Created on 2022-07-04.00:00:00 last changed 4 months ago

Messages

Date: 2023-11-16.21:27:26

Proposed resolution (approved by CWG 2023-11-11):

Change in 9.2.9.5 [dcl.type.elab] paragraph 4 as follows:

... Any unqualified lookup for the identifier (in the first case) does not consider scopes that contain the target nearest enclosing namespace or block scope; no name is bound. [ Note: ... ]
Date: 2024-03-15.00:00:00

[Accepted as a DR at the March, 2024 meeting.]

Consider:

auto f(struct X* ptr) {
  struct D {
    private:
      int d;
      friend class X;      // #1
  };
  return D{};
}
X* b = 0;
struct X {
  void show() {
    auto t = f(0);
    t.d = 10;              // #2 error: ::X is not a friend of f::D
  }
};

The target scope for #2 is f's block scope, making ::X not a friend of f::D. Thus the access at #2 is ill-formed. Clang disagrees.

Subclause 9.2.9.5 [dcl.type.elab] paragraph 3 specifies:

... If E contains an identifier but no nested-name-specifier and (unqualified) lookup for the identifier finds nothing, E shall not be introduced by the enum keyword and declares the identifier as a class-name. The target scope of E is the nearest enclosing namespace or block scope.

If an elaborated-type-specifier appears with the friend specifier as an entire member-declaration, the member-declaration shall have one of the following forms:

friend class-key nested-name-specifieropt identifier ;
...
Any unqualified lookup for the identifier (in the first case) does not consider scopes that contain the target scope; no name is bound.

This specification is circular in that the target scope that limits unqualified lookup is defined only if the identifier is actually declared, but the identifier is declared only if lookup finds nothing.

History
Date User Action Args
2024-07-20 13:52:34adminsetstatus: dr -> drwp
2024-04-05 21:43:46adminsetstatus: ready -> dr
2024-03-20 14:10:31adminsetstatus: tentatively ready -> ready
2023-11-16 21:27:26adminsetmessages: + msg7516
2023-11-16 21:27:26adminsetstatus: open -> tentatively ready
2022-07-04 00:00:00admincreate