Commit da67acb9 by Martin Sebor Committed by Martin Sebor

PR c/81117 - Improve buffer overflow checking in strncpy - part 1

gcc/ChangeLog:

        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.

gcc/c/ChangeLog:

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

gcc/c-family/ChangeLog:

	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.

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.

From-SVN: r251098
parent 9e3b1778
2017-08-14 Martin Sebor <msebor@redhat.com> 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 PR translation/79998
* gimple-ssa-sprintf.c (pass_sprintf_length::handle_gimple_call): * gimple-ssa-sprintf.c (pass_sprintf_length::handle_gimple_call):
Remove a stray space. Remove a stray space.
......
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> 2017-08-11 Martin Liska <mliska@suse.cz>
* c-opts.c (c_common_post_options): Replace ASM_OUTPUT_DEF with * c-opts.c (c_common_post_options): Replace ASM_OUTPUT_DEF with
......
...@@ -56,6 +56,7 @@ struct function_format_info ...@@ -56,6 +56,7 @@ struct function_format_info
/* Initialized in init_dynamic_diag_info. */ /* Initialized in init_dynamic_diag_info. */
static GTY(()) tree local_tree_type_node; static GTY(()) tree local_tree_type_node;
static GTY(()) tree local_gcall_ptr_node;
static GTY(()) tree locus; static GTY(()) tree locus;
static bool decode_format_attr (tree, function_format_info *, int); static bool decode_format_attr (tree, function_format_info *, int);
...@@ -689,7 +690,9 @@ static const format_char_info gcc_diag_char_table[] = ...@@ -689,7 +690,9 @@ static const format_char_info gcc_diag_char_table[] =
/* Custom conversion specifiers. */ /* 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 }, { "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 }, { "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[] = ...@@ -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 }, { "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 }, { "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 }, { "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 }, { "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[] = ...@@ -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 }, { "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 }, { "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 }, { "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 }, { "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_table[] = ...@@ -777,6 +786,9 @@ static const format_char_info gcc_cxxdiag_char_table[] =
{ "K", 1, STD_C89,{ T89_T, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN, BADLEN }, "", "\"", NULL }, { "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 }, { "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'.) */ /* 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 }, { "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) ...@@ -3834,6 +3846,29 @@ init_dynamic_diag_info (void)
local_tree_type_node = void_type_node; 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; static tree hwi;
if (!hwi) if (!hwi)
......
...@@ -298,6 +298,7 @@ struct format_kind_info ...@@ -298,6 +298,7 @@ struct format_kind_info
#define T_UC &unsigned_char_type_node #define T_UC &unsigned_char_type_node
#define T99_UC { STD_C99, NULL, T_UC } #define T99_UC { STD_C99, NULL, T_UC }
#define T_V &void_type_node #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_T { STD_C89, NULL, &local_tree_type_node }
#define T89_V { STD_C89, NULL, T_V } #define T89_V { STD_C89, NULL, T_V }
#define T_W &wchar_type_node #define T_W &wchar_type_node
......
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> 2017-08-11 Marek Polacek <polacek@redhat.com>
PR c/81795 PR c/81795
......
...@@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. If not see
#include "intl.h" #include "intl.h"
#include "c-family/c-pretty-print.h" #include "c-family/c-pretty-print.h"
#include "tree-pretty-print.h" #include "tree-pretty-print.h"
#include "gimple-pretty-print.h"
#include "langhooks.h" #include "langhooks.h"
#include "c-objc-common.h" #include "c-objc-common.h"
...@@ -66,6 +67,8 @@ c_objc_common_init (void) ...@@ -66,6 +67,8 @@ c_objc_common_init (void)
%D: a general decl, %D: a general decl,
%E: an identifier or expression, %E: an identifier or expression,
%F: a function declaration, %F: a function declaration,
%G: a Gimple call statement,
%K: a CALL_EXPR,
%T: a type. %T: a type.
%V: a list of type qualifiers from a tree. %V: a list of type qualifiers from a tree.
%v: an explicit list of type qualifiers %v: an explicit list of type qualifiers
...@@ -87,9 +90,16 @@ c_tree_printer (pretty_printer *pp, text_info *text, const char *spec, ...@@ -87,9 +90,16 @@ c_tree_printer (pretty_printer *pp, text_info *text, const char *spec,
if (precision != 0 || wide) if (precision != 0 || wide)
return false; return false;
if (*spec == 'G')
{
percent_G_format (text);
return true;
}
if (*spec == 'K') if (*spec == 'K')
{ {
percent_K_format (text); t = va_arg (*text->args_ptr, tree);
percent_K_format (text, t);
return true; return true;
} }
......
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> 2017-08-11 Martin Liska <mliska@suse.cz>
* decl2.c (get_tls_init_fn): Replace ASM_OUTPUT_DEF with * decl2.c (get_tls_init_fn): Replace ASM_OUTPUT_DEF with
......
...@@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -27,6 +27,7 @@ along with GCC; see the file COPYING3. If not see
#include "intl.h" #include "intl.h"
#include "cxx-pretty-print.h" #include "cxx-pretty-print.h"
#include "tree-pretty-print.h" #include "tree-pretty-print.h"
#include "gimple-pretty-print.h"
#include "c-family/c-objc.h" #include "c-family/c-objc.h"
#include "ubsan.h" #include "ubsan.h"
#include "internal-fn.h" #include "internal-fn.h"
...@@ -4050,8 +4051,13 @@ cp_printer (pretty_printer *pp, text_info *text, const char *spec, ...@@ -4050,8 +4051,13 @@ cp_printer (pretty_printer *pp, text_info *text, const char *spec,
case 'V': result = cv_to_string (next_tree, verbose); break; case 'V': result = cv_to_string (next_tree, verbose); break;
case 'X': result = eh_spec_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': case 'K':
percent_K_format (text); t = va_arg (*text->args_ptr, tree);
percent_K_format (text, t);
return true; return true;
case 'H': case 'H':
......
...@@ -2911,3 +2911,22 @@ gimple_dump_bb_for_graph (pretty_printer *pp, basic_block bb) ...@@ -2911,3 +2911,22 @@ gimple_dump_bb_for_graph (pretty_printer *pp, basic_block bb)
pp_write_text_as_dot_label_to_stream (pp, /*for_record=*/true); 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);
}
...@@ -35,5 +35,6 @@ extern void pp_gimple_stmt_1 (pretty_printer *, gimple *, int, dump_flags_t); ...@@ -35,5 +35,6 @@ extern void pp_gimple_stmt_1 (pretty_printer *, gimple *, int, dump_flags_t);
extern void gimple_dump_bb (FILE *, basic_block, int, dump_flags_t); 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 gimple_dump_bb_for_graph (pretty_printer *, basic_block);
extern void dump_ssaname_info_to_file (FILE *, tree, int); extern void dump_ssaname_info_to_file (FILE *, tree, int);
extern void percent_G_format (text_info *);
#endif /* ! GCC_GIMPLE_PRETTY_PRINT_H */ #endif /* ! GCC_GIMPLE_PRETTY_PRINT_H */
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> 2017-08-14 David Edelsohn <dje.gcc@gmail.com>
* gcc.dg/ucnid-5.c: Skip on AIX. * gcc.dg/ucnid-5.c: Skip on AIX.
......
...@@ -15,6 +15,9 @@ typedef struct location_s ...@@ -15,6 +15,9 @@ typedef struct location_s
union tree_node; union tree_node;
typedef union tree_node *tree; 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))) #define FORMAT(kind) __attribute__ ((format (__gcc_## kind ##__, 1, 2)))
...@@ -23,12 +26,13 @@ void cdiag (const char*, ...) FORMAT (cdiag); ...@@ -23,12 +26,13 @@ void cdiag (const char*, ...) FORMAT (cdiag);
void tdiag (const char*, ...) FORMAT (tdiag); void tdiag (const char*, ...) FORMAT (tdiag);
void cxxdiag (const char*, ...) FORMAT (cxxdiag); 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 "unterminated quoting directive" } */
diag ("%>"); /* { dg-warning "unmatched quoting directive " } */ diag ("%>"); /* { dg-warning "unmatched quoting directive " } */
diag ("%<foo%<bar%>%>"); /* { dg-warning "nested quoting directive" } */ diag ("%<foo%<bar%>%>"); /* { dg-warning "nested quoting directive" } */
diag ("%G", gc);
diag ("%K", t); diag ("%K", t);
diag ("%R"); /* { dg-warning "unmatched color reset directive" } */ diag ("%R"); /* { dg-warning "unmatched color reset directive" } */
...@@ -38,6 +42,7 @@ void test_diag (tree t) ...@@ -38,6 +42,7 @@ void test_diag (tree t)
diag ("%r%r%R", "", ""); diag ("%r%r%R", "", "");
diag ("%r%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 ("%<%K%>", t); /* { dg-warning ".K. conversion used within a quoted sequence" } */
diag ("%<%R%>"); /* { dg-warning "unmatched color reset directive" } */ diag ("%<%R%>"); /* { dg-warning "unmatched color reset directive" } */
...@@ -45,7 +50,7 @@ void test_diag (tree t) ...@@ -45,7 +50,7 @@ void test_diag (tree t)
diag ("%<%r%R%>", ""); diag ("%<%r%R%>", "");
} }
void test_cdiag (tree t) void test_cdiag (tree t, gcall *gc)
{ {
cdiag ("%<"); /* { dg-warning "unterminated quoting directive" } */ cdiag ("%<"); /* { dg-warning "unterminated quoting directive" } */
cdiag ("%>"); /* { dg-warning "unmatched quoting directive " } */ cdiag ("%>"); /* { dg-warning "unmatched quoting directive " } */
...@@ -54,6 +59,7 @@ void test_cdiag (tree t) ...@@ -54,6 +59,7 @@ void test_cdiag (tree t)
cdiag ("%D", t); /* { dg-warning ".D. conversion used unquoted" } */ cdiag ("%D", t); /* { dg-warning ".D. conversion used unquoted" } */
cdiag ("%E", t); cdiag ("%E", t);
cdiag ("%F", t); /* { dg-warning ".F. conversion used unquoted" } */ cdiag ("%F", t); /* { dg-warning ".F. conversion used unquoted" } */
cdiag ("%G", gc);
cdiag ("%K", t); cdiag ("%K", t);
cdiag ("%R"); /* { dg-warning "unmatched color reset directive" } */ cdiag ("%R"); /* { dg-warning "unmatched color reset directive" } */
...@@ -69,6 +75,7 @@ void test_cdiag (tree t) ...@@ -69,6 +75,7 @@ void test_cdiag (tree t)
cdiag ("%<%D%>", t); cdiag ("%<%D%>", t);
cdiag ("%<%E%>", t); cdiag ("%<%E%>", t);
cdiag ("%<%F%>", 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 ("%<%K%>", t); /* { dg-warning ".K. conversion used within a quoted sequence" } */
cdiag ("%<%R%>"); /* { dg-warning "unmatched color reset directive" } */ cdiag ("%<%R%>"); /* { dg-warning "unmatched color reset directive" } */
...@@ -83,7 +90,7 @@ void test_cdiag (tree t) ...@@ -83,7 +90,7 @@ void test_cdiag (tree t)
cdiag ("%<%qT%>", t); /* { dg-warning ".q. flag used within a quoted sequence" } */ 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 "unterminated quoting directive" } */
tdiag ("%>"); /* { dg-warning "unmatched quoting directive " } */ tdiag ("%>"); /* { dg-warning "unmatched quoting directive " } */
...@@ -91,6 +98,7 @@ void test_tdiag (tree t) ...@@ -91,6 +98,7 @@ void test_tdiag (tree t)
tdiag ("%D", t); /* { dg-warning ".D. conversion used unquoted" } */ tdiag ("%D", t); /* { dg-warning ".D. conversion used unquoted" } */
tdiag ("%E", t); tdiag ("%E", t);
tdiag ("%G", gc);
tdiag ("%K", t); tdiag ("%K", t);
tdiag ("%R"); /* { dg-warning "unmatched color reset directive" } */ tdiag ("%R"); /* { dg-warning "unmatched color reset directive" } */
...@@ -105,6 +113,7 @@ void test_tdiag (tree t) ...@@ -105,6 +113,7 @@ void test_tdiag (tree t)
tdiag ("%<%D%>", t); tdiag ("%<%D%>", t);
tdiag ("%<%E%>", 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 ("%<%K%>", t); /* { dg-warning ".K. conversion used within a quoted sequence" } */
tdiag ("%<%R%>"); /* { dg-warning "unmatched color reset directive" } */ tdiag ("%<%R%>"); /* { dg-warning "unmatched color reset directive" } */
...@@ -118,12 +127,14 @@ void test_tdiag (tree t) ...@@ -118,12 +127,14 @@ void test_tdiag (tree t)
tdiag ("%<%qT%>", t); /* { dg-warning ".q. flag used within a quoted sequence" } */ 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 ("%A", t); /* { dg-warning ".A. conversion used unquoted" } */
cxxdiag ("%D", t); /* { dg-warning ".D. conversion used unquoted" } */ cxxdiag ("%D", t); /* { dg-warning ".D. conversion used unquoted" } */
cxxdiag ("%E", t); cxxdiag ("%E", t);
cxxdiag ("%F", t); /* { dg-warning ".F. conversion used unquoted" } */ 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 "unmatched color reset directive" } */
cxxdiag ("%r", ""); /* { dg-warning "unterminated color directive" } */ cxxdiag ("%r", ""); /* { dg-warning "unterminated color directive" } */
......
...@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -25,6 +25,7 @@ along with GCC; see the file COPYING3. If not see
#include "tree.h" #include "tree.h"
#include "diagnostic.h" #include "diagnostic.h"
#include "tree-pretty-print.h" #include "tree-pretty-print.h"
#include "gimple-pretty-print.h"
#include "tree-diagnostic.h" #include "tree-diagnostic.h"
#include "langhooks.h" #include "langhooks.h"
#include "intl.h" #include "intl.h"
...@@ -275,8 +276,13 @@ default_tree_printer (pretty_printer *pp, text_info *text, const char *spec, ...@@ -275,8 +276,13 @@ default_tree_printer (pretty_printer *pp, text_info *text, const char *spec,
t = va_arg (*text->args_ptr, tree); t = va_arg (*text->args_ptr, tree);
break; break;
case 'G':
percent_G_format (text);
return true;
case 'K': case 'K':
percent_K_format (text); t = va_arg (*text->args_ptr, tree);
percent_K_format (text, t);
return true; return true;
default: default:
......
...@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -33,6 +33,7 @@ along with GCC; see the file COPYING3. If not see
#include "dumpfile.h" #include "dumpfile.h"
#include "internal-fn.h" #include "internal-fn.h"
#include "gomp-constants.h" #include "gomp-constants.h"
#include "gimple.h"
/* Local functions, macros and variables. */ /* Local functions, macros and variables. */
static const char *op_symbol (const_tree); static const char *op_symbol (const_tree);
...@@ -3970,18 +3971,17 @@ newline_and_indent (pretty_printer *pp, int spc) ...@@ -3970,18 +3971,17 @@ newline_and_indent (pretty_printer *pp, int spc)
INDENT (spc); INDENT (spc);
} }
/* Handle a %K format for TEXT. Separate from default_tree_printer so /* Handle the %K format for TEXT. Separate from default_tree_printer
it can also be used in front ends. so it can also be used in front ends.
%K: a statement, from which EXPR_LOCATION and TREE_BLOCK will be recorded. Argument is a statement from which EXPR_LOCATION and TREE_BLOCK will
*/ be recorded. */
void 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); text->set_location (0, EXPR_LOCATION (t), true);
gcc_assert (pp_ti_abstract_origin (text) != NULL); gcc_assert (pp_ti_abstract_origin (text) != NULL);
block = TREE_BLOCK (t); tree block = TREE_BLOCK (t);
*pp_ti_abstract_origin (text) = NULL; *pp_ti_abstract_origin (text) = NULL;
if (in_lto_p) if (in_lto_p)
......
...@@ -45,7 +45,7 @@ extern int op_code_prio (enum tree_code); ...@@ -45,7 +45,7 @@ extern int op_code_prio (enum tree_code);
extern int op_prio (const_tree); extern int op_prio (const_tree);
extern const char *op_symbol_code (enum tree_code); extern const char *op_symbol_code (enum tree_code);
extern void print_call_name (pretty_printer *, tree, dump_flags_t); 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 pp_tree_identifier (pretty_printer *, tree);
extern void dump_function_header (FILE *, tree, dump_flags_t); extern void dump_function_header (FILE *, tree, dump_flags_t);
extern void pp_double_int (pretty_printer *pp, double_int d, bool uns); extern void pp_double_int (pretty_printer *pp, double_int d, bool uns);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment