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.Crash;
  29 import vm.runtime.defmeth.shared.annotation.KnownFailure;
  30 import vm.runtime.defmeth.shared.annotation.NotApplicableFor;
  31 import vm.runtime.defmeth.shared.data.*;
  32 import static vm.runtime.defmeth.shared.data.method.body.CallMethod.Invoke.*;
  33 import static vm.runtime.defmeth.shared.data.method.body.CallMethod.IndexbyteOp.*;
  34 import vm.runtime.defmeth.shared.builder.TestBuilder;
  35 import static vm.runtime.defmeth.shared.ExecutionMode.*;
  36 
  37 /**
  38  * Scenarios on private methods in interfaces.
  39  */
  40 public class PrivateMethodsTest extends DefMethTest {
  41 
  42     public static void main(String[] args) {
  43         TestBase.runTest(new PrivateMethodsTest(), args);
  44     }
  45 
  46     // invokevirtual & invokeinterface from same/subintf
  47     // Spec change July 2013 to not allow invokevirtual or invokeinterface
  48     // to even see an interface private method
  49     // Throw ICCE if method resolution returns interface private method
  50 
  51     // Spec change JDK 11 - invokeinterface can be used for private interface
  52     // methods and is now the preferred invocation bytecode - so no ICCE.
  53     // Private methods are skipped during selection unless the resolved method
  54     // is private.
  55     // This change is not dependent on the classfile version.
  56 
  57     // Note on reflection testing:
  58     //   Reflection is only used for the initial callsite, which is not always
  59     //   the method of interest. For example where a default method m() calls
  60     //   the private interface method privateM(). It is the latter call we are
  61     //   really testing, but it is the call of the default method that occurs
  62     //   via reflection.
  63     //   In private cases reflection triggers a NoSuchMethodException instead of the
  64     //   expected IllegalAccessError. This indicates it is getDeclaredMethod() that is
  65     //   failing rather than the actual invoke(). Which in turn suggests the wrong class
  66     //   is being used, or that getMethod() is being used instead of getDeclaredMethod().
  67 
  68     /*
  69      * testPrivateInvokeVirtual
  70      *
  71      * interface I {
  72      *           private int privateM() { return 1; }
  73      *   default public  int m()        { return (I)this.privateM(); } // invokevirtual
  74      * }
  75      * class C implements I {}
  76      *
  77      * TEST: I o = new C(); o.m()I throws VerifyError
  78      * TEST: C o = new C(); o.m()I throws VerifyError
  79      */
  80     @NotApplicableFor(modes = { REDEFINITION }) // Can't redefine a class that gets error during loading
  81     public void testPrivateInvokeVirtual() {
  82         TestBuilder b = factory.getBuilder();
  83 
  84         Interface I = b.intf("I")
  85                 .defaultMethod("privateM", "()I")
  86                     .private_().returns(1).build()
  87 
  88                 // force an invokevirtual of an IMR to test verification code
  89                 .defaultMethod("m", "()I")
  90                     .invoke(VIRTUAL, b.intfByName("I"), null, "privateM", "()I", INTERFACEMETHODREF).build()
  91             .build();
  92 
  93         ConcreteClass C = b.clazz("C").implement(I).build();
  94 
  95         b.test().callSite(I, C, "m", "()I").throws_(VerifyError.class).done()
  96          .test().callSite(C, C, "m", "()I").throws_(VerifyError.class).done()
  97 
  98         .run();
  99     }
 100 
 101     /*
 102      * testPrivateInvokeIntf
 103      *
 104      * interface I {
 105      *           private int privateM() { return 1; }
 106      *   default public  int m()        { return (I)this.privateM(); } // invokeinterface
 107      * }
 108      * class C implements I {}
 109      *
 110      * TEST: I o = new C(); o.m()I returns 1
 111      * TEST: C o = new C(); o.m()I returns 1
 112      */
 113     public void testPrivateInvokeIntf() {
 114         TestBuilder b = factory.getBuilder();
 115 
 116         Interface I = b.intf("I")
 117                 .defaultMethod("privateM", "()I")
 118                     .private_().returns(1).build()
 119                 .defaultMethod("m", "()I")
 120                     .invoke(INTERFACE, b.intfByName("I"), null, "privateM", "()I", CALLSITE).build()
 121             .build();
 122 
 123         ConcreteClass C = b.clazz("C").implement(I).build();
 124 
 125         b.test().callSite(I, C, "m", "()I").returns(1).done()
 126          .test().callSite(C, C, "m", "()I").returns(1).done()
 127 
 128         .run();
 129     }
 130 
 131     /*
 132      * testPrivateInvokeStatic
 133      *
 134      * interface I {
 135      *           private int privateM() { return 1; }
 136      *   default public  int m()        { return I.privateM(); } // invokestatic
 137      * }
 138      * class C implements I {}
 139      *
 140      * TEST: I o = new C(); o.m()I throws IncompatibleClassChangeError
 141      * TEST: C o = new C(); o.m()I throws IncompatibleClassChangeError
 142      */
 143     public void testPrivateInvokeStatic() {
 144         TestBuilder b = factory.getBuilder();
 145 
 146         Interface I = b.intf("I")
 147                 .defaultMethod("privateM", "()I")
 148                     .private_().returns(1).build()
 149                 .defaultMethod("m", "()I")
 150                     .invoke(STATIC, b.intfByName("I"), null, "privateM", "()I", CALLSITE).build()
 151             .build();
 152 
 153         ConcreteClass C = b.clazz("C").implement(I).build();
 154 
 155         b.test().callSite(I, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done()
 156          .test().callSite(C, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done()
 157 
 158         .run();
 159     }
 160 
 161     // call from another default method in the same interface
 162     /*
 163      * testPrivateCallSameClass
 164      *
 165      * interface I {
 166      *           private privateM()I { return 1; }
 167      *   default public int m() { return I.super.privateM(); } // invokespecial
 168      * }
 169      * class C implements I {}
 170      *
 171      * TEST: { I o = new C(); o.m()I  == 1; }
 172      * TEST: { C o = new C(); o.m()I  == 1; }
 173      */
 174     public void testPrivateCallSameClass() {
 175         TestBuilder b = factory.getBuilder();
 176 
 177         Interface I = b.intf("I")
 178                 .defaultMethod("privateM", "()I")
 179                     .private_().returns(1).build()
 180                 .defaultMethod("m", "()I")
 181                     .invokeSpecial(b.intfByName("I"), "privateM", "()I").build()
 182             .build();
 183 
 184         ConcreteClass C = b.clazz("C").implement(I).build();
 185 
 186         b.test().callSite(I, C, "m", "()I").returns(1).done()
 187          .test().callSite(C, C, "m", "()I").returns(1).done()
 188 
 189         .run();
 190     }
 191 
 192     /*
 193      * testPrivateCallSubIntf
 194      *
 195      * Attempt to call from subinterface fails
 196 
 197      * interface I {
 198      *   private privateM()I { return 1; }
 199      * }
 200      * J, K, L use invokespecial
 201      * interface J extends I {
 202      *   default public int m() { return I.super.privateM(); }
 203      * }
 204      * interface K extends I {
 205      *   default public int m() { return K.super.privateM(); }
 206      * }
 207      * interface L extends J {
 208      *   default public int m() { return I.super.privateM(); }
 209      * }
 210      * class C implements J {}
 211      * class D implements K {}
 212      * class E implements L {}
 213      *
 214      * TEST: { J o = new C(); o.m()I throws IAE; }
 215      * TEST: { C o = new C(); o.m()I throws IAE; }
 216      * TEST: { K o = new D(); o.m()I throws NSME; } // does not see
 217      * TEST: { D o = new D(); o.m()I throws NSME; }
 218      * TEST: { L o = new E(); o.m()I throws VerifyError; } // VerifyError intfmethodref
 219      * TEST: { E o = new E(); o.m()I throws VerifyError; }
 220      */
 221     @NotApplicableFor(modes = { REDEFINITION }) // Can't redefine a class that gets error during loading
 222     public void testPrivateCallSubIntf() {
 223         TestBuilder b = factory.getBuilder();
 224 
 225         Interface I = b.intf("I")
 226                 .defaultMethod("privateM", "()I")
 227                     .private_().returns(1).build()
 228             .build();
 229 
 230         Interface J = b.intf("J").extend(I)
 231                 .defaultMethod("m", "()I")
 232                     .invokeSpecial(I, "privateM", "()I").build()
 233             .build();
 234 
 235         Interface K = b.intf("K").extend(J)
 236                 .defaultMethod("m", "()I")
 237                     .invokeSpecial(b.intfByName("K"), "privateM", "()I").build()
 238             .build();
 239 
 240         // L.privateM -> J -> L (I.privateM call)
 241         Interface L = b.intf("L").extend(J)
 242                 .defaultMethod("m", "()I")
 243                     .invokeSpecial(I, "privateM", "()I").build()
 244             .build();
 245 
 246         ConcreteClass C = b.clazz("C").implement(J).build();
 247 
 248         ConcreteClass D = b.clazz("D").implement(K).build();
 249 
 250         ConcreteClass E = b.clazz("E").implement(L).build();
 251 
 252         b.test().callSite(J, C, "m", "()I").throws_(IllegalAccessError.class).done()
 253          .test().callSite(C, C, "m", "()I").throws_(IllegalAccessError.class).done()
 254 
 255          .test().callSite(K, D, "m", "()I").throws_(NoSuchMethodError.class).done()
 256          .test().callSite(D, D, "m", "()I").throws_(NoSuchMethodError.class).done()
 257 
 258          .test().callSite(L, E, "m", "()I").throws_(VerifyError.class).done()
 259          .test().callSite(E, E, "m", "()I").throws_(VerifyError.class).done()
 260 
 261         .run();
 262     }
 263 
 264     /*
 265      * Attempt to call from subclass fails
 266      *
 267      * interface I {
 268      *   private privateM()I { return 1; }
 269      * }
 270      * class C implements I {
 271      *   public int m() { return I.super.privateM(); }
 272      * }
 273      * class D extends C {
 274      *   public int m() { return I.super.privateM(); }
 275      * }
 276      * class E extends C {
 277      *   public int m() { return C.super.privateM(); }
 278      * }
 279      *
 280      * TEST: { C o = new C(); o.m()I throws IllegalAccessError (or VerifyError) }
 281      * TEST: { D o = new D(); o.m()I throws VerifyError }
 282      * TEST: { E o = new E(); o.m()I throws NoSuchMethodError (or VerifyError); }
 283      */
 284     @NotApplicableFor(modes = { REDEFINITION }) // Can't redefine a class that gets error during loading
 285     public void testPrivateCallImplClass() {
 286         TestBuilder b = factory.getBuilder();
 287 
 288         Interface I = b.intf("I")
 289                 .defaultMethod("privateM", "()I")
 290                     .private_().returns(1).build()
 291             .build();
 292 
 293         ConcreteClass C = b.clazz("C").implement(I)
 294                 .concreteMethod("m", "()I")
 295                     .invokeSpecial(I, "privateM", "()I").build()
 296             .build();
 297 
 298         ConcreteClass D = b.clazz("D").extend(C)
 299                 .concreteMethod("m", "()I")
 300                     .invokeSpecial(I, "privateM", "()I").build()
 301             .build();
 302 
 303         ConcreteClass E = b.clazz("E").extend(C)
 304                 .concreteMethod("m", "()I")
 305                     .invokeSpecial(C, "privateM", "()I").build()
 306             .build();
 307 
 308         Class eeExpectedClass;
 309         Class ccExpectedClass;
 310         if (factory.getVer() >= 52) {
 311             eeExpectedClass = NoSuchMethodError.class;
 312             ccExpectedClass = IllegalAccessError.class;
 313         } else {
 314             // The test gets a VerifyError in this case due to an
 315             // invokespecial IMR bytecode.  This was not allowed
 316             // until class file version 52.  (See 8030249.)
 317             eeExpectedClass = VerifyError.class;
 318             ccExpectedClass = VerifyError.class;
 319         }
 320         b.test().callSite(C, C, "m", "()I").throws_(ccExpectedClass).done()
 321          .test().callSite(D, D, "m", "()I").throws_(VerifyError.class).done()
 322          .test().callSite(E, E, "m", "()I").throws_(eeExpectedClass).done()
 323 
 324         .run();
 325     }
 326 
 327     // doesn't participate in default method analysis
 328     //   method overriding
 329 
 330     /*
 331      * testPrivate
 332      *
 333      * interface I {
 334      *   private int m() { return 1; }
 335      * }
 336      * class C implements I {}
 337      *
 338      * TEST: { I o = new C(); o.m()I throws IllegalAccessError; }
 339      *                 -mode reflect throws NoSuchMethodException
 340      * TEST: { C o = new C(); o.m()I throws NoSuchMethodError; }
 341      */
 342     public void testPrivate() {
 343         TestBuilder b = factory.getBuilder();
 344 
 345         Interface I = b.intf("I")
 346                 .defaultMethod("m", "()I")
 347                     .private_().returns(1).build()
 348             .build();
 349 
 350         ConcreteClass C = b.clazz("C").implement(I).build();
 351 
 352         Class expectedClass;
 353         if (factory.getExecutionMode().equals("REFLECTION")) {
 354             expectedClass = NoSuchMethodException.class;
 355         } else {
 356             expectedClass = IllegalAccessError.class;
 357         }
 358 
 359         b.test().callSite(I, C, "m", "()I").throws_(expectedClass).done()
 360          .test().callSite(C, C, "m", "()I").throws_(NoSuchMethodError.class).done()
 361 
 362         .run();
 363     }
 364 
 365     /*
 366      * testPrivateVsConcrete
 367      *
 368      * interface I {
 369      *   private int m() { return 1; }
 370      * }
 371      * class C implements I {
 372      *   public int m() { return 2; }
 373      * }
 374      *
 375      * TEST: { I o = new C(); o.m()I  == IllegalAccessError; }
 376      *                 -mode reflect throws NoSuchMethodException
 377      * TEST: { C o = new C(); o.m()I  == 2; }
 378      */
 379     public void testPrivateVsConcrete() {
 380         TestBuilder b = factory.getBuilder();
 381 
 382         Interface I = b.intf("I")
 383                 .defaultMethod("m", "()I")
 384                     .private_().returns(1).build()
 385             .build();
 386 
 387         ConcreteClass C = b.clazz("C").implement(I)
 388                 .concreteMethod("m", "()I").returns(2).build()
 389             .build();
 390 
 391         Class expectedClass;
 392         if (factory.getExecutionMode().equals("REFLECTION")) {
 393             expectedClass = NoSuchMethodException.class;
 394         } else {
 395             expectedClass = IllegalAccessError.class;
 396         }
 397 
 398         b.test().callSite(I, C, "m", "()I").throws_(expectedClass).done()
 399          .test().callSite(C, C, "m", "()I").returns(2).done()
 400 
 401         .run();
 402     }
 403 
 404     /*
 405      * testPublicOverridePrivate
 406      *
 407      * interface I {
 408      *   private int m() { return 1; }
 409      * }
 410      * interface J extends I {
 411      *   default public int m() { return 2; }
 412      * }
 413      * class C implements J {}
 414      *
 415      * TEST: { I o = new C(); o.m()I throws IllegalAccessError; }
 416      *                 -mode reflect throws NoSuchMethodException
 417      * TEST: { J o = new C(); o.m()I  == 2; }
 418      * TEST: { C o = new C(); o.m()I  == 2; }
 419      */
 420     public void testPublicOverridePrivate() {
 421         TestBuilder b = factory.getBuilder();
 422 
 423         Interface I = b.intf("I")
 424                 .defaultMethod("m", "()I")
 425                     .private_().returns(1).build()
 426             .build();
 427 
 428         Interface J = b.intf("J").extend(I)
 429                 .defaultMethod("m", "()I")
 430                     .returns(2).build()
 431             .build();
 432 
 433         ConcreteClass C = b.clazz("C").implement(J).build();
 434 
 435         Class expectedClass;
 436         if (factory.getExecutionMode().equals("REFLECTION")) {
 437             expectedClass = NoSuchMethodException.class;
 438         } else {
 439             expectedClass = IllegalAccessError.class;
 440         }
 441 
 442         b.test().callSite(I, C, "m", "()I").throws_(expectedClass).done()
 443          .test().callSite(J, C, "m", "()I").returns(2).done()
 444          .test().callSite(C, C, "m", "()I").returns(2).done()
 445 
 446         .run();
 447     }
 448 
 449     /*
 450      * testPrivateOverrideDefault
 451      *
 452      * interface I {
 453      *   default public int m() { return 1; }
 454      * }
 455      * interface J extends I {
 456      *   private int m() { return 2; }
 457      * }
 458      * class C implements J {}
 459      *
 460      * TEST: { I o = new C(); o.m()I  == 1; }
 461      * TEST: { J o = new C(); o.m()I  == IllegalAccessError; } II J.m priv
 462      * TEST: { C o = new C(); o.m()I  == 1; }
 463      */
 464     public void testPrivateOverrideDefault() {
 465         TestBuilder b = factory.getBuilder();
 466 
 467         Interface I = b.intf("I")
 468                 .defaultMethod("m", "()I")
 469                     .returns(1).build()
 470             .build();
 471 
 472         Interface J = b.intf("J").extend(I)
 473                 .defaultMethod("m", "()I")
 474                     .private_().returns(2).build()
 475             .build();
 476 
 477         ConcreteClass C = b.clazz("C").implement(J).build();
 478 
 479         b.test().callSite(I, C, "m", "()I").returns(1).done()
 480          .test().privateCallSite(J, C, "m", "()I").throws_(IllegalAccessError.class).done()
 481          .test().callSite(C, C, "m", "()I").returns(1).done()
 482 
 483         .run();
 484     }
 485 
 486     /*
 487      * testPrivateReabstract
 488      *
 489      * interface I {
 490      *   private int m() { return 1; }
 491      * }
 492      * interface J extends I {
 493      *   abstract public int m();
 494      * }
 495      * class C implements J {}
 496      *
 497      * TEST: { I o = new C(); o.m()I throws IllegalAccessError; } II I.m
 498      *                 -mode reflect throws NoSuchMethodException
 499      * TEST: { J o = new C(); o.m()I throws java/lang/AbstractMethodError; }
 500      * TEST: { C o = new C(); o.m()I throws java/lang/AbstractMethodError; }
 501      */
 502     public void testPrivateReabstract() {
 503         TestBuilder b = factory.getBuilder();
 504 
 505         Interface I = b.intf("I")
 506                 .defaultMethod("m", "()I")
 507                     .private_().returns(1).build()
 508             .build();
 509 
 510         Interface J = b.intf("J").extend(I)
 511                 .abstractMethod("m", "()I").build()
 512             .build();
 513 
 514         ConcreteClass C = b.clazz("C").implement(J).build();
 515 
 516         Class expectedClass;
 517         if (factory.getExecutionMode().equals("REFLECTION")) {
 518             expectedClass = NoSuchMethodException.class;
 519         } else {
 520             expectedClass = IllegalAccessError.class;
 521         }
 522 
 523         b.test().callSite(I, C, "m", "()I").throws_(expectedClass).done()
 524          .test().callSite(J, C, "m", "()I").throws_(AbstractMethodError.class).done()
 525          .test().callSite(C, C, "m", "()I").throws_(AbstractMethodError.class).done()
 526 
 527         .run();
 528     }
 529 
 530     /*
 531      * testPrivateOverrideAbstract
 532      *
 533      * interface I {
 534      *   abstract public int m();
 535      * }
 536      * interface J extends I {
 537      *   private int m() { return 1; }
 538      * }
 539      * class C implements J {}
 540      *
 541      * TEST: { I o = new C(); o.m()I throws AbstractMethodError }
 542      * TEST: { J o = new C(); o.m()I throws IllegalAccessError }
 543      * TEST: { C o = new C(); o.m()I throws AbstractMethodError }
 544      */
 545     public void testPrivateOverrideAbstract() {
 546         TestBuilder b = factory.getBuilder();
 547 
 548         Interface I = b.intf("I")
 549                 .abstractMethod("m", "()I").build()
 550             .build();
 551 
 552         Interface J = b.intf("J").extend(I)
 553                 .defaultMethod("m", "()I")
 554                     .private_().returns(1).build()
 555             .build();
 556 
 557         ConcreteClass C = b.clazz("C").implement(J).build();
 558 
 559         b.test().callSite(I, C, "m", "()I").throws_(AbstractMethodError.class).done()
 560          .test().privateCallSite(J, C, "m", "()I").throws_(IllegalAccessError.class).done()
 561          .test().callSite(C, C, "m", "()I").throws_(AbstractMethodError.class).done()
 562          .run();
 563     }
 564 
 565     /*
 566      * testPrivateInherited
 567      *
 568      * interface I {
 569      *   private int m() { return 1; }
 570      * }
 571      * class B implements I {}
 572      * class C extends B {}
 573      *
 574      * TEST: { I o = new C(); o.m()I throws IllegalAccessError } II I.m
 575      *                 -mode reflect throws NoSuchMethodException
 576      * TEST: { B o = new C(); o.m()I throws NoSuchMethodError }
 577      * TEST: { C o = new C(); o.m()I throws NoSuchMethodError }
 578      */
 579     public void testPrivateInherited() {
 580         TestBuilder b = factory.getBuilder();
 581 
 582         Interface I = b.intf("I")
 583                 .defaultMethod("m", "()I")
 584                     .private_().returns(1).build()
 585             .build();
 586 
 587         ConcreteClass B = b.clazz("B").implement(I).build();
 588         ConcreteClass C = b.clazz("C").extend(B).build();
 589 
 590         Class expectedClass;
 591         if (factory.getExecutionMode().equals("REFLECTION")) {
 592             expectedClass = NoSuchMethodException.class;
 593         } else {
 594             expectedClass = IllegalAccessError.class;
 595         }
 596 
 597         b.test().callSite(I, C, "m","()I").throws_(expectedClass).done()
 598          .test().callSite(B, C, "m","()I").throws_(NoSuchMethodError.class).done()
 599          .test().callSite(C, C, "m","()I").throws_(NoSuchMethodError.class).done()
 600 
 601         .run();
 602 
 603     }
 604 
 605     /*
 606      * testPrivateVsConcreteInherited
 607      *
 608      * interface I {
 609      *    private int m() { return 1; }
 610      * }
 611      * class B {
 612      *   public int m() { return 2; }
 613      * }
 614      * class C extends B implements I {}
 615      *
 616      * TEST: { I o = new C(); o.m()I  == throws IllegalAccessError; }
 617      *                     -mode reflect throws NoSuchMethodException
 618      * TEST: { B o = new C(); o.m()I  == 2; }
 619      * TEST: { C o = new C(); o.m()I  == 2; }
 620      */
 621     public void testPrivateVsConcreteInherited() {
 622         TestBuilder b = factory.getBuilder();
 623 
 624         Interface I = b.intf("I")
 625                 .defaultMethod("m", "()I")
 626                     .private_().returns(1).build()
 627             .build();
 628 
 629         ConcreteClass B = b.clazz("B")
 630                 .concreteMethod("m", "()I").returns(2).build()
 631                 .build();
 632 
 633         ConcreteClass C = b.clazz("C").extend(B).implement(I).build();
 634 
 635         Class expectedClass;
 636         if (factory.getExecutionMode().equals("REFLECTION")) {
 637             expectedClass = NoSuchMethodException.class;
 638         } else {
 639             expectedClass = IllegalAccessError.class;
 640         }
 641 
 642         b.test().callSite(I, C, "m","()I").throws_(expectedClass).done()
 643          .test().callSite(B, C, "m","()I").returns(2).done()
 644          .test().callSite(C, C, "m","()I").returns(2).done()
 645 
 646         .run();
 647     }
 648 
 649     /*
 650      * testPrivateConflict
 651      *
 652      * Conflicting methods
 653      *
 654      * interface I {
 655      *   private int m() { return 1; }
 656      * }
 657      * interface J {
 658      *   default public int m() { return 2; }
 659      * }
 660      * class C implements I, J {}
 661      *
 662      * TEST: { I o = new C(); o.m()I throws IllegalAccessError; }
 663      *                 -mode reflect throws NoSuchMethodException
 664      * TEST: { J o = new C(); o.m()I  == 2; }
 665      * TEST: { C o = new C(); o.m()I  == 2; }
 666      */
 667     public void testPrivateConflict() {
 668         TestBuilder b = factory.getBuilder();
 669 
 670         Interface I = b.intf("I")
 671                 .defaultMethod("m", "()I").private_().returns(1).build()
 672             .build();
 673 
 674         Interface J = b.intf("J")
 675                 .defaultMethod("m", "()I").returns(2).build()
 676             .build();
 677 
 678         ConcreteClass C = b.clazz("C").implement(I,J).build();
 679 
 680         Class expectedClass;
 681         if (factory.getExecutionMode().equals("REFLECTION")) {
 682             expectedClass = NoSuchMethodException.class;
 683         } else {
 684             expectedClass = IllegalAccessError.class;
 685         }
 686 
 687         b.test().callSite(I, C, "m", "()I").throws_(expectedClass).done()
 688          .test().callSite(J, C, "m", "()I").returns(2).done()
 689          .test().callSite(C, C, "m", "()I").returns(2).done()
 690 
 691         .run();
 692     }
 693     /*
 694      * testPrivateSuperClassMethodNoDefaultMethod
 695      *
 696      * interface I {
 697      *  public int m();
 698      * }
 699      *
 700      * public class A {
 701      *  private int m() { return 1; }
 702      * }
 703      *
 704      * public class B extends A implements I {}
 705      *
 706      * public class C extends B {
 707      *  public int m() { return 2; }
 708      * }
 709      *
 710      * TEST: { B b = new C(); b.m()I throws IllegalAccessError; }
 711      */
 712     public void testPrivateSuperClassMethodNoDefaultMethod() {
 713         TestBuilder b = factory.getBuilder();
 714 
 715         ConcreteClass A = b.clazz("A")
 716                 .concreteMethod("m", "()I").private_().returns(1).build()
 717                 .build();
 718 
 719         Interface I = b.intf("I")
 720                 .abstractMethod("m", "()I").public_().build()
 721                 .build();
 722 
 723         ConcreteClass B = b.clazz("B").extend(A).implement(I).build();
 724 
 725         ConcreteClass C = b.clazz("C").extend(B)
 726                 .concreteMethod("m", "()I").public_().returns(2).build()
 727                 .build();
 728 
 729         b.test().privateCallSite(B, C, "m", "()I").throws_(IllegalAccessError.class).done()
 730         .run();
 731 
 732     }
 733 
 734     /*
 735      * testPrivateSuperClassMethodDefaultMethod
 736      *
 737      * interface I {
 738      *  public default int m() { return 3; }
 739      * }
 740      *
 741      * public class A {
 742      *  private int m() { return 1; }
 743      * }
 744      *
 745      * public class B extends A implements I {}
 746      *
 747      * public class C extends B {
 748      *  public int m() { return 2; }
 749      * }
 750      *
 751      * TEST: { B b = new C(); b.m()I throws IllegalAccessError; }
 752      */
 753     public void testPrivateSuperClassMethodDefaultMethod() {
 754         TestBuilder b = factory.getBuilder();
 755 
 756         ConcreteClass A = b.clazz("A")
 757                 .concreteMethod("m", "()I").private_().returns(1).build()
 758                 .build();
 759 
 760         Interface I = b.intf("I")
 761                 .defaultMethod("m", "()I").public_().returns(3).build()
 762                 .build();
 763 
 764         ConcreteClass B = b.clazz("B").extend(A).implement(I).build();
 765 
 766         ConcreteClass C = b.clazz("C").extend(B)
 767                 .concreteMethod("m", "()I").public_().returns(2).build()
 768                 .build();
 769 
 770         b.test().privateCallSite(B, C, "m", "()I").throws_(IllegalAccessError.class).done()
 771         .run();
 772     }
 773 
 774     /*
 775      * testPrivateSuperClassMethodDefaultMethodNoOverride
 776      *
 777      * interface I {
 778      *  public default int m() { return 3; }
 779      * }
 780      *
 781      * public class A {
 782      *  private int m() { return 1; }
 783      * }
 784      *
 785      * public class B extends A implements I {}
 786      *
 787      * public class C extends B { }
 788      *
 789      * TEST: { B b = new C(); b.m()I throws IllegalAccessError; }
 790      */
 791     public void testPrivateSuperClassMethodDefaultMethodNoOverride() {
 792         TestBuilder b = factory.getBuilder();
 793 
 794         ConcreteClass A = b.clazz("A")
 795                 .concreteMethod("m", "()I").private_().returns(1).build()
 796                 .build();
 797 
 798         Interface I = b.intf("I")
 799                 .defaultMethod("m", "()I").public_().returns(3).build()
 800                 .build();
 801 
 802         ConcreteClass B = b.clazz("B").extend(A).implement(I).build();
 803 
 804         ConcreteClass C = b.clazz("C").extend(B).build();
 805 
 806         b.test().privateCallSite(B, C, "m", "()I").throws_(IllegalAccessError.class).done()
 807         .run();
 808     }
 809 
 810 }