This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR c/12818
- From: Eric Botcazou <ebotcazou at libertysurf dot fr>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 29 Jan 2004 19:27:38 +0100
- Subject: [PATCH] Fix PR c/12818
Hi,
This is a regression present on 3.4 branch and mainline, which is related to
the now deprecated option -fwritable-strings.
The compiler emits two copies of each string for the string array
char *names[] = {"alice", "bob", "john"};
The first copy is correctly emitted, while the second is interspersed between
the labels that make up the array itself:
.LC0:
.string "alice"
.LC1:
.string "bob"
.LC2:
.string "john"
.globl names
.align 4
.type names, @object
.size names, 12
names:
.LC3:
.string "alice"
.long .LC3
.LC4:
.string "bob"
.long .LC4
.LC5:
.string "john"
.long .LC5
The problem is that the constant ouput machinery in varasm.c builds a new
label each time it is passed a string if -fwritable-strings is enabled,
even if the string has already been passed. The proposed fix is to change
the comparison operator for strings if -fwritable-strings is enabled, from
comparison of values to comparison of addresses.
I'm not sure how I should test this patch...
2004-01-29 Eric Botcazou <ebotcazou@libertysurf.fr>
PR c/12818
* varasm.c (const_hash_1) <STRING_CST>: Use the
address to compute the hash value if flag_writable_strings.
(compare_constant) <STRING_CST>: 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-29 Eric Botcazou <ebotcazou@libertysurf.fr>
* gcc.dg/fwritable-strings-1.c: New test.
--
Eric Botcazou
/* PR c/12818 */
/* Origin: <fnf@ninemoons.com> */
/* { dg-do run } */
/* { dg-options "-fwritable-strings" } */
char *names[] = {"alice", "bob", "john"};
int main (void)
{
if (names[1][0] != 'b')
abort();
return 0;
}
Index: varasm.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/varasm.c,v
retrieving revision 1.405
diff -u -p -r1.405 varasm.c
--- varasm.c 14 Jan 2004 00:49:00 -0000 1.405
+++ varasm.c 29 Jan 2004 17:48:09 -0000
@@ -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 t
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)