The current mainline produces invalid bytecode for the Jacks testsuite testcase 8.1.2-runtime-1. The testcase is: ---------------------------- 8< ---------------------------- class Hello { public static void main(String[] args) { new Hello().foo(1); } void foo(final int i) { class Local { Local() {} Local(int i) { this(); } int foo() { return new Local(0) { int j = i; }.j; } } System.out.println(new Local().foo()); } } ---------------------------- 8< ---------------------------- This should produce "1" as the output when compiled correctly. However, GCJ miscompiles it (for both native as well as bytecode output) and the gij verifier gives a verification error on the generated bytecode. The generated bytecode for "Hello$1$Local" looks like: ---------------------------- 8< ---------------------------- ~/src/test/tmp > javap -c Hello\$1\$Local Compiled from "Hello.java" class Hello$1$Local extends java.lang.Object{ static Hello access$0(Hello$1$Local); Code: 0: aload_0 1: getfield #14; //Field this$0:LHello; 4: areturn Hello$1$Local(Hello,int); Code: 0: aload_0 1: aload_1 2: putfield #14; //Field this$0:LHello; 5: aload_0 6: invokespecial #24; //Method java/lang/Object."<init>":()V 9: aload_0 10: iload_2 11: invokespecial #26; //Method finit$:(I)V 14: return Hello$1$Local(Hello,int,int); Code: 0: aload_0 1: aload_1 2: putfield #14; //Field this$0:LHello; 5: aload_0 6: aload_1 7: invokespecial #29; //Method "<init>":(LHello;I)V 10: return int foo(); Code: 0: new #33; //class Hello$Local$2 3: dup 4: aload_0 5: iconst_0 6: invokespecial #36; //Method Hello$Local$2."<init>":(LHello$1$Local;I)V 9: getfield #39; //Field Hello$Local$2.j:I 12: ireturn } ---------------------------- 8< ---------------------------- Note that for the method "Hello$1$Local(Hello,int,int);", the method called at PC=7 doesn't get the expected integer argument. Originally reported at: http://gcc.gnu.org/ml/java/2004-07/msg00002.html
Confirmed. I don't think this is a new failure - this test case is broken going back to at least GCC 3.3. I don't know why it recently started failing in Jacks. build_alias_initializer_parameter_list could be the source of the problem. In the case where a local class is instantiated within the same function that it is defined, the hidden constructor argument is found from the parameter list in the local function. But where the constructor call is made from a more deeply nested context, the argument must be loaded from the synthetic var$ field. It looks like the second case always fails, not just for anonymous instantiations.
All gcj front end bugs have been fixed by the gcj-eclipse branch merge. I'm mass-closing the affected PRs. If you believe one of these was closed in error, please reopen it with a note explaining why. Thanks.