A statement such as: String s; int i; while (i < s.length) { result[j++] = (byte) ((f(s.charAt(i++)) << 4) | (f(s.charAt(i++)))); } (f is e.g. a method to turn a hex digit [0-9A-Fa-f] into an integer) inverts the calls to 'f()' such that the result from the SECOND call is shifted left, not the first as expected. This bug only appears with native compilation with level 2 optimization or above. It appears only within loops and only with the two method calls. Release: gcc-3.2 Environment: linux-2.4.18-i686. gcc-3.2 Configured with: ../gcc-3.2/configure --enable-languages=c,c++,f77,java,objc How-To-Repeat: gcj -O2 --classpath=/path/to/libgcj.jar --main=bug -o bug bug.java ; ./bug Where 'bug.java' is the attached sample. This should print out 8 lines that all say 'false'. The expected behavior is 8 lines that say 'true'.
Fix: Unknown.
From: Casey Marshall <rsdio@metastatic.org> To: bangerth@dealii.org, gcc-gnats@gcc.gnu.org Cc: Subject: Re: java/8204: gcj -O2 to native reorders certain instructions improperly. Date: Sat, 22 Mar 2003 16:00:40 -0800 -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 bangerth@dealii.org wrote: | Synopsis: gcj -O2 to native reorders certain instructions improperly. | | State-Changed-From-To: open->feedback | State-Changed-By: bangerth | State-Changed-When: Sat Mar 22 18:09:51 2003 | State-Changed-Why: | In your code, you are modifying i twice in the same line: | (f(s.charAt(i++)) << 4) | (f(s.charAt(i++)))) | I don't know enough about Java, but in C/C++ this will invoke | undefined behavior, since the standard doesn't prescribe | which of the two function calls happen first, and with | which value of i. Is this different in Java, i.e. does | the Java standard give guarantees as to the order in which | the sub-statements are executed? | I haven't gone through the JLS very carefully, but it does seem that a construction of this sort *should* produce the behavior I'd expect. Specifically, the JLS says that when evaluating expressions (chapter 15): 1. The left operand of a binary operator is evaluated first. 2. Respect is paid to operator precedence and parentheses. 3. Operands are evaluated fully before operation. The problem appeared to be that when compiled with -O2 the right expression was evaluated first, rather than the left (at least this is what the result *looked* like). It would seem out of character for some behavior to be undefined in Java anyway ;) That said, this type of statement *is* unnecessary, and I can do without it. Cheers, - -- Casey Marshall || rsdio@metastatic.org -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.1 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQE+fPkngAuWMgRGsWsRAgfrAJ9hZQv3K56c1udOyKsdMFgTUeAApgCfS+QP uuQ/e75sLqsfNYtciqpic2k= =bTs/ -----END PGP SIGNATURE-----
State-Changed-From-To: open->feedback State-Changed-Why: In your code, you are modifying i twice in the same line: (f(s.charAt(i++)) << 4) | (f(s.charAt(i++)))) I don't know enough about Java, but in C/C++ this will invoke undefined behavior, since the standard doesn't prescribe which of the two function calls happen first, and with which value of i. Is this different in Java, i.e. does the Java standard give guarantees as to the order in which the sub-statements are executed? W.
State-Changed-From-To: feedback->open State-Changed-Why: Leave this to the Java experts
From: Tom Tromey <tromey@redhat.com> To: bangerth@dealii.org Cc: gcc-bugs@gcc.gnu.org, gcc-prs@gcc.gnu.org, java-prs@gcc.gnu.org, nobody@gcc.gnu.org, rsdio@metastatic.org, gcc-gnats@gcc.gnu.org Subject: Re: java/8204: gcj -O2 to native reorders certain instructions improperly. Date: 25 Mar 2003 15:36:42 -0700 >>>>> ">" == bangerth <bangerth@dealii.org> writes: >> (f(s.charAt(i++)) << 4) | (f(s.charAt(i++)))) >> I don't know enough about Java, but in C/C++ this will invoke >> undefined behavior, since the standard doesn't prescribe >> which of the two function calls happen first, and with >> which value of i. Is this different in Java, i.e. does >> the Java standard give guarantees as to the order in which >> the sub-statements are executed? Yes, Java specifies left-to-right evaluation in this situation. Chances are that this bug is fixed, but I haven't tried it. Tom
Can someone try this one with 3.3, on the mainline (20030525) it produces the right output: true 1 1 true 23 23 true 45 45 true 67 67 true 89 89 true ab ab true cd cd true ef ef
Fixed on at least 3.3.1 (20030526): env LD_LIBRARY_PATH=/home/gates/pinskia/ia32_linux_gcc3_3/ lib:${LD_LIBRARY_PATH} ./a.out true 1 1 true 23 23 true 45 45 true 67 67 true 89 89 true ab ab true cd cd true ef ef