The following compiled with jikes outputs 42. Compiled with gcj -C and ran with gij gives a java.lang.IllegalAccessError public class A { public static class B { private static int i = 42; } public static void main(String[] args) { System.out.println(B.i); } }
This is a dup of bug 9369. *** This bug has been marked as a duplicate of 9369 ***
Crap actually it is not.
Woops.
Confirmed.
gcj is generating code which references private members across class boundaries, which isn't legal at the class/VM level. To fix this, we need to generate package-private accessor methods when a private member is referenced from an enclosed or enclosing class. eg: jikes generates: Method name:"main" public static Signature: (java.lang.String[])void Attribute "Code", length:38, max_stack:2, max_locals:1, code_length:10 0: getstatic <Field java.lang.System.out java.io.PrintStream> 3: invokestatic <Method A$B.access$0 ()int> 6: invokevirtual <Method java.io.PrintStream.println (int)void> 9: return Attribute "LineNumberTable", length:10, count: 2 line: 10 at pc: 0 line: 11 at pc: 9 Method name:"access$0" static Signature: ()int Attribute "Synthetic", length:0 Attribute "Code", length:28, max_stack:1, max_locals:0, code_length:4 0: getstatic <Field A$B.i int> 3: ireturn Attribute "LineNumberTable", length:6, count: 1 line: 3 at pc: 0
I note that GCJ already seems to have the infrastructure in place to do this and possibly used to work properly for this case. For example, see the build_outer_field_access(), outer_field_access_p(), etc. methods in parse.y. The patch to turn this on seems to have been: 2000-02-03 Alexandre Petit-Bianco <apbianco@cygnus.com> * java-tree.h (FIELD_THISN): New macro. * jcf-write.c (append_synthetic_attribute): New function. (generate_classfile): Set "Synthetic" attribute on this$<n>, val$<name> fields, access$<n> and $finit$ methods. Fixed indentation. * parse.y (add_inner_class_fields): Set FIELD_THISN for created this$<n> fields. (build_outer_field_access): Turned on access functions usage and generation when compiling to bytecode. (maybe_use_access_method): Likewise. As with other such things in GCJ, this seems to have bitrotted over time. :-(
outer_field_access_p(), build_outer_field_access(), etc. are only for non-static fields (instance variables). Even for some simple testcases, I could not get GCJ to emit correct bytecode for non-static instance variables. Lastly these methods are for access from inside a nested class to a private member in a containing class, not the other way round as given in the testcase for this PR. So a significant surgery is indeed needed to make these cases work with GCJ. If anyone is working on a patch to fix this, I would certainly like to hear from them - I have a partially working patch, but I don't know if I'd be able to finish it given the lack of skills as well as time on my part.
I have now submitted a patch for fixing this bug: http://gcc.gnu.org/ml/java-patches/2005-q2/msg00570.html
Subject: Bug 19870 CVSROOT: /cvs/gcc Module name: gcc Changes by: rmathew@gcc.gnu.org 2005-05-27 05:11:44 Modified files: libjava : ChangeLog libjava/testsuite/libjava.jacks: jacks.xfail Added files: libjava/testsuite/libjava.lang: PR19870.java PR19870.out Log message: Testsuite adjustments for PR java/19870. * testsuite/libjava.lang/PR19870.java: New testcase. * testsuite/libjava.lang/PR19870.out: Expected output for the testcase. * testsuite/libjava.jacks/jacks.xfail: Add 8.5.2-accessible-static-member-usage-3 and 15.8.4-static-2 Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/ChangeLog.diff?cvsroot=gcc&r1=1.3636&r2=1.3637 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/testsuite/libjava.lang/PR19870.java.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/testsuite/libjava.lang/PR19870.out.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/testsuite/libjava.jacks/jacks.xfail.diff?cvsroot=gcc&r1=1.23&r2=1.24
Subject: Bug 19870 CVSROOT: /cvs/gcc Module name: gcc Changes by: rmathew@gcc.gnu.org 2005-05-27 05:15:30 Modified files: gcc/java : ChangeLog java-tree.h jcf-write.c parse.y Log message: PR java/19870. * java-tree.h (OUTER_FIELD_ACCESS_IDENTIFIER_P): Rename to NESTED_FIELD_ACCESS_IDENTIFIER_P. (FIELD_INNER_ACCESS): Rename to FIELD_NESTED_ACCESS. (FIELD_INNER_ACCESS_P): Rename to FIELD_NESTED_ACCESS_P. * jcf-write.c (generate_classfile): Use NESTED_FIELD_ACCESS_IDENTIFIER_P instead of OUTER_FIELD_ACCESS_IDENTIFIER_P. * parse.y (build_outer_field_access): Rename to build_nested_field_access. Support static fields and outer-to-inner class accesses. (outer_field_access_p): Rename to nested_field_access_p. Support static fields and generalise to outer-to-inner class and sibling inner class accesses. (outer_field_expanded_access_p): Rename to nested_field_expanded_access_p and support static fields. (outer_field_access_fix): Rename to nested_field_access_fix and support static fields. (build_outer_field_access_expr): Rename to build_nested_field_access_expr and support static fields. (build_outer_field_access_methods): Rename to build_nested_field_access_methods and support static fields. For static fields, generate accessors without class instance parameters. (build_outer_field_access_method): Rename to build_nested_field_access_method and support static fields. (build_outer_method_access_method): Use NESTED_FIELD_ACCESS_IDENTIFIER_P instead of OUTER_FIELD_ACCESS_IDENTIFIER_P. (resolve_expression_name): Consider static field accesses across nested classes. (resolve_qualified_expression_name): Likewise. (java_complete_lhs): Use nested_field_access_fix instead of outer_field_access_fix. (patch_unary_op): Rename outer_field_flag to nested_field_flag. Use nested_field_expanded_access_p instead of outer_field_expanded_access_p. Use nested_field_access_fix instead of outer_field_access_fix. (check_thrown_exceptions): Use NESTED_FIELD_ACCESS_IDENTIFIER_P instead of OUTER_FIELD_ACCESS_IDENTIFIER_P. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/java/ChangeLog.diff?cvsroot=gcc&r1=1.1618&r2=1.1619 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/java/java-tree.h.diff?cvsroot=gcc&r1=1.232&r2=1.233 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/java/jcf-write.c.diff?cvsroot=gcc&r1=1.164&r2=1.165 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/java/parse.y.diff?cvsroot=gcc&r1=1.535&r2=1.536
Note that this PR should not be closed as the checked-in patch was only for generating accessors for static fields. Methods are still a problem as is demonstrated by this simple testcase: public class A { public static class B { private static void snafu( ) { System.out.println( "Hello!"); } } public static void main( String[] args) { B.snafu( ); } }
A patch for the remaining bit is here: http://gcc.gnu.org/ml/java-patches/2005-q2/msg00742.html
Updated patch for Part 2 posted in: http://gcc.gnu.org/ml/java-patches/2005-q3/msg00195.html
Subject: Bug 19870 CVSROOT: /cvs/gcc Module name: gcc Changes by: rmathew@gcc.gnu.org 2005-08-16 18:22:34 Modified files: gcc/java : ChangeLog parse.y Log message: PR java/19870 * parse.y (nested_field_access_p): Rename to nested_member_access_p and expand to handle method accesses across nested classes. (build_outer_method_access_method): Rename to build_nested_method_access_method. Minor adjustments to comments. (resolve_expression_name): Use the newly-renamed nested_member_access_p method. (resolve_qualified_expression_name): Likewise. (patch_method_invocation): Also consider static methods for access method generation. Minor adjustments to comments. (maybe_use_access_method): Use the more general nested_memeber_access_p to determine access across nested class boundaries. Allow THIS_ARG to be NULL (for static methods). Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/java/ChangeLog.diff?cvsroot=gcc&r1=1.1656&r2=1.1657 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/java/parse.y.diff?cvsroot=gcc&r1=1.551&r2=1.552
Subject: Bug 19870 CVSROOT: /cvs/gcc Module name: gcc Changes by: rmathew@gcc.gnu.org 2005-08-16 18:32:14 Modified files: libjava : ChangeLog libjava/testsuite/libjava.jacks: jacks.xfail Added files: libjava/testsuite/libjava.lang: PR19870_2.java PR19870_2.out Log message: More testsuite adjustments for PR java/19870. * testsuite/libjava.lang/PR19870_2.java: New testcase. * testsuite/libjava.lang/PR19870_2.out: Expected output for the new testcase. * testsuite/libjava.jacks/jacks.xfail: Remove 8.5.2-non-static-member-usage-2 and add 15.12.3-explicit-constructor-9. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/ChangeLog.diff?cvsroot=gcc&r1=1.3718&r2=1.3719 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/testsuite/libjava.lang/PR19870_2.java.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/testsuite/libjava.lang/PR19870_2.out.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/testsuite/libjava.jacks/jacks.xfail.diff?cvsroot=gcc&r1=1.28&r2=1.29
Last part of the fix has now been checked in.
Subject: Bug 19870 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-4_0-branch Changes by: bryce@gcc.gnu.org 2005-10-05 19:35:46 Modified files: gcc/java : ChangeLog decl.c java-tree.h jcf-write.c parse.y libjava : ChangeLog libjava/testsuite/libjava.jacks: jacks.xfail Added files: libjava/testsuite/libjava.lang: PR19870.java PR19870.out PR19870_2.java PR19870_2.out Log message: gcc/java: 2005-10-05 Ranjit Mathew <rmathew@hotmail.com> PR java/20338 * decl.c (finish_method): Emit _Jv_InitClass for private static methods inside inner classes as well. 2005-10-05 Ranjit Mathew <rmathew@hotmail.com> PR java/19870 * parse.y (nested_field_access_p): Rename to nested_member_access_p and expand to handle method accesses across nested classes. (build_outer_method_access_method): Rename to build_nested_method_access_method. Minor adjustments to comments. (resolve_expression_name): Use the newly-renamed nested_member_access_p method. (resolve_qualified_expression_name): Likewise. (patch_method_invocation): Also consider static methods for access method generation. Minor adjustments to comments. (maybe_use_access_method): Use the more general nested_memeber_access_p to determine access across nested class boundaries. Allow THIS_ARG to be NULL (for static methods). 2005-10-05 Tom Tromey <tromey@redhat.com> PR java/21844: * parse.y (nested_field_access_p): Handle case where outer field is inherited by enclosing class. 2005-10-05 Ranjit Mathew <rmathew@hotmail.com> PR java/19870. * java-tree.h (OUTER_FIELD_ACCESS_IDENTIFIER_P): Rename to NESTED_FIELD_ACCESS_IDENTIFIER_P. (FIELD_INNER_ACCESS): Rename to FIELD_NESTED_ACCESS. (FIELD_INNER_ACCESS_P): Rename to FIELD_NESTED_ACCESS_P. * jcf-write.c (generate_classfile): Use NESTED_FIELD_ACCESS_IDENTIFIER_P instead of OUTER_FIELD_ACCESS_IDENTIFIER_P. * parse.y (build_outer_field_access): Rename to build_nested_field_access. Support static fields and outer-to-inner class accesses. (outer_field_access_p): Rename to nested_field_access_p. Support static fields and generalise to outer-to-inner class and sibling inner class accesses. (outer_field_expanded_access_p): Rename to nested_field_expanded_access_p and support static fields. (outer_field_access_fix): Rename to nested_field_access_fix and support static fields. (build_outer_field_access_expr): Rename to build_nested_field_access_expr and support static fields. (build_outer_field_access_methods): Rename to build_nested_field_access_methods and support static fields. For static fields, generate accessors without class instance parameters. (build_outer_field_access_method): Rename to build_nested_field_access_method and support static fields. (build_outer_method_access_method): Use NESTED_FIELD_ACCESS_IDENTIFIER_P instead of OUTER_FIELD_ACCESS_IDENTIFIER_P. (resolve_expression_name): Consider static field accesses across nested classes. (resolve_qualified_expression_name): Likewise. (java_complete_lhs): Use nested_field_access_fix instead of outer_field_access_fix. (patch_unary_op): Rename outer_field_flag to nested_field_flag. Use nested_field_expanded_access_p instead of outer_field_expanded_access_p. Use nested_field_access_fix instead of outer_field_access_fix. (check_thrown_exceptions): Use NESTED_FIELD_ACCESS_IDENTIFIER_P instead of OUTER_FIELD_ACCESS_IDENTIFIER_P. libjava: 2005-10-05 Ranjit Mathew <rmathew@hotmail.com> More testsuite adjustments for PR java/19870. * testsuite/libjava.lang/PR19870_2.java: New testcase. * testsuite/libjava.lang/PR19870_2.out: Expected output for the new testcase. * testsuite/libjava.jacks/jacks.xfail: Remove 8.5.2-non-static-member-usage-2 and add 15.12.3-explicit-constructor-9. 2005-10-05 Tom Tromey <tromey@redhat.com> PR java/21844: * testsuite/libjava.lang/pr21844.java: New file. * testsuite/libjava.lang/pr21844.out: New file. 2005-10-05 Ranjit Mathew <rmathew@hotmail.com> Testsuite adjustments for PR java/19870. * testsuite/libjava.lang/PR19870.java: New testcase. * testsuite/libjava.lang/PR19870.out: Expected output for the testcase. * testsuite/libjava.jacks/jacks.xfail: Add 8.5.2-accessible-static-member-usage-3 and 15.8.4-static-2 Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/java/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.1556.2.34&r2=1.1556.2.35 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/java/decl.c.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.209.4.4&r2=1.209.4.5 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/java/java-tree.h.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.226.8.3&r2=1.226.8.4 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/java/jcf-write.c.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.162.4.1&r2=1.162.4.2 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/gcc/java/parse.y.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.528.6.4&r2=1.528.6.5 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.3391.2.103&r2=1.3391.2.104 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/testsuite/libjava.jacks/jacks.xfail.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.19.8.2&r2=1.19.8.3 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/testsuite/libjava.lang/PR19870.java.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=NONE&r2=1.1.24.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/testsuite/libjava.lang/PR19870.out.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=NONE&r2=1.1.24.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/testsuite/libjava.lang/PR19870_2.java.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=NONE&r2=1.1.18.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libjava/testsuite/libjava.lang/PR19870_2.out.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=NONE&r2=1.1.18.1
Also fixed in 4.0.3.
The testcase in the following message still seems to fail: http://gcc.gnu.org/ml/java/2005-12/msg00181.html Here is a variant of the original example that also fails: public class A { public static class B { private int i = 42; } public static void main(String[] args) { System.out.println(new B().i); } } The only change is making i an instance field instead of a static class field.
*** Bug 27925 has been marked as a duplicate of this bug. ***
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.