8166700: NPE during invoking getEnclosedElements() on javax.lang.model.element.Element instance representing a package

Should not strip first parameter of a local class constructor for local classes in initializers.

Reviewed-by: jjg
This commit is contained in:
Jan Lahoda 2016-11-10 17:27:01 +01:00
parent acae42fd30
commit b40c63e9fb
11 changed files with 729 additions and 2 deletions

View file

@ -137,12 +137,18 @@ public abstract class Scope {
/** Returns true iff the given Symbol is in this scope or any outward scope.
*/
public boolean includes(final Symbol sym) {
return includes(sym, RECURSIVE);
}
/** Returns true iff the given Symbol is in this scope, optionally checking outward scopes.
*/
public boolean includes(final Symbol sym, LookupKind lookupKind) {
return getSymbolsByName(sym.name, new Filter<Symbol>() {
@Override
public boolean accepts(Symbol t) {
return t == sym;
}
}).iterator().hasNext();
}, lookupKind).iterator().hasNext();
}
/** Returns true iff this scope does not contain any Symbol. Does not inspect outward scopes.

View file

@ -62,6 +62,7 @@ import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
import static com.sun.tools.javac.code.Flags.*;
import static com.sun.tools.javac.code.Kinds.Kind.*;
import com.sun.tools.javac.code.Scope.LookupKind;
import static com.sun.tools.javac.code.TypeTag.ARRAY;
import static com.sun.tools.javac.code.TypeTag.CLASS;
import static com.sun.tools.javac.code.TypeTag.TYPEVAR;
@ -2186,7 +2187,11 @@ public class ClassReader {
// Sometimes anonymous classes don't have an outer
// instance, however, there is no reliable way to tell so
// we never strip this$n
if (!currentOwner.name.isEmpty())
// ditto for local classes. Local classes that have an enclosing method set
// won't pass the "hasOuterInstance" check above, but those that don't have an
// enclosing method (i.e. from initializers) will pass that check.
boolean local = !currentOwner.owner.members().includes(currentOwner, LookupKind.NON_RECURSIVE);
if (!currentOwner.name.isEmpty() && !local)
type = new MethodType(adjustMethodParams(flags, type.getParameterTypes()),
type.getReturnType(),
type.getThrownTypes(),

View file

@ -0,0 +1,73 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test
* @bug 8166700
* @summary Check that local classes originating in static initializer can be loaded properly.
* @modules jdk.compiler
* @build LocalTest$1Local LocalTest$2Local LocalTest$3Local LocalTest$4Local LocalTest$5Local LocalTest
* @compile LocalClassesModel.java
* @compile/process/ref=LocalClassesModel.out -processor LocalClassesModel LocalTest$1Local LocalTest$2Local LocalTest$3Local LocalTest$4Local LocalTest$5Local LocalTest
*/
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.util.ElementFilter;
@SupportedAnnotationTypes("*")
public class LocalClassesModel extends AbstractProcessor {
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
for (TypeElement root : ElementFilter.typesIn(roundEnv.getRootElements())) {
System.out.println(processingEnv.getElementUtils().getBinaryName(root));
for (ExecutableElement constr : ElementFilter.constructorsIn(root.getEnclosedElements())) {
System.out.print(" (");
boolean first = true;
for (VariableElement param : constr.getParameters()) {
if (!first) {
System.out.print(", ");
}
first = false;
System.out.print(param.asType().toString());
}
System.out.println(")");
}
}
return false;
}
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}
}

View file

@ -0,0 +1,12 @@
LocalTest$1Local
()
LocalTest$2Local
(LocalTest)
LocalTest$3Local
()
LocalTest$4Local
(LocalTest)
LocalTest$5Local
(LocalTest)
LocalTest
()

View file

