This CR shows a problem in Resolve.isAccessible() method. Accessibility rules for protected members doesn't take into consideration static members. Current javac rules impose that a protected member C.x, in order to be accessible from T the following conditions must hold:
1) C is in the same package of T, or C is inherited by T
2) No members in T overrides C.x
The implementation of 2) is a bit tricky and relies upon the Symbol.implementation() method: this how the rule looks like in javac:
2b) the implementation of C.x in T is C.x itself (which means that T is inheriting C.x wihout overriding it)
This trick works most of the times, but it relies on the internals of the implementation of the Symbol.implementation() method; in our case, since T.x is a static member, in principle there would be no no need of checking for overriding (that cannot take place!). Moreover, when Resolve.isAccessible() is called from the code in either Resolve.findFun() or Resolve.findVar(), strange things might happen if the static method/field to be resolved comes from a static import.
Static imports somehow need some special handling: when a field/method m is found in the static scope of a the type C (that has been statically imported), two situation may arise:
1) m is indeed a member of C - then resolution takes place as always, and no bug occurs; this process is similar to resolving a static method/field given the fully qualified type-expression C.m
2) m is in the static scope of C, but it has not been defined in some other type B from which C inherithed it. In this case javac replaces the owner of m's symbol to be C, so that B.m becomes C.m. But what does it mean? If B.m were a method, C.m compiler generated symbol would correspond to C's overriden version of B.m. But this means that when checking for accessibility we have that condition 2 for accessibilit ydoes not hold anymore, since:
- No members in T overrides C.x --
it's not true (C.x seems to override B.x).
The solution to this problem, has anticipated, is to avoid the overriding check when checking for accessibility of static protected methods, as static methods cannot be overriden. This check generates only confusion and badly copes with features likes static imports.