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] print full STRING_CST in Gimple dumps (PR 87052)


In the discussion of the fallout from the enhancement for pr71625
it was pointed out that STRING_CSts in Gimple dumps extend only
to the first nul and don't include any subsequent characters,
and that this makes the dumps harder to read and might give rise
to the question whether the code is correct.

In the attached patch I enhance the pretty_print_string() function
to print the full contents of a STRING_CST, including any embedded
nuls to make the dumps clearer.  I got rid of the single digit
escapes like '\1' since they make the string look ambiguous.
If TREE_STRING_LENGTH (node) is guaranteed to be non-zero these
days the test for it being so may be redundant but I figured it's
better to be safe than sorry.

A further enhancement might be to also distinguish the type of
the STRING_CST.

Martin

PR middle-end/87052 - STRING_CST printing incomplete in Gimple dumps

gcc/testsuite/ChangeLog:

	PR middle-end/87052
	* gcc.dg/pr87052.c: New test.

gcc/ChangeLog:

	PR middle-end/87052
	* tree-pretty-print.c (pretty_print_string): Add argument.
	(dump_generic_node): Call to pretty_print_string with string size.

Index: gcc/tree-pretty-print.c
===================================================================
--- gcc/tree-pretty-print.c	(revision 263754)
+++ gcc/tree-pretty-print.c	(working copy)
@@ -37,7 +37,7 @@ along with GCC; see the file COPYING3.  If not see
 
 /* Local functions, macros and variables.  */
 static const char *op_symbol (const_tree);
-static void pretty_print_string (pretty_printer *, const char*);
+static void pretty_print_string (pretty_printer *, const char*, unsigned);
 static void newline_and_indent (pretty_printer *, int);
 static void maybe_init_pretty_print (FILE *);
 static void print_struct_decl (pretty_printer *, const_tree, int, dump_flags_t);
@@ -1800,10 +1800,13 @@ dump_generic_node (pretty_printer *pp, tree node,
       break;
 
     case STRING_CST:
-      pp_string (pp, "\"");
-      pretty_print_string (pp, TREE_STRING_POINTER (node));
-      pp_string (pp, "\"");
-      break;
+      {
+	pp_string (pp, "\"");
+	if (unsigned nbytes = TREE_STRING_LENGTH (node))
+	  pretty_print_string (pp, TREE_STRING_POINTER (node), nbytes);
+	pp_string (pp, "\"");
+	break;
+      }
 
     case VECTOR_CST:
       {
@@ -3865,15 +3868,16 @@ print_call_name (pretty_printer *pp, tree node, du
     }
 }
 
-/* Parses the string STR and replaces new-lines by '\n', tabs by '\t', ...  */
+/* Print the first N characters in the array STR, replacing non-printable
+   characters (including embedded nuls) with unambiguous escape sequences.  */
 
 static void
-pretty_print_string (pretty_printer *pp, const char *str)
+pretty_print_string (pretty_printer *pp, const char *str, unsigned n)
 {
   if (str == NULL)
     return;
 
-  while (*str)
+  for ( ; n; --n, ++str)
     {
       switch (str[0])
 	{
@@ -3913,48 +3917,20 @@ static void
 	  pp_string (pp, "\\'");
 	  break;
 
-	  /* No need to handle \0; the loop terminates on \0.  */
-
-	case '\1':
-	  pp_string (pp, "\\1");
-	  break;
-
-	case '\2':
-	  pp_string (pp, "\\2");
-	  break;
-
-	case '\3':
-	  pp_string (pp, "\\3");
-	  break;
-
-	case '\4':
-	  pp_string (pp, "\\4");
-	  break;
-
-	case '\5':
-	  pp_string (pp, "\\5");
-	  break;
-
-	case '\6':
-	  pp_string (pp, "\\6");
-	  break;
-
-	case '\7':
-	  pp_string (pp, "\\7");
-	  break;
-
 	default:
-	  if (!ISPRINT (str[0]))
+	  if (str[0] || n > 1)
 	    {
-	      char buf[5];
-	      sprintf (buf, "\\x%x", (unsigned char)str[0]);
-	      pp_string (pp, buf);
+	      if (!ISPRINT (str[0]))
+		{
+		  char buf[5];
+		  sprintf (buf, "\\x%02x", (unsigned char)str[0]);
+		  pp_string (pp, buf);
+		}
+	      else
+		pp_character (pp, str[0]);
+	      break;
 	    }
-	  else
-	    pp_character (pp, str[0]);
-	  break;
 	}
-      str++;
     }
 }
 
Index: gcc/testsuite/gcc.dg/pr87052.c
===================================================================
--- gcc/testsuite/gcc.dg/pr87052.c	(nonexistent)
+++ gcc/testsuite/gcc.dg/pr87052.c	(working copy)
@@ -0,0 +1,41 @@
+/* PR middle-end/87052 - STRING_CST printing incomplete in Gimple dumps
+   { dg-do compile }
+   { dg-options "-fdump-tree-gimple" } */
+
+void sink (const void*, ...);
+
+void test (void)
+{
+  const char a[3] = "\000ab";
+
+  /* Expect the following in the dump:
+     a = "\x00ab"; */
+
+  const char b[] = { 'a', 0, 'b', 'c' };
+
+  /* Expect the following:
+     b = "a\x00bc"; */
+
+  const char c[] = "";
+
+  /* Expect the following:
+     c = ""; */
+
+  const char d[0] = { };
+
+  /* Expect the following:
+     d = ""; */
+
+  const char e[0] = "";
+
+  /* Expect nothing.  */
+
+  sink (a, b, c, d, e);
+}
+
+/* { dg-final { scan-tree-dump-times "a = \"\\\\x00ab\";" 1 "gimple" } }
+   { dg-final { scan-tree-dump-times "b = \"a\\\\x00bc\";"  1 "gimple" } }
+   { dg-final { scan-tree-dump-times "c = \"\";"  1 "gimple" } }
+   { dg-final { scan-tree-dump-times "d = { *};"  1 "gimple" } }
+   { dg-final { scan-tree-dump-times "e = "  1 "gimple" } }
+   { dg-final { scan-tree-dump-times "e = {CLOBBER}"  1 "gimple" } }  */

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