middle-end/97855 - avoid recursing into pp_printf
authorRichard Biener <rguenther@suse.de>
Thu, 4 Mar 2021 08:00:55 +0000 (09:00 +0100)
committerRichard Biener <rguenther@suse.de>
Thu, 4 Mar 2021 10:32:34 +0000 (11:32 +0100)
When diagnostic messages use pretty-printer formats like %D or %E
the pp_printf invocation can end up in tree pretty-printers which
then have to avoid using pp_printf themselves since this function
is not re-entrant.

The following removes all pp_printf uses from tree-pretty-print.c
fixing the observed malformed diagnostics.  It also poisons the
identifier so new uses are less likely to creep in.

2021-03-04  Richard Biener  <rguenther@suse.de>

PR middle-end/97855
* tree-pretty-print.c: Poison pp_printf.
(dump_decl_name): Avoid use of pp_printf.
(dump_block_node): Likewise.
(dump_generic_node): Likewise.

gcc/tree-pretty-print.c

index 986f75d..62899df 100644 (file)
@@ -36,6 +36,11 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple.h"
 #include "fold-const.h"
 
+/* Routines in this file get invoked via the default tree printer
+   used by diagnostics and thus they are called from pp_printf which
+   isn't reentrant.  Avoid using pp_printf in this file.  */
+#pragma GCC poison pp_printf
+
 /* Disable warnings about quoting issues in the pp_xxx calls below
    that (intentionally) don't follow GCC diagnostic conventions.  */
 #if __GNUC__ >= 10
@@ -293,29 +298,41 @@ dump_decl_name (pretty_printer *pp, tree node, dump_flags_t flags)
   if ((flags & TDF_UID) || name == NULL_TREE)
     {
       if (TREE_CODE (node) == LABEL_DECL && LABEL_DECL_UID (node) != -1)
-       pp_printf (pp, "L%c%d", uid_sep, (int) LABEL_DECL_UID (node));
+       {
+         pp_character (pp, 'L');
+         pp_character (pp, uid_sep);
+         pp_decimal_int (pp, (int) LABEL_DECL_UID (node));
+       }
       else if (TREE_CODE (node) == DEBUG_EXPR_DECL)
        {
          if (flags & TDF_NOUID)
            pp_string (pp, "D#xxxx");
          else
-           pp_printf (pp, "D#%i", DEBUG_TEMP_UID (node));
+           {
+             pp_string (pp, "D#");
+             pp_decimal_int (pp, (int) DEBUG_TEMP_UID (node));
+           }
        }
       else
        {
          char c = TREE_CODE (node) == CONST_DECL ? 'C' : 'D';
+         pp_character (pp, c);
+         pp_character (pp, uid_sep);
          if (flags & TDF_NOUID)
-           pp_printf (pp, "%c.xxxx", c);
+           pp_string (pp, "xxxx");
          else
-           pp_printf (pp, "%c%c%u", c, uid_sep, DECL_UID (node));
+           pp_scalar (pp, "%u", DECL_UID (node));
        }
     }
   if ((flags & TDF_ALIAS) && DECL_PT_UID (node) != DECL_UID (node))
     {
       if (flags & TDF_NOUID)
-       pp_printf (pp, "ptD.xxxx");
+       pp_string (pp, "ptD.xxxx");
       else
-       pp_printf (pp, "ptD.%u", DECL_PT_UID (node));
+       {
+         pp_string (pp, "ptD.");
+         pp_scalar (pp, "%u", DECL_PT_UID (node));
+       }
     }
 }
 
