The restrictions on protected access in 11.8.5 [class.protected] apply only to forming pointers to members and to member access expressions. It should be considered whether to extend these restrictions to pointer-to-member expressions as well. For example,
struct base { protected: int x; }; struct derived : base { void foo(base* b) { b->x = 123; // not ok (b->*(&derived::x)) = 123; // ok?! } };