fold-const.c versus Java, part the ninety-ninth

Andrew Haley aph@redhat.com
Mon Nov 4 09:27:00 GMT 2002


fold-const.c assumes that we can transform

   thing .op. compound(a,b)

into

   compound(a, thing .op. b)

This is true if thing and a have no side effects.

OK?

Andrew.

2002-11-04  Andrew Haley  <aph@redhat.com>

	* fold-const.c (fold): Don't transform (a0 op compound(a1,a2))
	to (compound(a1,a0 op a2)) if a0 or a1 have side effects.

Index: fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.223
diff -w -p -2 -c -r1.223 fold-const.c
*** fold-const.c	11 Oct 2002 01:28:24 -0000	1.223
--- fold-const.c	4 Nov 2002 17:18:05 -0000
*************** fold (expr)
*** 4762,4766 ****
  	   || TREE_CODE_CLASS (code) == '<')
      {
!       if (TREE_CODE (arg1) == COMPOUND_EXPR)
  	return build (COMPOUND_EXPR, type, TREE_OPERAND (arg1, 0),
  		      fold (build (code, type,
--- 4762,4768 ----
  	   || TREE_CODE_CLASS (code) == '<')
      {
!       if (TREE_CODE (arg1) == COMPOUND_EXPR
! 	  && ! TREE_SIDE_EFFECTS (TREE_OPERAND (arg1, 0))
! 	  && ! TREE_SIDE_EFFECTS (arg0))
  	return build (COMPOUND_EXPR, type, TREE_OPERAND (arg1, 0),
  		      fold (build (code, type,


Mark Wielaard writes:
 > Hi,
 > 
 > On Wed, 2002-10-16 at 15:09, Andrew Haley wrote:
 > > Ranjit Mathew writes:
 > >  > Sorry guys, but I just referred to the JLS (section 15.12.4.2,
 > >  > "Evaluate Arguments"):
 > >  > 
 > >  > http://java.sun.com/docs/books/jls/second_edition/html/expressions.doc.html#45449
 > >  > 
 > >  > and I quote:
 > >  > 
 > >  > "The argument expressions are evaluated in order, from left to right..."
 > >  > 
 > >  > Therefore, the coder for StringTokenizer *can* assume the
 > >  > order of evaluation - there must be some other problem that
 > >  > I need to figure out.
 > >  > 
 > >  > BTW, does GCJ guarantee this order at all times? (I just saw
 > >  > Andrew Haley's patch for a fix for *static* method invocation,
 > >  > but the StringTokenizer problem is in a member method.)
 > > 
 > > Ah, here's another version of that patch.  I won't commit it because
 > > it's not fully tested yet.
 > > [...] 
 > > 2002-10-15  Andrew Haley  <aph@redhat.com>
 > > 
 > > 	* parse.y (patch_invoke): Call force_evaluation_order on a static
 > > 	arg list.
 > > 	(resolve_qualified_expression_name): Call force_evaluation_order
 > > 	on a arg list that is part of a Qualified Expression Name.
 > > 
 > > 	* lang.c (dump_compound_expr): New.
 > > 	(java_dump_tree): New.
 > 
 > I saw that you applied this patch so I tried a new gcj checkout on the
 > attached testcase from Casey Marshall that he found when trying to
 > analyse why compiling GNU Crypto with gcj -O2 produced incorrect
 > results.
 > 
 > GNU Crypto already contains a workaround for this issue but the attached
 > program does not produce correct results (with or without! -O2).
 > 
 > It seems that the arguments to the methods get mixed up in the following
 > statement:
 > 
 > result[j++] = (byte)(
 >     (fromDigit(s.charAt(i++)) << 4) | fromDigit(s.charAt(i++)));
 > 
 > Compiling with gcj -C produces bytecode that runs correctly with gij.
 > 
 > Correct output should be:
 > 
 > 0123456789ABCDEF
 > 0123456789ABCDEF
 > 0123456789ABCDEF
 > 
 > But is:
 > 
 > 0123456789ABCDEF
 > 0123456789ABCDEF
 > 1032547698BADCFE
 > 
 > Cheers,
 > 
 > Mark
 > class utilTest {
 > 
 >    public static void main(String[] argv) throws Throwable {
 >        byte[] b = new byte[] {
 >            0x01, 0x23, 0x45, 0x67, (byte) 0x89, (byte) 0xab,
 >            (byte) 0xcd, (byte) 0xef
 >        };
 >        String s = "0123456789ABCDEF";
 >        System.err.println(toString(b));
 >        System.err.println(s);
 >        System.err.println(toString(toBytesFromString(s)));
 >    }
 > 
 >    // The following comes from the GNU Crypto project gnu.crypto.util.Util
 > 
 >    private static final char[] HEX_DIGITS = {
 >       '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'
 >    };
 > 
 >    public static byte[] toBytesFromString(String s) {
 >       int limit = s.length();
 >       byte[] result = new byte[((limit + 1) / 2)];
 >       int i = 0, j = 0;
 >       if ((limit % 2) == 1) {
 >          result[j++] = (byte) fromDigit(s.charAt(i++));
 >       }
 >       while (i < limit) {
 >          result[j++] = (byte)(
 >                (fromDigit(s.charAt(i++)) << 4) | fromDigit(s.charAt(i++)));
 >       }
 >       return result;
 >    }
 > 
 >    public static int fromDigit(char c) {
 >       if (c >= '0' && c <= '9') {
 >          return c - '0';
 >       } else if (c >= 'A' && c <= 'F') {
 >          return c - 'A' + 10;
 >       } else if (c >= 'a' && c <= 'f') {
 >          return c - 'a' + 10;
 >       } else
 >          throw new IllegalArgumentException("Invalid hexadecimal digit: " + c);
 >    }
 > 
 >    public static String toString(byte[] ba) {
 >       return toString(ba, 0, ba.length);
 >    }
 > 
 >    public static final String toString(byte[] ba, int offset, int length) {
 >       char[] buf = new char[length * 2];
 >       for (int i = 0, j = 0, k; i < length; ) {
 >          k = ba[offset + i++];
 >          buf[j++] = HEX_DIGITS[(k >>> 4) & 0x0F];
 >          buf[j++] = HEX_DIGITS[ k        & 0x0F];
 >       }
 >       return new String(buf);
 >    }
 > }



More information about the Gcc-patches mailing list