Q:

Can the protected member access check be subverted using static_cast?

Consider
class A {
  protected:
    int m;
};
class B : public A {
    void foo(A& a) {
        a.m = 42;  // ill-formed
    }
    void bar(A& a) {
        auto pm = &B::m;
        auto pm2 = static_cast<int A::*>(pm);
        a.*pm2 = 42;  // is this ok?
    }
};

Trying to access A::m directly is ill-formed according to [class.protected]. However, it appears that we can always (?) circumvent this using static_cast, which allows a derived-to-base cast with pointers to members. Or is this somehow UB?
[Coliru link showing that bar compiles]

A:

Yes, you can circumvent the protected mechanism in this way by using static_cast. 
I think this is not undefined behavior in this particular case.
By using the static_cast you tell the compiler two things:

You ask the compiler to convert the B pointer into an A pointer.
You tell the compiler that this is ok to do so. 

For 1. the compiler applies very limited checks of whether this is okay or not, and for static_cast it allows to cast from derived to base and the other way round, and that is it. So the compiler is happy. Whether a variable or pointer is protected or public is not part of the variable or pointer type. Neither pm nor pm2 carry the protected information. 
For 2. the compiler completely leaves it up to you to make the decision whether this is okay or not in your design. It is not undefined behavior. It may still not be a good idea.  pm2 is just a pointer to an int in A. You can reset it to a pointer to a different int in A which is public.
The background is that access control in C++ is generally per-class, plus there are some extra rules around protected which try to provide some level of access control on a per instance basis, but this protection is not perfect as you have demonstrated in your interesting question.

