From dfa3226153fbfe4999f2af6d916fd597e1d5ce3e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Manuel=20L=C3=B3pez-Ib=C3=A1=C3=B1ez?= Date: Wed, 24 Oct 2012 22:01:50 +0000 Subject: [PATCH] re PR c++/54928 (Infinite output with after ICE with macro) MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit 2012-10-24 Manuel López-Ibáñez PR c++/54928 * tree-diagnostic.c (maybe_unwind_expanded_macro_loc): Use diagnostic_append_note. * diagnostic.c (diagnostic_build_prefix): Make diagnostic const. (default_diagnostic_finalizer): Do not destroy prefix here. (diagnostic_report_diagnostic): Destroy it here. (diagnostic_append_note): New. * diagnostic.h (diagnostic_append_note): Declare. From-SVN: r192786 --- gcc/ChangeLog | 11 ++++++ gcc/diagnostic.c | 29 +++++++++++++-- gcc/diagnostic.h | 4 ++- gcc/tree-diagnostic.c | 99 +++++++++++++++++---------------------------------- 4 files changed, 72 insertions(+), 71 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9ee494d..1052580 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2012-10-24 Manuel López-Ibáñez + + PR c++/54928 + * tree-diagnostic.c (maybe_unwind_expanded_macro_loc): + Use diagnostic_append_note. + * diagnostic.c (diagnostic_build_prefix): Make diagnostic const. + (default_diagnostic_finalizer): Do not destroy prefix here. + (diagnostic_report_diagnostic): Destroy it here. + (diagnostic_append_note): New. + * diagnostic.h (diagnostic_append_note): Declare. + 2012-10-24 Vladimir Makarov PR rtl-optimization/55055 diff --git a/gcc/diagnostic.c b/gcc/diagnostic.c index b2ba901..ff210dc 100644 --- a/gcc/diagnostic.c +++ b/gcc/diagnostic.c @@ -208,7 +208,7 @@ diagnostic_set_info (diagnostic_info *diagnostic, const char *gmsgid, responsible for freeing the memory. */ char * diagnostic_build_prefix (diagnostic_context *context, - diagnostic_info *diagnostic) + const diagnostic_info *diagnostic) { static const char *const diagnostic_kind_text[] = { #define DEFINE_DIAGNOSTIC_KIND(K, T) (T), @@ -519,10 +519,9 @@ default_diagnostic_starter (diagnostic_context *context, } void -default_diagnostic_finalizer (diagnostic_context *context, +default_diagnostic_finalizer (diagnostic_context *context ATTRIBUTE_UNUSED, diagnostic_info *diagnostic ATTRIBUTE_UNUSED) { - pp_destroy_prefix (context->printer); } /* Interface to specify diagnostic kind overrides. Returns the @@ -759,6 +758,7 @@ diagnostic_report_diagnostic (diagnostic_context *context, pp_output_formatted_text (context->printer); diagnostic_show_locus (context, diagnostic); (*diagnostic_finalizer (context)) (context, diagnostic); + pp_destroy_prefix (context->printer); pp_newline_and_flush (context->printer); diagnostic_action_after_output (context, diagnostic); diagnostic->message.format_spec = saved_format_spec; @@ -821,6 +821,29 @@ verbatim (const char *gmsgid, ...) va_end (ap); } +/* Add a note with text GMSGID and with LOCATION to the diagnostic CONTEXT. */ +void +diagnostic_append_note (diagnostic_context *context, + location_t location, + const char * gmsgid, ...) +{ + diagnostic_info diagnostic; + va_list ap; + + va_start (ap, gmsgid); + diagnostic_set_info (&diagnostic, gmsgid, &ap, location, DK_NOTE); + if (context->inhibit_notes_p) + return; + pp_set_prefix (context->printer, + diagnostic_build_prefix (context, &diagnostic)); + pp_newline (context->printer); + pp_format (context->printer, &diagnostic.message); + pp_output_formatted_text (context->printer); + pp_destroy_prefix (context->printer); + diagnostic_show_locus (context, &diagnostic); + va_end(ap); +} + bool emit_diagnostic (diagnostic_t kind, location_t location, int opt, const char *gmsgid, ...) diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h index 976754e..e1d2146 100644 --- a/gcc/diagnostic.h +++ b/gcc/diagnostic.h @@ -282,8 +282,10 @@ extern void diagnostic_set_info_translated (diagnostic_info *, const char *, va_list *, location_t, diagnostic_t) ATTRIBUTE_GCC_DIAG(2,0); +extern void diagnostic_append_note (diagnostic_context *, location_t, + const char *, ...) ATTRIBUTE_GCC_DIAG(3,4); #endif -extern char *diagnostic_build_prefix (diagnostic_context *, diagnostic_info *); +extern char *diagnostic_build_prefix (diagnostic_context *, const diagnostic_info *); void default_diagnostic_starter (diagnostic_context *, diagnostic_info *); void default_diagnostic_finalizer (diagnostic_context *, diagnostic_info *); void diagnostic_set_caret_max_width (diagnostic_context *context, int value); diff --git a/gcc/tree-diagnostic.c b/gcc/tree-diagnostic.c index 2756ed2..3eab7ec 100644 --- a/gcc/tree-diagnostic.c +++ b/gcc/tree-diagnostic.c @@ -102,7 +102,7 @@ DEF_VEC_ALLOC_O (loc_map_pair, heap); static void maybe_unwind_expanded_macro_loc (diagnostic_context *context, - diagnostic_info *diagnostic, + const diagnostic_info *diagnostic, source_location where) { const struct line_map *map; @@ -144,14 +144,12 @@ maybe_unwind_expanded_macro_loc (diagnostic_context *context, /* Walk LOC_VEC and print the macro expansion trace, unless the first macro which expansion triggered this trace was expanded inside a system header. */ + int saved_location_line = + expand_location_to_spelling_point (diagnostic->location).line; + if (!LINEMAP_SYSP (map)) FOR_EACH_VEC_ELT (loc_map_pair, loc_vec, ix, iter) { - source_location resolved_def_loc = 0, resolved_exp_loc = 0, - saved_location = 0; - int resolved_def_loc_line = 0, saved_location_line = 0; - diagnostic_t saved_kind; - const char *saved_prefix; /* Sometimes, in the unwound macro expansion trace, we want to print a part of the context that shows where, in the definition of the relevant macro, is the token (we are @@ -174,11 +172,7 @@ maybe_unwind_expanded_macro_loc (diagnostic_context *context, A contrario, when the first interesting diagnostic line points into the definition of the macro, we don't need to display any line for that macro definition in the trace - anymore, otherwise it'd be redundant. - - This flag is true when we need to display the context of - the macro definition. */ - bool print_definition_context_p = false; + anymore, otherwise it'd be redundant. */ /* Okay, now here is what we want. For each token resulting from macro expansion we want to show: 1/ where in the @@ -187,75 +181,46 @@ maybe_unwind_expanded_macro_loc (diagnostic_context *context, /* Resolve the location iter->where into the locus 1/ of the comment above. */ - resolved_def_loc = + source_location resolved_def_loc = linemap_resolve_location (line_table, iter->where, LRK_MACRO_DEFINITION_LOCATION, NULL); /* Don't print trace for locations that are reserved or from within a system header. */ - { - const struct line_map *m = NULL; - source_location l = linemap_resolve_location (line_table, resolved_def_loc, - LRK_SPELLING_LOCATION, - &m); - if (l < RESERVED_LOCATION_COUNT - || LINEMAP_SYSP (m)) - continue; - - resolved_def_loc_line = SOURCE_LINE (m, l); - } + const struct line_map *m = NULL; + source_location l = + linemap_resolve_location (line_table, resolved_def_loc, + LRK_SPELLING_LOCATION, &m); + if (l < RESERVED_LOCATION_COUNT || LINEMAP_SYSP (m)) + continue; + + /* We need to print the context of the macro definition only + when the locus of the first displayed diagnostic (displayed + before this trace) was inside the definition of the + macro. */ + int resolved_def_loc_line = SOURCE_LINE (m, l); + if (ix == 0 && saved_location_line != resolved_def_loc_line) + { + diagnostic_append_note (context, resolved_def_loc, + "in definition of macro %qs", + linemap_map_get_macro_name (iter->map)); + /* At this step, as we've printed the context of the macro + definition, we don't want to print the context of its + expansion, otherwise, it'd be redundant. */ + continue; + } /* Resolve the location of the expansion point of the macro which expansion gave the token represented by def_loc. This is the locus 2/ of the earlier comment. */ - resolved_exp_loc = + source_location resolved_exp_loc = linemap_resolve_location (line_table, MACRO_MAP_EXPANSION_POINT_LOCATION (iter->map), LRK_MACRO_DEFINITION_LOCATION, NULL); - saved_kind = diagnostic->kind; - saved_prefix = pp_get_prefix (context->printer); - saved_location = diagnostic->location; - saved_location_line = - expand_location_to_spelling_point (saved_location).line; - - diagnostic->kind = DK_NOTE; - - /* We need to print the context of the macro definition only - when the locus of the first displayed diagnostic (displayed - before this trace) was inside the definition of the - macro. */ - print_definition_context_p = - (ix == 0 && (saved_location_line != resolved_def_loc_line)); - - if (print_definition_context_p) - { - diagnostic->location = resolved_def_loc; - pp_set_prefix (context->printer, - diagnostic_build_prefix (context, diagnostic)); - pp_newline (context->printer); - pp_printf (context->printer, "in definition of macro '%s'", - linemap_map_get_macro_name (iter->map)); - pp_destroy_prefix (context->printer); - diagnostic_show_locus (context, diagnostic); - /* At this step, as we've printed the context of the macro - definition, we don't want to print the context of its - expansion, otherwise, it'd be redundant. */ - continue; - } - - diagnostic->location = resolved_exp_loc; - pp_set_prefix (context->printer, - diagnostic_build_prefix (context, diagnostic)); - pp_newline (context->printer); - pp_printf (context->printer, "in expansion of macro '%s'", - linemap_map_get_macro_name (iter->map)); - pp_destroy_prefix (context->printer); - diagnostic_show_locus (context, diagnostic); - - diagnostic->kind = saved_kind; - diagnostic->location = saved_location; - pp_set_prefix (context->printer, saved_prefix); + diagnostic_append_note (context, resolved_exp_loc, + "in expansion of macro %qs", + linemap_map_get_macro_name (iter->map)); } VEC_free (loc_map_pair, heap, loc_vec); -- 2.7.4