46 // invokevirtual & invokeinterface from same/subintf |
46 // invokevirtual & invokeinterface from same/subintf |
47 // Spec change July 2013 to not allow invokevirtual or invokeinterface |
47 // Spec change July 2013 to not allow invokevirtual or invokeinterface |
48 // to even see an interface private method |
48 // to even see an interface private method |
49 // Throw ICCE if method resolution returns interface private method |
49 // Throw ICCE if method resolution returns interface private method |
50 |
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 |
51 /* |
68 /* |
52 * testPrivateInvokeVirtual |
69 * testPrivateInvokeVirtual |
53 * |
70 * |
54 * interface I { |
71 * interface I { |
55 * default private int privateM() { return 1; } |
72 * private int privateM() { return 1; } |
56 * default public int m() { return (I)this.privateM(); } // invokevirtual |
73 * default public int m() { return (I)this.privateM(); } // invokevirtual |
57 * } |
74 * } |
58 * class C implements I {} |
75 * class C implements I {} |
59 * |
76 * |
60 * TEST: I o = new C(); o.m()I throws VerifyError |
77 * TEST: I o = new C(); o.m()I throws VerifyError |
83 |
100 |
84 /* |
101 /* |
85 * testPrivateInvokeIntf |
102 * testPrivateInvokeIntf |
86 * |
103 * |
87 * interface I { |
104 * interface I { |
88 * default private int privateM() { return 1; } |
105 * private int privateM() { return 1; } |
89 * default public int m() { return (I)this.privateM(); } // invokeinterface |
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 |
90 * } |
137 * } |
91 * class C implements I {} |
138 * class C implements I {} |
92 * |
139 * |
93 * TEST: I o = new C(); o.m()I throws IncompatibleClassChangeError |
140 * TEST: I o = new C(); o.m()I throws IncompatibleClassChangeError |
94 * TEST: C o = new C(); o.m()I throws IncompatibleClassChangeError |
141 * TEST: C o = new C(); o.m()I throws IncompatibleClassChangeError |
95 */ |
142 */ |
96 public void testPrivateInvokeIntf() { |
143 public void testPrivateInvokeStatic() { |
97 TestBuilder b = factory.getBuilder(); |
144 TestBuilder b = factory.getBuilder(); |
98 |
145 |
99 Interface I = b.intf("I") |
146 Interface I = b.intf("I") |
100 .defaultMethod("privateM", "()I") |
147 .defaultMethod("privateM", "()I") |
101 .private_().returns(1).build() |
148 .private_().returns(1).build() |
102 .defaultMethod("m", "()I") |
149 .defaultMethod("m", "()I") |
103 .invoke(INTERFACE, b.intfByName("I"), null, "privateM", "()I", CALLSITE).build() |
150 .invoke(STATIC, b.intfByName("I"), null, "privateM", "()I", CALLSITE).build() |
104 .build(); |
151 .build(); |
105 |
152 |
106 ConcreteClass C = b.clazz("C").implement(I).build(); |
153 ConcreteClass C = b.clazz("C").implement(I).build(); |
107 |
154 |
108 b.test().callSite(I, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done() |
155 b.test().callSite(I, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done() |
109 .test().callSite(C, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done() |
156 .test().callSite(C, C, "m", "()I").throws_(IncompatibleClassChangeError.class).done() |
110 |
157 |
111 .run(); |
158 .run(); |
112 } |
159 } |
113 |
160 |
114 /* |
|
115 * testPrivateInvokeStatic |
|
116 * |
|
117 * interface I { |
|
118 * default private int privateM() { return 1; } |
|
119 * default public int m() { return I.privateM(); } // invokestatic |
|
120 * } |
|
121 * class C implements I {} |
|
122 * |
|
123 * TEST: I o = new C(); o.m()I throws LinkageError |
|
124 * TEST: C o = new C(); o.m()I throws LinkageError |
|
125 */ |
|
126 public void testPrivateInvokeStatic() { |
|
127 TestBuilder b = factory.getBuilder(); |
|
128 |
|
129 Interface I = b.intf("I") |
|
130 .defaultMethod("privateM", "()I") |
|
131 .private_().returns(1).build() |
|
132 .defaultMethod("m", "()I") |
|
133 .invoke(STATIC, b.intfByName("I"), null, "privateM", "()I", CALLSITE).build() |
|
134 .build(); |
|
135 |
|
136 ConcreteClass C = b.clazz("C").implement(I).build(); |
|
137 |
|
138 b.test().callSite(I, C, "m", "()I").throws_(LinkageError.class).done() |
|
139 .test().callSite(C, C, "m", "()I").throws_(LinkageError.class).done() |
|
140 |
|
141 .run(); |
|
142 } |
|
143 |
|
144 // call from another default method in the same interface |
161 // call from another default method in the same interface |
145 /* |
162 /* |
146 * testPrivateCallSameClass |
163 * testPrivateCallSameClass |
147 * |
164 * |
148 * interface I { |
165 * interface I { |
149 * default private privateM()I { return 1; } |
166 * private privateM()I { return 1; } |
150 * default public int m() { return I.super.privateM(); } |
167 * default public int m() { return I.super.privateM(); } // invokespecial |
151 * } |
168 * } |
152 * class C implements I {} |
169 * class C implements I {} |
153 * |
170 * |
154 * TEST: { I o = new C(); o.m()I == 1; } |
171 * TEST: { I o = new C(); o.m()I == 1; } |
155 * TEST: { C o = new C(); o.m()I == 1; } |
172 * TEST: { C o = new C(); o.m()I == 1; } |
287 .concreteMethod("m", "()I") |
304 .concreteMethod("m", "()I") |
288 .invokeSpecial(C, "privateM", "()I").build() |
305 .invokeSpecial(C, "privateM", "()I").build() |
289 .build(); |
306 .build(); |
290 |
307 |
291 Class eeExpectedClass; |
308 Class eeExpectedClass; |
|
309 Class ccExpectedClass; |
292 if (factory.getVer() >= 52) { |
310 if (factory.getVer() >= 52) { |
293 eeExpectedClass = NoSuchMethodError.class; |
311 eeExpectedClass = NoSuchMethodError.class; |
|
312 ccExpectedClass = IllegalAccessError.class; |
294 } else { |
313 } else { |
295 // The test gets a VerifyError in this case due to an |
314 // The test gets a VerifyError in this case due to an |
296 // invokespecial IMR bytecode. This was not allowed |
315 // invokespecial IMR bytecode. This was not allowed |
297 // until class file version 52. (See 8030249.) |
316 // until class file version 52. (See 8030249.) |
298 eeExpectedClass = VerifyError.class; |
317 eeExpectedClass = VerifyError.class; |
|
318 ccExpectedClass = VerifyError.class; |
299 } |
319 } |
300 b.test().callSite(C, C, "m", "()I").throws_(LinkageError.class).done() |
320 b.test().callSite(C, C, "m", "()I").throws_(ccExpectedClass).done() |
301 .test().callSite(D, D, "m", "()I").throws_(LinkageError.class).done() |
321 .test().callSite(D, D, "m", "()I").throws_(VerifyError.class).done() |
302 .test().callSite(E, E, "m", "()I").throws_(eeExpectedClass).done() |
322 .test().callSite(E, E, "m", "()I").throws_(eeExpectedClass).done() |
303 |
323 |
304 .run(); |
324 .run(); |
305 } |
325 } |
306 |
326 |
307 // doesn't participate in default method analysis |
327 // doesn't participate in default method analysis |
308 // method overriding |
328 // method overriding |
309 |
329 |
310 /* |
330 /* |
311 * testPrivateDefault |
331 * testPrivate |
312 * |
332 * |
313 * interface I { |
333 * interface I { |
314 * default private int m() { return 1; } |
334 * private int m() { return 1; } |
315 * } |
335 * } |
316 * class C implements I {} |
336 * class C implements I {} |
317 * |
337 * |
318 * TEST: { I o = new C(); o.m()I throws IllegalAccessError; } |
338 * TEST: { I o = new C(); o.m()I throws IllegalAccessError; } |
319 * -mode reflect throws NoSuchMethodException |
339 * -mode reflect throws NoSuchMethodException |
320 * TEST: { C o = new C(); o.m()I throws java/lang/NoSuchMethodError; } |
340 * TEST: { C o = new C(); o.m()I throws NoSuchMethodError; } |
321 */ |
341 */ |
322 public void testPrivateDefault() { |
342 public void testPrivate() { |
323 TestBuilder b = factory.getBuilder(); |
343 TestBuilder b = factory.getBuilder(); |
324 |
344 |
325 Interface I = b.intf("I") |
345 Interface I = b.intf("I") |
326 .defaultMethod("m", "()I") |
346 .defaultMethod("m", "()I") |
327 .private_().returns(1).build() |
347 .private_().returns(1).build() |
341 |
361 |
342 .run(); |
362 .run(); |
343 } |
363 } |
344 |
364 |
345 /* |
365 /* |
346 * testPrivateDefaultVsConcrete |
366 * testPrivateVsConcrete |
347 * |
367 * |
348 * interface I { |
368 * interface I { |
349 * default private int m() { return 1; } |
369 * private int m() { return 1; } |
350 * } |
370 * } |
351 * class C implements I { |
371 * class C implements I { |
352 * public int m() { return 2; } |
372 * public int m() { return 2; } |
353 * } |
373 * } |
354 * |
374 * |
355 * TEST: { I o = new C(); o.m()I == IllegalAccessError; } |
375 * TEST: { I o = new C(); o.m()I == IllegalAccessError; } |
356 * -mode reflect throws NoSuchMethodException |
376 * -mode reflect throws NoSuchMethodException |
357 * TEST: { C o = new C(); o.m()I == 2; } |
377 * TEST: { C o = new C(); o.m()I == 2; } |
358 */ |
378 */ |
359 public void testPrivateDefaultVsConcrete() { |
379 public void testPrivateVsConcrete() { |
360 TestBuilder b = factory.getBuilder(); |
380 TestBuilder b = factory.getBuilder(); |
361 |
381 |
362 Interface I = b.intf("I") |
382 Interface I = b.intf("I") |
363 .defaultMethod("m", "()I") |
383 .defaultMethod("m", "()I") |
364 .private_().returns(1).build() |
384 .private_().returns(1).build() |
431 * |
451 * |
432 * interface I { |
452 * interface I { |
433 * default public int m() { return 1; } |
453 * default public int m() { return 1; } |
434 * } |
454 * } |
435 * interface J extends I { |
455 * interface J extends I { |
436 * default private int m() { return 2; } |
456 * private int m() { return 2; } |
437 * } |
457 * } |
438 * class C implements J {} |
458 * class C implements J {} |
439 * |
459 * |
440 * TEST: { I o = new C(); o.m()I == 1; } |
460 * TEST: { I o = new C(); o.m()I == 1; } |
441 * TEST: { J o = new C(); o.m()I == IllegalAccessError; } II J.m priv |
461 * TEST: { J o = new C(); o.m()I == IllegalAccessError; } II J.m priv |
442 * TEST: { C o = new C(); o.m()I == 1; } |
462 * TEST: { C o = new C(); o.m()I == 1; } |
443 */ |
463 */ |
444 /* |
|
445 |
|
446 REFLECTION: |
|
447 Test2_J_C_m : FAILED |
|
448 nsk.share.TestFailure: Caught exception as expected, but its type is wrong: |
|
449 expected: java.lang.IllegalAccessError; |
|
450 actual: java.lang.NoSuchMethodException. |
|
451 */ |
|
452 public void testPrivateOverrideDefault() { |
464 public void testPrivateOverrideDefault() { |
453 TestBuilder b = factory.getBuilder(); |
465 TestBuilder b = factory.getBuilder(); |
454 |
466 |
455 Interface I = b.intf("I") |
467 Interface I = b.intf("I") |
456 .defaultMethod("m", "()I") |
468 .defaultMethod("m", "()I") |
520 * |
532 * |
521 * interface I { |
533 * interface I { |
522 * abstract public int m(); |
534 * abstract public int m(); |
523 * } |
535 * } |
524 * interface J extends I { |
536 * interface J extends I { |
525 * default private int m() { return 1; } |
537 * private int m() { return 1; } |
526 * } |
538 * } |
527 * class C implements J {} |
539 * class C implements J {} |
528 * |
540 * |
529 * TEST: { I o = new C(); o.m()I throws AbstractMethodError } |
541 * TEST: { I o = new C(); o.m()I throws AbstractMethodError } |
530 * TEST: { J o = new C(); o.m()I throws IncompatibleClassChangeError } |
542 * TEST: { J o = new C(); o.m()I throws IllegalAccessError } |
531 * TEST: { C o = new C(); o.m()I throws AbstractMethodError } |
543 * TEST: { C o = new C(); o.m()I throws AbstractMethodError } |
532 */ |
544 */ |
533 /* |
|
534 REFLECTION: |
|
535 Test1_I_C_m : FAILED |
|
536 nsk.share.TestFailure: No exception was thrown: java.lang.AbstractMethodError |
|
537 Test2_J_C_m : FAILED |
|
538 nsk.share.TestFailure: No exception was thrown: java.lang.AbstractMethodError |
|
539 Test3_C_C_m : FAILED |
|
540 nsk.share.TestFailure: No exception was thrown: java.lang.AbstractMethodError |
|
541 */ |
|
542 public void testPrivateOverrideAbstract() { |
545 public void testPrivateOverrideAbstract() { |
543 TestBuilder b = factory.getBuilder(); |
546 TestBuilder b = factory.getBuilder(); |
544 |
547 |
545 Interface I = b.intf("I") |
548 Interface I = b.intf("I") |
546 .abstractMethod("m", "()I").build() |
549 .abstractMethod("m", "()I").build() |
551 .private_().returns(1).build() |
554 .private_().returns(1).build() |
552 .build(); |
555 .build(); |
553 |
556 |
554 ConcreteClass C = b.clazz("C").implement(J).build(); |
557 ConcreteClass C = b.clazz("C").implement(J).build(); |
555 |
558 |
556 Class expectedClass; |
|
557 if (factory.getExecutionMode().equals("REFLECTION")) { |
|
558 expectedClass = IllegalAccessException.class; |
|
559 } else { |
|
560 expectedClass = IncompatibleClassChangeError.class; |
|
561 } |
|
562 |
|
563 b.test().callSite(I, C, "m", "()I").throws_(AbstractMethodError.class).done() |
559 b.test().callSite(I, C, "m", "()I").throws_(AbstractMethodError.class).done() |
564 .test().privateCallSite(J, C, "m", "()I").throws_(expectedClass).done() |
560 .test().privateCallSite(J, C, "m", "()I").throws_(IllegalAccessError.class).done() |
565 .test().callSite(C, C, "m", "()I").throws_(AbstractMethodError.class).done() |
561 .test().callSite(C, C, "m", "()I").throws_(AbstractMethodError.class).done() |
566 .run(); |
562 .run(); |
567 } |
563 } |
568 |
564 |
569 /* |
565 /* |
570 * testPrivateInheritedDefault |
566 * testPrivateInherited |
571 * |
567 * |
572 * interface I { |
568 * interface I { |
573 * default private int m() { return 1; } |
569 * private int m() { return 1; } |
574 * } |
570 * } |
575 * class B implements I {} |
571 * class B implements I {} |
576 * class C extends B {} |
572 * class C extends B {} |
577 * |
573 * |
578 * TEST: { I o = new C(); o.m()I throws IllegalAccessError } II I.m |
574 * TEST: { I o = new C(); o.m()I throws IllegalAccessError } II I.m |
579 * -mode reflect throws NoSuchMethodException |
575 * -mode reflect throws NoSuchMethodException |
580 * TEST: { B o = new C(); o.m()I throws NoSuchMethodError } |
576 * TEST: { B o = new C(); o.m()I throws NoSuchMethodError } |
581 * TEST: { C o = new C(); o.m()I throws NoSuchMethodError } |
577 * TEST: { C o = new C(); o.m()I throws NoSuchMethodError } |
582 */ |
578 */ |
583 public void testPrivateInheritedDefault() { |
579 public void testPrivateInherited() { |
584 TestBuilder b = factory.getBuilder(); |
580 TestBuilder b = factory.getBuilder(); |
585 |
581 |
586 Interface I = b.intf("I") |
582 Interface I = b.intf("I") |
587 .defaultMethod("m", "()I") |
583 .defaultMethod("m", "()I") |
588 .private_().returns(1).build() |
584 .private_().returns(1).build() |