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 
main(String[] args)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
testPrivateInvokeVirtual()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      */
testPrivateInvokeIntf()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      */
testPrivateInvokeStatic()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      */
testPrivateCallSameClass()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
testPrivateCallSubIntf()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
testPrivateCallImplClass()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      */
testPrivate()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      */
testPrivateVsConcrete()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      */
testPublicOverridePrivate()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      */
testPrivateOverrideDefault()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      */
testPrivateReabstract()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      */
testPrivateOverrideAbstract()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      */
testPrivateInherited()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      */
testPrivateVsConcreteInherited()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      */
testPrivateConflict()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      */
testPrivateSuperClassMethodNoDefaultMethod()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      */
testPrivateSuperClassMethodDefaultMethod()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      */
testPrivateSuperClassMethodDefaultMethodNoOverride()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 }
811