If by “illegal” you mean ill-formed, then it is illegal if the base class is inaccessible or ambiguous.
-
It is inaccessible when, for example, the base class is private.
class A {}; class B : A {}; ... B b; A *pa = &b; // ERROR: base class is inaccessibleNote that even in C++11 a C-style cast can “break through” access protection and perform a formally correct upcast
A *pa = (A *) &b; // OK, not a `reinterpret_cast`, but a valid upcastThis usage should be avoided, of course.
-
It is ambiguous if your source type contains multiple base subobjects of the target type (through multiple inheritance).
class A {}; class B : public A {}; class C : public A {}; class D : public B, public C {}; D d; A *pa = &d; // ERROR: base class is ambiguousIn such cases the upcast can be performed by explicitly “walking” the desired upcast path with intermediate upcasts to the point where the base is no longer ambiguous
B* pb = &d; A* pa = pb; // OK: points to 'D::B::A' subobject