From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20119 invoked by alias); 5 Dec 2002 21:46:04 -0000 Mailing-List: contact gcc-prs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-prs-owner@gcc.gnu.org Received: (qmail 20091 invoked by uid 71); 5 Dec 2002 21:46:03 -0000 Resent-Date: 5 Dec 2002 21:46:03 -0000 Resent-Message-ID: <20021205214603.20090.qmail@sources.redhat.com> Resent-From: gcc-gnats@gcc.gnu.org (GNATS Filer) Resent-Cc: gcc-prs@gcc.gnu.org, gcc-bugs@gcc.gnu.org, java-prs@gcc.gnu.org Resent-Reply-To: gcc-gnats@gcc.gnu.org, ebb9@email.byu.edu Received: (qmail 15969 invoked by uid 61); 5 Dec 2002 21:37:37 -0000 Message-Id: <20021205213737.15968.qmail@sources.redhat.com> Date: Thu, 05 Dec 2002 13:46:00 -0000 From: ebb9@email.byu.edu Reply-To: ebb9@email.byu.edu To: gcc-gnats@gcc.gnu.org X-Send-Pr-Version: gnatsweb-2.9.3 (1.1.1.1.2.31) Subject: java/8830: Incorrect semantics for Foo.class X-SW-Source: 2002-12/txt/msg00317.txt.bz2 List-Id: >Number: 8830 >Category: java >Synopsis: Incorrect semantics for Foo.class >Confidential: no >Severity: serious >Priority: medium >Responsible: unassigned >State: open >Class: wrong-code >Submitter-Id: net >Arrival-Date: Thu Dec 05 13:46:02 PST 2002 >Closed-Date: >Last-Modified: >Originator: Eric Blake >Release: 3.2 >Organization: >Environment: Reading specs from /usr/lib/gcc-lib/i686-pc-cygwin/3.2/specs Reading specs from /usr/lib/gcc-lib/i686-pc-cygwin/3.2/../../../libgcj.spec rename spec lib to liborig Configured with: /netrel/src/gcc-3.2-3/configure --enable-languages=c,c++,f77,ja va --enable-libgcj --enable-threads=posix --with-system-zlib --enable-nls --with out-included-gettext --enable-interpreter --disable-sjlj-exceptions --disable-ve rsion-specific-runtime-libs --enable-shared --build=i686-pc-linux --host=i686-pc -cygwin --target=i686-pc-cygwin --enable-haifa --prefix=/usr --exec-prefix=/usr --sysconfdir=/etc --libdir=/usr/lib --includedir=/nonexistent/include --libexecd ir=/usr/sbin Thread model: posix gcc version 3.2 20020927 (prerelease) >Description: JLS 12.4.1 does not permit class literals to cause class initialization. GCJ, on the other hand, compiles them to initialize the underlying class, because of the specification of Class.forName(). Javac has always got this wrong, but it was recently corrected in jikes 1.17. This is also a test in the Jacks test suite. The sample program below should never initialize Sub, since the only use of Sub is via a class literal (and not a static field, method, or constructor). Therefore, i should still be 1, not 2, when the println is executed. Also, gcj does not cache the result when compiled to bytecode, when both javac and jikes do. Caching is useful, because the reflection overhead of Class.forName is expensive. (Note that any implementation of class literals that does not match Sun's will break serialization compatibility, since adding or removing cache variables, or changing parameters to class$(), will affect the UID. But I've already pointed this out as the reason why all classes in libgcj should explicitly state their serialVersionUID. Also note that Sun has proposed a VM extension in JDK 1.5, which will allow 'ldc CONSTANT_Class' to resolve a class literal, rather than the current hack of invisibly calling Class.forName()). >How-To-Repeat: $ cat Foo.java class Foo { static int i = 1; static void m(Class c) { System.out.println(i); } public static void main(String[] args) { m(Sub.class); } } class Sub extends Foo { static int j = i = 1; // should not execute } $ gcj -C Foo.java $ java Foo 2 $ jikes Foo.java $ java Foo 1 >Fix: Currently, gcj emits: private static Class class$(String s) { try { return Class.forName(s); } catch (ClassNotFoundException e) { throw new NoClassDefFoundError(e.getMessage()); } } and translates Sub.class to class$("Sub") Jikes emits this: static Class class$Sub; static Class class$(String s, boolean arraytype) { try { Class c = Class.forName(s); if (! arraytype) c = c.getComponentType(); } catch (ClassNotFoundException e) { throw (Error) new NoClassDefFoundError().initCause(e); } } and translates Sub.class to: (class$Sub == null ? class$Sub = class$("LSub;", false) : class$Sub) >Release-Note: >Audit-Trail: >Unformatted: