User account creation filtered due to spam.

Bug 8204 - gcj -O2 to native reorders certain instructions improperly.
Summary: gcj -O2 to native reorders certain instructions improperly.
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: java (show other bugs)
Version: 3.2
: P3 normal
Target Milestone: 3.3.1
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2002-10-11 18:36 UTC by rsdio
Modified: 2005-07-23 22:49 UTC (History)
4 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
bug.java (457 bytes, text/plain)
2003-05-21 15:17 UTC, rsdio
Details

Note You need to log in before you can comment on or make changes to this bug.
Description rsdio 2002-10-11 18:36:00 UTC
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'.
Comment 1 rsdio 2002-10-11 18:36:00 UTC
Fix:
Unknown.
Comment 2 rsdio 2003-03-22 16:00:40 UTC
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-----
 
Comment 3 Wolfgang Bangerth 2003-03-22 18:09:51 UTC
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.
Comment 4 Wolfgang Bangerth 2003-03-24 15:16:42 UTC
State-Changed-From-To: feedback->open
State-Changed-Why: Leave this to the Java experts
Comment 5 Tom Tromey 2003-03-25 15:36:42 UTC
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
Comment 6 Andrew Pinski 2003-05-25 22:23:02 UTC
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
Comment 7 Andrew Pinski 2003-06-02 04:38:05 UTC
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