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 }