diff options
| -rw-r--r-- | test/181-default-methods/expected-stdout.txt | 1 | ||||
| -rw-r--r-- | test/181-default-methods/src/Main.java | 116 |
2 files changed, 117 insertions, 0 deletions
diff --git a/test/181-default-methods/expected-stdout.txt b/test/181-default-methods/expected-stdout.txt index 987ba9e71d..6005a9f3db 100644 --- a/test/181-default-methods/expected-stdout.txt +++ b/test/181-default-methods/expected-stdout.txt @@ -65,3 +65,4 @@ Output from Default_D1_D2_D3M_x_D1D2D: D1D2D.testMethod() Miranda in class Miranda_D1_D2_D3M_x_D1D2M Output from Default_D1_D2_D3M_x_AD1D2D: AD1D2D.testMethod() Miranda in class Miranda_D1_D2_D3M_x_AD1D2M +B215510819 test result: D1.testMethod() diff --git a/test/181-default-methods/src/Main.java b/test/181-default-methods/src/Main.java index a6138add46..c4bf158847 100644 --- a/test/181-default-methods/src/Main.java +++ b/test/181-default-methods/src/Main.java @@ -158,6 +158,16 @@ public class Main { expectMiranda(new Miranda_D1_D2_D3M_x_D1D2M()); expectDefault(new Default_D1_D2_D3M_x_AD1D2D()); expectMiranda(new Miranda_D1_D2_D3M_x_AD1D2M()); + + regressionTestB215510819(); + } + + static public void regressionTestB215510819() { + // The failure to fill IMT correctly would have resulted in calling the wrong method, + // or triggering a check when interpreting in debug mode. + Abstract abstractTarget = new B215510819Test(); + String result = abstractTarget.testMethod(); + System.out.println("B215510819 test result: " + result); } } @@ -233,3 +243,109 @@ class Default_D1_D2_D3M_x_D1D2D extends Conflict_D1_D2_D3M implements D1D2D {} class Miranda_D1_D2_D3M_x_AD1D2M extends Conflict_D1_D2_D3M implements AD1D2M {} class Default_D1_D2_D3M_x_AD1D2D extends Conflict_D1_D2_D3M implements AD1D2D {} +interface B215510819Iface { + // The IMT size is currently 43 and we want to cover all 43 indexes with non-copied + // implementations. The IMT index for abstract methods is calculated with a hash that + // includes the method name, so 43 consecutive characters in the method name would be best. + // (The fact that the name hash is multiplied by 16 is OK because the size of the IMT is a + // prime number and thus GCD(16, 43) = 1.) However, we do not have a contiguous range of 43 + // valid characters, so we need to rely on the `hash % 43` to mask out the difference when + // we use `0`..`5` between `Z` and `a`. ('Z' + 1 - 43 = '0' and '5' + 1 + 43 = 'a'.) + String method_A(); + String method_B(); + String method_C(); + String method_D(); + String method_E(); + String method_F(); + String method_G(); + String method_H(); + String method_I(); + String method_J(); + String method_K(); + String method_L(); + String method_M(); + String method_N(); + String method_O(); + String method_P(); + String method_Q(); + String method_R(); + String method_S(); + String method_T(); + String method_U(); + String method_V(); + String method_W(); + String method_X(); + String method_Y(); + String method_Z(); + String method_0(); + String method_1(); + String method_2(); + String method_3(); + String method_4(); + String method_5(); + String method_a(); + String method_b(); + String method_c(); + String method_d(); + String method_e(); + String method_f(); + String method_g(); + String method_h(); + String method_i(); + String method_j(); + String method_k(); +} +// Note: Marked as abstract to avoid IMT table in this class. +abstract class B215510819Base extends Default_D1 implements B215510819Iface { + public String method_A() { return "B215510819 - wrong method_A!"; } + public String method_B() { return "B215510819 - wrong method_B!"; } + public String method_C() { return "B215510819 - wrong method_C!"; } + public String method_D() { return "B215510819 - wrong method_D!"; } + public String method_E() { return "B215510819 - wrong method_E!"; } + public String method_F() { return "B215510819 - wrong method_F!"; } + public String method_G() { return "B215510819 - wrong method_G!"; } + public String method_H() { return "B215510819 - wrong method_H!"; } + public String method_I() { return "B215510819 - wrong method_I!"; } + public String method_J() { return "B215510819 - wrong method_J!"; } + public String method_K() { return "B215510819 - wrong method_K!"; } + public String method_L() { return "B215510819 - wrong method_L!"; } + public String method_M() { return "B215510819 - wrong method_M!"; } + public String method_N() { return "B215510819 - wrong method_N!"; } + public String method_O() { return "B215510819 - wrong method_O!"; } + public String method_P() { return "B215510819 - wrong method_P!"; } + public String method_Q() { return "B215510819 - wrong method_Q!"; } + public String method_R() { return "B215510819 - wrong method_R!"; } + public String method_S() { return "B215510819 - wrong method_S!"; } + public String method_T() { return "B215510819 - wrong method_T!"; } + public String method_U() { return "B215510819 - wrong method_U!"; } + public String method_V() { return "B215510819 - wrong method_V!"; } + public String method_W() { return "B215510819 - wrong method_W!"; } + public String method_X() { return "B215510819 - wrong method_X!"; } + public String method_Y() { return "B215510819 - wrong method_Y!"; } + public String method_Z() { return "B215510819 - wrong method_Z!"; } + public String method_0() { return "B215510819 - wrong method_0!"; } + public String method_1() { return "B215510819 - wrong method_1!"; } + public String method_2() { return "B215510819 - wrong method_2!"; } + public String method_3() { return "B215510819 - wrong method_3!"; } + public String method_4() { return "B215510819 - wrong method_4!"; } + public String method_5() { return "B215510819 - wrong method_5!"; } + public String method_a() { return "B215510819 - wrong method_a!"; } + public String method_b() { return "B215510819 - wrong method_b!"; } + public String method_c() { return "B215510819 - wrong method_c!"; } + public String method_d() { return "B215510819 - wrong method_d!"; } + public String method_e() { return "B215510819 - wrong method_e!"; } + public String method_f() { return "B215510819 - wrong method_f!"; } + public String method_g() { return "B215510819 - wrong method_g!"; } + public String method_h() { return "B215510819 - wrong method_h!"; } + public String method_i() { return "B215510819 - wrong method_i!"; } + public String method_j() { return "B215510819 - wrong method_j!"; } + public String method_k() { return "B215510819 - wrong method_k!"; } +} +// Regression test for bug 215510819 where we failed to properly fill the IMT table +// when there were no new methods or interfaces and the superclass did not have an IMT +// table, so we filled the IMT from the superclass IfTable and erroneously ignored +// copied implementation methods in the process. Thus calls that should go to copied +// methods via an IMT conflict resolution trampoline would just end up in unrelated +// concrete method when called from compiled code or from interpreter in release mode. +// In debug mode, interpreter would fail a debug check. +class B215510819Test extends B215510819Base {} // No new interfaces or virtuals. |