-
Notifications
You must be signed in to change notification settings - Fork 7
Description
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
namingdesignating 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 classC. 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 whosethenested-name-specifiershall denotedesignatesCor a class derived fromC. All other accesses involve a (possibly implicit) object expression ([expr.ref]). In this case, the class of the object expression shall beCor a class derived fromC.
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
Cor a class derived fromC.
But if the interaction to CWG2902 is too close, then we can ignore it for now.