Bug 16327

Summary: Invalid Bytecode Generated for Jacks Test 8.1.2-runtime-1
Product: gcc Reporter: Ranjit Mathew <rmathew>
Component: javaAssignee: Not yet assigned to anyone <unassigned>
Status: RESOLVED FIXED    
Severity: normal CC: gcc-bugs, java-prs
Priority: P2    
Version: 4.0.0   
Target Milestone: 4.3.0   
Host: Target:
Build: Known to work:
Known to fail: Last reconfirmed: 2005-07-23 05:29:10
Bug Depends on: 28067    
Bug Blocks:    

Description Ranjit Mathew 2004-07-02 05:39:21 UTC
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
Comment 1 Bryce McKinlay 2004-07-09 02:37:55 UTC
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.
Comment 2 Tom Tromey 2007-01-09 20:46:12 UTC
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.