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 -fmerge-all-constants


Hi!

As shown on the attached testcase, GCC was emitting invalid assembler
like:
        .section        .rodata.str1.32,"aMS",@progbits,1
        .align 32
        .type   str1, @object
        .size   str1, 36
str1:
        .ascii  "0123456789abcdefghijklmnopqrstuvwxyz"
        .section        .rodata
(the string is not zero terminated, so must not use mergeable string section).
On the other side, say
const char a[3] = "ab\0def";
with -fmerge-all-constants can be safely put into mergeable string section,
as '\0' is at the end of the object.
This problem shows up with recent glibcs, so eventhough it doesn't appear
to be a regression, I'd like to see this fixed not only on the trunk, but
also on 4.1 branch.

Ok for trunk/4.1?

2006-06-19  Jakub Jelinek  <jakub@redhat.com>

	* varasm.c (mergeable_string_section): Check for embedded NULs and
	NUL termination in the first int_size_in_bytes (TREE_TYPE (decl))
	rather than TREE_STRING_LENGTH bytes.

	* gcc.dg/merge-all-constants-1.c: New test.

--- gcc/varasm.c.jj	2006-06-19 12:49:52.000000000 +0200
+++ gcc/varasm.c	2006-06-19 12:50:13.000000000 +0200
@@ -655,16 +655,20 @@ mergeable_string_section (tree decl ATTR
 			  unsigned HOST_WIDE_INT align ATTRIBUTE_UNUSED,
 			  unsigned int flags ATTRIBUTE_UNUSED)
 {
+  HOST_WIDE_INT len;
+
   if (HAVE_GAS_SHF_MERGE && flag_merge_constants
       && TREE_CODE (decl) == STRING_CST
       && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE
       && align <= 256
-      && TREE_STRING_LENGTH (decl) >= int_size_in_bytes (TREE_TYPE (decl)))
+      && (len = int_size_in_bytes (TREE_TYPE (decl))) > 0
+      && TREE_STRING_LENGTH (decl) >= len)
     {
       enum machine_mode mode;
       unsigned int modesize;
       const char *str;
-      int i, j, len, unit;
+      HOST_WIDE_INT i;
+      int j, unit;
       char name[30];
 
       mode = TYPE_MODE (TREE_TYPE (TREE_TYPE (decl)));
@@ -676,7 +680,6 @@ mergeable_string_section (tree decl ATTR
 	    align = modesize;
 
 	  str = TREE_STRING_POINTER (decl);
-	  len = TREE_STRING_LENGTH (decl);
 	  unit = GET_MODE_SIZE (mode);
 
 	  /* Check for embedded NUL characters.  */
--- gcc/testsuite/gcc.dg/merge-all-constants-1.c.jj	2006-06-19 13:02:37.000000000 +0200
+++ gcc/testsuite/gcc.dg/merge-all-constants-1.c	2006-06-19 13:05:23.000000000 +0200
@@ -0,0 +1,8 @@
+/* { dg-do compile } */
+/* { dg-options "-w -O2 -fmerge-all-constants" } */
+
+const char str1[36] = "0123456789abcdefghijklmnopqrstuvwxyz";
+const char str2[38] = "0123456789abcdefghijklmnopqrstuvwxyz";
+const char str3[10] = "0123456789abcdefghijklmnopqrstuvwxyz";
+
+/* { dg-final { scan-assembler-not "\.rodata\.str" } } */

	Jakub


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