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]

Re: [PATCH 1/4] enhance overflow and truncation detection in strncpy and strncat (PR 81117)


On 08/09/2017 10:44 PM, Jeff Law wrote:
On 08/06/2017 02:07 PM, Martin Sebor wrote:
The attached patch adds support for a new GCC format specifier,
G, that behaves like %K but accepts a gcall* argument.  This
makes it possible to provide inlining context for "artificial"
inline functions like strncpy (with _FORTIFY_SOURCE) in
diagnostics issued from the middle end.

Martin

gcc-81117-1.diff


PR c/81117 - Improve buffer overflow checking in strncpy

gcc/ChangeLog:

	PR c/81117
	* tree-diagnostic.c (default_tree_printer): Handle %G.
	* tree-pretty-print.h (percent_G_format): Declare new function.
	* tree-pretty-print.c (percent_K_format): Define a static overload.
	(percent_G_format): New function.

gcc/c/ChangeLog:

	PR c/81117
	* c-objc-common.c (c_objc_common_init): Handle 'G'.

gcc/c-family/ChangeLog:

	* c-format.h (T89_G): New macro.
	* c-format.c (local_gcall_ptr_node): New variable.
	(init_dynamic_diag_info): Initialize it.

gcc/cp/ChangeLog:

	PR c/81117
	* error.c (cp_printer): Handle 'G'.

gcc/testsuite/ChangeLog:

	PR c/81117
	* gcc.dg/format/gcc_diag-10.c: Exercise %G.

diff --git a/gcc/tree-diagnostic.c b/gcc/tree-diagnostic.c
index 52b7e7f..ad58b69 100644
--- a/gcc/tree-diagnostic.c
+++ b/gcc/tree-diagnostic.c
@@ -275,6 +275,10 @@ default_tree_printer (pretty_printer *pp, text_info *text, const char *spec,
       t = va_arg (*text->args_ptr, tree);
       break;

+    case 'G':
+      percent_G_format (text);
+      return true;
+
     case 'K':
       percent_K_format (text);
       return true;
diff --git a/gcc/tree-pretty-print.c b/gcc/tree-pretty-print.c
index 4d8177c..7c4c805 100644
--- a/gcc/tree-pretty-print.c
+++ b/gcc/tree-pretty-print.c
@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "dumpfile.h"
 #include "internal-fn.h"
 #include "gomp-constants.h"
+#include "gimple.h"
This is an indication you're probably putting the 'G' handling in the
wrong place.  Wouldn't gimple-pretty-print.c be more correct?

That's my only objection to this patch, so if it moves trivially, then
it's pre-approved.  If it's non-trivial, then we'll want another iteration.

I moved it and after retesting committed in r251098.  The diff
is attached for reference.

Btw., there are lots of test suite failures that make it tricky
to spot regressions, mostly in ASan tests but others too (e.g.,
g++.dg/debug/debug9.C, g++.dg/template/nontype10.C, and some
others).

Martin

Index: gcc/tree-pretty-print.c
===================================================================
--- gcc/tree-pretty-print.c	(revision 251097)
+++ gcc/tree-pretty-print.c	(revision 251098)
@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "dumpfile.h"
 #include "internal-fn.h"
 #include "gomp-constants.h"
+#include "gimple.h"
 
 /* Local functions, macros and variables.  */
 static const char *op_symbol (const_tree);
@@ -3970,18 +3971,17 @@ newline_and_indent (pretty_printer *pp, int spc)
   INDENT (spc);
 }
 
-/* Handle a %K format for TEXT.  Separate from default_tree_printer so
-   it can also be used in front ends.
-   %K: a statement, from which EXPR_LOCATION and TREE_BLOCK will be recorded.
-*/
+/* Handle the %K format for TEXT.  Separate from default_tree_printer
+   so it can also be used in front ends.
+   Argument is a statement from which EXPR_LOCATION and TREE_BLOCK will
+   be recorded.  */
 
 void