@@ -1328,10 +1345,16 @@ dump_block_node (pretty_printer *pp, tree block, int spc, dump_flags_t flags)
 {
   tree t;
 
-  pp_printf (pp, "BLOCK #%d ", BLOCK_NUMBER (block));
+  pp_string (pp, "BLOCK #");
+  pp_decimal_int (pp, BLOCK_NUMBER (block));
+  pp_character (pp, ' ');
 
   if (flags & TDF_ADDRESS)
-    pp_printf (pp, "[%p] ", (void *) block);
+    {
+      pp_character (pp, '[');
+      pp_scalar (pp, "%p", (void *) block);
+      pp_string (pp, "] ");
+    }
 
   if (TREE_ASM_WRITTEN (block))
     pp_string (pp, "[written] ");
@@ -1650,7 +1673,11 @@ dump_generic_node (pretty_printer *pp, tree node, int spc, dump_flags_t flags,
   is_expr = EXPR_P (node);
 
   if (is_stmt && (flags & TDF_STMTADDR))
-    pp_printf (pp, "<&%p> ", (void *)node);
+    {
+      pp_string (pp, "<&");
+      pp_scalar (pp, "%p", (void *)node);
+      pp_string (pp, "> ");
+    }
 
   if ((flags & TDF_LINENO) && EXPR_HAS_LOCATION (node))
     dump_location (pp, EXPR_LOCATION (node));
@@ -1857,9 +1884,13 @@ dump_generic_node (pretty_printer *pp, tree node, int spc, dump_flags_t flags,
          if (TYPE_IDENTIFIER (node))
            dump_generic_node (pp, TYPE_NAME (node), spc, flags, false);
          else if (flags & TDF_NOUID)
-           pp_printf (pp, "<Txxxx>");
+           pp_string (pp, "<Txxxx>");
          else
-           pp_printf (pp, "<T%x>", TYPE_UID (node));
+           {
+             pp_string (pp, "<T");
+             pp_scalar (pp, "%x", TYPE_UID (node));
+             pp_character (pp, '>');
+           }
 
          pp_right_paren (pp);
          dump_function_declaration (pp, fnode, spc, flags);
@@ -2137,9 +2168,13 @@ dump_generic_node (pretty_printer *pp, tree node, int spc, dump_flags_t flags,
       else if (TYPE_NAME (node) && DECL_NAME (TYPE_NAME (node)))
        dump_decl_name (pp, TYPE_NAME (node), flags);
       else if (flags & TDF_NOUID)
-       pp_printf (pp, "<Txxxx>");
+       pp_string (pp, "<Txxxx>");
       else
-       pp_printf (pp, "<T%x>", TYPE_UID (node));
+       {
+         pp_string (pp, "<T");
+         pp_scalar (pp, "%x", TYPE_UID (node));
+         pp_character (pp, '>');
+       }
       dump_function_declaration (pp, node, spc, flags);
       break;
 
@@ -2154,9 +2189,16 @@ dump_generic_node (pretty_printer *pp, tree node, int spc, dump_flags_t flags,
       else if (LABEL_DECL_UID (node) != -1)
        {
          if (flags & TDF_GIMPLE)
-           pp_printf (pp, "L%d", (int) LABEL_DECL_UID (node));
+           {
+             pp_character (pp, 'L');
+             pp_decimal_int (pp, (int) LABEL_DECL_UID (node));
+           }
          else
-           pp_printf (pp, "<L%d>", (int) LABEL_DECL_UID (node));
+           {
+             pp_string (pp, "<L");
+             pp_decimal_int (pp, (int) LABEL_DECL_UID (node));
+             pp_character (pp, '>');
+           }
        }
       else
        {
@@ -2165,9 +2207,16 @@ dump_generic_node (pretty_printer *pp, tree node, int spc, dump_flags_t flags,
          else
            {
              if (flags & TDF_GIMPLE)
-               pp_printf (pp, "<D%u>", DECL_UID (node));
+               {
+                 pp_character (pp, 'D');
+                 pp_scalar (pp, "%u", DECL_UID (node));
+               }
              else
-               pp_printf (pp, "<D.%u>", DECL_UID (node));
+               {
+                 pp_string (pp, "<D.");
+                 pp_scalar (pp, "%u", DECL_UID (node));
+                 pp_character (pp, '>');
+               }
            }
        }
       break;
@@ -3021,9 +3070,12 @@ dump_generic_node (pretty_printer *pp, tree node, int spc, dump_flags_t flags,
          pp_string (pp, ", ivdep");
          break;
        case annot_expr_unroll_kind:
-         pp_printf (pp, ", unroll %d",
-                    (int) TREE_INT_CST_LOW (TREE_OPERAND (node, 2)));
-         break;
+         {
+           pp_string (pp, ", unroll ");
+           pp_decimal_int (pp,
+                           (int) TREE_INT_CST_LOW (TREE_OPERAND (node, 2)));
+           break;
+         }
        case annot_expr_no_vector_kind:
          pp_string (pp, ", no-vector");
          break;
@@ -3205,7 +3257,8 @@ dump_generic_node (pretty_printer *pp, tree node, int spc, dump_flags_t flags,
       dump_generic_node (pp, CHREC_LEFT (node), spc, flags, false);
       pp_string (pp, ", +, ");
       dump_generic_node (pp, CHREC_RIGHT (node), spc, flags, false);
-      pp_printf (pp, "}_%u", CHREC_VARIABLE (node));
+      pp_string (pp, "}_");
+      pp_scalar (pp, "%u", CHREC_VARIABLE (node));
       is_stmt = false;
       break;