This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] PR java/10253 (""+0), version 2
- From: Eric Blake <ebb9 at email dot byu dot edu>
- To: GCJ Patches <java-patches at gcc dot gnu dot org>,gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 10 Apr 2003 09:09:14 -0600
- Subject: [PATCH] PR java/10253 (""+0), version 2
Yesterday's version had some flaws. In part, I had mistaken the comment
about an ASCII dependence to assume that '0' through '9' might not be
consecutive; I was reminded that C guarantees that they are consecutive.
Rather, the dependence is on whether '0' == 060.
Tested on i686-pc-cygwin. OK to commit to 3.3 branch and HEAD?
2003-04-10 Eric Blake <ebb9 at email dot byu dot edu>
PR java/10253:
* parse.y (string_convert_int_cst): Always use at least one digit
in string conversion. Remove ASCII dependence.
(merge_string_cste): Fix merging of 3-byte UTF-8 characters.
--
This signature intentionally left boring.
Eric Blake ebb9 at email dot byu dot edu
BYU student, free software programmer
Index: parse.y
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/parse.y,v
retrieving revision 1.427
diff -u -r1.427 parse.y
--- parse.y 25 Mar 2003 17:00:47 -0000 1.427
+++ parse.y 10 Apr 2003 15:05:44 -0000
@@ -12489,17 +12489,18 @@
static char *
string_convert_int_cst (tree node)
{
- static char buffer[80];
+ /* Long.MIN_VALUE is -9223372036854775808, 20 characters. */
+ static char buffer[21];
unsigned HOST_WIDE_INT lo = TREE_INT_CST_LOW (node);
unsigned HOST_WIDE_INT hi = TREE_INT_CST_HIGH (node);
- char *p = buffer + sizeof (buffer) - 1;
+ char *p = buffer + sizeof (buffer);
int neg = 0;
unsigned HOST_WIDE_INT hibit = (((unsigned HOST_WIDE_INT) 1)
<< (HOST_BITS_PER_WIDE_INT - 1));
- *p-- = '\0';
+ *--p = '\0';
/* If negative, note the fact and negate the value. */
if ((hi & hibit))
@@ -12512,7 +12513,7 @@
}
/* Divide by 10 until there are no bits left. */
- while (hi || lo)
+ do
{
unsigned HOST_WIDE_INT acc = 0;
unsigned HOST_WIDE_INT outhi = 0, outlo = 0;
@@ -12544,17 +12545,18 @@
}
}
- /* FIXME: ASCII assumption. */
- *p-- = '0' + acc;
+ /* '0' == 060 in Java, even if the host machine is EBCDIC. */
+ *--p = '\060' + acc;
hi = outhi;
lo = outlo;
}
+ while (hi || lo);
if (neg)
- *p-- = '-';
+ *--p = '-';
- return p + 1;
+ return p;
}
/* Print an INTEGER_CST node in a static buffer, and return the
@@ -13678,23 +13680,23 @@
}
/* Tries to merge OP1 (a STRING_CST) and OP2 (if suitable). Return a
- new STRING_CST on success, NULL_TREE on failure */
+ new STRING_CST on success, NULL_TREE on failure. */
static tree
merge_string_cste (tree op1, tree op2, int after)
{
- /* Handle two string constants right away */
+ /* Handle two string constants right away. */
if (TREE_CODE (op2) == STRING_CST)
return do_merge_string_cste (op1, TREE_STRING_POINTER (op2),
TREE_STRING_LENGTH (op2), after);
- /* Reasonable integer constant can be treated right away */
+ /* Reasonable integer constant can be treated right away. */
if (TREE_CODE (op2) == INTEGER_CST && !TREE_CONSTANT_OVERFLOW (op2))
{
static const char *const boolean_true = "true";
static const char *const boolean_false = "false";
static const char *const null_pointer = "null";
- char ch[3];
+ char ch[4];
const char *string;
if (op2 == boolean_true_node)
@@ -13702,19 +13704,27 @@
else if (op2 == boolean_false_node)
string = boolean_false;
else if (op2 == null_pointer_node)
+ /* FIXME: null is not a compile-time constant, so it only safe to
+ merge if the overall expression is non-constant. However, this
+ code always merges without checking the overall expression. */
string = null_pointer;
else if (TREE_TYPE (op2) == char_type_node)
{
/* Convert the character into UTF-8. */
- unsigned char c = (unsigned char) TREE_INT_CST_LOW (op2);
+ unsigned int c = (unsigned int) TREE_INT_CST_LOW (op2);
unsigned char *p = (unsigned char *) ch;
- if (0x01 <= c
- && c <= 0x7f)
- *p++ = c;
+ if (0x01 <= c && c <= 0x7f)
+ *p++ = (unsigned char) c;
+ else if (c < 0x7ff)
+ {
+ *p++ = (unsigned char) (c >> 6 | 0xc0);
+ *p++ = (unsigned char) ((c & 0x3f) | 0x80);
+ }
else
{
- *p++ = c >> 6 | 0xc0;
- *p++ = (c & 0x3f) | 0x80;
+ *p++ = (unsigned char) (c >> 12 | 0xe0);
+ *p++ = (unsigned char) (((c >> 6) & 0x3f) | 0x80);
+ *p++ = (unsigned char) ((c & 0x3f) | 0x80);
}
*p = '\0';