changeset 1073:88bf21461a6b

Merge from main OpenJDK repository
author Greg Lewis <glewis@eyesbeyond.com>
date Fri, 20 May 2011 20:04:23 -0700
parents 17e2954b3ec2 8987de9a4ab8
children b9c11a152207
files
diffstat 11 files changed, 606 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/.hgtags	Thu May 12 20:55:14 2011 -0700
+++ b/.hgtags	Fri May 20 20:04:23 2011 -0700
@@ -117,3 +117,4 @@
 258e6654aba25aab91c9ba3b4c53d05bc895a86c jdk7-b140
 90adb5d6adc7d99d27c8b142a31ac8921070274f jdk7-b141
 7476b164194c1814704153e74d5ff7e965c6fdbf jdk7-b142
+5faa9eedc44e201f2b13ad837e9077668b823d28 jdk7-b143
--- a/src/share/classes/com/sun/source/tree/SynchronizedTree.java	Thu May 12 20:55:14 2011 -0700
+++ b/src/share/classes/com/sun/source/tree/SynchronizedTree.java	Fri May 20 20:04:23 2011 -0700
@@ -31,7 +31,7 @@
  * For example:
  * <pre>
  *   synchronized ( <em>expression</em> )
- *       </em>block</em>
+ *       <em>block</em>
  * </pre>
  *
  * @jls section 14.19
--- a/src/share/classes/com/sun/tools/javac/code/Symbol.java	Thu May 12 20:55:14 2011 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Symbol.java	Fri May 20 20:04:23 2011 -0700
@@ -1006,7 +1006,6 @@
                 try {
                     data = eval.call();
                 } catch (Exception ex) {
-                    ex.printStackTrace();
                     throw new AssertionError(ex);
                 }
             }
--- a/src/share/classes/com/sun/tools/javac/code/Types.java	Thu May 12 20:55:14 2011 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Types.java	Fri May 20 20:04:23 2011 -0700
@@ -955,7 +955,9 @@
         if (t.isPrimitive() != s.isPrimitive())
             return allowBoxing && (
                     isConvertible(t, s, warn)
-                    || (allowObjectToPrimitiveCast && isConvertible(s, t, warn)));
+                    || (allowObjectToPrimitiveCast &&
+                        s.isPrimitive() &&
+                        isSubtype(boxedClass(s).type, t)));
         if (warn != warnStack.head) {
             try {
                 warnStack = warnStack.prepend(warn);
--- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu May 12 20:55:14 2011 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Fri May 20 20:04:23 2011 -0700
@@ -1708,20 +1708,24 @@
             // that we are referring to a superclass instance of the
             // current instance (JLS ???).
             else {
-                localEnv.info.selectSuper = cdef != null;
-                localEnv.info.varArgs = false;
+                //the following code alters some of the fields in the current
+                //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.pos(), localEnv, clazztype, argtypes, typeargtypes);
+                    tree.pos(), rsEnv, clazztype, argtypes, typeargtypes);
                 tree.constructorType = tree.constructor.type.isErroneous() ?
                     syms.errType :
                     checkMethod(clazztype,
                         tree.constructor,
-                        localEnv,
+                        rsEnv,
                         tree.args,
                         argtypes,
                         typeargtypes,
-                        localEnv.info.varArgs);
-                if (localEnv.info.varArgs)
+                        rsEnv.info.varArgs);
+                if (rsEnv.info.varArgs)
                     Assert.check(tree.constructorType.isErroneous() || tree.varargsElement != null);
             }
 
@@ -1779,9 +1783,10 @@
 
                 // Reassign clazztype and recompute constructor.
                 clazztype = cdef.sym.type;
+                boolean useVarargs = tree.varargsElement != null;
                 Symbol sym = rs.resolveConstructor(
                     tree.pos(), localEnv, clazztype, argtypes,
-                    typeargtypes, true, tree.varargsElement != null);
+                    typeargtypes, true, useVarargs);
                 Assert.check(sym.kind < AMBIGUOUS || tree.constructor.type.isErroneous());
                 tree.constructor = sym;
                 if (tree.constructor.kind > ERRONEOUS) {
@@ -1794,7 +1799,7 @@
                             tree.args,
                             argtypes,
                             typeargtypes,
-                            localEnv.info.varArgs);
+                            useVarargs);
                 }
             }
 
