JDK-8189335: NPE in Lower due to class name clash
B. Blaser
bsrbnd at gmail.com
Wed Feb 21 15:58:34 UTC 2018
On 19 February 2018 at 15:53, B. Blaser <bsrbnd at gmail.com> wrote:
> On 19 February 2018 at 00:42, B. Blaser <bsrbnd at gmail.com> wrote:
>> Hi,
>>
>> As explained in JDK-8189335, the following example crashes javac with
>> a NPE in Lower:
>>
>> class R {
>> private class R$1 {}
>> void f() {
>> new R$1();
>> }
>> }
>> class R$1 {}
Some precisions related to my laconic explanation about the problem and the fix.
All starts in 'Lower.accessConstructorTag()' when searching for the
anonymous class 'R$1':
http://hg.openjdk.java.net/jdk/jdk/file/02404e27d356/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java#l1238
The top level class 'R$1' (not anonymous) is found and wrongly added
to 'accessConstrTags'.
Then, when checking the access constructor tags in
'Lower.checkAccessConstructorTags()', the 'outermostClass()' of the
top level class 'R$1' is requested:
http://hg.openjdk.java.net/jdk/jdk/file/02404e27d356/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java#l778
'R$1' being a top level class, its outermost class doesn't exist,
causing the NPE in 'Lower.makeEmptyClass()'.
The fix I suggested two days ago (here under) is then quite
straightforward. If a class 'R$1' exists but isn't anonymous, it has
to be skipped and a fresh anonymous class 'R$2' has to be created as
access constructor tag:
http://hg.openjdk.java.net/jdk/jdk/file/02404e27d356/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java#l1239
Nothing seems to be broken and the provided example compiles successfully.
What do you think (I hope this is clearer)?
Thanks,
Bernard
> diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java
> b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java
> --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java
> +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Lower.java
> @@ -1236,7 +1236,7 @@
> target.syntheticNameChar() +
> "1");
> ClassSymbol ctag = chk.getCompiled(topModle, flatname);
> - if (ctag == null)
> + if (ctag == null || !ctag.isAnonymous())
> ctag = makeEmptyClass(STATIC | SYNTHETIC, topClass).sym;
> // keep a record of all tags, to verify that all are
> generated as required
> accessConstrTags = accessConstrTags.prepend(ctag);
More information about the compiler-dev
mailing list