-percent_K_format (text_info *text)
+percent_K_format (text_info *text, tree t)
 {
-  tree t = va_arg (*text->args_ptr, tree), block;
   text->set_location (0, EXPR_LOCATION (t), true);
   gcc_assert (pp_ti_abstract_origin (text) != NULL);
-  block = TREE_BLOCK (t);
+  tree block = TREE_BLOCK (t);
   *pp_ti_abstract_origin (text) = NULL;
 
   if (in_lto_p)
Index: gcc/c-family/ChangeLog
===================================================================
--- gcc/c-family/ChangeLog	(revision 251097)
+++ gcc/c-family/ChangeLog	(revision 251098)
@@ -1,3 +1,10 @@
+2017-08-14  Martin Sebor  <msebor@redhat.com>
+
+	PR c/81117
+	* c-format.h (T89_G): New macro.
+	* c-format.c (local_gcall_ptr_node): New variable.
+	(init_dynamic_diag_info): Initialize it.
+
 2017-08-11  Martin Liska  <mliska@suse.cz>
 
 	* c-opts.c (c_common_post_options): Replace ASM_OUTPUT_DEF with
Index: gcc/c-family/c-format.c
===================================================================
--- gcc/c-family/c-format.c	(revision 251097)
+++ gcc/c-family/c-format.c	(revision 251098)
@@ -56,6 +56,7 @@ struct function_format_info
 
 /* Initialized in init_dynamic_diag_info.  */
 static GTY(()) tree local_tree_type_node;
+static GTY(()) tree local_gcall_ptr_node;
 static GTY(()) tree locus;
 
 static bool decode_format_attr (tree, function_format_info *, int);
@@ -689,7 +690,9 @@ static const format_char_info gcc_diag_char_table[
 
   /* Custom conversion specifiers.  */
 
-  /* These will require a "tree" at runtime.  */
+  /* G requires a "gcall*" argument at runtime.  */
+  { "G",   1, STD_C89, { T89_G,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",    "\"",   NULL },
+  /* K requires a "tree" argument at runtime.  */
   { "K",   1, STD_C89, { T89_T,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",    "\"",   NULL },
 
   { "r",   1, STD_C89, { T89_C,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",    "//cR",   NULL },
@@ -718,6 +721,9 @@ static const format_char_info gcc_tdiag_char_table
   { "E", 1, STD_C89, { T89_T,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q+", "",   NULL },
   { "K", 1, STD_C89, { T89_T,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "", "\"",   NULL },
 
+  /* G requires a "gcall*" argument at runtime.  */
+  { "G", 1, STD_C89, { T89_G,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "", "\"",   NULL },
+
   { "v",   0, STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q#",  "",   NULL },
 
   { "r",   1, STD_C89, { T89_C,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",    "/cR",   NULL },
@@ -747,6 +753,9 @@ static const format_char_info gcc_cdiag_char_table
   { "E",   1, STD_C89, { T89_T,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q+", "",   NULL },
   { "K",   1, STD_C89, { T89_T,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "", "\"",   NULL },
 
+  /* G requires a "gcall*" argument at runtime.  */
+  { "G",   1, STD_C89, { T89_G,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "", "\"",   NULL },
+
   { "v",   0, STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q#",  "",   NULL },
 
   { "r",   1, STD_C89, { T89_C,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",    "/cR",   NULL },
@@ -777,6 +786,9 @@ static const format_char_info gcc_cxxdiag_char_tab
   { "K", 1, STD_C89,{ T89_T,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",   "\"",   NULL },
   { "v", 0,STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q#",  "",   NULL },
 
+  /* G requires a "gcall*" argument at runtime.  */
+  { "G", 1, STD_C89,{ T89_G,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "",   "\"",   NULL },
+
   /* These accept either an 'int' or an 'enum tree_code' (which is handled as an 'int'.)  */
   { "CLOPQ",0,STD_C89, { T89_I,   BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN,  BADLEN  }, "q",  "",   NULL },
 
@@ -3834,6 +3846,29 @@ init_dynamic_diag_info (void)
 	local_tree_type_node = void_type_node;
     }
 
+  /* Similar to the above but for gcall*.  */
+  if (!local_gcall_ptr_node
+      || local_gcall_ptr_node == void_type_node)
+    {
+      if ((local_gcall_ptr_node = maybe_get_identifier ("gcall")))
+	{
+	  local_gcall_ptr_node
+	    = identifier_global_value (local_gcall_ptr_node);
+	  if (local_gcall_ptr_node)
+	    {
+	      if (TREE_CODE (local_gcall_ptr_node) != TYPE_DECL)
+		{
+		  error ("%<gcall%> is not defined as a type");
+		  local_gcall_ptr_node = 0;
+		}
+	      else
+		local_gcall_ptr_node = TREE_TYPE (local_gcall_ptr_node);
+	    }
+	}
+      else
+	local_gcall_ptr_node = void_type_node;
+    }
+
   static tree hwi;
 
   if (!hwi)
Index: gcc/c-family/c-format.h
===================================================================
--- gcc/c-family/c-format.h	(revision 251097)
+++ gcc/c-family/c-format.h	(revision 251098)
@@ -298,6 +298,7 @@ struct format_kind_info
 #define T_UC	&unsigned_char_type_node
 #define T99_UC	{ STD_C99, NULL, T_UC }
 #define T_V	&void_type_node
+#define T89_G   { STD_C89, NULL, &local_gcall_ptr_node }
 #define T89_T   { STD_C89, NULL, &local_tree_type_node }
 #define T89_V	{ STD_C89, NULL, T_V }
 #define T_W	&wchar_type_node
Index: gcc/tree-pretty-print.h
===================================================================
--- gcc/tree-pretty-print.h	(revision 251097)
+++ gcc/tree-pretty-print.h	(revision 251098)
@@ -45,7 +45,7 @@ extern int op_code_prio (enum tree_code);
 extern int op_prio (const_tree);
 extern const char *op_symbol_code (enum tree_code);
 extern void print_call_name (pretty_printer *, tree, dump_flags_t);
-extern void percent_K_format (text_info *);
+extern void percent_K_format (text_info *, tree);
 extern void pp_tree_identifier (pretty_printer *, tree);
 extern void dump_function_header (FILE *, tree, dump_flags_t);
 extern void pp_double_int (pretty_printer *pp, double_int d, bool uns);
Index: gcc/c/ChangeLog
===================================================================
--- gcc/c/ChangeLog	(revision 251097)
+++ gcc/c/ChangeLog	(revision 251098)
@@ -1,3 +1,8 @@
+2017-08-14  Martin Sebor  <msebor@redhat.com>
+
+	PR c/81117
+	* c-objc-common.c (c_objc_common_init): Handle 'G'.
+
 2017-08-11  Marek Polacek  <polacek@redhat.com>
 
 	PR c/81795
Index: gcc/c/c-objc-common.c
===================================================================
--- gcc/c/c-objc-common.c	(revision 251097)
+++ gcc/c/c-objc-common.c	(revision 251098)
@@ -24,6 +24,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "intl.h"
 #include "c-family/c-pretty-print.h"
 #include "tree-pretty-print.h"
+#include "gimple-pretty-print.h"
 #include "langhooks.h"
 #include "c-objc-common.h"
 
@@ -66,6 +67,8 @@ c_objc_common_init (void)
    %D: a general decl,
    %E: an identifier or expression,
    %F: a function declaration,
+   %G: a Gimple call statement,
+   %K: a CALL_EXPR,
    %T: a type.
    %V: a list of type qualifiers from a tree.
    %v: an explicit list of type qualifiers
@@ -87,9 +90,16 @@ c_tree_printer (pretty_printer *pp, text_info *tex
   if (precision != 0 || wide)
     return false;
 
+  if (*spec == 'G')
+    {
+      percent_G_format (text);
+      return true;
+    }
+
   if (*spec == 'K')
     {
-      percent_K_format (text);
+      t = va_arg (*text->args_ptr, tree);
+      percent_K_format (text, t);
       return true;
     }
 
Index: gcc/tree-diagnostic.c
===================================================================
--- gcc/tree-diagnostic.c	(revision 251097)
+++ gcc/tree-diagnostic.c	(revision 251098)
@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree.h"
 #include "diagnostic.h"
 #include "tree-pretty-print.h"
+#include "gimple-pretty-print.h"
 #include "tree-diagnostic.h"
 #include "langhooks.h"
 #include "intl.h"
@@ -275,8 +276,13 @@ default_tree_printer (pretty_printer *pp, text_inf
       t = va_arg (*text->args_ptr, tree);
       break;
 
+    case 'G':
+      percent_G_format (text);
+      return true;
+
     case 'K':
-      percent_K_format (text);
+      t = va_arg (*text->args_ptr, tree);
+      percent_K_format (text, t);
       return true;
 
     default:
Index: gcc/ChangeLog
===================================================================
--- gcc/ChangeLog	(revision 251097)
+++ gcc/ChangeLog	(revision 251098)
@@ -1,5 +1,13 @@
 2017-08-14  Martin Sebor  <msebor@redhat.com>
 
+	PR c/81117
+	* tree-diagnostic.c (default_tree_printer): Handle %G.
+	* gimple-pretty-print.h (percent_G_format): Declare new function.
+	* gimple-pretty-print.c (percent_G_format): Define.
+	* tree-pretty-print.c (percent_K_format): Add argument.
+
+2017-08-14  Martin Sebor  <msebor@redhat.com>
+
 	PR translation/79998
 	* gimple-ssa-sprintf.c (pass_sprintf_length::handle_gimple_call):
 	Remove a stray space.
Index: gcc/testsuite/gcc.dg/format/gcc_diag-10.c
===================================================================
--- gcc/testsuite/gcc.dg/format/gcc_diag-10.c	(revision 251097)
+++ gcc/testsuite/gcc.dg/format/gcc_diag-10.c	(revision 251098)
@@ -15,6 +15,9 @@ typedef struct location_s
 union tree_node;
 typedef union tree_node *tree;
 
+/* Define gcall as a dummy type.  The typedef must be provided for
+   the C test to find the symbol.  */
+typedef struct gcall gcall;
 
 #define FORMAT(kind) __attribute__ ((format (__gcc_## kind ##__, 1, 2)))
 
@@ -23,12 +26,13 @@ void cdiag (const char*, ...) FORMAT (cdiag);
 void tdiag (const char*, ...) FORMAT (tdiag);
 void cxxdiag (const char*, ...) FORMAT (cxxdiag);
 
-void test_diag (tree t)
+void test_diag (tree t, gcall *gc)
 {
   diag ("%<");   /* { dg-warning "unterminated quoting directive" } */
   diag ("%>");   /* { dg-warning "unmatched quoting directive " } */
   diag ("%<foo%<bar%>%>");   /* { dg-warning "nested quoting directive" } */
 
+  diag ("%G", gc);
   diag ("%K", t);
 
   diag ("%R");       /* { dg-warning "unmatched color reset directive" } */
@@ -38,6 +42,7 @@ void cxxdiag (const char*, ...) FORMAT (cxxdiag);
   diag ("%r%r%R", "", "");
   diag ("%r%R%r%R", "", "");
 
+  diag ("%<%G%>", gc);  /* { dg-warning ".G. conversion used within a quoted sequence" } */
   diag ("%<%K%>", t);   /* { dg-warning ".K. conversion used within a quoted sequence" } */
 
   diag ("%<%R%>");      /* { dg-warning "unmatched color reset directive" } */
@@ -45,7 +50,7 @@ void cxxdiag (const char*, ...) FORMAT (cxxdiag);
   diag ("%<%r%R%>", "");
 }
 
-void test_cdiag (tree t)
+void test_cdiag (tree t, gcall *gc)
 {
   cdiag ("%<");   /* { dg-warning "unterminated quoting directive" } */
   cdiag ("%>");   /* { dg-warning "unmatched quoting directive " } */
@@ -54,6 +59,7 @@ void cxxdiag (const char*, ...) FORMAT (cxxdiag);
   cdiag ("%D", t);       /* { dg-warning ".D. conversion used unquoted" } */
   cdiag ("%E", t);
   cdiag ("%F", t);       /* { dg-warning ".F. conversion used unquoted" } */
+  cdiag ("%G", gc);
   cdiag ("%K", t);
 
   cdiag ("%R");       /* { dg-warning "unmatched color reset directive" } */
@@ -69,6 +75,7 @@ void cxxdiag (const char*, ...) FORMAT (cxxdiag);
   cdiag ("%<%D%>", t);
   cdiag ("%<%E%>", t);
   cdiag ("%<%F%>", t);
+  cdiag ("%<%G%>", gc);  /* { dg-warning ".G. conversion used within a quoted sequence" } */
   cdiag ("%<%K%>", t);   /* { dg-warning ".K. conversion used within a quoted sequence" } */
 
   cdiag ("%<%R%>");      /* { dg-warning "unmatched color reset directive" } */
@@ -83,7 +90,7 @@ void cxxdiag (const char*, ...) FORMAT (cxxdiag);
   cdiag ("%<%qT%>", t);  /* { dg-warning ".q. flag used within a quoted sequence" } */
 }
 
-void test_tdiag (tree t)
+void test_tdiag (tree t, gcall *gc)
 {
   tdiag ("%<");       /* { dg-warning "unterminated quoting directive" } */
   tdiag ("%>");       /* { dg-warning "unmatched quoting directive " } */
@@ -91,6 +98,7 @@ void cxxdiag (const char*, ...) FORMAT (cxxdiag);
 
   tdiag ("%D", t);       /* { dg-warning ".D. conversion used unquoted" } */
   tdiag ("%E", t);
+  tdiag ("%G", gc);
   tdiag ("%K", t);
 
   tdiag ("%R");          /* { dg-warning "unmatched color reset directive" } */
@@ -105,6 +113,7 @@ void cxxdiag (const char*, ...) FORMAT (cxxdiag);
 
   tdiag ("%<%D%>", t);
   tdiag ("%<%E%>", t);
+  tdiag ("%<%G%>", gc);  /* { dg-warning ".G. conversion used within a quoted sequence" } */
   tdiag ("%<%K%>", t);   /* { dg-warning ".K. conversion used within a quoted sequence" } */
 
   tdiag ("%<%R%>");      /* { dg-warning "unmatched color reset directive" } */
@@ -118,12 +127,14 @@ void cxxdiag (const char*, ...) FORMAT (cxxdiag);
   tdiag ("%<%qT%>", t);  /* { dg-warning ".q. flag used within a quoted sequence" } */
 }
 
-void test_cxxdiag (tree t)
+void test_cxxdiag (tree t, gcall *gc)
 {
   cxxdiag ("%A", t);     /* { dg-warning ".A. conversion used unquoted" } */
   cxxdiag ("%D", t);     /* { dg-warning ".D. conversion used unquoted" } */
   cxxdiag ("%E", t);
   cxxdiag ("%F", t);     /* { dg-warning ".F. conversion used unquoted" } */
+  cxxdiag ("%G", gc);
+  cxxdiag ("%K", t);
 
   cxxdiag ("%R");        /* { dg-warning "unmatched color reset directive" } */
   cxxdiag ("%r", "");    /* { dg-warning "unterminated color directive" } */
Index: gcc/testsuite/ChangeLog
===================================================================
--- gcc/testsuite/ChangeLog	(revision 251097)
+++ gcc/testsuite/ChangeLog	(revision 251098)
@@ -1,3 +1,8 @@
+2017-08-14  Martin Sebor  <msebor@redhat.com>
+
+	PR c/81117
+	* gcc.dg/format/gcc_diag-10.c: Exercise %G.
+
 2017-08-14  David Edelsohn  <dje.gcc@gmail.com>
 
 	* gcc.dg/ucnid-5.c: Skip on AIX.
Index: gcc/cp/error.c
===================================================================
--- gcc/cp/error.c	(revision 251097)
+++ gcc/cp/error.c	(revision 251098)
@@ -27,6 +27,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "intl.h"
 #include "cxx-pretty-print.h"
 #include "tree-pretty-print.h"
+#include "gimple-pretty-print.h"
 #include "c-family/c-objc.h"
 #include "ubsan.h"
 #include "internal-fn.h"
@@ -4050,8 +4051,13 @@ cp_printer (pretty_printer *pp, text_info *text, c
     case 'V': result = cv_to_string (next_tree, verbose);	break;
     case 'X': result = eh_spec_to_string (next_tree, verbose);  break;
 
+    case 'G':
+      percent_G_format (text);
+      return true;
+
     case 'K':
-      percent_K_format (text);
+      t = va_arg (*text->args_ptr, tree);
+      percent_K_format (text, t);
       return true;
 
     case 'H':
Index: gcc/cp/ChangeLog
===================================================================
--- gcc/cp/ChangeLog	(revision 251097)
+++ gcc/cp/ChangeLog	(revision 251098)
@@ -1,3 +1,8 @@
+2017-08-14  Martin Sebor  <msebor@redhat.com>
+
+	PR c/81117
+	* error.c (cp_printer): Handle 'G'.
+
 2017-08-11  Martin Liska  <mliska@suse.cz>
 
 	* decl2.c (get_tls_init_fn): Replace ASM_OUTPUT_DEF with
Index: gcc/gimple-pretty-print.c
===================================================================
--- gcc/gimple-pretty-print.c	(revision 251097)
+++ gcc/gimple-pretty-print.c	(revision 251098)
@@ -2911,3 +2911,22 @@ gimple_dump_bb_for_graph (pretty_printer *pp, basi
   pp_write_text_as_dot_label_to_stream (pp, /*for_record=*/true);
 }
 
+
+/* Handle the %G format for TEXT.  Same as %K in handle_K_format in
+   tree-pretty-print.c but with a Gimple call statement as an argument.  */
+
+void
+percent_G_format (text_info *text)
+{
+  gcall *stmt = va_arg (*text->args_ptr, gcall*);
+
+  /* Build a call expression from the Gimple call statement and
+     pass it to the K formatter that knows how to format it.  */
+  tree exp = build_vl_exp (CALL_EXPR, gimple_call_num_args (stmt) + 3);
+  CALL_EXPR_FN (exp) = gimple_call_fn (stmt);
+  TREE_TYPE (exp) = gimple_call_return_type (stmt);
+  CALL_EXPR_STATIC_CHAIN (exp) = gimple_call_chain (stmt);
+  SET_EXPR_LOCATION (exp, gimple_location (stmt));
+
+  percent_K_format (text, exp);
+}
Index: gcc/gimple-pretty-print.h
===================================================================
--- gcc/gimple-pretty-print.h	(revision 251097)
+++ gcc/gimple-pretty-print.h	(revision 251098)
@@ -35,5 +35,6 @@ extern void pp_gimple_stmt_1 (pretty_printer *, gi
 extern void gimple_dump_bb (FILE *, basic_block, int, dump_flags_t);
 extern void gimple_dump_bb_for_graph (pretty_printer *, basic_block);
 extern void dump_ssaname_info_to_file (FILE *, tree, int);
+extern void percent_G_format (text_info *);
 
 #endif /* ! GCC_GIMPLE_PRETTY_PRINT_H */

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