@ -0,0 +1,77 @@
class LocalTest$1Local {
0xCAFEBABE;
0; // minor version
52; // version
[] { // Constant Pool
; // first element is empty
Method #3 #12; // #1
class #13; // #2
class #16; // #3
Utf8 "<init>"; // #4
Utf8 "()V"; // #5
Utf8 "Code"; // #6
Utf8 "LineNumberTable"; // #7
Utf8 "SourceFile"; // #8
Utf8 "LocalTest.java"; // #9
Utf8 "EnclosingMethod"; // #10
class #17; // #11
NameAndType #4 #5; // #12
Utf8 "LocalTest$1Local"; // #13
Utf8 "Local"; // #14
Utf8 "InnerClasses"; // #15
Utf8 "java/lang/Object"; // #16
Utf8 "LocalTest"; // #17
} // Constant Pool
0x0020; // access
#2;// this_cpx
#3;// super_cpx
[] { // Interfaces
} // Interfaces
[] { // fields
} // fields
[] { // methods
{ // Member
0x0000; // access
#4; // name_cpx
#5; // sig_cpx
[] { // Attributes
Attr(#6) { // Code
1; // max_stack
1; // max_locals
Bytes[]{
0x2AB70001B1;
};
[] { // Traps
} // end Traps
[] { // Attributes
Attr(#7) { // LineNumberTable
[] { // LineNumberTable
0 3;
}
} // end LineNumberTable
} // Attributes
} // end Code
} // Attributes
} // Member
} // methods
[] { // Attributes
Attr(#8) { // SourceFile
#9;
} // end SourceFile
;
Attr(#10) { // EnclosingMethod
#11 #0;
} // end EnclosingMethod
;
Attr(#15) { // InnerClasses
[] { // InnerClasses
#2 #0 #14 0;
}
} // end InnerClasses
} // Attributes
} // end class LocalTest$1Local

View file

@ -0,0 +1,90 @@
class LocalTest$2Local {
0xCAFEBABE;
0; // minor version
52; // version
[] { // Constant Pool
; // first element is empty
Field #3 #15; // #1
Method #4 #16; // #2
class #17; // #3
class #20; // #4
Utf8 "this$0"; // #5
Utf8 "LLocalTest;"; // #6
Utf8 "<init>"; // #7
Utf8 "(LLocalTest;)V"; // #8
Utf8 "Code"; // #9
Utf8 "LineNumberTable"; // #10
Utf8 "SourceFile"; // #11
Utf8 "LocalTest.java"; // #12
Utf8 "EnclosingMethod"; // #13
class #21; // #14
NameAndType #5 #6; // #15
NameAndType #7 #22; // #16
Utf8 "LocalTest$2Local"; // #17
Utf8 "Local"; // #18
Utf8 "InnerClasses"; // #19
Utf8 "java/lang/Object"; // #20
Utf8 "LocalTest"; // #21
Utf8 "()V"; // #22
} // Constant Pool
0x0020; // access
#3;// this_cpx
#4;// super_cpx
[] { // Interfaces
} // Interfaces
[] { // fields
{ // Member
0x1010; // access
#5; // name_cpx
#6; // sig_cpx
[] { // Attributes
} // Attributes
} // Member
} // fields
[] { // methods
{ // Member
0x0000; // access
#7; // name_cpx
#8; // sig_cpx
[] { // Attributes
Attr(#9) { // Code
2; // max_stack
2; // max_locals
Bytes[]{
0x2A2BB500012AB700;
0x02B1;
};
[] { // Traps
} // end Traps
[] { // Attributes
Attr(#10) { // LineNumberTable
[] { // LineNumberTable
0 6;
}
} // end LineNumberTable
} // Attributes
} // end Code
} // Attributes
} // Member
} // methods
[] { // Attributes
Attr(#11) { // SourceFile
#12;
} // end SourceFile
;
Attr(#13) { // EnclosingMethod
#14 #0;
} // end EnclosingMethod
;
Attr(#19) { // InnerClasses
[] { // InnerClasses
#3 #0 #18 0;
}
} // end InnerClasses
} // Attributes
} // end class LocalTest$2Local

View file

@ -0,0 +1,79 @@
class LocalTest$3Local {
0xCAFEBABE;
0; // minor version
52; // version
[] { // Constant Pool
; // first element is empty
Method #3 #13; // #1
class #14; // #2
class #17; // #3
Utf8 "<init>"; // #4
Utf8 "()V"; // #5
Utf8 "Code"; // #6
Utf8 "LineNumberTable"; // #7
Utf8 "SourceFile"; // #8
Utf8 "LocalTest.java"; // #9
Utf8 "EnclosingMethod"; // #10
class #18; // #11
NameAndType #19 #5; // #12
NameAndType #4 #5; // #13
Utf8 "LocalTest$3Local"; // #14
Utf8 "Local"; // #15
Utf8 "InnerClasses"; // #16
Utf8 "java/lang/Object"; // #17
Utf8 "LocalTest"; // #18
Utf8 "test1"; // #19
} // Constant Pool
0x0020; // access
#2;// this_cpx
#3;// super_cpx
[] { // Interfaces
} // Interfaces
[] { // fields
} // fields
[] { // methods
{ // Member
0x0000; // access
#4; // name_cpx
#5; // sig_cpx
[] { // Attributes
Attr(#6) { // Code
1; // max_stack
1; // max_locals
Bytes[]{
0x2AB70001B1;
};
[] { // Traps
} // end Traps
[] { // Attributes
Attr(#7) { // LineNumberTable
[] { // LineNumberTable
0 9;
}
} // end LineNumberTable
} // Attributes
} // end Code
} // Attributes
} // Member
} // methods
[] { // Attributes
Attr(#8) { // SourceFile
#9;
} // end SourceFile
;
Attr(#10) { // EnclosingMethod
#11 #12;
} // end EnclosingMethod
;
Attr(#16) { // InnerClasses
[] { // InnerClasses
#2 #0 #15 0;
}
} // end InnerClasses
} // Attributes
} // end class LocalTest$3Local

