test/hotspot/jtreg/vmTestbase/vm/runtime/defmeth/SuperCallTest.java
changeset 50243 4fac3c99487d
equal deleted inserted replaced
50242:9a87afc49148 50243:4fac3c99487d
       
     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 }