--- a/src/share/classes/com/sun/tools/javac/comp/Infer.java	Thu May 12 20:55:14 2011 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java	Fri May 20 20:04:23 2011 -0700
@@ -407,9 +407,7 @@
 
         // for varargs arguments as well
         if (useVarargs) {
-            //note: if applicability check is triggered by most specific test,
-            //the last argument of a varargs is _not_ an array type (see JLS 15.12.2.5)
-            Type elemType = types.elemtypeOrType(varargsFormal);
+            Type elemType = types.elemtype(varargsFormal);
             Type elemUndet = types.subst(elemType, tvars, undetvars);
             while (actuals.nonEmpty()) {
                 Type actual = actuals.head.baseType();
--- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Thu May 12 20:55:14 2011 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Fri May 20 20:04:23 2011 -0700
@@ -458,9 +458,7 @@
             throw inapplicableMethodException.setMessage("arg.length.mismatch"); // not enough args
 
         if (useVarargs) {
-            //note: if applicability check is triggered by most specific test,
-            //the last argument of a varargs is _not_ an array type (see JLS 15.12.2.5)
-            Type elt = types.elemtypeOrType(varargsFormal);
+            Type elt = types.elemtype(varargsFormal);
             while (argtypes.nonEmpty()) {
                 if (!types.isConvertible(argtypes.head, elt, warn))
                     throw inapplicableMethodException.setMessage("varargs.argument.mismatch",
@@ -819,10 +817,10 @@
     private boolean signatureMoreSpecific(Env<AttrContext> env, Type site, Symbol m1, Symbol m2, boolean allowBoxing, boolean useVarargs) {
         noteWarner.clear();
         Type mtype1 = types.memberType(site, adjustVarargs(m1, m2, useVarargs));
-        return (instantiate(env, site, adjustVarargs(m2, m1, useVarargs), types.lowerBoundArgtypes(mtype1), null,
-                             allowBoxing, false, noteWarner) != null ||
-                 useVarargs && instantiate(env, site, adjustVarargs(m2, m1, useVarargs), types.lowerBoundArgtypes(mtype1), null,
-                                           allowBoxing, true, noteWarner) != null) &&
+        Type mtype2 = instantiate(env, site, adjustVarargs(m2, m1, useVarargs),
+                types.lowerBoundArgtypes(mtype1), null,
+                allowBoxing, false, noteWarner);
+        return mtype2 != null &&
                 !noteWarner.hasLint(Lint.LintCategory.UNCHECKED);
     }
     //where
@@ -855,7 +853,7 @@
             //append varargs element type as last synthetic formal
             args.append(types.elemtype(varargsTypeTo));
             Type mtype = types.createMethodTypeWithParameters(to.type, args.toList());
-            return new MethodSymbol(to.flags_field, to.name, mtype, to.owner);
+            return new MethodSymbol(to.flags_field & ~VARARGS, to.name, mtype, to.owner);
         } else {
             return to;
         }
--- a/test/tools/javac/types/BoxingConversionTest.java	Thu May 12 20:55:14 2011 -0700
+++ b/test/tools/javac/types/BoxingConversionTest.java	Fri May 20 20:04:23 2011 -0700
@@ -118,7 +118,6 @@
     static final Result T = Result.OK_BOTH;
     static final Result F = Result.FAIL_BOTH;
     static final Result A = Result.OK_ASSIGN_ONLY;
-    static final Result X = Result.FAIL_BOTH.FAIL_BOTH;
 
     Result[][] results1 = {
                    //byte, short, int, long, float, double, char, bool, Byte, Short, Integer, Long, Float, Double, Character, Boolean
--- a/test/tools/javac/types/CastTest.java	Thu May 12 20:55:14 2011 -0700
+++ b/test/tools/javac/types/CastTest.java	Fri May 20 20:04:23 2011 -0700
@@ -42,12 +42,13 @@
  */
 public class CastTest extends TypeHarness {
 
-    Type[] allTypes;
+    Type[] types_no_boxing;
+    Type[] types_boxing;
 
     static final boolean T = true;
     static final boolean F = false;
 
-    boolean[][] cast_result = {
+    boolean[][] cast_result_no_boxing = {
                 //byte, short, int, long, float, double, char, bool, C, +C, I, T, byte[], short[], int[], long[], float[], double[], char[], bool[], C[], +C[], I[], T[]
     /*byte*/    { T   , T    , T  , T   , T    , T     , T   , F   , F, F , F, F, F     , F      , F    , F     , F      , F       , F     , F     , F  , F   , F  , F },
     /*short*/   { T   , T    , T  , T   , T    , T     , T   , F   , F, F , F, F, F     , F      , F    , F     , F      , F       , F     , F     , F  , F   , F  , F },
@@ -74,6 +75,25 @@
     /*I[]*/     { F   , F    , F  , F   , F    , F     , F   , F   , F, F , F, T, F     , F      , F    , F     , F      , F       , F     , F     , T  , F   , T  , T },
     /*T[]*/     { F   , F    , F  , F   , F    , F     , F   , F   , F, F , F, T, F     , F      , F    , F     , F      , F       , F     , F     , T  , T   , T  , T }};
 
+    boolean[][] cast_result_boxing = {
+                   //byte, short, int, long, float, double, char, bool, Byte, Short, Integer, Long, Float, Double, Character, Boolean, Object
+    /*byte*/       { T   , T    , T  , T   , T    , T     , T   , F   , T   , F    , F      , F   , F    , F     , F        , F ,      T },
+    /*short*/      { T   , T    , T  , T   , T    , T     , T   , F   , F   , T    , F      , F   , F    , F     , F        , F ,      T  },
+    /*int*/        { T   , T    , T  , T   , T    , T     , T   , F   , F   , F    , T      , F   , F    , F     , F        , F ,      T  },
+    /*long*/       { T   , T    , T  , T   , T    , T     , T   , F   , F   , F    , F      , T   , F    , F     , F        , F ,      T  },
+    /*float*/      { T   , T    , T  , T   , T    , T     , T   , F   , F   , F    , F      , F   , T    , F     , F        , F ,      T  },
+    /*double*/     { T   , T    , T  , T   , T    , T     , T   , F   , F   , F    , F      , F   , F    , T     , F        , F ,      T  },
+    /*char*/       { T   , T    , T  , T   , T    , T     , T   , F   , F   , F    , F      , F   , F    , F     , T        , F ,      T  },
+    /*bool*/       { F   , F    , F  , F   , F    , F     , F   , T   , F   , F    , F      , F   , F    , F     , F        , T ,      T  },
+    /*Byte*/       { T   , T    , T  , T   , T    , T     , F   , F   , T   , F    , F      , F   , F    , F     , F        , F ,      T  },
+    /*Short*/      { F   , T    , T  , T   , T    , T     , F   , F   , F   , T    , F      , F   , F    , F     , F        , F ,      T  },
+    /*Integer*/    { F   , F    , T  , T   , T    , T     , F   , F   , F   , F    , T      , F   , F    , F     , F        , F ,      T  },
+    /*Long*/       { F   , F    , F  , T   , T    , T     , F   , F   , F   , F    , F      , T   , F    , F     , F        , F ,      T  },
+    /*Float*/      { F   , F    , F  , F   , T    , T     , F   , F   , F   , F    , F      , F   , T    , F     , F        , F ,      T  },
+    /*Double*/     { F   , F    , F  , F   , F    , T     , F   , F   , F   , F    , F      , F   , F    , T     , F        , F ,      T  },
+    /*Character*/  { F   , F    , T  , T   , T    , T     , T   , F   , F   , F    , F      , F   , F    , F     , T        , F ,      T  },
+    /*Boolean*/    { F   , F    , F  , F   , F    , F     , F   , T   , F   , F    , F      , F   , F    , F     , F        , T ,      T  },
+    /*Object*/     { T   , T    , T  , T   , T    , T     , T   , T   , T   , T    , T      , T   , T    , T     , T        , T ,      T  }};
     CastTest() {
         Type[] primitiveTypes = {
             predef.byteType,
@@ -85,6 +105,15 @@
             predef.charType,
             predef.booleanType };
 
+        Type[] boxedTypes = new Type[primitiveTypes.length + 1];
+        for (int i = 0 ; i < primitiveTypes.length ; i++) {
+            boxedTypes[i] = box(primitiveTypes[i]);
+        }
+
+        boxedTypes[primitiveTypes.length] = predef.objectType;
+
+        types_boxing = join(Type.class, primitiveTypes, boxedTypes);
+
         Type[] referenceTypes = {
             fac.Class(),
             fac.Class(FINAL),
@@ -97,17 +126,22 @@
             arrayTypes[idx++] = fac.Array(t);
         }
 
-        allTypes = join(Type.class, primitiveTypes, referenceTypes, arrayTypes);
+        types_no_boxing = join(Type.class, primitiveTypes, referenceTypes, arrayTypes);
     }
 
-    void test() {
-        for (int i = 0; i < allTypes.length ; i++) {
-            for (int j = 0; j < allTypes.length ; j++) {
-                assertCastable(allTypes[i], allTypes[j], cast_result[i][j]);
+    void test(Type[] all_types, boolean[][] cast_result) {
+        for (int i = 0; i < all_types.length ; i++) {
+            for (int j = 0; j < all_types.length ; j++) {
+                assertCastable(all_types[i], all_types[j], cast_result[i][j]);
             }
         }
     }
 
+    void runTests() {
+        test(types_no_boxing, cast_result_no_boxing);
+        test(types_boxing, cast_result_boxing);
+    }
+
     @SuppressWarnings("unchecked")
     <T> T[] join(Class<T> type, T[]... args) {
         int totalLength = 0;
@@ -124,6 +158,6 @@
     }
 
     public static void main(String[] args) {
-        new CastTest().test();
+        new CastTest().runTests();
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/varargs/7042566/T7042566.java	Fri May 20 20:04:23 2011 -0700
@@ -0,0 +1,350 @@
+/*
+ * 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 7042566
+ * @summary Unambiguous varargs method calls flagged as ambiguous
+ */
+
+import com.sun.source.util.JavacTask;
+import com.sun.tools.classfile.Instruction;
+import com.sun.tools.classfile.Attribute;
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.Code_attribute;
+import com.sun.tools.classfile.ConstantPool.*;
+import com.sun.tools.classfile.Method;
+import com.sun.tools.javac.api.JavacTool;
+import com.sun.tools.javac.util.List;
+
+import java.io.File;
+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 T7042566 {
+
+    VarargsMethod m1;
+    VarargsMethod m2;
+    TypeConfiguration actuals;
+
+    T7042566(TypeConfiguration m1_conf, TypeConfiguration m2_conf, TypeConfiguration actuals) {
+        this.m1 = new VarargsMethod(m1_conf);
+        this.m2 = new VarargsMethod(m2_conf);
+        this.actuals = actuals;
+    }
+
+    void compileAndCheck() throws Exception {
+        final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
+        JavaSource source = new JavaSource();
+        ErrorChecker ec = new ErrorChecker();
+        JavacTask ct = (JavacTask)tool.getTask(null, fm, ec,
+                null, null, Arrays.asList(source));
+        ct.call();
+        check(source, ec);
+    }
+
+    void check(JavaSource source, ErrorChecker ec) {
+        checkCount++;
+        boolean resolutionError = false;
+        VarargsMethod selectedMethod = null;
+
+        boolean m1_applicable = m1.isApplicable(actuals);
+        boolean m2_applicable = m2.isApplicable(actuals);
+
+        if (!m1_applicable && !m2_applicable) {
+            resolutionError = true;
+        } else if (m1_applicable && m2_applicable) {
+            //most specific
+            boolean m1_moreSpecific = m1.isMoreSpecificThan(m2);
+            boolean m2_moreSpecific = m2.isMoreSpecificThan(m1);
+
+            resolutionError = m1_moreSpecific == m2_moreSpecific;
+            selectedMethod = m1_moreSpecific ? m1 : m2;
+        } else {
+            selectedMethod = m1_applicable ?
+                m1 : m2;
+        }
+
+        if (ec.errorFound != resolutionError) {
+            throw new Error("invalid diagnostics for source:\n" +
+                    source.getCharContent(true) +
+                    "\nExpected resolution error: " + resolutionError +
+                    "\nFound error: " + ec.errorFound +
+                    "\nCompiler diagnostics:\n" + ec.printDiags());
+        } else if (!resolutionError) {
+            verifyBytecode(selectedMethod, source);
+        }
+    }
+
+    void verifyBytecode(VarargsMethod selected, JavaSource source) {
+        bytecodeCheckCount++;
+        File compiledTest = new File("Test.class");
+        try {
+            ClassFile cf = ClassFile.read(compiledTest);
+            Method testMethod = null;
+            for (Method m : cf.methods) {
+                if (m.getName(cf.constant_pool).equals("test")) {
+                    testMethod = m;
+                    break;
+                }
+            }
+            if (testMethod == null) {
+                throw new Error("Test method not found");
+            }
+            Code_attribute ea = (Code_attribute)testMethod.attributes.get(Attribute.Code);
+            if (testMethod == null) {
+                throw new Error("Code attribute for test() method not found");
+            }
+
+            for (Instruction i : ea.getInstructions()) {
+                if (i.getMnemonic().equals("invokevirtual")) {
+                    int cp_entry = i.getUnsignedShort(1);
+                    CONSTANT_Methodref_info methRef =
+                            (CONSTANT_Methodref_info)cf.constant_pool.get(cp_entry);
+                    String type = methRef.getNameAndTypeInfo().getType();
+                    String sig = selected.parameterTypes.bytecodeSigStr;
+                    if (!type.contains(sig)) {
+                        throw new Error("Unexpected type method call: " + type + "" +
+                                        "\nfound: " + sig +
+                                        "\n" + source.getCharContent(true));
+                    }
+                    break;
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new Error("error reading " + compiledTest +": " + e);
+        }
+    }
+
+    class JavaSource extends SimpleJavaFileObject {
+
+        static final String source_template = "class Test {\n" +
+                "   #V1\n" +
+                "   #V2\n" +
+                "   void test() { m(#E); }\n" +
+                "}";
+
+        String source;
+
+        public JavaSource() {
+            super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
+            source = source_template.replaceAll("#V1", m1.toString()).
+                    replaceAll("#V2", m2.toString()).
+                    replaceAll("#E", actuals.expressionListStr);
+        }
+
+        @Override
+        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
+            return source;
+        }
+    }
+
+    /** global decls ***/
+
+    // Create a single file manager and reuse it for each compile to save time.
+    static StandardJavaFileManager fm = JavacTool.create().getStandardFileManager(null, null, null);
+
+    //statistics
+    static int checkCount = 0;
+    static int bytecodeCheckCount = 0;
+
+    public static void main(String... args) throws Exception {
+        for (TypeConfiguration tconf1 : TypeConfiguration.values()) {
+            for (TypeConfiguration tconf2 : TypeConfiguration.values()) {
+                for (TypeConfiguration tconf3 : TypeConfiguration.values()) {
+                    new T7042566(tconf1, tconf2, tconf3).compileAndCheck();
+                }
+            }
+        }
+
+        System.out.println("Total checks made: " + checkCount);
+        System.out.println("Bytecode checks made: " + bytecodeCheckCount);
+    }
+
+    enum TypeKind {
+        OBJECT("Object", "(Object)null", "Ljava/lang/Object;"),
+        STRING("String", "(String)null", "Ljava/lang/String;");
+
+        String typeString;
+        String valueString;
+        String bytecodeString;
+
+        TypeKind(String typeString, String valueString, String bytecodeString) {
+            this.typeString = typeString;
+            this.valueString = valueString;
+            this.bytecodeString = bytecodeString;
+        }
+
+        boolean isSubtypeOf(TypeKind that) {
+            return that == OBJECT ||
+                    (that == STRING && this == STRING);
+        }
+    }
+
+    enum TypeConfiguration {
+        A(TypeKind.OBJECT),
+        B(TypeKind.STRING),
+        AA(TypeKind.OBJECT, TypeKind.OBJECT),
+        AB(TypeKind.OBJECT, TypeKind.STRING),
+        BA(TypeKind.STRING, TypeKind.OBJECT),
+        BB(TypeKind.STRING, TypeKind.STRING),
+        AAA(TypeKind.OBJECT, TypeKind.OBJECT, TypeKind.OBJECT),
+        AAB(TypeKind.OBJECT, TypeKind.OBJECT, TypeKind.STRING),
+        ABA(TypeKind.OBJECT, TypeKind.STRING, TypeKind.OBJECT),
+        ABB(TypeKind.OBJECT, TypeKind.STRING, TypeKind.STRING),
+        BAA(TypeKind.STRING, TypeKind.OBJECT, TypeKind.OBJECT),
+        BAB(TypeKind.STRING, TypeKind.OBJECT, TypeKind.STRING),
+        BBA(TypeKind.STRING, TypeKind.STRING, TypeKind.OBJECT),
+        BBB(TypeKind.STRING, TypeKind.STRING, TypeKind.STRING);
+
+        List<TypeKind> typeKindList;
+        String expressionListStr;
+        String parameterListStr;
+        String bytecodeSigStr;
+
+        private TypeConfiguration(TypeKind... typeKindList) {
+            this.typeKindList = List.from(typeKindList);
+            expressionListStr = asExpressionList();
+            parameterListStr = asParameterList();
+            bytecodeSigStr = asBytecodeString();
+        }
+
+        private String asExpressionList() {
+            StringBuilder buf = new StringBuilder();
+            String sep = "";
+            for (TypeKind tk : typeKindList) {
+                buf.append(sep);
+                buf.append(tk.valueString);
+                sep = ",";
+            }
+            return buf.toString();
+        }
+
+        private String asParameterList() {
+            StringBuilder buf = new StringBuilder();
+            String sep = "";
+            int count = 0;
+            for (TypeKind arg : typeKindList) {
+                buf.append(sep);
+                buf.append(arg.typeString);
+                if (count == (typeKindList.size() - 1)) {
+                    buf.append("...");
+                }
+                buf.append(" ");
+                buf.append("arg" + count++);
+                sep = ",";
+            }
+            return buf.toString();
+        }
+
+        private String asBytecodeString() {
+            StringBuilder buf = new StringBuilder();
+            int count = 0;
+            for (TypeKind arg : typeKindList) {
+                if (count == (typeKindList.size() - 1)) {
+                    buf.append("[");
+                }
+                buf.append(arg.bytecodeString);
+                count++;
+            }
+            return buf.toString();
+        }
+    }
+
+    static class VarargsMethod {
+        TypeConfiguration parameterTypes;
+
+        public VarargsMethod(TypeConfiguration parameterTypes) {
+            this.parameterTypes = parameterTypes;
+        }
+
+        @Override
+        public String toString() {
+            return "void m( " + parameterTypes.parameterListStr + ") {}";
+        }
+
+        boolean isApplicable(TypeConfiguration that) {
+            List<TypeKind> actuals = that.typeKindList;
+            List<TypeKind> formals = parameterTypes.typeKindList;
+            if ((actuals.size() - formals.size()) < -1)
+                return false; //not enough args
+            for (TypeKind actual : actuals) {
+                if (!actual.isSubtypeOf(formals.head))
+                    return false; //type mismatch
+                formals = formals.tail.isEmpty() ?
+                    formals :
+                    formals.tail;
+            }
+            return true;
+        }
+
+        boolean isMoreSpecificThan(VarargsMethod that) {
+            List<TypeKind> actuals = parameterTypes.typeKindList;
+            List<TypeKind> formals = that.parameterTypes.typeKindList;
+            int checks = 0;
+            int expectedCheck = Math.max(actuals.size(), formals.size());
+            while (checks < expectedCheck) {
+                if (!actuals.head.isSubtypeOf(formals.head))
+                    return false; //type mismatch
+                formals = formals.tail.isEmpty() ?
+                    formals :
+                    formals.tail;
+                actuals = actuals.tail.isEmpty() ?
+                    actuals :
+                    actuals.tail;
+                checks++;
+            }
+            return true;
+        }
+    }
+
+    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();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/varargs/7043922/T7043922.java	Fri May 20 20:04:23 2011 -0700
@@ -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();
+        }
+    }
+}