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 vm.runtime.defmeth.shared.builder.TestBuilder; 32 import static vm.runtime.defmeth.shared.ExecutionMode.*; 33 34 /* 35 * Tests on invoke-super-default. 36 * 37 * Invoke-super-default is used by a subclass to defer to a default method 38 * implementation or to disambiguate between conflicting inherited default 39 * methods. 40 * 41 * Invoke-super-default appears in the source code as 42 * "<interface-name>.super.<method-name>(<args>)". It is compiled into an 43 * invokespecial instruction whose target is <interface-name>.<method-name>, 44 * where the interface is a direct supertype of the current class (the current class 45 * must directly implement <interface-name>). 46 * 47 * 0.6.3 JVMS draft for JDK8 updated. 48 * Invokespecial on any superinterface method will run interface method 49 * resolution, and then the selected method will be set to the resolved method. 50 * super defaults no longer check for lack of shadowing, other languages 51 * want this capability. 52 */ 53 public class SuperCallTest extends DefMethTest { 54 55 @Override 56 protected void configure() { 57 // Since invoke-super-default relies on new semantics of invokespecial, 58 // the tests are applicable only to class files of 52 version. 59 if (factory.getVer() != 52) { 60 getLog().warn("WARN: SuperCallTest is applicable only for class files w/ version 52."); 61 getLog().warn("WARN: Overriding \"-ver " + factory.getVer() + "\" w/ \"-ver 52\"."); 62 63 factory.setVer(52); 64 } 65 } 66 67 public static void main(String[] args) { 68 TestBase.runTest(new SuperCallTest(), args); 69 } 70 71 /* 72 * Basic case 73 * 74 * interface I { int m() default { return 1; } } 75 * interface J extends I { int m() default { return I.super.m(); } } 76 * class C implements J {} 77 * 78 * TEST: C c = new C(); c.m() == 88; 79 * TEST: I i = new C(); i.m() == 88; 80 */ 81 public void testSuperBasic1() { 82 TestBuilder b = factory.getBuilder(); 83 84 Interface I = b.intf("I") 85 .defaultMethod("m", "()I").returns(1).build() 86 .build(); 87 88 Interface J = b.intf("J").extend(I) 89 .defaultMethod("m", "()I").callSuper(I, "m", "()I").build() 90 .build(); 91 92 ConcreteClass C = b.clazz("C").implement(J).build(); 93 94 b.test().callSite(I, C, "m", "()I").returns(1).done() 95 .test().callSite(J, C, "m", "()I").returns(1).done() 96 .test().callSite(C, C, "m", "()I").returns(1).done() 97 98 .run(); 99 } 100 101 /* 102 * Super Conflict Resolution 103 * 104 * interface K { int m() default { return 1; } } 105 * interface L { int m() default { return 2; } } 106 * interface I extends K,L { int m() default { K.super.m(); } } 107 * class C implements I {} 108 * class D implements K,L {} 109 * 110 * TEST: K k = new C(); k.m() == 1 111 * TEST: L l = new C(); l.m() == 1 112 * TEST: I i = new C(); i.m() == 1 113 * TEST: C c = new C(); c.m() == 1 114 * 115 * TEST: K k = new D(); k.m() == 1 116 * TEST: L l = new D(); l.m() == 1 117 * TEST: D d = new D(); d.m() == 1 118 */ 119 public void testSuperConflictResolution() { 120 TestBuilder b = factory.getBuilder(); 121 122 Interface K = b.intf("K") 123 .defaultMethod("m", "()I").returns(1).build() 124 .build(); 125 126 Interface L = b.intf("L") 127 .defaultMethod("m", "()I").returns(2).build() 128 .build(); 129 130 Interface I = b.intf("I").extend(K, L) 131 .defaultMethod("m", "()I").callSuper(K, "m", "()I").build() 132 .build(); 133 134 ConcreteClass C = b.clazz("C").implement(I).build(); 135 136 ConcreteClass D = b.clazz("D").implement(K,L) 137 .concreteMethod("m", "()I").callSuper(K, "m", "()I").build() 138 .build(); 139 140 141 b.test().callSite(K, C, "m", "()I").returns(1).done() 142 .test().callSite(L, C, "m", "()I").returns(1).done() 143 .test().callSite(I, C, "m", "()I").returns(1).done() 144 .test().callSite(C, C, "m", "()I").returns(1).done() 145 146 .test().callSite(K, D, "m", "()I").returns(1).done() 147 .test().callSite(L, D, "m", "()I").returns(1).done() 148 .test().callSite(D, D, "m", "()I").returns(1).done() 149 150 .run(); 151 } 152 153 /* 154 * Super call of conflicting default method from different method name 155 * 156 * interface K { 157 * default public int m(int) { return 1; } 158 * } 159 * interface L { 160 * default public int m(int) { return 2; } 161 * } 162 * interface I extends K, L { 163 * default public int k() { return K.super.m((int)0); } 164 * default public int l() { return L.super.m((int)0); } 165 * } 166 * class C implements I {} 167 * class D implements K, L { 168 * public int k() { return K.super.m((int)0); } 169 * public int l() { return L.super.m((int)0); } 170 * } 171 * 172 * TEST: K o = new C(); o.m(I)I throws ICCE 173 * TEST: L o = new C(); o.m(I)I throws ICCE 174 * TEST: C o = new C(); o.m(I)I throws ICCE 175 * TEST: I o = new C(); o.k()I == 1 176 * TEST: C o = new C(); o.k()I == 1 177 * TEST: I o = new C(); o.l()I == 2 178 * TEST: C o = new C(); o.l()I == 2 179 * TEST: K o = new D(); o.m(I)I throws ICCE 180 * TEST: L o = new D(); o.m(I)I throws ICCE 181 * TEST: D o = new D(); o.m(I)I throws ICCE 182 * TEST: D o = new D(); o.k()I == 1 183 * TEST: D o = new D(); o.l()I == 2 184 */ 185 public void testSuperConflictDiffMethod() { 186 TestBuilder b = factory.getBuilder(); 187 188 Interface K = b.intf("K") 189 .defaultMethod("m", "(I)I").returns(1).build() 190 .build(); 191 192 Interface L = b.intf("L") 193 .defaultMethod("m", "(I)I").returns(2).build() 194 .build(); 195 196 Interface I = b.intf("I").extend(K, L) 197 .defaultMethod("k", "()I").callSuper(K, "m", "(I)I").build() 198 .defaultMethod("l", "()I").callSuper(L, "m", "(I)I").build() 199 .build(); 200 201 ConcreteClass C = b.clazz("C").implement(I).build(); 202 203 ConcreteClass D = b.clazz("D").implement(K,L) 204 .concreteMethod("k", "()I").callSuper(K, "m", "(I)I").build() 205 .concreteMethod("l", "()I").callSuper(L, "m", "(I)I").build() 206 .build(); 207 208 b.test().callSite(K, C, "m", "(I)I").throws_(IncompatibleClassChangeError.class).done() 209 .test().callSite(L, C, "m", "(I)I").throws_(IncompatibleClassChangeError.class).done() 210 .test().callSite(C, C, "m", "(I)I").throws_(IncompatibleClassChangeError.class).done() 211 212 .test().callSite(I, C, "k", "()I").returns(1).done() 213 .test().callSite(C, C, "k", "()I").returns(1).done() 214 .test().callSite(I, C, "l", "()I").returns(2).done() 215 .test().callSite(C, C, "l", "()I").returns(2).done() 216 217 .test().callSite(K, D, "m", "(I)I").throws_(IncompatibleClassChangeError.class).done() 218 .test().callSite(L, D, "m", "(I)I").throws_(IncompatibleClassChangeError.class).done() 219 .test().callSite(D, D, "m", "(I)I").throws_(IncompatibleClassChangeError.class).done() 220 221 .test().callSite(D, D, "k", "()I").returns(1).done() 222 .test().callSite(D, D, "l", "()I").returns(2).done() 223 224 .run(); 225 } 226 227 /* 228 * SuperConflict 229 * 230 * interface K { int m() default { return 1; } } 231 * interface L { int m() default { return 2; } } 232 * interface J extends K, L {} 233 * interface I extends J, K { int m() default { J.super.m(); } } 234 * class C implements I {} 235 * 236 * TEST: K k = new C(); k.m() ==> ICCE 237 * TEST: L l = new C(); l.m() ==> ICCE 238 * TEST: J j = new C(); j.m() ==> ICCE 239 * TEST: I i = new C(); i.m() ==> ICCE 240 * TEST: C c = new C(); c.m() ==> ICCE 241 */ 242 public void testSuperConflict() { 243 TestBuilder b = factory.getBuilder(); 244 245 Interface K = b.intf("K") 246 .defaultMethod("m", "()I").returns(1).build() 247 .build(); 248 249 Interface L = b.intf("L") 250 .defaultMethod("m", "()I").returns(2).build() 251 .build(); 252 253 Interface J = b.intf("J").extend(K, L).build(); 254 255 Interface I = b.intf("I").extend(K, J) 256 .defaultMethod("m", "()I").callSuper(J, "m", "()I").build() 257 .build(); 258 259 ConcreteClass C = b.clazz("C").implement(I).build(); 260 261 b.test().callSite(K, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done() 262 .test().callSite(L, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done() 263 .test().callSite(J, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done() 264 .test().callSite(I, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done() 265 .test().callSite(C, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done() 266 267 .run(); 268 } 269 270 /* 271 * SuperDisqual 272 * 273 * interface I { int m() default { return 1; } } 274 * interface J { int m() default { return 2; } } 275 * class C implements I, J { public int m() { return I.super.m(); } } 276 * 277 * TEST: C c = new C(); c.m() ==> 1 278 * TEST: J j = new C(); j.m() ==> 1 279 */ 280 public void testSuperDisqual() { 281 TestBuilder b = factory.getBuilder(); 282 283 Interface I = b.intf("I") 284 .defaultMethod("m", "()I").returns(1).build() 285 .build(); 286 287 Interface J = b.intf("J") 288 .defaultMethod("m", "()I").returns(2).build() 289 .build(); 290 291 ConcreteClass C = b.clazz("C").implement(I, J) 292 .concreteMethod("m", "()I").callSuper(I, "m", "()I").build() 293 .build(); 294 295 b.test().callSite(I, C, "m", "()I").returns(1).done() 296 .test().callSite(J, C, "m", "()I").returns(1).done() 297 .test().callSite(C, C, "m", "()I").returns(1).done() 298 299 .run(); 300 } 301 302 /* 303 * SuperNull 304 * 305 * interface I { int m(); } 306 * interface J extends I { int m() default { return I.super.m(); } } 307 * interface K extends I { int m() default { return I.super.n(); } } 308 * class C implements J {} 309 * class D implements K {} 310 * 311 * TEST: I i = new C(); i.m() ==> AME 312 * TEST: J j = new C(); j.m() ==> AME 313 * TEST: C c = new C(); c.m() ==> AME 314 * TEST: K k = new D(); k.m() ==> NSME 315 */ 316 public void testSuperNull() { 317 TestBuilder b = factory.getBuilder(); 318 319 Interface I = b.intf("I") 320 .abstractMethod("m", "()I").build() 321 .build(); 322 323 Interface J = b.intf("J").extend(I) 324 .defaultMethod("m", "()I").callSuper(I, "m", "()I").build() 325 .build(); 326 327 Interface K = b.intf("K").extend(I) 328 .defaultMethod("m", "()I").callSuper(I, "n", "()I").build() 329 .build(); 330 331 ConcreteClass C = b.clazz("C").implement(J).build(); 332 ConcreteClass D = b.clazz("D").implement(K).build(); 333 334 b.test().callSite(I, C, "m", "()I").throws_(AbstractMethodError.class).done() 335 .test().callSite(J, C, "m", "()I").throws_(AbstractMethodError.class).done() 336 .test().callSite(C, C, "m", "()I").throws_(AbstractMethodError.class).done() 337 .test().callSite(K, D, "m", "()I").throws_(NoSuchMethodError.class).done() 338 339 .run(); 340 } 341 342 /* 343 * SuperGeneric 344 * 345 * interface J<T> { int m(T t) default { return 1; } } 346 * interface I extends J<String> { int m(String s) default { return J.super.m(); } } 347 * class C implements I {} 348 * 349 * TEST: I i = new C(); i.m(new Object()) == 1; 350 * TESTL J j = new C(); j.m(new Object()) == 1; 351 * TEST: J j = new C(); j.m("") == 1; 352 * TEST: C c = new C(); c.m(new Object()) == 1; 353 * TEST: C c = new C(); c.m("") == 1; 354 */ 355 @KnownFailure(modes = { INVOKE_EXACT, INVOKE_GENERIC, INVOKE_WITH_ARGS, INDY }) // Test2_J_C_m: AME => IAE => ICCE instead of successful call 356 public void testSuperGeneric() { 357 TestBuilder b = factory.getBuilder(); 358 359 // interface I<T> { 360 // default int m(T t) { return 1; } 361 // } 362 Interface I = b.intf("I") 363 .sig("<T:Ljava/lang/Object;>Ljava/lang/Object;") 364 .defaultMethod("m", "(Ljava/lang/Object;)I").sig("(TT;)I").returns(1).build() 365 .build(); 366 367 // interface J extends I<String> { 368 // default int m(String s) { return I.super.m(); } 369 // } 370 Interface J = b.intf("J").extend(I) 371 .sig("Ljava/lang/Object;LI<Ljava/lang/String;>;") 372 .defaultMethod("m", "(Ljava/lang/String;)I").callSuper(I, "m", "(Ljava/lang/Object;)I").build() 373 .build(); 374 375 ConcreteClass C = b.clazz("C").implement(J).build(); 376 377 b.test().callSite(I, C, "m", "(Ljava/lang/Object;)I").returns(1).done() 378 379 .test().callSite(J, C, "m", "(Ljava/lang/Object;)I").returns(1).done() 380 .test().callSite(J, C, "m", "(Ljava/lang/String;)I").returns(1).done() 381 382 .test().callSite(C, C, "m", "(Ljava/lang/Object;)I").returns(1).done() 383 .test().callSite(C, C, "m", "(Ljava/lang/String;)I").returns(1).done() 384 385 .run(); 386 } 387 388 /* 389 * SuperGenericDisqual 390 * 391 * interface I<T> { int m(T t) default { return 1; } } 392 * interface J extends I<String> { int m(String s) default { return 2; } } 393 * class C implements I<String>, J { public int m(String s) { return I.super.m(s); } } 394 * 395 * TEST: C c = new C(); c.m("string") == 1 396 */ 397 @KnownFailure(modes = { INVOKE_EXACT, INVOKE_GENERIC, INVOKE_WITH_ARGS, INDY }) // Test2_J_C_m: AME => IAE => ICCE instead of successful call 398 public void testSuperGenericDisqual() { 399 TestBuilder b = factory.getBuilder(); 400 401 Interface I = b.intf("I").sig("<T:Ljava/lang/Object;>Ljava/lang/Object;") 402 .defaultMethod("m", "(Ljava/lang/Object;)I").sig("(TT;)I").returns(1).build() 403 .build(); 404 405 Interface J = b.intf("J").extend(I) 406 .sig("Ljava/lang/Object;LJ<Ljava/lang/String;>;") 407 .defaultMethod("m", "(Ljava/lang/String;)I").returns(2).build() 408 .build(); 409 410 ConcreteClass C = b.clazz("C").implement(I,J) 411 .sig("Ljava/lang/Object;LI;LJ<Ljava/lang/String;>;") 412 .concreteMethod("m", "(Ljava/lang/String;)I").callSuper(I, "m", "(Ljava/lang/Object;)I").build() 413 .build(); 414 415 b.test().callSite(I, C, "m", "(Ljava/lang/Object;)I").returns(1).done() 416 417 .test().callSite(J, C, "m", "(Ljava/lang/Object;)I").returns(1).done() 418 .test().callSite(J, C, "m", "(Ljava/lang/String;)I").returns(1).done() 419 420 .test().callSite(C, C, "m", "(Ljava/lang/Object;)I").returns(1).done() 421 .test().callSite(C, C, "m", "(Ljava/lang/String;)I").returns(1).done() 422 423 .run(); 424 } 425 426 /* 427 * Super-call of non-default method 428 * 429 * class C { int m() { return 1; } } 430 * class D extends C { int m() { return C.super.m(); } } 431 * 432 * TEST: C d = new D(); d.m() == 1 433 * TEST: D d = new D(); d.m() == 1 434 */ 435 public void testSuperNonDefault() { 436 TestBuilder b = factory.getBuilder(); 437 438 ConcreteClass C = b.clazz("C") 439 .concreteMethod("m", "()I").returns(1).build() 440 .build(); 441 442 ConcreteClass D = b.clazz("D").extend(C) 443 .concreteMethod("m", "()I").callSuper(C, "m", "()I").build() 444 .build(); 445 446 b.test().callSite(C, D, "m", "()I").returns(1).done() 447 .test().callSite(D, D, "m", "()I").returns(1).done() 448 449 .run(); 450 } 451 452 /* 453 * Super-call of non-default method 454 * 455 * interface I { int m(); } 456 * class C { int m() { return 1; } } 457 * class D extends C implements I { int m() { return I.super.m(); } } 458 * class E extends C implements I { int m() { return C.super.m(); } } 459 * 460 * TEST: I d = new D(); d.m() ==> AME 461 * TEST: C d = new D(); d.m() ==> AME 462 * TEST: D d = new D(); d.m() ==> AME 463 * TEST: I e = new E(); e.m() == 1 464 * TEST: C e = new E(); e.m() == 1 465 * TEST: E e = new E(); e.m() == 1 466 */ 467 public void testSuperNonDefault1() { 468 TestBuilder b = factory.getBuilder(); 469 470 Interface I = b.intf("I") 471 .abstractMethod("m", "()I").build() 472 .build(); 473 474 ConcreteClass C = b.clazz("C") 475 .concreteMethod("m", "()I").returns(1).build() 476 .build(); 477 478 ConcreteClass D = b.clazz("D").extend(C).implement(I) 479 .concreteMethod("m", "()I").callSuper(I, "m", "()I").build() 480 .build(); 481 482 ConcreteClass E = b.clazz("E").extend(C).implement(I) 483 .concreteMethod("m", "()I").callSuper(C, "m", "()I").build() 484 .build(); 485 486 b.test().callSite(I, D, "m", "()I").throws_(AbstractMethodError.class).done() 487 .test().callSite(C, D, "m", "()I").throws_(AbstractMethodError.class).done() 488 .test().callSite(D, D, "m", "()I").throws_(AbstractMethodError.class).done() 489 490 .test().callSite(I, E, "m", "()I").returns(1).done() 491 .test().callSite(C, E, "m", "()I").returns(1).done() 492 .test().callSite(E, E, "m", "()I").returns(1).done() 493 494 .run(); 495 } 496 497 /* 498 * Super-call of non-default method 499 * 500 * interface I { int m() {return 1;} } 501 * class C { int m() { return 2; } } 502 * class D extends C implements I { int m() { return I.super.m(); } } 503 * class E extends C implements I { int m() { return C.super.m(); } } 504 * 505 * TEST: I d = new D(); d.m() == 1 506 * TEST: C d = new D(); d.m() == 1 507 * TEST: D d = new D(); d.m() == 1 508 * 509 * TEST: I e = new E(); e.m() == 2 510 * TEST: C e = new E(); e.m() == 2 511 * TEST: E e = new E(); e.m() == 2 512 */ 513 public void testSuperNonDefault2() { 514 TestBuilder b = factory.getBuilder(); 515 516 Interface I = b.intf("I") 517 .defaultMethod("m", "()I").returns(1).build() 518 .build(); 519 520 ConcreteClass C = b.clazz("C") 521 .concreteMethod("m", "()I").returns(2).build() 522 .build(); 523 524 ConcreteClass D = b.clazz("D").extend(C).implement(I) 525 .concreteMethod("m", "()I").callSuper(I, "m", "()I").build() 526 .build(); 527 528 ConcreteClass E = b.clazz("E").extend(C).implement(I) 529 .concreteMethod("m", "()I").callSuper(C, "m", "()I").build() 530 .build(); 531 532 b.test().callSite(I, D, "m", "()I").returns(1).done() 533 .test().callSite(C, D, "m", "()I").returns(1).done() 534 .test().callSite(D, D, "m", "()I").returns(1).done() 535 536 .test().callSite(I, E, "m", "()I").returns(2).done() 537 .test().callSite(C, E, "m", "()I").returns(2).done() 538 .test().callSite(E, E, "m", "()I").returns(2).done() 539 540 .run(); 541 } 542 543 /* 544 * Disambig 545 * 546 * interface I { int m() default { return 1; } } 547 * interface J { int m() default { return 2; } } 548 * class C implements I, J { int q() { return I.super.m(); } 549 * int r() { return J.super.m(); } } 550 * 551 * TEST: C c = new C(); c.m() == ICCE; 552 * TEST: C c = new C(); c.q() == 1; 553 * TEST: C c = new C(); c.r() == 2; 554 */ 555 public void testDisambig() { 556 TestBuilder b = factory.getBuilder(); 557 558 Interface I = b.intf("I") 559 .defaultMethod("m", "()I").returns(1).build() 560 .build(); 561 562 Interface J = b.intf("J") 563 .defaultMethod("m", "()I").returns(2).build() 564 .build(); 565 566 ConcreteClass C = b.clazz("C").implement(I,J) 567 .concreteMethod("q", "()I").callSuper(I, "m", "()I").build() 568 .concreteMethod("r", "()I").callSuper(J, "m", "()I").build() 569 .build(); 570 571 b.test().callSite(C, C, "q", "()I").returns(1).done() 572 .test().callSite(C, C, "r", "()I").returns(2).done() 573 .test().callSite(C, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done() 574 575 .run(); 576 } 577 578 /* 579 * Disambig2 580 * 581 * interface I { int m() default { return 1; } } 582 * interface J { int m() default { return 2; } } 583 * interface K extends I 584 * interface L extends J 585 * class C implements K, L { int q() { return K.super.m(); } 586 * int r() { return L.super.m(); } } 587 * 588 * TEST: C c = new C(); c.m() == ICCE; 589 * TEST: C c = new C(); c.q() == 1; 590 * TEST: C c = new C(); c.r() == 2; 591 */ 592 public void testDisambig2() { 593 TestBuilder b = factory.getBuilder(); 594 595 Interface I = b.intf("I") 596 .defaultMethod("m", "()I").returns(1).build() 597 .build(); 598 599 Interface J = b.intf("J") 600 .defaultMethod("m", "()I").returns(2).build() 601 .build(); 602 603 Interface K = b.intf("K").extend(I).build(); 604 605 Interface L = b.intf("L").extend(J).build(); 606 607 ConcreteClass C = b.clazz("C").implement(K,L) 608 .concreteMethod("q", "()I").callSuper(K, "m", "()I").build() 609 .concreteMethod("r", "()I").callSuper(L, "m", "()I").build() 610 .build(); 611 612 b.test().callSite(C, C, "q", "()I").returns(1).done() 613 .test().callSite(C, C, "r", "()I").returns(2).done() 614 .test().callSite(C, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done() 615 616 .run(); 617 } 618 619 /* 620 * testResolvedShadowed 621 * 622 * interface I { int m() default { return 1; } } 623 * interface K extends I { int m() default { return 2; } } 624 * interface J extends I { } 625 * class C implements J,K { int q { J.super.m(); } } 626 * 627 * TEST: C c = new C(); c.m() == 2 628 * TEST: C c = new C(); c.q() == 1 629 */ 630 public void testResolvedShadowed() { 631 TestBuilder b = factory.getBuilder(); 632 633 Interface I = b.intf("I") 634 .defaultMethod("m", "()I").returns(1).build() 635 .build(); 636 637 Interface K = b.intf("K").extend(I) 638 .defaultMethod("m", "()I").returns(2).build() 639 .build(); 640 641 Interface J = b.intf("J").extend(I) 642 .build(); 643 644 ConcreteClass C = b.clazz("C").implement(J,K) 645 .concreteMethod("q", "()I").callSuper(J, "m", "()I").build() 646 .build(); 647 648 b.test().callSite(C, C, "m", "()I").returns(2).done() 649 .test().callSite(C, C, "q", "()I").returns(1).done() 650 651 .run(); 652 } 653 654 /* 655 * testResolvedButSuperClass 656 * 657 * interface I { int m() default { return 1; } } 658 * interface J { } 659 * class A { public int m() { return 2; } } 660 * class C implements J extends A { int q { J.super.m(); } } 661 * 662 * TEST: C c = new C(); c.q() == 1 663 * TEST: C c = new C(); c.m() == 2 664 */ 665 public void testResolvedButSuperClass() { 666 TestBuilder b = factory.getBuilder(); 667 668 Interface I = b.intf("I") 669 .defaultMethod("m", "()I").returns(1).build() 670 .build(); 671 672 Interface J = b.intf("J").extend(I) 673 .build(); 674 675 ConcreteClass A = b.clazz("A") 676 .concreteMethod("m", "()I").returns(2).build() 677 .build(); 678 679 ConcreteClass C = b.clazz("C").implement(J).extend(A) 680 .concreteMethod("q", "()I").callSuper(J, "m", "()I").build() 681 .build(); 682 683 b.test().callSite(C, C, "q", "()I").returns(1).done() 684 .test().callSite(C, C, "m", "()I").returns(2).done() 685 686 .run(); 687 } 688 689 /* 690 * testResolved1Caller2NotShadowed 691 * 692 * interface I { int m() default { return 1; } } 693 * interface J extends I { } 694 * interface L { int m() default { return 2; } } 695 * interface K extends I, L { } 696 * class C implements J,K { int q { J.super.m(); } } 697 * 698 * TEST: C c = new C(); c.m() == ICCE 699 * TEST: C c = new C(); c.q() == 1 700 */ 701 public void testResolved1Caller2NotShadowed() { 702 TestBuilder b = factory.getBuilder(); 703 704 Interface I = b.intf("I") 705 .defaultMethod("m", "()I").returns(1).build() 706 .build(); 707 708 Interface J = b.intf("J").extend(I).build(); 709 710 Interface L = b.intf("L") 711 .defaultMethod("m", "()I").returns(2).build() 712 .build(); 713 714 Interface K = b.intf("K").extend(I,L) 715 .build(); 716 717 ConcreteClass C = b.clazz("C").implement(J,K) 718 .concreteMethod("q", "()I").callSuper(J, "m", "()I").build() 719 .build(); 720 721 b.test().callSite(C, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done() 722 .test().callSite(C, C, "q", "()I").returns(1).done() 723 724 .run(); 725 } 726 727 /* 728 * Test validity of invokespecial on indirect superinterface's method, 729 * this test should receive a verification error. 730 * 731 * (JVMS draft 0.7.0) JVMS 4.9.2 Structural Constraints 732 * Each invokespecial instruction must name an instance initialization 733 * method (2.9), or must reference a method in the current class or interface, 734 * a method in a superclass of the current class or interface, or a method 735 * in a direct superinterface of the current class or interface 736 * 737 * Note: Normally javac would reject this test case complaining that, 738 * InDirectSuper.java:5: error: not an enclosing class: I 739 * interface K extends J { default public void m() { I.super.m(); } } 740 * ^ 741 * However, the below test case allows us to check for this structural 742 * constraint on invokespecial in the JVM. 743 * 744 * interface I { int m() default { return 1; } } 745 * interface J extends I { } 746 * interface K extends J { int m() default { return I.super.m(); } } 747 * class C implements K {} 748 * 749 * TEST: K k = new C(); k.m() == VerifyError 750 */ 751 @NotApplicableFor(modes = { REDEFINITION }) // Can't redefine a class that gets VerifyError 752 public void testSuperInvalidIndirectInterfaceMethodInvokeSpecial() { 753 TestBuilder b = factory.getBuilder(); 754 755 Interface I = b.intf("I") 756 .defaultMethod("m", "()I").returns(1).build() 757 .build(); 758 759 Interface J = b.intf("J").extend(I).build(); 760 761 Interface K = b.intf("K").extend(J) 762 .defaultMethod("m", "()I").callSuper(I, "m", "()I").build() 763 .build(); 764 765 ConcreteClass C = b.clazz("C").implement(K).build(); 766 767 b.test().callSite(K, C, "m", "()I").throws_(VerifyError.class).done() 768 769 .run(); 770 } 771 }