1 /* 2 * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 package vm.runtime.defmeth; 25 26 import nsk.share.test.TestBase; 27 import vm.runtime.defmeth.shared.DefMethTest; 28 import vm.runtime.defmeth.shared.annotation.KnownFailure; 29 import vm.runtime.defmeth.shared.annotation.NotApplicableFor; 30 import vm.runtime.defmeth.shared.data.*; 31 import static vm.runtime.defmeth.shared.data.method.body.CallMethod.Invoke.*; 32 import static vm.runtime.defmeth.shared.data.method.body.CallMethod.IndexbyteOp.*; 33 import vm.runtime.defmeth.shared.builder.TestBuilder; 34 import static vm.runtime.defmeth.shared.ExecutionMode.*; 35 36 /** 37 * Tests on conflicting defaults. 38 * 39 * It is allowable to inherit a default through multiple paths (such as 40 * through a diamond-shaped interface hierarchy), but the resolution procedure 41 * is looking for a unique, most specific default-providing interface. 42 * 43 * If one default shadows another (where a subinterface provides a different 44 * default for an extension method declared in a superinterface), then the less 45 * specific interface is pruned from consideration no matter where it appears 46 * in the inheritance hierarchy. If two or more extended interfaces provide 47 * default implementations, and one is not a superinterface of the other, then 48 * neither is used and a linkage exception is thrown indicating conflicting 49 * default implementations. 50 */ 51 public class ConflictingDefaultsTest extends DefMethTest { main(String[] args)52 public static void main(String[] args) { 53 TestBase.runTest(new ConflictingDefaultsTest(), args); 54 } 55 56 /* 57 * Conflict 58 * 59 * interface I { int m() default { return 1; } } 60 * interface J { int m() default { return 2; } } 61 * class C implements I, J {} 62 * 63 * TEST: C c = new C(); c.m() ==> ICCE 64 */ testConflict()65 public void testConflict() { 66 TestBuilder b = factory.getBuilder(); 67 68 Interface I = b.intf("I") 69 .defaultMethod("m", "()I").returns(1).build() 70 .build(); 71 72 Interface J = b.intf("J") 73 .defaultMethod("m", "()I").returns(2).build() 74 .build(); 75 76 ConcreteClass C = b.clazz("C").implement(I,J).build(); 77 78 b.test().callSite(C, C, "m","()I") 79 .throws_(IncompatibleClassChangeError.class) 80 .done() 81 82 .run(); 83 } 84 85 /* 86 * Maximally-specific Default (0.6.3 spec change) 87 * 88 * interface I { int m(); } 89 * interface J { int m() default { return 2; } } 90 * class C implements I, J {} 91 * 92 * TEST: C c = new C(); c.m() return 2 93 */ testMaximallySpecificDefault()94 public void testMaximallySpecificDefault() { 95 TestBuilder b = factory.getBuilder(); 96 97 Interface I = b.intf("I") 98 .abstractMethod("m", "()I").build() 99 .build(); 100 101 Interface J = b.intf("J") 102 .defaultMethod("m", "()I").returns(2).build() 103 .build(); 104 105 ConcreteClass C = b.clazz("C").implement(I,J).build(); 106 107 b.test().callSite(C, C, "m","()I") 108 .returns(2) 109 .done() 110 111 .run(); 112 } 113 114 /* 115 * Reabstract 116 * 117 * interface I { int m() default { return 1; } } 118 * interface J extends I { int m(); } 119 * class C implements J {} 120 * 121 * TEST: C c = new C(); c.m() ==> AME 122 */ testReabstract()123 public void testReabstract() { 124 TestBuilder b = factory.getBuilder(); 125 126 Interface I = b.intf("I") 127 .defaultMethod("m", "()I").returns(1).build() 128 .build(); 129 130 Interface J = b.intf("J").extend(I) 131 .abstractMethod("m", "()I").build() 132 .build(); 133 134 ConcreteClass C = b.clazz("C").implement(J).build(); 135 136 b.test().callSite(C, C, "m","()I") 137 .throws_(AbstractMethodError.class) 138 .done() 139 140 .run(); 141 } 142 143 /* 144 * Reabstract2 145 * 146 * interface I { int m() default { return 1; } } 147 * interface J extends I { int m(); } 148 * class C implements J {} 149 * class D extends C { callSuper C.m} 150 * 151 * TEST: C c = new C(); c.m() ==> AME 152 * TEST: J j = new C(); j.m() ==> AME 153 * TEST: I i = new C(); i.m() ==> AME 154 * TEST: D d = new D(); d.m() ==> callSuper C.m ==> AME 155 */ testReabstract2()156 public void testReabstract2() { 157 TestBuilder b = factory.getBuilder(); 158 159 Interface I = b.intf("I") 160 .defaultMethod("m", "()I").returns(1).build() 161 .build(); 162 163 Interface J = b.intf("J").extend(I) 164 .abstractMethod("m", "()I").build() 165 .build(); 166 167 ConcreteClass C = b.clazz("C").implement(J).build(); 168 ConcreteClass D = b.clazz("D").extend(C) 169 .concreteMethod("m", "()I").callSuper(C, "m", "()I").build() 170 .build(); 171 172 b.test().callSite(C, C, "m","()I") 173 .throws_(AbstractMethodError.class) 174 .done() 175 .test().callSite(J, C, "m","()I") 176 .throws_(AbstractMethodError.class) 177 .done() 178 .test().callSite(I, C, "m","()I") 179 .throws_(AbstractMethodError.class) 180 .done() 181 .test().callSite(D, D, "m","()I") 182 .throws_(AbstractMethodError.class) 183 .done() 184 185 .run(); 186 } 187 188 /* 189 * ReabstractConflictingDefaults 190 * 191 * interface I { int m() default { return 1; } } 192 * interface J { int m() default { return 2; } } 193 * interface K extends I,J { int m(); } 194 * class A implements I,J {} 195 * class C extends A implements K {} 196 * 197 * TEST: A c = new C(); c.m() ==> AME 198 */ testReabstractConflictingDefaults()199 public void testReabstractConflictingDefaults() { 200 TestBuilder b = factory.getBuilder(); 201 202 Interface I = b.intf("I") 203 .defaultMethod("m", "()I").returns(1).build() 204 .build(); 205 206 Interface J = b.intf("J") 207 .defaultMethod("m", "()I").returns(2).build() 208 .build(); 209 210 Interface K = b.intf("K").extend(I,J) 211 .abstractMethod("m", "()I").build() 212 .build(); 213 214 ConcreteClass A = b.clazz("A").implement(I,J).build(); 215 ConcreteClass C = b.clazz("C").extend(A).implement(K).build(); 216 217 b.test().callSite(A, C, "m","()I") 218 .throws_(AbstractMethodError.class) 219 .done() 220 221 .run(); 222 } 223 224 225 /* 226 * ReabstractConflictingDefaultsInvokeInterface 227 * 228 * interface I { int m() default { return 1; } } 229 * interface J { int m() default { return 2; } } 230 * interface K extends I,J { int m(); } 231 * interface L extends K { } 232 * class A implements I,J {} 233 * class C extends A implements K {} 234 * class D extends C implements L {} 235 * 236 * TEST: I i = new A(); i.m() ==> ICCE 237 * TEST: K k = new C(); k.m() ==> AME 238 * TEST: L l = new D(); l.m() ==> AME 239 */ testReabstractConflictingDefaultsInvokeInterface()240 public void testReabstractConflictingDefaultsInvokeInterface() { 241 TestBuilder b = factory.getBuilder(); 242 243 Interface I = b.intf("I") 244 .defaultMethod("m", "()I").returns(1).build() 245 .build(); 246 247 Interface J = b.intf("J") 248 .defaultMethod("m", "()I").returns(2).build() 249 .build(); 250 251 Interface K = b.intf("K").extend(I,J) 252 .abstractMethod("m", "()I").build() 253 .build(); 254 255 Interface L = b.intf("L").extend(K) 256 .build(); 257 258 ConcreteClass A = b.clazz("A").implement(I,J).build(); 259 ConcreteClass C = b.clazz("C").extend(A).implement(K).build(); 260 ConcreteClass D = b.clazz("D").extend(C).implement(L).build(); 261 262 b.test().callSite(I, A, "m","()I") 263 .throws_(IncompatibleClassChangeError.class) 264 .done() 265 .test().callSite(K, C, "m","()I") 266 .throws_(AbstractMethodError.class) 267 .done() 268 .test().callSite(L, D, "m","()I") 269 .throws_(AbstractMethodError.class) 270 .done() 271 272 .run(); 273 } 274 275 /* 276 * ReabstractConflictingDefaultsSuper 277 * 278 * interface I { int m() default { return 1; } } 279 * interface J { int m() default { return 2; } } 280 * interface K extends I,J { int m(); } 281 * interface L extends K { } 282 * class A implements I,J {} 283 * class C extends A implements K {} 284 * class D extends C implements L {int m() {callSuper A.m } 285 * 286 * TEST: I i = new A(); i.m() ==> ICCE 287 * TEST: K k = new C(); CallSuper k.m() ==> AME 288 * TEST: L l = new D(); l.m() ==> AME 289 */ testReabstractConflictingDefaultsSuper()290 public void testReabstractConflictingDefaultsSuper() { 291 TestBuilder b = factory.getBuilder(); 292 293 Interface I = b.intf("I") 294 .defaultMethod("m", "()I").returns(1).build() 295 .build(); 296 297 Interface J = b.intf("J") 298 .defaultMethod("m", "()I").returns(2).build() 299 .build(); 300 301 Interface K = b.intf("K").extend(I,J) 302 .abstractMethod("m", "()I").build() 303 .build(); 304 305 Interface L = b.intf("L").extend(K) 306 .build(); 307 308 ConcreteClass A = b.clazz("A").implement(I,J).build(); 309 ConcreteClass C = b.clazz("C").extend(A).implement(K).build(); 310 ConcreteClass D = b.clazz("D").extend(C).implement(L) 311 .concreteMethod("m", "()I").callSuper(A, "m", "()I").build() 312 .build(); 313 314 b.test().callSite(I, A, "m","()I") 315 .throws_(IncompatibleClassChangeError.class) 316 .done() 317 .test().callSite(L, D, "m","()I") 318 .throws_(AbstractMethodError.class) 319 .done() 320 321 .run(); 322 } 323 324 /* 325 * testReabstractResolveMethod00705m2 326 * 327 * Test case for JDK-8027804: JCK resolveMethod test fails expecting AME 328 * 329 * This test is an extension of the JCK test resolveMethod00705m2 330 * with additional invoke* bytecodes specified for testing purposes. 331 * 332 * interface I { int m() default { return 1; } } 333 * interface J implements I { int m(); } 334 * class A implements J,I {} 335 * class C extends A {} 336 * 337 * TEST: A a = new C(); a.m() ==> AME (invokevirtual) 338 * C c = new C(); c.m() ==> AME (invokevirtual) 339 * J j = new C(); j.m() ==> AME (invokeinterface) 340 * I i = new C(); i.m() ==> AME (invokeinterface) 341 * c.test_Cmethod_ISMR(); c.super.m() ==> AME (invokespecial MR) 342 * a.test_Amethod_ISIMR(); j.super.m() ==> AME (invokespecial IMR) 343 * 344 * For ver > 49, error will be AME 345 * For ver = 49, error will be VE 346 */ 347 348 @NotApplicableFor(modes = { REDEFINITION }) // Can't redefine a class that gets error during loading testReabstractResolveMethod00705m2()349 public void testReabstractResolveMethod00705m2() { 350 TestBuilder b = factory.getBuilder(); 351 352 Interface I = b.intf("I") 353 .defaultMethod("m", "()I").returns(1).build() 354 .build(); 355 356 Interface J = b.intf("J").extend(I) 357 .abstractMethod("m", "()I").build() 358 .build(); 359 360 ConcreteClass A = b.clazz("A").implement(J,I) 361 .concreteMethod("test_Amethod_ISIMR", "()V") 362 .invoke(SPECIAL, b.clazzByName("J"), b.clazzByName("A"), 363 "m", "()I", INTERFACEMETHODREF) 364 .build() 365 .build(); 366 367 ConcreteClass C = b.clazz("C").extend(A) 368 .concreteMethod("test_Cmethod_ISMR", "()V") 369 .invoke(SPECIAL, b.clazzByName("C"), b.clazzByName("C"), 370 "m", "()I", CALLSITE) 371 .build() 372 .build(); 373 374 Class expectedError1, expectedError2; 375 if (factory.getVer() >=52) { 376 expectedError1 = expectedError2 = AbstractMethodError.class; 377 } else { 378 expectedError1 = expectedError2 = VerifyError.class; 379 } 380 381 b.test().callSite(A, C, "m", "()I") 382 .throws_(expectedError2) 383 .done() 384 .test().callSite(C, C, "m", "()I") 385 .throws_(expectedError2) 386 .done() 387 .test().callSite(J, C, "m", "()I") 388 .throws_(expectedError1) 389 .done() 390 .test().callSite(I, C, "m", "()I") 391 .throws_(expectedError1) 392 .done() 393 .test().callSite(C, C, "test_Cmethod_ISMR", "()V") 394 .throws_(expectedError2) 395 .done() 396 .test().callSite(A, C, "test_Amethod_ISIMR", "()V") 397 .throws_(expectedError2) 398 .done() 399 400 .run(); 401 } 402 403 /* 404 * Shadow 405 * 406 * interface I { int m() default { return 1; } } 407 * interface J extends I { int m() default { return 2; } } 408 * class C implements J {} 409 * 410 * TEST: [I|J|C] c = new C(); c.m() == 2; 411 */ testShadow()412 public void testShadow() { 413 TestBuilder b = factory.getBuilder(); 414 415 Interface I = b.intf("I") 416 .defaultMethod("m", "()I").returns(1).build() 417 .build(); 418 419 Interface J = b.intf("J").extend(I) 420 .defaultMethod("m", "()I").returns(2).build() 421 .build(); 422 423 ConcreteClass C = b.clazz("C").implement(J).build(); 424 425 b.test().callSite(I, C, "m","()I") 426 .returns(2) 427 .done() 428 .test() 429 .callSite(J, C, "m","()I") 430 .returns(2) 431 .done() 432 .test() 433 .callSite(C, C, "m","()I") 434 .returns(2) 435 .done() 436 437 .run(); 438 } 439 440 /* 441 * Disqualified 442 * 443 * interface I { int m() default { return 1; } } 444 * interface J extends I { int m() default { return 2; } } 445 * class C implements I, J {} 446 * 447 * TEST: [I|J|C] c = new C(); c.m() == 2; 448 */ testDisqualified()449 public void testDisqualified() { 450 TestBuilder b = factory.getBuilder(); 451 452 Interface I = b.intf("I") 453 .defaultMethod("m", "()I").returns(1).build() 454 .build(); 455 456 Interface J = b.intf("J").extend(I) 457 .defaultMethod("m", "()I").returns(2).build() 458 .build(); 459 460 ConcreteClass C = b.clazz("C").implement(I,J).build(); 461 462 b.test() 463 .callSite(I, C, "m","()I") 464 .returns(2) 465 .done() 466 .test() 467 .callSite(J, C, "m","()I") 468 .returns(2) 469 .done() 470 .test() 471 .callSite(C, C, "m","()I") 472 .returns(2) 473 .done() 474 475 .run(); 476 } 477 478 /* 479 * Mixed arity 480 * 481 * interface I { int m() default { return 1; } } 482 * interface J { int m(int i) default { return 2; } } 483 * class C implements I, J {} 484 * 485 * TEST: I i = new C(); i.m() == 1; i.m(0) ==> NSME 486 * TEST: J j = new C(); j.m() ==> NSME; j.m(0) == 2 487 * TEST: C c = new C(); c.m() == 1; c.m(0) == 2 488 */ 489 @KnownFailure(modes = { INVOKE_EXACT, INVOKE_GENERIC, INDY }) // IncompatibleClassChangeError instead of NoSuchMethodError testMixedArity1()490 public void testMixedArity1() { 491 TestBuilder b = factory.getBuilder(); 492 493 Interface I = b.intf("I") 494 .defaultMethod("m", "()I").returns(1).build() 495 .build(); 496 497 Interface J = b.intf("J") 498 .defaultMethod("m", "(I)I").returns(2).build() 499 .build(); 500 501 ConcreteClass C = b.clazz("C").implement(I,J).build(); 502 503 // I i = new C(); ... 504 b.test() 505 .callSite(I, C, "m","()I") 506 .returns(1) 507 .done() 508 .test() 509 .callSite(I, C, "m","(I)I") 510 .params(0) 511 .throws_(NoSuchMethodError.class) 512 .done() 513 514 // J j = new C(); ... 515 .test() 516 .callSite(J, C, "m","()I") 517 .throws_(NoSuchMethodError.class) 518 .done() 519 .test() 520 .callSite(J, C, "m","(I)I") 521 .params(0) 522 .returns(2) 523 .done() 524 525 // C c = new C(); ... 526 .test() 527 .callSite(C, C, "m","()I") 528 .returns(1) 529 .done() 530 .test() 531 .callSite(C, C, "m","(I)I") 532 .params(0) 533 .returns(2) 534 .done() 535 536 .run(); 537 } 538 539 /* 540 * Mixed arity 541 * 542 * interface I { int m() default { return 1; } } 543 * interface J { int m() default { return 2; } } 544 * class C implements I, J { int m(int i) { return 3; }} 545 * 546 * TEST: I i = new C(); i.m() ==> ICCE 547 * TEST: J j = new C(); j.m() ==> ICCE 548 * TEST: C c = new C(); c.m() ==> ICCE; c.m(0) == 3 549 */ testMixedArity2()550 public void testMixedArity2() { 551 TestBuilder b = factory.getBuilder(); 552 553 Interface I = b.intf("I") 554 .defaultMethod("m", "()I").returns(1).build() 555 .build(); 556 557 Interface J = b.intf("J") 558 .defaultMethod("m", "()I").returns(2).build() 559 .build(); 560 561 ConcreteClass C = b.clazz("C").implement(I,J) 562 .concreteMethod("m", "(I)I").returns(3).build() 563 .build(); 564 565 // I i = new C(); ... 566 b.test() 567 .callSite(I, C, "m","()I") 568 .throws_(IncompatibleClassChangeError.class) 569 .done() 570 571 // J j = new C(); ... 572 .test() 573 .callSite(J, C, "m","()I") 574 .throws_(IncompatibleClassChangeError.class) 575 .done() 576 577 // C c = new C(); ... 578 .test() 579 .callSite(C, C, "m","()I") 580 .throws_(IncompatibleClassChangeError.class) 581 .done() 582 .test() 583 .callSite(C, C, "m","(I)I") 584 .params(0) 585 .returns(3) 586 .done() 587 588 .run(); 589 } 590 } 591