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.
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
mis a private member ofBase:but [class.protected]/1 implies that the same is ill-formed when
mis a protected member ofBase, since there is no nested-name-specifier that denotesDerivedor a class derived fromDerived. 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:
Optionally, we could try to drive-by fix the "unevaluated context issue" by modifying the last two sentences as follows:
But if the interaction to CWG2902 is too close, then we can ignore it for now.