7043922: Regression: internal compiler error for nested anonymous inner class featuring varargs constructor
Attributing a constructor call does not clean up the compiler's attribution context Reviewed-by: jjg
This commit is contained in:
parent
40e9a55470
commit
1ee0f8da66
@ -1708,20 +1708,24 @@ public class Attr extends JCTree.Visitor {
|
|||||||
// that we are referring to a superclass instance of the
|
// that we are referring to a superclass instance of the
|
||||||
// current instance (JLS ???).
|
// current instance (JLS ???).
|
||||||
else {
|
else {
|
||||||
localEnv.info.selectSuper = cdef != null;
|
//the following code alters some of the fields in the current
|
||||||
localEnv.info.varArgs = false;
|
//AttrContext - hence, the current context must be dup'ed in
|
||||||
|
//order to avoid downstream failures
|
||||||
|
Env<AttrContext> rsEnv = localEnv.dup(tree);
|
||||||
|
rsEnv.info.selectSuper = cdef != null;
|
||||||
|
rsEnv.info.varArgs = false;
|
||||||
tree.constructor = rs.resolveConstructor(
|
tree.constructor = rs.resolveConstructor(
|
||||||
tree.pos(), localEnv, clazztype, argtypes, typeargtypes);
|
tree.pos(), rsEnv, clazztype, argtypes, typeargtypes);
|
||||||
tree.constructorType = tree.constructor.type.isErroneous() ?
|
tree.constructorType = tree.constructor.type.isErroneous() ?
|
||||||
syms.errType :
|
syms.errType :
|
||||||
checkMethod(clazztype,
|
checkMethod(clazztype,
|
||||||
tree.constructor,
|
tree.constructor,
|
||||||
localEnv,
|
rsEnv,
|
||||||
tree.args,
|
tree.args,
|
||||||
argtypes,
|
argtypes,
|
||||||
typeargtypes,
|
typeargtypes,
|
||||||
localEnv.info.varArgs);
|
rsEnv.info.varArgs);
|
||||||
if (localEnv.info.varArgs)
|
if (rsEnv.info.varArgs)
|
||||||
Assert.check(tree.constructorType.isErroneous() || tree.varargsElement != null);
|
Assert.check(tree.constructorType.isErroneous() || tree.varargsElement != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1779,9 +1783,10 @@ public class Attr extends JCTree.Visitor {
|
|||||||
|
|
||||||
// Reassign clazztype and recompute constructor.
|
// Reassign clazztype and recompute constructor.
|
||||||
clazztype = cdef.sym.type;
|
clazztype = cdef.sym.type;
|
||||||
|
boolean useVarargs = tree.varargsElement != null;
|
||||||
Symbol sym = rs.resolveConstructor(
|
Symbol sym = rs.resolveConstructor(
|
||||||
tree.pos(), localEnv, clazztype, argtypes,
|
tree.pos(), localEnv, clazztype, argtypes,
|
||||||
typeargtypes, true, tree.varargsElement != null);
|
typeargtypes, true, useVarargs);
|
||||||
Assert.check(sym.kind < AMBIGUOUS || tree.constructor.type.isErroneous());
|
Assert.check(sym.kind < AMBIGUOUS || tree.constructor.type.isErroneous());
|
||||||
tree.constructor = sym;
|
tree.constructor = sym;
|
||||||
if (tree.constructor.kind > ERRONEOUS) {
|
if (tree.constructor.kind > ERRONEOUS) {
|
||||||
@ -1794,7 +1799,7 @@ public class Attr extends JCTree.Visitor {
|
|||||||
tree.args,
|
tree.args,
|
||||||
argtypes,
|
argtypes,
|
||||||
typeargtypes,
|
typeargtypes,
|
||||||
localEnv.info.varArgs);
|
useVarargs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
189
langtools/test/tools/javac/varargs/7043922/T7043922.java
Normal file
189
langtools/test/tools/javac/varargs/7043922/T7043922.java
Normal file
@ -0,0 +1,189 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2011, 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 7043922
|
||||||
|
* @summary Regression: internal compiler error for nested anonymous inner class featuring varargs constructor
|
||||||
|
*/
|
||||||
|
|
||||||
|
import com.sun.source.util.JavacTask;
|
||||||
|
import com.sun.tools.javac.api.JavacTool;
|
||||||
|
import com.sun.tools.javac.util.List;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Locale;
|
||||||
|
import javax.tools.Diagnostic;
|
||||||
|
import javax.tools.JavaCompiler;
|
||||||
|
import javax.tools.JavaFileObject;
|
||||||
|
import javax.tools.SimpleJavaFileObject;
|
||||||
|
import javax.tools.StandardJavaFileManager;
|
||||||
|
import javax.tools.ToolProvider;
|
||||||
|
|
||||||
|
public class T7043922 {
|
||||||
|
|
||||||
|
ClassKind[] classKinds;
|
||||||
|
ConstructorKind[] constructorKinds;
|
||||||
|
|
||||||
|
T7043922(ClassKind[] classKinds, ConstructorKind[] constructorKinds) {
|
||||||
|
this.classKinds = classKinds;
|
||||||
|
this.constructorKinds = constructorKinds;
|
||||||
|
}
|
||||||
|
|
||||||
|
void compileAndCheck() throws Exception {
|
||||||
|
JavaSource source = new JavaSource();
|
||||||
|
ErrorChecker ec = new ErrorChecker();
|
||||||
|
JavacTask ct = (JavacTask)tool.getTask(null, fm, ec,
|
||||||
|
null, null, Arrays.asList(source));
|
||||||
|
ct.analyze();
|
||||||
|
if (ec.errorFound) {
|
||||||
|
throw new Error("invalid diagnostics for source:\n" +
|
||||||
|
source.getCharContent(true) +
|
||||||
|
"\nCompiler diagnostics:\n" + ec.printDiags());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class JavaSource extends SimpleJavaFileObject {
|
||||||
|
|
||||||
|
static final String source_template = "#C0 A0 { #K0 }\n" +
|
||||||
|
"#C1 A1 { #K1 }\n" +
|
||||||
|
"#C2 A2 { #K2 }\n" +
|
||||||
|
"class D {\n" +
|
||||||
|
" void test() {\n" +
|
||||||
|
" new A0(#V0) {\n" +
|
||||||
|
" void test() {\n" +
|
||||||
|
" new A1(#V1) {\n" +
|
||||||
|
" void test() {\n" +
|
||||||
|
" new A2(#V2) {};\n" +
|
||||||
|
" }\n" +
|
||||||
|
" };\n" +
|
||||||
|
" }\n" +
|
||||||
|
" };\n" +
|
||||||
|
" }\n" +
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
String source;
|
||||||
|
|
||||||
|
public JavaSource() {
|
||||||
|
super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
|
||||||
|
source = source_template;
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
source = source.replaceAll("#C" + i, classKinds[i].classKind).
|
||||||
|
replaceAll("#K" + i, classKinds[i].getConstructor("A" + i, constructorKinds[i])).
|
||||||
|
replaceAll("#V" + i, constructorKinds[i].constrArgs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** global decls ***/
|
||||||
|
|
||||||
|
enum ConstructorKind {
|
||||||
|
DEFAULT("", ""),
|
||||||
|
FIXED_ARITY("String s", "\"\""),
|
||||||
|
VARIABLE_ARITY("String... ss", "\"\",\"\"");
|
||||||
|
|
||||||
|
String constrParam;
|
||||||
|
String constrArgs;
|
||||||
|
|
||||||
|
private ConstructorKind(String constrParam, String constrArgs) {
|
||||||
|
this.constrParam = constrParam;
|
||||||
|
this.constrArgs = constrArgs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ClassKind {
|
||||||
|
ABSTRACT("abstract class"),
|
||||||
|
CLASS("class"),
|
||||||
|
INTERFACE("interface");
|
||||||
|
|
||||||
|
String classKind;
|
||||||
|
|
||||||
|
private ClassKind(String classKind) {
|
||||||
|
this.classKind = classKind;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isConstructorOk(ConstructorKind ck) {
|
||||||
|
return this != INTERFACE ||
|
||||||
|
ck == ConstructorKind.DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getConstructor(String className, ConstructorKind ck) {
|
||||||
|
return this == INTERFACE ?
|
||||||
|
"" :
|
||||||
|
(className + "(" + ck.constrParam + ") {}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a single file manager and JavaCompiler tool
|
||||||
|
// and reuse them for each compile to save time.
|
||||||
|
static final StandardJavaFileManager fm = JavacTool.create().getStandardFileManager(null, null, null);
|
||||||
|
static final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
|
||||||
|
|
||||||
|
public static void main(String... args) throws Exception {
|
||||||
|
for (ClassKind classKind1 : ClassKind.values()) {
|
||||||
|
for (ConstructorKind constrKind1 : ConstructorKind.values()) {
|
||||||
|
if (!classKind1.isConstructorOk(constrKind1)) continue;
|
||||||
|
for (ClassKind classKind2 : ClassKind.values()) {
|
||||||
|
for (ConstructorKind constrKind2 : ConstructorKind.values()) {
|
||||||
|
if (!classKind2.isConstructorOk(constrKind2)) continue;
|
||||||
|
for (ClassKind classKind3 : ClassKind.values()) {
|
||||||
|
for (ConstructorKind constrKind3 : ConstructorKind.values()) {
|
||||||
|
if (!classKind3.isConstructorOk(constrKind3)) continue;
|
||||||
|
new T7043922(new ClassKind[] { classKind1, classKind2, classKind3 },
|
||||||
|
new ConstructorKind[] { constrKind1, constrKind2, constrKind3 }).compileAndCheck();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class ErrorChecker implements javax.tools.DiagnosticListener<JavaFileObject> {
|
||||||
|
|
||||||
|
boolean errorFound;
|
||||||
|
List<String> errDiags = List.nil();
|
||||||
|
|
||||||
|
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
|
||||||
|
if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
|
||||||
|
errDiags = errDiags.append(diagnostic.getMessage(Locale.getDefault()));
|
||||||
|
errorFound = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String printDiags() {
|
||||||
|
StringBuilder buf = new StringBuilder();
|
||||||
|
for (String s : errDiags) {
|
||||||
|
buf.append(s);
|
||||||
|
buf.append("\n");
|
||||||
|
}
|
||||||
|
return buf.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user