Skip to content

CWG3109 [class.protected] Update to cover splices #784

@katzdm

Description

@katzdm

Full name of submitter: Dan Katz

Reference (section label): [class.protected]/1

Issue description
[class.protected] establishes the "additional rule" for access to non-static data members in the context of forming a pointer-to-member. Just as [class.access.base]/5.3 waives access rules for members designated through a splice-expression, this clause should do the same. As the rules currently stand, the following is well-formed when m is a private member of Base:

class Base {
private:
  int m;
public:
  static constexpr auto rm = ^^m;
};
class Derived { static constexpr auto mp = &[:Base::rm:]; };

but [class.protected]/1 implies that the same is ill-formed when m is a protected member of Base, since there is no nested-name-specifier that denotes Derived or a class derived from Derived. Furthermore, the phrase "naming class" is used, whereas P2996 replaced this term with "designating class". Lastly, because a nested-name-specifier can be a splice-expression (e.g., &[:reflection_of_class:]::member), the verb "designates" should be preferred in lieu of "denotes".

Worth noting: This paragraph fails to account for access that occur in unevaluated contexts, but addressing this seems to tread too closely to CWG2902 for comfort, so I'm leaving that as-is for now (but added a comment on the relevant issue).

Suggested resolution
Apply the following changes to [class.protected]/1:

An additional access check beyond those described earlier in [class.access] is applied when a non-static data member or non-static member function is a protected member of its naming designating class ([class.access.base]).98 As described earlier, access to a protected member is granted because the reference occurs in a friend or direct member of some class C. If the access is to form a pointer to member ([expr.unary.op]), that member shall either be designated with a splice-expression or with a qualified name whose the nested-name-specifier shall denote designates C or a class derived from C. All other accesses involve a (possibly implicit) object expression ([expr.ref]). In this case, the class of the object expression shall be C or a class derived from C.

Optionally, we could try to drive-by fix the "unevaluated context issue" by modifying the last two sentences as follows:

All other potentially evaluated accesses involve a (possibly implicit) object expression ([expr.ref]). In this case, the class of the object expression shall be C or a class derived from C.

But if the interaction to CWG2902 is too close, then we can ignore it for now.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions