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" } } */