re PR c++/54928 (Infinite output with after ICE with macro)

2012-10-24  Manuel López-Ibáñez  <manu@gcc.gnu.org>

	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
This commit is contained in:
Manuel López-Ibáñez 2012-10-24 22:01:50 +00:00
parent 0931831120
commit dfa3226153
4 changed files with 74 additions and 73 deletions

View File

@ -1,3 +1,14 @@
2012-10-24 Manuel López-Ibáñez <manu@gcc.gnu.org>
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 <vmakarov@redhat.com>
PR rtl-optimization/55055

View File

@ -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, ...)

View File

@ -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);

View File

@ -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);
}
/* 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 =
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;
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. */
print_definition_context_p =
(ix == 0 && (saved_location_line != resolved_def_loc_line));
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;
}
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;
}
/* 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. */
source_location resolved_exp_loc =
linemap_resolve_location (line_table,
MACRO_MAP_EXPANSION_POINT_LOCATION (iter->map),
LRK_MACRO_DEFINITION_LOCATION, NULL);
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);