diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 55bc44157e1..834142a7f64 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2004-01-30 Eric Botcazou + + PR c/12818 + * varasm.c (const_hash_1) : Use the + address to compute the hash value if flag_writable_strings. + (compare_constant) : Compare the addresses + if flag_writable_strings. + (build_constant_desc): Do not copy the expression for a + STRING_CST if flag_writable_strings. + 2004-01-30 Jan Hubicka * alloc-pool.c: Include hashtab.h diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e00e0742e7f..4f95129b9e9 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2004-01-30 Eric Botcazou + + * gcc.dg/fwritable-strings-1.c: New test. + 2004-01-30 Eric Botcazou * gcc.c-torture/compile/20040130-1.c: New test. diff --git a/gcc/testsuite/gcc.dg/fwritable-strings-1.c b/gcc/testsuite/gcc.dg/fwritable-strings-1.c new file mode 100644 index 00000000000..e519231c368 --- /dev/null +++ b/gcc/testsuite/gcc.dg/fwritable-strings-1.c @@ -0,0 +1,17 @@ +/* PR c/12818 */ +/* Origin: */ + +/* { dg-do run } */ +/* { dg-options "-fwritable-strings" } */ + +extern void abort(void); + +char *names[] = {"alice", "bob", "john"}; + +int main (void) +{ + if (names[1][0] != 'b') + abort(); + + return 0; +} diff --git a/gcc/varasm.c b/gcc/varasm.c index e44d288dbc8..7af71bf196f 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -2057,7 +2057,7 @@ struct rtx_const GTY(()) /* Uniquize all constants that appear in memory. Each constant in memory thus far output is recorded - in `const_hash_table'. */ + in `const_desc_table'. */ struct constant_descriptor_tree GTY(()) { @@ -2104,9 +2104,18 @@ const_hash_1 (const tree exp) return real_hash (TREE_REAL_CST_PTR (exp)); case STRING_CST: - p = TREE_STRING_POINTER (exp); - len = TREE_STRING_LENGTH (exp); + if (flag_writable_strings) + { + p = (char *) &exp; + len = sizeof exp; + } + else + { + p = TREE_STRING_POINTER (exp); + len = TREE_STRING_LENGTH (exp); + } break; + case COMPLEX_CST: return (const_hash_1 (TREE_REALPART (exp)) * 5 + const_hash_1 (TREE_IMAGPART (exp))); @@ -2221,7 +2230,7 @@ compare_constant (const tree t1, const tree t2) case STRING_CST: if (flag_writable_strings) - return 0; + return t1 == t2; if (TYPE_MODE (TREE_TYPE (t1)) != TYPE_MODE (TREE_TYPE (t2))) return 0; @@ -2425,7 +2434,10 @@ build_constant_desc (tree exp) struct constant_descriptor_tree *desc; desc = ggc_alloc (sizeof (*desc)); - desc->value = copy_constant (exp); + if (flag_writable_strings && TREE_CODE (exp) == STRING_CST) + desc->value = exp; + else + desc->value = copy_constant (exp); /* Create a string containing the label name, in LABEL. */ labelno = const_labelno++; @@ -2466,7 +2478,7 @@ build_constant_desc (tree exp) If DEFER is nonzero, this constant can be deferred and output only if referenced in the function after all optimizations. - The const_hash_table records which constants already have label strings. */ + `const_desc_table' records which constants already have label strings. */ rtx output_constant_def (tree exp, int defer)