This is the mail archive of the java-patches@gcc.gnu.org mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] java.util.StringTokenizer assumes order of parameterevaluation


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);
   }
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]