Path: blob/master/test/hotspot/jtreg/vmTestbase/vm/runtime/defmeth/SuperCallTest.java
41159 views
/*1* Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223/*24* @test25*26* @modules java.base/jdk.internal.org.objectweb.asm:+open java.base/jdk.internal.org.objectweb.asm.util:+open27* @library /vmTestbase /test/lib28*29* @comment build retransform.jar in current dir30* @run driver vm.runtime.defmeth.shared.BuildJar31*32* @run driver jdk.test.lib.FileInstaller . .33* @run main/othervm/native34* -agentlib:redefineClasses35* -javaagent:retransform.jar36* vm.runtime.defmeth.SuperCallTest37*/38package vm.runtime.defmeth;3940import java.util.Set;4142import vm.runtime.defmeth.shared.DefMethTest;43import vm.runtime.defmeth.shared.annotation.NotApplicableFor;44import vm.runtime.defmeth.shared.data.*;45import vm.runtime.defmeth.shared.builder.TestBuilder;4647import static jdk.internal.org.objectweb.asm.Opcodes.ACC_SYNCHRONIZED;48import static vm.runtime.defmeth.shared.ExecutionMode.*;4950/*51* Tests on invoke-super-default.52*53* Invoke-super-default is used by a subclass to defer to a default method54* implementation or to disambiguate between conflicting inherited default55* methods.56*57* Invoke-super-default appears in the source code as58* "<interface-name>.super.<method-name>(<args>)". It is compiled into an59* invokespecial instruction whose target is <interface-name>.<method-name>,60* where the interface is a direct supertype of the current class (the current class61* must directly implement <interface-name>).62*63* Invokespecial on any superinterface method will run interface method64* resolution, and then the selected method will be set to the resolved method.65* super defaults no longer check for lack of shadowing, other languages66* want this capability.67*/68public class SuperCallTest extends DefMethTest {6970public static void main(String[] args) {71DefMethTest.runTest(SuperCallTest.class,72/* majorVer */ Set.of(MAX_MAJOR_VER),73/* flags */ Set.of(0, ACC_SYNCHRONIZED),74/* redefine */ Set.of(false, true),75/* execMode */ Set.of(DIRECT, REFLECTION, INVOKE_EXACT, INVOKE_GENERIC, INVOKE_WITH_ARGS, INDY));76}7778@Override79protected void configure() {80// Since invoke-super-default relies on new semantics of invokespecial,81// the tests are applicable only to class files of 52 version.82if (factory.getVer() < 52) {83getLog().warn("WARN: SuperCallTest is applicable only for class files w/ version >=52.");84getLog().warn("WARN: Overriding \"-ver " + factory.getVer() + "\" w/ \"-ver 52\".");8586factory.setVer(52);87}88}8990/*91* Basic case92*93* interface I { int m() default { return 1; } }94* interface J extends I { int m() default { return I.super.m(); } }95* class C implements J {}96*97* TEST: C c = new C(); c.m() == 88;98* TEST: I i = new C(); i.m() == 88;99*/100public void testSuperBasic1(TestBuilder b) {101Interface I = b.intf("I")102.defaultMethod("m", "()I").returns(1).build()103.build();104105Interface J = b.intf("J").extend(I)106.defaultMethod("m", "()I").callSuper(I, "m", "()I").build()107.build();108109ConcreteClass C = b.clazz("C").implement(J).build();110111b.test().callSite(I, C, "m", "()I").returns(1).done()112.test().callSite(J, C, "m", "()I").returns(1).done()113.test().callSite(C, C, "m", "()I").returns(1).done();114}115116/*117* Super Conflict Resolution118*119* interface K { int m() default { return 1; } }120* interface L { int m() default { return 2; } }121* interface I extends K,L { int m() default { K.super.m(); } }122* class C implements I {}123* class D implements K,L {}124*125* TEST: K k = new C(); k.m() == 1126* TEST: L l = new C(); l.m() == 1127* TEST: I i = new C(); i.m() == 1128* TEST: C c = new C(); c.m() == 1129*130* TEST: K k = new D(); k.m() == 1131* TEST: L l = new D(); l.m() == 1132* TEST: D d = new D(); d.m() == 1133*/134public void testSuperConflictResolution(TestBuilder b) {135Interface K = b.intf("K")136.defaultMethod("m", "()I").returns(1).build()137.build();138139Interface L = b.intf("L")140.defaultMethod("m", "()I").returns(2).build()141.build();142143Interface I = b.intf("I").extend(K, L)144.defaultMethod("m", "()I").callSuper(K, "m", "()I").build()145.build();146147ConcreteClass C = b.clazz("C").implement(I).build();148149ConcreteClass D = b.clazz("D").implement(K,L)150.concreteMethod("m", "()I").callSuper(K, "m", "()I").build()151.build();152153154b.test().callSite(K, C, "m", "()I").returns(1).done()155.test().callSite(L, C, "m", "()I").returns(1).done()156.test().callSite(I, C, "m", "()I").returns(1).done()157.test().callSite(C, C, "m", "()I").returns(1).done()158159.test().callSite(K, D, "m", "()I").returns(1).done()160.test().callSite(L, D, "m", "()I").returns(1).done()161.test().callSite(D, D, "m", "()I").returns(1).done();162}163164/*165* Super call of conflicting default method from different method name166*167* interface K {168* default public int m(int) { return 1; }169* }170* interface L {171* default public int m(int) { return 2; }172* }173* interface I extends K, L {174* default public int k() { return K.super.m((int)0); }175* default public int l() { return L.super.m((int)0); }176* }177* class C implements I {}178* class D implements K, L {179* public int k() { return K.super.m((int)0); }180* public int l() { return L.super.m((int)0); }181* }182*183* TEST: K o = new C(); o.m(I)I throws ICCE184* TEST: L o = new C(); o.m(I)I throws ICCE185* TEST: C o = new C(); o.m(I)I throws ICCE186* TEST: I o = new C(); o.k()I == 1187* TEST: C o = new C(); o.k()I == 1188* TEST: I o = new C(); o.l()I == 2189* TEST: C o = new C(); o.l()I == 2190* TEST: K o = new D(); o.m(I)I throws ICCE191* TEST: L o = new D(); o.m(I)I throws ICCE192* TEST: D o = new D(); o.m(I)I throws ICCE193* TEST: D o = new D(); o.k()I == 1194* TEST: D o = new D(); o.l()I == 2195*/196public void testSuperConflictDiffMethod(TestBuilder b) {197Interface K = b.intf("K")198.defaultMethod("m", "(I)I").returns(1).build()199.build();200201Interface L = b.intf("L")202.defaultMethod("m", "(I)I").returns(2).build()203.build();204205Interface I = b.intf("I").extend(K, L)206.defaultMethod("k", "()I").callSuper(K, "m", "(I)I").build()207.defaultMethod("l", "()I").callSuper(L, "m", "(I)I").build()208.build();209210ConcreteClass C = b.clazz("C").implement(I).build();211212ConcreteClass D = b.clazz("D").implement(K,L)213.concreteMethod("k", "()I").callSuper(K, "m", "(I)I").build()214.concreteMethod("l", "()I").callSuper(L, "m", "(I)I").build()215.build();216217b.test().callSite(K, C, "m", "(I)I").throws_(IncompatibleClassChangeError.class).done()218.test().callSite(L, C, "m", "(I)I").throws_(IncompatibleClassChangeError.class).done()219.test().callSite(C, C, "m", "(I)I").throws_(IncompatibleClassChangeError.class).done()220221.test().callSite(I, C, "k", "()I").returns(1).done()222.test().callSite(C, C, "k", "()I").returns(1).done()223.test().callSite(I, C, "l", "()I").returns(2).done()224.test().callSite(C, C, "l", "()I").returns(2).done()225226.test().callSite(K, D, "m", "(I)I").throws_(IncompatibleClassChangeError.class).done()227.test().callSite(L, D, "m", "(I)I").throws_(IncompatibleClassChangeError.class).done()228.test().callSite(D, D, "m", "(I)I").throws_(IncompatibleClassChangeError.class).done()229230.test().callSite(D, D, "k", "()I").returns(1).done()231.test().callSite(D, D, "l", "()I").returns(2).done();232}233234/*235* SuperConflict236*237* interface K { int m() default { return 1; } }238* interface L { int m() default { return 2; } }239* interface J extends K, L {}240* interface I extends J, K { int m() default { J.super.m(); } }241* class C implements I {}242*243* TEST: K k = new C(); k.m() ==> ICCE244* TEST: L l = new C(); l.m() ==> ICCE245* TEST: J j = new C(); j.m() ==> ICCE246* TEST: I i = new C(); i.m() ==> ICCE247* TEST: C c = new C(); c.m() ==> ICCE248*/249public void testSuperConflict(TestBuilder b) {250Interface K = b.intf("K")251.defaultMethod("m", "()I").returns(1).build()252.build();253254Interface L = b.intf("L")255.defaultMethod("m", "()I").returns(2).build()256.build();257258Interface J = b.intf("J").extend(K, L).build();259260Interface I = b.intf("I").extend(K, J)261.defaultMethod("m", "()I").callSuper(J, "m", "()I").build()262.build();263264ConcreteClass C = b.clazz("C").implement(I).build();265266b.test().callSite(K, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done()267.test().callSite(L, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done()268.test().callSite(J, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done()269.test().callSite(I, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done()270.test().callSite(C, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done();271}272273/*274* SuperDisqual275*276* interface I { int m() default { return 1; } }277* interface J { int m() default { return 2; } }278* class C implements I, J { public int m() { return I.super.m(); } }279*280* TEST: C c = new C(); c.m() ==> 1281* TEST: J j = new C(); j.m() ==> 1282*/283public void testSuperDisqual(TestBuilder b) {284Interface I = b.intf("I")285.defaultMethod("m", "()I").returns(1).build()286.build();287288Interface J = b.intf("J")289.defaultMethod("m", "()I").returns(2).build()290.build();291292ConcreteClass C = b.clazz("C").implement(I, J)293.concreteMethod("m", "()I").callSuper(I, "m", "()I").build()294.build();295296b.test().callSite(I, C, "m", "()I").returns(1).done()297.test().callSite(J, C, "m", "()I").returns(1).done()298.test().callSite(C, C, "m", "()I").returns(1).done();299}300301/*302* SuperNull303*304* interface I { int m(); }305* interface J extends I { int m() default { return I.super.m(); } }306* interface K extends I { int m() default { return I.super.n(); } }307* class C implements J {}308* class D implements K {}309*310* TEST: I i = new C(); i.m() ==> AME311* TEST: J j = new C(); j.m() ==> AME312* TEST: C c = new C(); c.m() ==> AME313* TEST: K k = new D(); k.m() ==> NSME314*/315public void testSuperNull(TestBuilder b) {316Interface I = b.intf("I")317.abstractMethod("m", "()I").build()318.build();319320Interface J = b.intf("J").extend(I)321.defaultMethod("m", "()I").callSuper(I, "m", "()I").build()322.build();323324Interface K = b.intf("K").extend(I)325.defaultMethod("m", "()I").callSuper(I, "n", "()I").build()326.build();327328ConcreteClass C = b.clazz("C").implement(J).build();329ConcreteClass D = b.clazz("D").implement(K).build();330331b.test().callSite(I, C, "m", "()I").throws_(AbstractMethodError.class).done()332.test().callSite(J, C, "m", "()I").throws_(AbstractMethodError.class).done()333.test().callSite(C, C, "m", "()I").throws_(AbstractMethodError.class).done()334.test().callSite(K, D, "m", "()I").throws_(NoSuchMethodError.class).done();335}336337/*338* SuperGeneric339*340* interface J<T> { int m(T t) default { return 1; } }341* interface I extends J<String> { int m(String s) default { return J.super.m(); } }342* class C implements I {}343*344* TEST: I i = new C(); i.m(new Object()) == 1;345* TESTL J j = new C(); j.m(new Object()) == 1;346* TEST: J j = new C(); j.m("") == 1;347* TEST: C c = new C(); c.m(new Object()) == 1;348* TEST: C c = new C(); c.m("") == 1;349*/350public void testSuperGeneric(TestBuilder b) {351// interface I<T> {352// default int m(T t) { return 1; }353// }354Interface I = b.intf("I")355.sig("<T:Ljava/lang/Object;>Ljava/lang/Object;")356.defaultMethod("m", "(Ljava/lang/Object;)I").sig("(TT;)I").returns(1).build()357.build();358359// interface J extends I<String> {360// default int m(String s) { return I.super.m(); }361// }362Interface J = b.intf("J").extend(I)363.sig("Ljava/lang/Object;LI<Ljava/lang/String;>;")364.defaultMethod("m", "(Ljava/lang/String;)I").callSuper(I, "m", "(Ljava/lang/Object;)I").build()365.build();366367ConcreteClass C = b.clazz("C").implement(J).build();368369b.test().callSite(I, C, "m", "(Ljava/lang/Object;)I").returns(1).done()370371.test().callSite(J, C, "m", "(Ljava/lang/Object;)I").returns(1).done()372.test().callSite(J, C, "m", "(Ljava/lang/String;)I").returns(1).done()373374.test().callSite(C, C, "m", "(Ljava/lang/Object;)I").returns(1).done()375.test().callSite(C, C, "m", "(Ljava/lang/String;)I").returns(1).done();376}377378/*379* SuperGenericDisqual380*381* interface I<T> { int m(T t) default { return 1; } }382* interface J extends I<String> { int m(String s) default { return 2; } }383* class C implements I<String>, J { public int m(String s) { return I.super.m(s); } }384*385* TEST: C c = new C(); c.m("string") == 1386*/387public void testSuperGenericDisqual(TestBuilder b) {388Interface I = b.intf("I").sig("<T:Ljava/lang/Object;>Ljava/lang/Object;")389.defaultMethod("m", "(Ljava/lang/Object;)I").sig("(TT;)I").returns(1).build()390.build();391392Interface J = b.intf("J").extend(I)393.sig("Ljava/lang/Object;LJ<Ljava/lang/String;>;")394.defaultMethod("m", "(Ljava/lang/String;)I").returns(2).build()395.build();396397ConcreteClass C = b.clazz("C").implement(I,J)398.sig("Ljava/lang/Object;LI;LJ<Ljava/lang/String;>;")399.concreteMethod("m", "(Ljava/lang/String;)I").callSuper(I, "m", "(Ljava/lang/Object;)I").build()400.build();401402b.test().callSite(I, C, "m", "(Ljava/lang/Object;)I").returns(1).done()403404.test().callSite(J, C, "m", "(Ljava/lang/Object;)I").returns(1).done()405.test().callSite(J, C, "m", "(Ljava/lang/String;)I").returns(1).done()406407.test().callSite(C, C, "m", "(Ljava/lang/Object;)I").returns(1).done()408.test().callSite(C, C, "m", "(Ljava/lang/String;)I").returns(1).done();409}410411/*412* Super-call of non-default method413*414* class C { int m() { return 1; } }415* class D extends C { int m() { return C.super.m(); } }416*417* TEST: C d = new D(); d.m() == 1418* TEST: D d = new D(); d.m() == 1419*/420public void testSuperNonDefault(TestBuilder b) {421ConcreteClass C = b.clazz("C")422.concreteMethod("m", "()I").returns(1).build()423.build();424425ConcreteClass D = b.clazz("D").extend(C)426.concreteMethod("m", "()I").callSuper(C, "m", "()I").build()427.build();428429b.test().callSite(C, D, "m", "()I").returns(1).done()430.test().callSite(D, D, "m", "()I").returns(1).done();431}432433/*434* Super-call of non-default method435*436* interface I { int m(); }437* class C { int m() { return 1; } }438* class D extends C implements I { int m() { return I.super.m(); } }439* class E extends C implements I { int m() { return C.super.m(); } }440*441* TEST: I d = new D(); d.m() ==> AME442* TEST: C d = new D(); d.m() ==> AME443* TEST: D d = new D(); d.m() ==> AME444* TEST: I e = new E(); e.m() == 1445* TEST: C e = new E(); e.m() == 1446* TEST: E e = new E(); e.m() == 1447*/448public void testSuperNonDefault1(TestBuilder b) {449Interface I = b.intf("I")450.abstractMethod("m", "()I").build()451.build();452453ConcreteClass C = b.clazz("C")454.concreteMethod("m", "()I").returns(1).build()455.build();456457ConcreteClass D = b.clazz("D").extend(C).implement(I)458.concreteMethod("m", "()I").callSuper(I, "m", "()I").build()459.build();460461ConcreteClass E = b.clazz("E").extend(C).implement(I)462.concreteMethod("m", "()I").callSuper(C, "m", "()I").build()463.build();464465b.test().callSite(I, D, "m", "()I").throws_(AbstractMethodError.class).done()466.test().callSite(C, D, "m", "()I").throws_(AbstractMethodError.class).done()467.test().callSite(D, D, "m", "()I").throws_(AbstractMethodError.class).done()468469.test().callSite(I, E, "m", "()I").returns(1).done()470.test().callSite(C, E, "m", "()I").returns(1).done()471.test().callSite(E, E, "m", "()I").returns(1).done();472}473474/*475* Super-call of non-default method476*477* interface I { int m() {return 1;} }478* class C { int m() { return 2; } }479* class D extends C implements I { int m() { return I.super.m(); } }480* class E extends C implements I { int m() { return C.super.m(); } }481*482* TEST: I d = new D(); d.m() == 1483* TEST: C d = new D(); d.m() == 1484* TEST: D d = new D(); d.m() == 1485*486* TEST: I e = new E(); e.m() == 2487* TEST: C e = new E(); e.m() == 2488* TEST: E e = new E(); e.m() == 2489*/490public void testSuperNonDefault2(TestBuilder b) {491Interface I = b.intf("I")492.defaultMethod("m", "()I").returns(1).build()493.build();494495ConcreteClass C = b.clazz("C")496.concreteMethod("m", "()I").returns(2).build()497.build();498499ConcreteClass D = b.clazz("D").extend(C).implement(I)500.concreteMethod("m", "()I").callSuper(I, "m", "()I").build()501.build();502503ConcreteClass E = b.clazz("E").extend(C).implement(I)504.concreteMethod("m", "()I").callSuper(C, "m", "()I").build()505.build();506507b.test().callSite(I, D, "m", "()I").returns(1).done()508.test().callSite(C, D, "m", "()I").returns(1).done()509.test().callSite(D, D, "m", "()I").returns(1).done()510511.test().callSite(I, E, "m", "()I").returns(2).done()512.test().callSite(C, E, "m", "()I").returns(2).done()513.test().callSite(E, E, "m", "()I").returns(2).done();514}515516/*517* Disambig518*519* interface I { int m() default { return 1; } }520* interface J { int m() default { return 2; } }521* class C implements I, J { int q() { return I.super.m(); }522* int r() { return J.super.m(); } }523*524* TEST: C c = new C(); c.m() == ICCE;525* TEST: C c = new C(); c.q() == 1;526* TEST: C c = new C(); c.r() == 2;527*/528public void testDisambig(TestBuilder b) {529Interface I = b.intf("I")530.defaultMethod("m", "()I").returns(1).build()531.build();532533Interface J = b.intf("J")534.defaultMethod("m", "()I").returns(2).build()535.build();536537ConcreteClass C = b.clazz("C").implement(I,J)538.concreteMethod("q", "()I").callSuper(I, "m", "()I").build()539.concreteMethod("r", "()I").callSuper(J, "m", "()I").build()540.build();541542b.test().callSite(C, C, "q", "()I").returns(1).done()543.test().callSite(C, C, "r", "()I").returns(2).done()544.test().callSite(C, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done();545}546547/*548* Disambig2549*550* interface I { int m() default { return 1; } }551* interface J { int m() default { return 2; } }552* interface K extends I553* interface L extends J554* class C implements K, L { int q() { return K.super.m(); }555* int r() { return L.super.m(); } }556*557* TEST: C c = new C(); c.m() == ICCE;558* TEST: C c = new C(); c.q() == 1;559* TEST: C c = new C(); c.r() == 2;560*/561public void testDisambig2(TestBuilder b) {562Interface I = b.intf("I")563.defaultMethod("m", "()I").returns(1).build()564.build();565566Interface J = b.intf("J")567.defaultMethod("m", "()I").returns(2).build()568.build();569570Interface K = b.intf("K").extend(I).build();571572Interface L = b.intf("L").extend(J).build();573574ConcreteClass C = b.clazz("C").implement(K,L)575.concreteMethod("q", "()I").callSuper(K, "m", "()I").build()576.concreteMethod("r", "()I").callSuper(L, "m", "()I").build()577.build();578579b.test().callSite(C, C, "q", "()I").returns(1).done()580.test().callSite(C, C, "r", "()I").returns(2).done()581.test().callSite(C, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done();582}583584/*585* testResolvedShadowed586*587* interface I { int m() default { return 1; } }588* interface K extends I { int m() default { return 2; } }589* interface J extends I { }590* class C implements J,K { int q { J.super.m(); } }591*592* TEST: C c = new C(); c.m() == 2593* TEST: C c = new C(); c.q() == 1594*/595public void testResolvedShadowed(TestBuilder b) {596Interface I = b.intf("I")597.defaultMethod("m", "()I").returns(1).build()598.build();599600Interface K = b.intf("K").extend(I)601.defaultMethod("m", "()I").returns(2).build()602.build();603604Interface J = b.intf("J").extend(I)605.build();606607ConcreteClass C = b.clazz("C").implement(J,K)608.concreteMethod("q", "()I").callSuper(J, "m", "()I").build()609.build();610611b.test().callSite(C, C, "m", "()I").returns(2).done()612.test().callSite(C, C, "q", "()I").returns(1).done();613}614615/*616* testResolvedButSuperClass617*618* interface I { int m() default { return 1; } }619* interface J { }620* class A { public int m() { return 2; } }621* class C implements J extends A { int q { J.super.m(); } }622*623* TEST: C c = new C(); c.q() == 1624* TEST: C c = new C(); c.m() == 2625*/626public void testResolvedButSuperClass(TestBuilder b) {627Interface I = b.intf("I")628.defaultMethod("m", "()I").returns(1).build()629.build();630631Interface J = b.intf("J").extend(I)632.build();633634ConcreteClass A = b.clazz("A")635.concreteMethod("m", "()I").returns(2).build()636.build();637638ConcreteClass C = b.clazz("C").implement(J).extend(A)639.concreteMethod("q", "()I").callSuper(J, "m", "()I").build()640.build();641642b.test().callSite(C, C, "q", "()I").returns(1).done()643.test().callSite(C, C, "m", "()I").returns(2).done();644}645646/*647* testResolved1Caller2NotShadowed648*649* interface I { int m() default { return 1; } }650* interface J extends I { }651* interface L { int m() default { return 2; } }652* interface K extends I, L { }653* class C implements J,K { int q { J.super.m(); } }654*655* TEST: C c = new C(); c.m() == ICCE656* TEST: C c = new C(); c.q() == 1657*/658public void testResolved1Caller2NotShadowed(TestBuilder b) {659Interface I = b.intf("I")660.defaultMethod("m", "()I").returns(1).build()661.build();662663Interface J = b.intf("J").extend(I).build();664665Interface L = b.intf("L")666.defaultMethod("m", "()I").returns(2).build()667.build();668669Interface K = b.intf("K").extend(I,L)670.build();671672ConcreteClass C = b.clazz("C").implement(J,K)673.concreteMethod("q", "()I").callSuper(J, "m", "()I").build()674.build();675676b.test().callSite(C, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done()677.test().callSite(C, C, "q", "()I").returns(1).done();678}679680/*681* Test validity of invokespecial on indirect superinterface's method,682* this test should receive a verification error.683*684* JVMS-4.9.2 Structural Constraints685* Each invokespecial instruction must name an instance initialization686* method (2.9), or must reference a method in the current class or interface,687* a method in a superclass of the current class or interface, or a method688* in a direct superinterface of the current class or interface689*690* Note: Normally javac would reject this test case complaining that,691* InDirectSuper.java:5: error: not an enclosing class: I692* interface K extends J { default public void m() { I.super.m(); } }693* ^694* However, the below test case allows us to check for this structural695* constraint on invokespecial in the JVM.696*697* interface I { int m() default { return 1; } }698* interface J extends I { }699* interface K extends J { int m() default { return I.super.m(); } }700* class C implements K {}701*702* TEST: K k = new C(); k.m() == VerifyError703*/704@NotApplicableFor(modes = { REDEFINITION }) // Can't redefine a class that gets VerifyError705public void testSuperInvalidIndirectInterfaceMethodInvokeSpecial(TestBuilder b) {706Interface I = b.intf("I")707.defaultMethod("m", "()I").returns(1).build()708.build();709710Interface J = b.intf("J").extend(I).build();711712Interface K = b.intf("K").extend(J)713.defaultMethod("m", "()I").callSuper(I, "m", "()I").build()714.build();715716ConcreteClass C = b.clazz("C").implement(K).build();717718b.test().callSite(K, C, "m", "()I").throws_(VerifyError.class).done();719}720}721722723