View file

@ -0,0 +1,92 @@
class LocalTest$4Local {
0xCAFEBABE;
0; // minor version
52; // version
[] { // Constant Pool
; // first element is empty
Field #3 #16; // #1
Method #4 #17; // #2
class #18; // #3
class #21; // #4
Utf8 "this$0"; // #5
Utf8 "LLocalTest;"; // #6
Utf8 "<init>"; // #7
Utf8 "(LLocalTest;)V"; // #8
Utf8 "Code"; // #9
Utf8 "LineNumberTable"; // #10
Utf8 "SourceFile"; // #11
Utf8 "LocalTest.java"; // #12
Utf8 "EnclosingMethod"; // #13
class #22; // #14
NameAndType #23 #24; // #15
NameAndType #5 #6; // #16
NameAndType #7 #24; // #17
Utf8 "LocalTest$4Local"; // #18
Utf8 "Local"; // #19
Utf8 "InnerClasses"; // #20
Utf8 "java/lang/Object"; // #21
Utf8 "LocalTest"; // #22
Utf8 "test2"; // #23
Utf8 "()V"; // #24
} // Constant Pool
0x0020; // access
#3;// this_cpx
#4;// super_cpx
[] { // Interfaces
} // Interfaces
[] { // fields
{ // Member
0x1010; // access
#5; // name_cpx
#6; // sig_cpx
[] { // Attributes
} // Attributes
} // Member
} // fields
[] { // methods
{ // Member
0x0000; // access
#7; // name_cpx
#8; // sig_cpx
[] { // Attributes
Attr(#9) { // Code
2; // max_stack
2; // max_locals
Bytes[]{
0x2A2BB500012AB700;
0x02B1;
};
[] { // Traps
} // end Traps
[] { // Attributes
Attr(#10) { // LineNumberTable
[] { // LineNumberTable
0 12;
}
} // end LineNumberTable
} // Attributes
} // end Code
} // Attributes
} // Member
} // methods
[] { // Attributes
Attr(#11) { // SourceFile
#12;
} // end SourceFile
;
Attr(#13) { // EnclosingMethod
#14 #15;
} // end EnclosingMethod
;
Attr(#20) { // InnerClasses
[] { // InnerClasses
#3 #0 #19 0;
}
} // end InnerClasses
} // Attributes
} // end class LocalTest$4Local

View file

@ -0,0 +1,90 @@
class LocalTest$5Local {
0xCAFEBABE;
0; // minor version
52; // version
[] { // Constant Pool
; // first element is empty
Field #3 #16; // #1
Method #4 #15; // #2
class #17; // #3
class #20; // #4
Utf8 "this$0"; // #5
Utf8 "LLocalTest;"; // #6
Utf8 "<init>"; // #7
Utf8 "(LLocalTest;)V"; // #8
Utf8 "Code"; // #9
Utf8 "LineNumberTable"; // #10
Utf8 "SourceFile"; // #11
Utf8 "LocalTest.java"; // #12
Utf8 "EnclosingMethod"; // #13
class #21; // #14
NameAndType #7 #22; // #15
NameAndType #5 #6; // #16
Utf8 "LocalTest$5Local"; // #17
Utf8 "Local"; // #18
Utf8 "InnerClasses"; // #19
Utf8 "java/lang/Object"; // #20
Utf8 "LocalTest"; // #21
Utf8 "()V"; // #22
} // Constant Pool
0x0020; // access
#3;// this_cpx
#4;// super_cpx
[] { // Interfaces
} // Interfaces
[] { // fields
{ // Member
0x1010; // access
#5; // name_cpx
#6; // sig_cpx
[] { // Attributes
} // Attributes
} // Member
} // fields
[] { // methods
{ // Member
0x0000; // access
#7; // name_cpx
#8; // sig_cpx
[] { // Attributes
Attr(#9) { // Code
2; // max_stack
2; // max_locals
Bytes[]{
0x2A2BB500012AB700;
0x02B1;
};
[] { // Traps
} // end Traps
[] { // Attributes
Attr(#10) { // LineNumberTable
[] { // LineNumberTable
0 15;
}
} // end LineNumberTable
} // Attributes
} // end Code
} // Attributes
} // Member
} // methods
[] { // Attributes
Attr(#11) { // SourceFile
#12;
} // end SourceFile
;
Attr(#13) { // EnclosingMethod
#14 #15;
} // end EnclosingMethod
;
Attr(#19) { // InnerClasses
[] { // InnerClasses
#3 #0 #18 0;
}
} // end InnerClasses
} // Attributes
} // end class LocalTest$5Local

