test/tools/javac/varargs/7042566/T7042566.java

Wed, 23 Jan 2013 20:57:40 +0000

author
vromero
date
Wed, 23 Jan 2013 20:57:40 +0000
changeset 1520
5c956be64b9e
parent 1482
954541f13717
child 2525
2eb010b6cb22
permissions
-rw-r--r--

8006694: temporarily workaround combo tests are causing time out in several platforms
Reviewed-by: jjg
Contributed-by: maurizio.cimadamore@oracle.com

mcimadamore@1006 1 /*
vromero@1482 2 * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
mcimadamore@1006 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
mcimadamore@1006 4 *
mcimadamore@1006 5 * This code is free software; you can redistribute it and/or modify it
mcimadamore@1006 6 * under the terms of the GNU General Public License version 2 only, as
mcimadamore@1006 7 * published by the Free Software Foundation.
mcimadamore@1006 8 *
mcimadamore@1006 9 * This code is distributed in the hope that it will be useful, but WITHOUT
mcimadamore@1006 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
mcimadamore@1006 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
mcimadamore@1006 12 * version 2 for more details (a copy is included in the LICENSE file that
mcimadamore@1006 13 * accompanied this code).
mcimadamore@1006 14 *
mcimadamore@1006 15 * You should have received a copy of the GNU General Public License version
mcimadamore@1006 16 * 2 along with this work; if not, write to the Free Software Foundation,
mcimadamore@1006 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
mcimadamore@1006 18 *
mcimadamore@1006 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
mcimadamore@1006 20 * or visit www.oracle.com if you need additional information or have any
mcimadamore@1006 21 * questions.
mcimadamore@1006 22 */
mcimadamore@1006 23
mcimadamore@1006 24 /*
mcimadamore@1006 25 * @test
vromero@1520 26 * @bug 7042566 8006694
mcimadamore@1006 27 * @summary Unambiguous varargs method calls flagged as ambiguous
vromero@1520 28 * temporarily workaround combo tests are causing time out in several platforms
vromero@1482 29 * @library ../../lib
vromero@1482 30 * @build JavacTestingAbstractThreadedTest
vromero@1520 31 * @run main/othervm T7042566
mcimadamore@1006 32 */
mcimadamore@1006 33
vromero@1520 34 // use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047)
vromero@1520 35 // see JDK-8006746
vromero@1520 36
vromero@1482 37 import java.io.File;
vromero@1482 38 import java.net.URI;
vromero@1482 39 import java.util.Arrays;
vromero@1482 40 import java.util.Locale;
vromero@1482 41 import java.util.concurrent.atomic.AtomicInteger;
vromero@1482 42 import javax.tools.Diagnostic;
vromero@1482 43 import javax.tools.JavaCompiler;
vromero@1482 44 import javax.tools.JavaFileObject;
vromero@1482 45 import javax.tools.SimpleJavaFileObject;
vromero@1482 46 import javax.tools.ToolProvider;
vromero@1482 47
mcimadamore@1006 48 import com.sun.source.util.JavacTask;
mcimadamore@1006 49 import com.sun.tools.classfile.Instruction;
mcimadamore@1006 50 import com.sun.tools.classfile.Attribute;
mcimadamore@1006 51 import com.sun.tools.classfile.ClassFile;
mcimadamore@1006 52 import com.sun.tools.classfile.Code_attribute;
mcimadamore@1006 53 import com.sun.tools.classfile.ConstantPool.*;
mcimadamore@1006 54 import com.sun.tools.classfile.Method;
mcimadamore@1006 55 import com.sun.tools.javac.util.List;
mcimadamore@1006 56
vromero@1482 57 public class T7042566
vromero@1482 58 extends JavacTestingAbstractThreadedTest
vromero@1482 59 implements Runnable {
mcimadamore@1006 60
mcimadamore@1006 61 VarargsMethod m1;
mcimadamore@1006 62 VarargsMethod m2;
mcimadamore@1006 63 TypeConfiguration actuals;
mcimadamore@1006 64
vromero@1482 65 T7042566(TypeConfiguration m1_conf, TypeConfiguration m2_conf,
vromero@1482 66 TypeConfiguration actuals) {
mcimadamore@1006 67 this.m1 = new VarargsMethod(m1_conf);
mcimadamore@1006 68 this.m2 = new VarargsMethod(m2_conf);
mcimadamore@1006 69 this.actuals = actuals;
mcimadamore@1006 70 }
mcimadamore@1006 71
vromero@1482 72 @Override
vromero@1482 73 public void run() {
vromero@1482 74 int id = checkCount.incrementAndGet();
mcimadamore@1006 75 final JavaCompiler tool = ToolProvider.getSystemJavaCompiler();
vromero@1482 76 JavaSource source = new JavaSource(id);
mcimadamore@1006 77 ErrorChecker ec = new ErrorChecker();
vromero@1482 78 JavacTask ct = (JavacTask)tool.getTask(null, fm.get(), ec,
mcimadamore@1006 79 null, null, Arrays.asList(source));
mcimadamore@1006 80 ct.call();
vromero@1482 81 check(source, ec, id);
mcimadamore@1006 82 }
mcimadamore@1006 83
vromero@1482 84 void check(JavaSource source, ErrorChecker ec, int id) {
mcimadamore@1006 85 boolean resolutionError = false;
mcimadamore@1006 86 VarargsMethod selectedMethod = null;
mcimadamore@1006 87
mcimadamore@1006 88 boolean m1_applicable = m1.isApplicable(actuals);
mcimadamore@1006 89 boolean m2_applicable = m2.isApplicable(actuals);
mcimadamore@1006 90
mcimadamore@1006 91 if (!m1_applicable && !m2_applicable) {
mcimadamore@1006 92 resolutionError = true;
mcimadamore@1006 93 } else if (m1_applicable && m2_applicable) {
mcimadamore@1006 94 //most specific
mcimadamore@1006 95 boolean m1_moreSpecific = m1.isMoreSpecificThan(m2);
mcimadamore@1006 96 boolean m2_moreSpecific = m2.isMoreSpecificThan(m1);
mcimadamore@1006 97
mcimadamore@1006 98 resolutionError = m1_moreSpecific == m2_moreSpecific;
mcimadamore@1006 99 selectedMethod = m1_moreSpecific ? m1 : m2;
mcimadamore@1006 100 } else {
mcimadamore@1006 101 selectedMethod = m1_applicable ?
mcimadamore@1006 102 m1 : m2;
mcimadamore@1006 103 }
mcimadamore@1006 104
mcimadamore@1006 105 if (ec.errorFound != resolutionError) {
mcimadamore@1006 106 throw new Error("invalid diagnostics for source:\n" +
mcimadamore@1006 107 source.getCharContent(true) +
mcimadamore@1006 108 "\nExpected resolution error: " + resolutionError +
mcimadamore@1006 109 "\nFound error: " + ec.errorFound +
mcimadamore@1006 110 "\nCompiler diagnostics:\n" + ec.printDiags());
mcimadamore@1006 111 } else if (!resolutionError) {
vromero@1482 112 verifyBytecode(selectedMethod, source, id);
mcimadamore@1006 113 }
mcimadamore@1006 114 }
mcimadamore@1006 115
vromero@1482 116 void verifyBytecode(VarargsMethod selected, JavaSource source, int id) {
vromero@1482 117 bytecodeCheckCount.incrementAndGet();
vromero@1482 118 File compiledTest = new File(String.format("Test%d.class", id));
mcimadamore@1006 119 try {
mcimadamore@1006 120 ClassFile cf = ClassFile.read(compiledTest);
mcimadamore@1006 121 Method testMethod = null;
mcimadamore@1006 122 for (Method m : cf.methods) {
mcimadamore@1006 123 if (m.getName(cf.constant_pool).equals("test")) {
mcimadamore@1006 124 testMethod = m;
mcimadamore@1006 125 break;
mcimadamore@1006 126 }
mcimadamore@1006 127 }
mcimadamore@1006 128 if (testMethod == null) {
mcimadamore@1006 129 throw new Error("Test method not found");
mcimadamore@1006 130 }
vromero@1482 131 Code_attribute ea =
vromero@1482 132 (Code_attribute)testMethod.attributes.get(Attribute.Code);
mcimadamore@1006 133 if (testMethod == null) {
mcimadamore@1006 134 throw new Error("Code attribute for test() method not found");
mcimadamore@1006 135 }
mcimadamore@1006 136
mcimadamore@1006 137 for (Instruction i : ea.getInstructions()) {
mcimadamore@1006 138 if (i.getMnemonic().equals("invokevirtual")) {
mcimadamore@1006 139 int cp_entry = i.getUnsignedShort(1);
mcimadamore@1006 140 CONSTANT_Methodref_info methRef =
vromero@1482 141 (CONSTANT_Methodref_info)cf.constant_pool.get(cp_entry);
mcimadamore@1006 142 String type = methRef.getNameAndTypeInfo().getType();
mcimadamore@1006 143 String sig = selected.parameterTypes.bytecodeSigStr;
mcimadamore@1006 144 if (!type.contains(sig)) {
vromero@1482 145 throw new Error("Unexpected type method call: " +
vromero@1482 146 type + "" +
mcimadamore@1006 147 "\nfound: " + sig +
mcimadamore@1006 148 "\n" + source.getCharContent(true));
mcimadamore@1006 149 }
mcimadamore@1006 150 break;
mcimadamore@1006 151 }
mcimadamore@1006 152 }
mcimadamore@1006 153 } catch (Exception e) {
mcimadamore@1006 154 e.printStackTrace();
mcimadamore@1006 155 throw new Error("error reading " + compiledTest +": " + e);
mcimadamore@1006 156 }
mcimadamore@1006 157 }
mcimadamore@1006 158
mcimadamore@1006 159 class JavaSource extends SimpleJavaFileObject {
mcimadamore@1006 160
vromero@1482 161 static final String source_template = "class Test#ID {\n" +
mcimadamore@1006 162 " #V1\n" +
mcimadamore@1006 163 " #V2\n" +
mcimadamore@1006 164 " void test() { m(#E); }\n" +
mcimadamore@1006 165 "}";
mcimadamore@1006 166
mcimadamore@1006 167 String source;
mcimadamore@1006 168
vromero@1482 169 public JavaSource(int id) {
vromero@1482 170 super(URI.create(String.format("myfo:/Test%d.java", id)),
vromero@1482 171 JavaFileObject.Kind.SOURCE);
vromero@1482 172 source = source_template.replaceAll("#V1", m1.toString())
vromero@1482 173 .replaceAll("#V2", m2.toString())
vromero@1482 174 .replaceAll("#E", actuals.expressionListStr)
vromero@1482 175 .replaceAll("#ID", String.valueOf(id));
mcimadamore@1006 176 }
mcimadamore@1006 177
mcimadamore@1006 178 @Override
mcimadamore@1006 179 public CharSequence getCharContent(boolean ignoreEncodingErrors) {
mcimadamore@1006 180 return source;
mcimadamore@1006 181 }
mcimadamore@1006 182 }
mcimadamore@1006 183
mcimadamore@1006 184 public static void main(String... args) throws Exception {
mcimadamore@1006 185 for (TypeConfiguration tconf1 : TypeConfiguration.values()) {
mcimadamore@1006 186 for (TypeConfiguration tconf2 : TypeConfiguration.values()) {
mcimadamore@1006 187 for (TypeConfiguration tconf3 : TypeConfiguration.values()) {
vromero@1482 188 pool.execute(new T7042566(tconf1, tconf2, tconf3));
mcimadamore@1006 189 }
mcimadamore@1006 190 }
mcimadamore@1006 191 }
mcimadamore@1006 192
vromero@1482 193 outWriter.println("Bytecode checks made: " + bytecodeCheckCount.get());
vromero@1482 194 checkAfterExec();
mcimadamore@1006 195 }
mcimadamore@1006 196
mcimadamore@1006 197 enum TypeKind {
mcimadamore@1006 198 OBJECT("Object", "(Object)null", "Ljava/lang/Object;"),
mcimadamore@1006 199 STRING("String", "(String)null", "Ljava/lang/String;");
mcimadamore@1006 200
mcimadamore@1006 201 String typeString;
mcimadamore@1006 202 String valueString;
mcimadamore@1006 203 String bytecodeString;
mcimadamore@1006 204
mcimadamore@1006 205 TypeKind(String typeString, String valueString, String bytecodeString) {
mcimadamore@1006 206 this.typeString = typeString;
mcimadamore@1006 207 this.valueString = valueString;
mcimadamore@1006 208 this.bytecodeString = bytecodeString;
mcimadamore@1006 209 }
mcimadamore@1006 210
mcimadamore@1006 211 boolean isSubtypeOf(TypeKind that) {
mcimadamore@1006 212 return that == OBJECT ||
mcimadamore@1006 213 (that == STRING && this == STRING);
mcimadamore@1006 214 }
mcimadamore@1006 215 }
mcimadamore@1006 216
mcimadamore@1006 217 enum TypeConfiguration {
mcimadamore@1006 218 A(TypeKind.OBJECT),
mcimadamore@1006 219 B(TypeKind.STRING),
mcimadamore@1006 220 AA(TypeKind.OBJECT, TypeKind.OBJECT),
mcimadamore@1006 221 AB(TypeKind.OBJECT, TypeKind.STRING),
mcimadamore@1006 222 BA(TypeKind.STRING, TypeKind.OBJECT),
mcimadamore@1006 223 BB(TypeKind.STRING, TypeKind.STRING),
mcimadamore@1006 224 AAA(TypeKind.OBJECT, TypeKind.OBJECT, TypeKind.OBJECT),
mcimadamore@1006 225 AAB(TypeKind.OBJECT, TypeKind.OBJECT, TypeKind.STRING),
mcimadamore@1006 226 ABA(TypeKind.OBJECT, TypeKind.STRING, TypeKind.OBJECT),
mcimadamore@1006 227 ABB(TypeKind.OBJECT, TypeKind.STRING, TypeKind.STRING),
mcimadamore@1006 228 BAA(TypeKind.STRING, TypeKind.OBJECT, TypeKind.OBJECT),
mcimadamore@1006 229 BAB(TypeKind.STRING, TypeKind.OBJECT, TypeKind.STRING),
mcimadamore@1006 230 BBA(TypeKind.STRING, TypeKind.STRING, TypeKind.OBJECT),
mcimadamore@1006 231 BBB(TypeKind.STRING, TypeKind.STRING, TypeKind.STRING);
mcimadamore@1006 232
mcimadamore@1006 233 List<TypeKind> typeKindList;
mcimadamore@1006 234 String expressionListStr;
mcimadamore@1006 235 String parameterListStr;
mcimadamore@1006 236 String bytecodeSigStr;
mcimadamore@1006 237
mcimadamore@1006 238 private TypeConfiguration(TypeKind... typeKindList) {
mcimadamore@1006 239 this.typeKindList = List.from(typeKindList);
mcimadamore@1006 240 expressionListStr = asExpressionList();
mcimadamore@1006 241 parameterListStr = asParameterList();
mcimadamore@1006 242 bytecodeSigStr = asBytecodeString();
mcimadamore@1006 243 }
mcimadamore@1006 244
mcimadamore@1006 245 private String asExpressionList() {
mcimadamore@1006 246 StringBuilder buf = new StringBuilder();
mcimadamore@1006 247 String sep = "";
mcimadamore@1006 248 for (TypeKind tk : typeKindList) {
mcimadamore@1006 249 buf.append(sep);
mcimadamore@1006 250 buf.append(tk.valueString);
mcimadamore@1006 251 sep = ",";
mcimadamore@1006 252 }
mcimadamore@1006 253 return buf.toString();
mcimadamore@1006 254 }
mcimadamore@1006 255
mcimadamore@1006 256 private String asParameterList() {
mcimadamore@1006 257 StringBuilder buf = new StringBuilder();
mcimadamore@1006 258 String sep = "";
mcimadamore@1006 259 int count = 0;
mcimadamore@1006 260 for (TypeKind arg : typeKindList) {
mcimadamore@1006 261 buf.append(sep);
mcimadamore@1006 262 buf.append(arg.typeString);
mcimadamore@1006 263 if (count == (typeKindList.size() - 1)) {
mcimadamore@1006 264 buf.append("...");
mcimadamore@1006 265 }
mcimadamore@1006 266 buf.append(" ");
mcimadamore@1006 267 buf.append("arg" + count++);
mcimadamore@1006 268 sep = ",";
mcimadamore@1006 269 }
mcimadamore@1006 270 return buf.toString();
mcimadamore@1006 271 }
mcimadamore@1006 272
mcimadamore@1006 273 private String asBytecodeString() {
mcimadamore@1006 274 StringBuilder buf = new StringBuilder();
mcimadamore@1006 275 int count = 0;
mcimadamore@1006 276 for (TypeKind arg : typeKindList) {
mcimadamore@1006 277 if (count == (typeKindList.size() - 1)) {
mcimadamore@1006 278 buf.append("[");
mcimadamore@1006 279 }
mcimadamore@1006 280 buf.append(arg.bytecodeString);
mcimadamore@1006 281 count++;
mcimadamore@1006 282 }
mcimadamore@1006 283 return buf.toString();
mcimadamore@1006 284 }
mcimadamore@1006 285 }
mcimadamore@1006 286
mcimadamore@1006 287 static class VarargsMethod {
mcimadamore@1006 288 TypeConfiguration parameterTypes;
mcimadamore@1006 289
mcimadamore@1006 290 public VarargsMethod(TypeConfiguration parameterTypes) {
mcimadamore@1006 291 this.parameterTypes = parameterTypes;
mcimadamore@1006 292 }
mcimadamore@1006 293
mcimadamore@1006 294 @Override
mcimadamore@1006 295 public String toString() {
mcimadamore@1006 296 return "void m( " + parameterTypes.parameterListStr + ") {}";
mcimadamore@1006 297 }
mcimadamore@1006 298
mcimadamore@1006 299 boolean isApplicable(TypeConfiguration that) {
mcimadamore@1006 300 List<TypeKind> actuals = that.typeKindList;
mcimadamore@1006 301 List<TypeKind> formals = parameterTypes.typeKindList;
mcimadamore@1006 302 if ((actuals.size() - formals.size()) < -1)
mcimadamore@1006 303 return false; //not enough args
mcimadamore@1006 304 for (TypeKind actual : actuals) {
mcimadamore@1006 305 if (!actual.isSubtypeOf(formals.head))
mcimadamore@1006 306 return false; //type mismatch
mcimadamore@1006 307 formals = formals.tail.isEmpty() ?
mcimadamore@1006 308 formals :
mcimadamore@1006 309 formals.tail;
mcimadamore@1006 310 }
mcimadamore@1006 311 return true;
mcimadamore@1006 312 }
mcimadamore@1006 313
mcimadamore@1006 314 boolean isMoreSpecificThan(VarargsMethod that) {
mcimadamore@1006 315 List<TypeKind> actuals = parameterTypes.typeKindList;
mcimadamore@1006 316 List<TypeKind> formals = that.parameterTypes.typeKindList;
mcimadamore@1006 317 int checks = 0;
mcimadamore@1006 318 int expectedCheck = Math.max(actuals.size(), formals.size());
mcimadamore@1006 319 while (checks < expectedCheck) {
mcimadamore@1006 320 if (!actuals.head.isSubtypeOf(formals.head))
mcimadamore@1006 321 return false; //type mismatch
mcimadamore@1006 322 formals = formals.tail.isEmpty() ?
mcimadamore@1006 323 formals :
mcimadamore@1006 324 formals.tail;
mcimadamore@1006 325 actuals = actuals.tail.isEmpty() ?
mcimadamore@1006 326 actuals :
mcimadamore@1006 327 actuals.tail;
mcimadamore@1006 328 checks++;
mcimadamore@1006 329 }
mcimadamore@1006 330 return true;
mcimadamore@1006 331 }
mcimadamore@1006 332 }
mcimadamore@1006 333
vromero@1482 334 static class ErrorChecker
vromero@1482 335 implements javax.tools.DiagnosticListener<JavaFileObject> {
mcimadamore@1006 336
mcimadamore@1006 337 boolean errorFound;
mcimadamore@1006 338 List<String> errDiags = List.nil();
mcimadamore@1006 339
mcimadamore@1006 340 public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
mcimadamore@1006 341 if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
vromero@1482 342 errDiags = errDiags
vromero@1482 343 .append(diagnostic.getMessage(Locale.getDefault()));
mcimadamore@1006 344 errorFound = true;
mcimadamore@1006 345 }
mcimadamore@1006 346 }
mcimadamore@1006 347
mcimadamore@1006 348 String printDiags() {
mcimadamore@1006 349 StringBuilder buf = new StringBuilder();
mcimadamore@1006 350 for (String s : errDiags) {
mcimadamore@1006 351 buf.append(s);
mcimadamore@1006 352 buf.append("\n");
mcimadamore@1006 353 }
mcimadamore@1006 354 return buf.toString();
mcimadamore@1006 355 }
mcimadamore@1006 356 }
vromero@1482 357
vromero@1482 358 //number of bytecode checks made while running combo tests
vromero@1482 359 static AtomicInteger bytecodeCheckCount = new AtomicInteger();
vromero@1482 360
mcimadamore@1006 361 }

mercurial