This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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]

[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)

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