View file

@ -0,0 +1,160 @@
class LocalTest {
0xCAFEBABE;
0; // minor version
52; // version
[] { // Constant Pool
; // first element is empty
Method #3 #20; // #1
class #21; // #2
class #22; // #3
class #23; // #4
Utf8 "Local"; // #5
Utf8 "InnerClasses"; // #6
class #24; // #7
class #25; // #8
class #26; // #9
class #27; // #10
Utf8 "test1"; // #11
Utf8 "()V"; // #12
Utf8 "Code"; // #13
Utf8 "LineNumberTable"; // #14
Utf8 "test2"; // #15
Utf8 "<init>"; // #16
Utf8 "<clinit>"; // #17
Utf8 "SourceFile"; // #18
Utf8 "LocalTest.java"; // #19
NameAndType #16 #12; // #20
Utf8 "LocalTest"; // #21
Utf8 "java/lang/Object"; // #22
Utf8 "LocalTest$5Local"; // #23
Utf8 "LocalTest$4Local"; // #24
Utf8 "LocalTest$3Local"; // #25
Utf8 "LocalTest$2Local"; // #26
Utf8 "LocalTest$1Local"; // #27
} // Constant Pool
0x0021; // access
#2;// this_cpx
#3;// super_cpx
[] { // Interfaces
} // Interfaces
[] { // fields
} // fields
[] { // methods
{ // Member
0x0008; // access
#11; // name_cpx
#12; // sig_cpx
[] { // Attributes
Attr(#13) { // Code
0; // max_stack
0; // max_locals
Bytes[]{
0xB1;
};
[] { // Traps
} // end Traps
[] { // Attributes
Attr(#14) { // LineNumberTable
[] { // LineNumberTable
0 10;
}
} // end LineNumberTable
} // Attributes
} // end Code
} // Attributes
} // Member
;
{ // Member
0x0000; // access
#15; // name_cpx
#12; // sig_cpx
[] { // Attributes
Attr(#13) { // Code
0; // max_stack
1; // max_locals
Bytes[]{
0xB1;
};
[] { // Traps
} // end Traps
[] { // Attributes
Attr(#14) { // LineNumberTable
[] { // LineNumberTable
0 13;
}
} // end LineNumberTable
} // Attributes
} // end Code
} // Attributes
} // Member
;
{ // Member
0x0000; // access
#16; // name_cpx
#12; // sig_cpx
[] { // Attributes
Attr(#13) { // Code
1; // max_stack
1; // max_locals
Bytes[]{
0x2AB70001B1;
};
[] { // Traps
} // end Traps
[] { // Attributes
Attr(#14) { // LineNumberTable
[] { // LineNumberTable
0 14;
4 16;
}
} // end LineNumberTable
} // Attributes
} // end Code
} // Attributes
} // Member
;
{ // Member
0x0008; // access
#17; // name_cpx
#12; // sig_cpx
[] { // Attributes
Attr(#13) { // Code
0; // max_stack
0; // max_locals
Bytes[]{
0xB1;
};
[] { // Traps
} // end Traps
[] { // Attributes
Attr(#14) { // LineNumberTable
[] { // LineNumberTable
0 4;
}
} // end LineNumberTable
} // Attributes
} // end Code
} // Attributes
} // Member
} // methods
[] { // Attributes
Attr(#18) { // SourceFile
#19;
} // end SourceFile
;
Attr(#6) { // InnerClasses
[] { // InnerClasses
#4 #0 #5 0;
#7 #0 #5 0;
#8 #0 #5 0;
#9 #0 #5 0;
#10 #0 #5 0;
}
} // end InnerClasses
} // Attributes
} // end class LocalTest

View file

@ -0,0 +1,43 @@
/*
* Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**The jcod files are generated from this file, compiled by JDK 8 javac.
*/
public class LocalTest {
static {
class Local { }
}
{
class Local { }
}
static void test1() {
class Local { }
}
void test2() {
class Local { }
}
LocalTest() {
class Local { }
}
}