runtime: copy runtime package time code from Go 1.7
[official-gcc.git] / gcc / diagnostic.c
blob24aceec558ccec4d2f67659ee5000db1ad0ba591
1 /* Language-independent diagnostic subroutines for the GNU Compiler Collection
2 Copyright (C) 1999-2016 Free Software Foundation, Inc.
3 Contributed by Gabriel Dos Reis <gdr@codesourcery.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
22 /* This file implements the language independent aspect of diagnostic
23 message module. */
25 #include "config.h"
26 #include "system.h"
27 #include "coretypes.h"
28 #include "version.h"
29 #include "demangle.h"
30 #include "intl.h"
31 #include "backtrace.h"
32 #include "diagnostic.h"
33 #include "diagnostic-color.h"
34 #include "edit-context.h"
35 #include "selftest.h"
37 #ifdef HAVE_TERMIOS_H
38 # include <termios.h>
39 #endif
41 #ifdef GWINSZ_IN_SYS_IOCTL
42 # include <sys/ioctl.h>
43 #endif
45 #define pedantic_warning_kind(DC) \
46 ((DC)->pedantic_errors ? DK_ERROR : DK_WARNING)
47 #define permissive_error_kind(DC) ((DC)->permissive ? DK_WARNING : DK_ERROR)
48 #define permissive_error_option(DC) ((DC)->opt_permissive)
50 /* Prototypes. */
51 static bool diagnostic_impl (rich_location *, int, const char *,
52 va_list *, diagnostic_t) ATTRIBUTE_GCC_DIAG(3,0);
53 static bool diagnostic_n_impl (location_t, int, int, const char *,
54 const char *, va_list *,
55 diagnostic_t) ATTRIBUTE_GCC_DIAG(5,0);
56 static bool diagnostic_n_impl_richloc (rich_location *, int, int, const char *,
57 const char *, va_list *,
58 diagnostic_t) ATTRIBUTE_GCC_DIAG(5,0);
60 static void error_recursion (diagnostic_context *) ATTRIBUTE_NORETURN;
61 static void real_abort (void) ATTRIBUTE_NORETURN;
63 /* Name of program invoked, sans directories. */
65 const char *progname;
67 /* A diagnostic_context surrogate for stderr. */
68 static diagnostic_context global_diagnostic_context;
69 diagnostic_context *global_dc = &global_diagnostic_context;
71 /* Return a malloc'd string containing MSG formatted a la printf. The
72 caller is responsible for freeing the memory. */
73 char *
74 build_message_string (const char *msg, ...)
76 char *str;
77 va_list ap;
79 va_start (ap, msg);
80 str = xvasprintf (msg, ap);
81 va_end (ap);
83 return str;
86 /* Same as diagnostic_build_prefix, but only the source FILE is given. */
87 char *
88 file_name_as_prefix (diagnostic_context *context, const char *f)
90 const char *locus_cs
91 = colorize_start (pp_show_color (context->printer), "locus");
92 const char *locus_ce = colorize_stop (pp_show_color (context->printer));
93 return build_message_string ("%s%s:%s ", locus_cs, f, locus_ce);
98 /* Return the value of the getenv("COLUMNS") as an integer. If the
99 value is not set to a positive integer, use ioctl to get the
100 terminal width. If it fails, return INT_MAX. */
102 get_terminal_width (void)
104 const char * s = getenv ("COLUMNS");
105 if (s != NULL) {
106 int n = atoi (s);
107 if (n > 0)
108 return n;
111 #ifdef TIOCGWINSZ
112 struct winsize w;
113 w.ws_col = 0;
114 if (ioctl (0, TIOCGWINSZ, &w) == 0 && w.ws_col > 0)
115 return w.ws_col;
116 #endif
118 return INT_MAX;
121 /* Set caret_max_width to value. */
122 void
123 diagnostic_set_caret_max_width (diagnostic_context *context, int value)
125 /* One minus to account for the leading empty space. */
126 value = value ? value - 1
127 : (isatty (fileno (pp_buffer (context->printer)->stream))
128 ? get_terminal_width () - 1: INT_MAX);
130 if (value <= 0)
131 value = INT_MAX;
133 context->caret_max_width = value;
136 /* Initialize the diagnostic message outputting machinery. */
137 void
138 diagnostic_initialize (diagnostic_context *context, int n_opts)
140 int i;
142 /* Allocate a basic pretty-printer. Clients will replace this a
143 much more elaborated pretty-printer if they wish. */
144 context->printer = XNEW (pretty_printer);
145 new (context->printer) pretty_printer ();
147 memset (context->diagnostic_count, 0, sizeof context->diagnostic_count);
148 context->warning_as_error_requested = false;
149 context->n_opts = n_opts;
150 context->classify_diagnostic = XNEWVEC (diagnostic_t, n_opts);
151 for (i = 0; i < n_opts; i++)
152 context->classify_diagnostic[i] = DK_UNSPECIFIED;
153 context->show_caret = false;
154 diagnostic_set_caret_max_width (context, pp_line_cutoff (context->printer));
155 for (i = 0; i < rich_location::STATICALLY_ALLOCATED_RANGES; i++)
156 context->caret_chars[i] = '^';
157 context->show_option_requested = false;
158 context->abort_on_error = false;
159 context->show_column = false;
160 context->pedantic_errors = false;
161 context->permissive = false;
162 context->opt_permissive = 0;
163 context->fatal_errors = false;
164 context->dc_inhibit_warnings = false;
165 context->dc_warn_system_headers = false;
166 context->max_errors = 0;
167 context->internal_error = NULL;
168 diagnostic_starter (context) = default_diagnostic_starter;
169 context->start_span = default_diagnostic_start_span_fn;
170 diagnostic_finalizer (context) = default_diagnostic_finalizer;
171 context->option_enabled = NULL;
172 context->option_state = NULL;
173 context->option_name = NULL;
174 context->last_location = UNKNOWN_LOCATION;
175 context->last_module = 0;
176 context->x_data = NULL;
177 context->lock = 0;
178 context->inhibit_notes_p = false;
179 context->colorize_source_p = false;
180 context->show_ruler_p = false;
181 context->parseable_fixits_p = false;
182 context->edit_context_ptr = NULL;
185 /* Maybe initialize the color support. We require clients to do this
186 explicitly, since most clients don't want color. When called
187 without a VALUE, it initializes with DIAGNOSTICS_COLOR_DEFAULT. */
189 void
190 diagnostic_color_init (diagnostic_context *context, int value /*= -1 */)
192 /* value == -1 is the default value. */
193 if (value < 0)
195 /* If DIAGNOSTICS_COLOR_DEFAULT is -1, default to
196 -fdiagnostics-color=auto if GCC_COLORS is in the environment,
197 otherwise default to -fdiagnostics-color=never, for other
198 values default to that
199 -fdiagnostics-color={never,auto,always}. */
200 if (DIAGNOSTICS_COLOR_DEFAULT == -1)
202 if (!getenv ("GCC_COLORS"))
203 return;
204 value = DIAGNOSTICS_COLOR_AUTO;
206 else
207 value = DIAGNOSTICS_COLOR_DEFAULT;
209 pp_show_color (context->printer)
210 = colorize_init ((diagnostic_color_rule_t) value);
213 /* Do any cleaning up required after the last diagnostic is emitted. */
215 void
216 diagnostic_finish (diagnostic_context *context)
218 /* Some of the errors may actually have been warnings. */
219 if (diagnostic_kind_count (context, DK_WERROR))
221 /* -Werror was given. */
222 if (context->warning_as_error_requested)
223 pp_verbatim (context->printer,
224 _("%s: all warnings being treated as errors"),
225 progname);
226 /* At least one -Werror= was given. */
227 else
228 pp_verbatim (context->printer,
229 _("%s: some warnings being treated as errors"),
230 progname);
231 pp_newline_and_flush (context->printer);
234 diagnostic_file_cache_fini ();
236 XDELETEVEC (context->classify_diagnostic);
237 context->classify_diagnostic = NULL;
239 /* diagnostic_initialize allocates context->printer using XNEW
240 and placement-new. */
241 context->printer->~pretty_printer ();
242 XDELETE (context->printer);
243 context->printer = NULL;
245 if (context->edit_context_ptr)
247 delete context->edit_context_ptr;
248 context->edit_context_ptr = NULL;
252 /* Initialize DIAGNOSTIC, where the message MSG has already been
253 translated. */
254 void
255 diagnostic_set_info_translated (diagnostic_info *diagnostic, const char *msg,
256 va_list *args, rich_location *richloc,
257 diagnostic_t kind)
259 gcc_assert (richloc);
260 diagnostic->message.err_no = errno;
261 diagnostic->message.args_ptr = args;
262 diagnostic->message.format_spec = msg;
263 diagnostic->message.m_richloc = richloc;
264 diagnostic->richloc = richloc;
265 diagnostic->kind = kind;
266 diagnostic->option_index = 0;
269 /* Initialize DIAGNOSTIC, where the message GMSGID has not yet been
270 translated. */
271 void
272 diagnostic_set_info (diagnostic_info *diagnostic, const char *gmsgid,
273 va_list *args, rich_location *richloc,
274 diagnostic_t kind)
276 gcc_assert (richloc);
277 diagnostic_set_info_translated (diagnostic, _(gmsgid), args, richloc, kind);
280 static const char *const diagnostic_kind_color[] = {
281 #define DEFINE_DIAGNOSTIC_KIND(K, T, C) (C),
282 #include "diagnostic.def"
283 #undef DEFINE_DIAGNOSTIC_KIND
284 NULL
287 /* Get a color name for diagnostics of type KIND
288 Result could be NULL. */
290 const char *
291 diagnostic_get_color_for_kind (diagnostic_t kind)
293 return diagnostic_kind_color[kind];
296 /* Return a malloc'd string describing a location e.g. "foo.c:42:10".
297 The caller is responsible for freeing the memory. */
299 static char *
300 diagnostic_get_location_text (diagnostic_context *context,
301 expanded_location s)
303 pretty_printer *pp = context->printer;
304 const char *locus_cs = colorize_start (pp_show_color (pp), "locus");
305 const char *locus_ce = colorize_stop (pp_show_color (pp));
307 if (s.file == NULL)
308 return build_message_string ("%s%s:%s", locus_cs, progname, locus_ce);
310 if (!strcmp (s.file, N_("<built-in>")))
311 return build_message_string ("%s%s:%s", locus_cs, s.file, locus_ce);
313 if (context->show_column)
314 return build_message_string ("%s%s:%d:%d:%s", locus_cs, s.file, s.line,
315 s.column, locus_ce);
316 else
317 return build_message_string ("%s%s:%d:%s", locus_cs, s.file, s.line,
318 locus_ce);
321 /* Return a malloc'd string describing a location and the severity of the
322 diagnostic, e.g. "foo.c:42:10: error: ". The caller is responsible for
323 freeing the memory. */
324 char *
325 diagnostic_build_prefix (diagnostic_context *context,
326 const diagnostic_info *diagnostic)
328 static const char *const diagnostic_kind_text[] = {
329 #define DEFINE_DIAGNOSTIC_KIND(K, T, C) (T),
330 #include "diagnostic.def"
331 #undef DEFINE_DIAGNOSTIC_KIND
332 "must-not-happen"
334 gcc_assert (diagnostic->kind < DK_LAST_DIAGNOSTIC_KIND);
336 const char *text = _(diagnostic_kind_text[diagnostic->kind]);
337 const char *text_cs = "", *text_ce = "";
338 pretty_printer *pp = context->printer;
340 if (diagnostic_kind_color[diagnostic->kind])
342 text_cs = colorize_start (pp_show_color (pp),
343 diagnostic_kind_color[diagnostic->kind]);
344 text_ce = colorize_stop (pp_show_color (pp));
347 expanded_location s = diagnostic_expand_location (diagnostic);
348 char *location_text = diagnostic_get_location_text (context, s);
350 char *result = build_message_string ("%s %s%s%s", location_text,
351 text_cs, text, text_ce);
352 free (location_text);
353 return result;
356 /* Functions at which to stop the backtrace print. It's not
357 particularly helpful to print the callers of these functions. */
359 static const char * const bt_stop[] =
361 "main",
362 "toplev::main",
363 "execute_one_pass",
364 "compile_file",
367 /* A callback function passed to the backtrace_full function. */
369 static int
370 bt_callback (void *data, uintptr_t pc, const char *filename, int lineno,
371 const char *function)
373 int *pcount = (int *) data;
375 /* If we don't have any useful information, don't print
376 anything. */
377 if (filename == NULL && function == NULL)
378 return 0;
380 /* Skip functions in diagnostic.c. */
381 if (*pcount == 0
382 && filename != NULL
383 && strcmp (lbasename (filename), "diagnostic.c") == 0)
384 return 0;
386 /* Print up to 20 functions. We could make this a --param, but
387 since this is only for debugging just use a constant for now. */
388 if (*pcount >= 20)
390 /* Returning a non-zero value stops the backtrace. */
391 return 1;
393 ++*pcount;
395 char *alc = NULL;
396 if (function != NULL)
398 char *str = cplus_demangle_v3 (function,
399 (DMGL_VERBOSE | DMGL_ANSI
400 | DMGL_GNU_V3 | DMGL_PARAMS));
401 if (str != NULL)
403 alc = str;
404 function = str;
407 for (size_t i = 0; i < ARRAY_SIZE (bt_stop); ++i)
409 size_t len = strlen (bt_stop[i]);
410 if (strncmp (function, bt_stop[i], len) == 0
411 && (function[len] == '\0' || function[len] == '('))
413 if (alc != NULL)
414 free (alc);
415 /* Returning a non-zero value stops the backtrace. */
416 return 1;
421 fprintf (stderr, "0x%lx %s\n\t%s:%d\n",
422 (unsigned long) pc,
423 function == NULL ? "???" : function,
424 filename == NULL ? "???" : filename,
425 lineno);
427 if (alc != NULL)
428 free (alc);
430 return 0;
433 /* A callback function passed to the backtrace_full function. This is
434 called if backtrace_full has an error. */
436 static void
437 bt_err_callback (void *data ATTRIBUTE_UNUSED, const char *msg, int errnum)
439 if (errnum < 0)
441 /* This means that no debug info was available. Just quietly
442 skip printing backtrace info. */
443 return;
445 fprintf (stderr, "%s%s%s\n", msg, errnum == 0 ? "" : ": ",
446 errnum == 0 ? "" : xstrerror (errnum));
449 /* Take any action which is expected to happen after the diagnostic
450 is written out. This function does not always return. */
451 void
452 diagnostic_action_after_output (diagnostic_context *context,
453 diagnostic_t diag_kind)
455 switch (diag_kind)
457 case DK_DEBUG:
458 case DK_NOTE:
459 case DK_ANACHRONISM:
460 case DK_WARNING:
461 break;
463 case DK_ERROR:
464 case DK_SORRY:
465 if (context->abort_on_error)
466 real_abort ();
467 if (context->fatal_errors)
469 fnotice (stderr, "compilation terminated due to -Wfatal-errors.\n");
470 diagnostic_finish (context);
471 exit (FATAL_EXIT_CODE);
473 /* -fmax-error handling is just before the next diagnostic is
474 emitted. */
475 break;
477 case DK_ICE:
478 case DK_ICE_NOBT:
480 struct backtrace_state *state = NULL;
481 if (diag_kind == DK_ICE)
482 state = backtrace_create_state (NULL, 0, bt_err_callback, NULL);
483 int count = 0;
484 if (state != NULL)
485 backtrace_full (state, 2, bt_callback, bt_err_callback,
486 (void *) &count);
488 if (context->abort_on_error)
489 real_abort ();
491 fnotice (stderr, "Please submit a full bug report,\n"
492 "with preprocessed source if appropriate.\n");
493 if (count > 0)
494 fnotice (stderr,
495 ("Please include the complete backtrace "
496 "with any bug report.\n"));
497 fnotice (stderr, "See %s for instructions.\n", bug_report_url);
499 exit (ICE_EXIT_CODE);
502 case DK_FATAL:
503 if (context->abort_on_error)
504 real_abort ();
505 diagnostic_finish (context);
506 fnotice (stderr, "compilation terminated.\n");
507 exit (FATAL_EXIT_CODE);
509 default:
510 gcc_unreachable ();
514 void
515 diagnostic_report_current_module (diagnostic_context *context, location_t where)
517 const line_map_ordinary *map = NULL;
519 if (pp_needs_newline (context->printer))
521 pp_newline (context->printer);
522 pp_needs_newline (context->printer) = false;
525 if (where <= BUILTINS_LOCATION)
526 return;
528 linemap_resolve_location (line_table, where,
529 LRK_MACRO_DEFINITION_LOCATION,
530 &map);
532 if (map && diagnostic_last_module_changed (context, map))
534 diagnostic_set_last_module (context, map);
535 if (! MAIN_FILE_P (map))
537 map = INCLUDED_FROM (line_table, map);
538 if (context->show_column)
539 pp_verbatim (context->printer,
540 "In file included from %r%s:%d:%d%R", "locus",
541 LINEMAP_FILE (map),
542 LAST_SOURCE_LINE (map), LAST_SOURCE_COLUMN (map));
543 else
544 pp_verbatim (context->printer,
545 "In file included from %r%s:%d%R", "locus",
546 LINEMAP_FILE (map), LAST_SOURCE_LINE (map));
547 while (! MAIN_FILE_P (map))
549 map = INCLUDED_FROM (line_table, map);
550 pp_verbatim (context->printer,
551 ",\n from %r%s:%d%R", "locus",
552 LINEMAP_FILE (map), LAST_SOURCE_LINE (map));
554 pp_verbatim (context->printer, ":");
555 pp_newline (context->printer);
560 void
561 default_diagnostic_starter (diagnostic_context *context,
562 diagnostic_info *diagnostic)
564 diagnostic_report_current_module (context, diagnostic_location (diagnostic));
565 pp_set_prefix (context->printer, diagnostic_build_prefix (context,
566 diagnostic));
569 void
570 default_diagnostic_start_span_fn (diagnostic_context *context,
571 expanded_location exploc)
573 pp_set_prefix (context->printer,
574 diagnostic_get_location_text (context, exploc));
575 pp_string (context->printer, "");
576 pp_newline (context->printer);
579 void
580 default_diagnostic_finalizer (diagnostic_context *context,
581 diagnostic_info *diagnostic)
583 diagnostic_show_locus (context, diagnostic->richloc, diagnostic->kind);
584 pp_destroy_prefix (context->printer);
585 pp_flush (context->printer);
588 /* Interface to specify diagnostic kind overrides. Returns the
589 previous setting, or DK_UNSPECIFIED if the parameters are out of
590 range. If OPTION_INDEX is zero, the new setting is for all the
591 diagnostics. */
592 diagnostic_t
593 diagnostic_classify_diagnostic (diagnostic_context *context,
594 int option_index,
595 diagnostic_t new_kind,
596 location_t where)
598 diagnostic_t old_kind;
600 if (option_index < 0
601 || option_index >= context->n_opts
602 || new_kind >= DK_LAST_DIAGNOSTIC_KIND)
603 return DK_UNSPECIFIED;
605 old_kind = context->classify_diagnostic[option_index];
607 /* Handle pragmas separately, since we need to keep track of *where*
608 the pragmas were. */
609 if (where != UNKNOWN_LOCATION)
611 int i;
613 /* Record the command-line status, so we can reset it back on DK_POP. */
614 if (old_kind == DK_UNSPECIFIED)
616 old_kind = !context->option_enabled (option_index,
617 context->option_state)
618 ? DK_IGNORED : (context->warning_as_error_requested
619 ? DK_ERROR : DK_WARNING);
620 context->classify_diagnostic[option_index] = old_kind;
623 for (i = context->n_classification_history - 1; i >= 0; i --)
624 if (context->classification_history[i].option == option_index)
626 old_kind = context->classification_history[i].kind;
627 break;
630 i = context->n_classification_history;
631 context->classification_history =
632 (diagnostic_classification_change_t *) xrealloc (context->classification_history, (i + 1)
633 * sizeof (diagnostic_classification_change_t));
634 context->classification_history[i].location = where;
635 context->classification_history[i].option = option_index;
636 context->classification_history[i].kind = new_kind;
637 context->n_classification_history ++;
639 else
640 context->classify_diagnostic[option_index] = new_kind;
642 return old_kind;
645 /* Save all diagnostic classifications in a stack. */
646 void
647 diagnostic_push_diagnostics (diagnostic_context *context, location_t where ATTRIBUTE_UNUSED)
649 context->push_list = (int *) xrealloc (context->push_list, (context->n_push + 1) * sizeof (int));
650 context->push_list[context->n_push ++] = context->n_classification_history;
653 /* Restore the topmost classification set off the stack. If the stack
654 is empty, revert to the state based on command line parameters. */
655 void
656 diagnostic_pop_diagnostics (diagnostic_context *context, location_t where)
658 int jump_to;
659 int i;
661 if (context->n_push)
662 jump_to = context->push_list [-- context->n_push];
663 else
664 jump_to = 0;
666 i = context->n_classification_history;
667 context->classification_history =
668 (diagnostic_classification_change_t *) xrealloc (context->classification_history, (i + 1)
669 * sizeof (diagnostic_classification_change_t));
670 context->classification_history[i].location = where;
671 context->classification_history[i].option = jump_to;
672 context->classification_history[i].kind = DK_POP;
673 context->n_classification_history ++;
676 /* Helper function for print_parseable_fixits. Print TEXT to PP, obeying the
677 escaping rules for -fdiagnostics-parseable-fixits. */
679 static void
680 print_escaped_string (pretty_printer *pp, const char *text)
682 gcc_assert (pp);
683 gcc_assert (text);
685 pp_character (pp, '"');
686 for (const char *ch = text; *ch; ch++)
688 switch (*ch)
690 case '\\':
691 /* Escape backslash as two backslashes. */
692 pp_string (pp, "\\\\");
693 break;
694 case '\t':
695 /* Escape tab as "\t". */
696 pp_string (pp, "\\t");
697 break;
698 case '\n':
699 /* Escape newline as "\n". */
700 pp_string (pp, "\\n");
701 break;
702 case '"':
703 /* Escape doublequotes as \". */
704 pp_string (pp, "\\\"");
705 break;
706 default:
707 if (ISPRINT (*ch))
708 pp_character (pp, *ch);
709 else
710 /* Use octal for non-printable chars. */
712 unsigned char c = (*ch & 0xff);
713 pp_printf (pp, "\\%o%o%o", (c / 64), (c / 8) & 007, c & 007);
715 break;
718 pp_character (pp, '"');
721 /* Implementation of -fdiagnostics-parseable-fixits. Print a
722 machine-parseable version of all fixits in RICHLOC to PP. */
724 static void
725 print_parseable_fixits (pretty_printer *pp, rich_location *richloc)
727 gcc_assert (pp);
728 gcc_assert (richloc);
730 for (unsigned i = 0; i < richloc->get_num_fixit_hints (); i++)
732 const fixit_hint *hint = richloc->get_fixit_hint (i);
733 source_location start_loc = hint->get_start_loc ();
734 expanded_location start_exploc = expand_location (start_loc);
735 pp_string (pp, "fix-it:");
736 print_escaped_string (pp, start_exploc.file);
737 source_location end_loc;
739 /* For compatibility with clang, print as a half-open range. */
740 if (hint->maybe_get_end_loc (&end_loc))
742 expanded_location end_exploc = expand_location (end_loc);
743 pp_printf (pp, ":{%i:%i-%i:%i}:",
744 start_exploc.line, start_exploc.column,
745 end_exploc.line, end_exploc.column + 1);
747 else
749 pp_printf (pp, ":{%i:%i-%i:%i}:",
750 start_exploc.line, start_exploc.column,
751 start_exploc.line, start_exploc.column);
753 switch (hint->get_kind ())
755 case fixit_hint::INSERT:
757 const fixit_insert *insert
758 = static_cast <const fixit_insert *> (hint);
759 print_escaped_string (pp, insert->get_string ());
761 break;
763 case fixit_hint::REPLACE:
765 const fixit_replace *replace
766 = static_cast <const fixit_replace *> (hint);
767 print_escaped_string (pp, replace->get_string ());
769 break;
771 default:
772 gcc_unreachable ();
774 pp_newline (pp);
778 /* Report a diagnostic message (an error or a warning) as specified by
779 DC. This function is *the* subroutine in terms of which front-ends
780 should implement their specific diagnostic handling modules. The
781 front-end independent format specifiers are exactly those described
782 in the documentation of output_format.
783 Return true if a diagnostic was printed, false otherwise. */
785 bool
786 diagnostic_report_diagnostic (diagnostic_context *context,
787 diagnostic_info *diagnostic)
789 location_t location = diagnostic_location (diagnostic);
790 diagnostic_t orig_diag_kind = diagnostic->kind;
791 const char *saved_format_spec;
793 /* Give preference to being able to inhibit warnings, before they
794 get reclassified to something else. */
795 if ((diagnostic->kind == DK_WARNING || diagnostic->kind == DK_PEDWARN)
796 && !diagnostic_report_warnings_p (context, location))
797 return false;
799 if (diagnostic->kind == DK_PEDWARN)
801 diagnostic->kind = pedantic_warning_kind (context);
802 /* We do this to avoid giving the message for -pedantic-errors. */
803 orig_diag_kind = diagnostic->kind;
806 if (diagnostic->kind == DK_NOTE && context->inhibit_notes_p)
807 return false;
809 if (context->lock > 0)
811 /* If we're reporting an ICE in the middle of some other error,
812 try to flush out the previous error, then let this one
813 through. Don't do this more than once. */
814 if ((diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT)
815 && context->lock == 1)
816 pp_newline_and_flush (context->printer);
817 else
818 error_recursion (context);
821 /* If the user requested that warnings be treated as errors, so be
822 it. Note that we do this before the next block so that
823 individual warnings can be overridden back to warnings with
824 -Wno-error=*. */
825 if (context->warning_as_error_requested
826 && diagnostic->kind == DK_WARNING)
827 diagnostic->kind = DK_ERROR;
829 if (diagnostic->option_index
830 && diagnostic->option_index != permissive_error_option (context))
832 diagnostic_t diag_class = DK_UNSPECIFIED;
834 /* This tests if the user provided the appropriate -Wfoo or
835 -Wno-foo option. */
836 if (! context->option_enabled (diagnostic->option_index,
837 context->option_state))
838 return false;
840 /* This tests for #pragma diagnostic changes. */
841 if (context->n_classification_history > 0)
843 /* FIXME: Stupid search. Optimize later. */
844 for (int i = context->n_classification_history - 1; i >= 0; i --)
846 if (linemap_location_before_p
847 (line_table,
848 context->classification_history[i].location,
849 location))
851 if (context->classification_history[i].kind == (int) DK_POP)
853 i = context->classification_history[i].option;
854 continue;
856 int option = context->classification_history[i].option;
857 /* The option 0 is for all the diagnostics. */
858 if (option == 0 || option == diagnostic->option_index)
860 diag_class = context->classification_history[i].kind;
861 if (diag_class != DK_UNSPECIFIED)
862 diagnostic->kind = diag_class;
863 break;
869 /* This tests if the user provided the appropriate -Werror=foo
870 option. */
871 if (diag_class == DK_UNSPECIFIED
872 && (context->classify_diagnostic[diagnostic->option_index]
873 != DK_UNSPECIFIED))
874 diagnostic->kind
875 = context->classify_diagnostic[diagnostic->option_index];
877 /* This allows for future extensions, like temporarily disabling
878 warnings for ranges of source code. */
879 if (diagnostic->kind == DK_IGNORED)
880 return false;
883 if (diagnostic->kind != DK_NOTE && context->max_errors)
885 /* Check, before emitting the diagnostic, whether we would
886 exceed the limit. This way we will emit notes relevant to
887 the final emitted error. */
888 int count = (diagnostic_kind_count (context, DK_ERROR)
889 + diagnostic_kind_count (context, DK_SORRY)
890 + diagnostic_kind_count (context, DK_WERROR));
892 if ((unsigned) count >= context->max_errors)
894 fnotice (stderr,
895 "compilation terminated due to -fmax-errors=%u.\n",
896 context->max_errors);
897 diagnostic_finish (context);
898 exit (FATAL_EXIT_CODE);
902 context->lock++;
904 if (diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT)
906 /* When not checking, ICEs are converted to fatal errors when an
907 error has already occurred. This is counteracted by
908 abort_on_error. */
909 if (!CHECKING_P
910 && (diagnostic_kind_count (context, DK_ERROR) > 0
911 || diagnostic_kind_count (context, DK_SORRY) > 0)
912 && !context->abort_on_error)
914 expanded_location s
915 = expand_location (diagnostic_location (diagnostic));
916 fnotice (stderr, "%s:%d: confused by earlier errors, bailing out\n",
917 s.file, s.line);
918 exit (ICE_EXIT_CODE);
920 if (context->internal_error)
921 (*context->internal_error) (context,
922 diagnostic->message.format_spec,
923 diagnostic->message.args_ptr);
925 if (diagnostic->kind == DK_ERROR && orig_diag_kind == DK_WARNING)
926 ++diagnostic_kind_count (context, DK_WERROR);
927 else
928 ++diagnostic_kind_count (context, diagnostic->kind);
930 saved_format_spec = diagnostic->message.format_spec;
931 if (context->show_option_requested)
933 char *option_text;
935 option_text = context->option_name (context, diagnostic->option_index,
936 orig_diag_kind, diagnostic->kind);
938 if (option_text)
940 const char *cs
941 = colorize_start (pp_show_color (context->printer),
942 diagnostic_kind_color[diagnostic->kind]);
943 const char *ce = colorize_stop (pp_show_color (context->printer));
944 diagnostic->message.format_spec
945 = ACONCAT ((diagnostic->message.format_spec,
946 " ",
947 "[", cs, option_text, ce, "]",
948 NULL));
949 free (option_text);
952 diagnostic->message.x_data = &diagnostic->x_data;
953 diagnostic->x_data = NULL;
954 pp_format (context->printer, &diagnostic->message);
955 (*diagnostic_starter (context)) (context, diagnostic);
956 pp_output_formatted_text (context->printer);
957 (*diagnostic_finalizer (context)) (context, diagnostic);
958 if (context->parseable_fixits_p)
960 print_parseable_fixits (context->printer, diagnostic->richloc);
961 pp_flush (context->printer);
963 diagnostic_action_after_output (context, diagnostic->kind);
964 diagnostic->message.format_spec = saved_format_spec;
965 diagnostic->x_data = NULL;
967 if (context->edit_context_ptr)
968 context->edit_context_ptr->add_fixits (diagnostic->richloc);
970 context->lock--;
972 return true;
975 /* Given a partial pathname as input, return another pathname that
976 shares no directory elements with the pathname of __FILE__. This
977 is used by fancy_abort() to print `Internal compiler error in expr.c'
978 instead of `Internal compiler error in ../../GCC/gcc/expr.c'. */
980 const char *
981 trim_filename (const char *name)
983 static const char this_file[] = __FILE__;
984 const char *p = name, *q = this_file;
986 /* First skip any "../" in each filename. This allows us to give a proper
987 reference to a file in a subdirectory. */
988 while (p[0] == '.' && p[1] == '.' && IS_DIR_SEPARATOR (p[2]))
989 p += 3;
991 while (q[0] == '.' && q[1] == '.' && IS_DIR_SEPARATOR (q[2]))
992 q += 3;
994 /* Now skip any parts the two filenames have in common. */
995 while (*p == *q && *p != 0 && *q != 0)
996 p++, q++;
998 /* Now go backwards until the previous directory separator. */
999 while (p > name && !IS_DIR_SEPARATOR (p[-1]))
1000 p--;
1002 return p;
1005 /* Standard error reporting routines in increasing order of severity.
1006 All of these take arguments like printf. */
1008 /* Text to be emitted verbatim to the error message stream; this
1009 produces no prefix and disables line-wrapping. Use rarely. */
1010 void
1011 verbatim (const char *gmsgid, ...)
1013 text_info text;
1014 va_list ap;
1016 va_start (ap, gmsgid);
1017 text.err_no = errno;
1018 text.args_ptr = &ap;
1019 text.format_spec = _(gmsgid);
1020 text.x_data = NULL;
1021 pp_format_verbatim (global_dc->printer, &text);
1022 pp_newline_and_flush (global_dc->printer);
1023 va_end (ap);
1026 /* Add a note with text GMSGID and with LOCATION to the diagnostic CONTEXT. */
1027 void
1028 diagnostic_append_note (diagnostic_context *context,
1029 location_t location,
1030 const char * gmsgid, ...)
1032 diagnostic_info diagnostic;
1033 va_list ap;
1034 const char *saved_prefix;
1035 rich_location richloc (line_table, location);
1037 va_start (ap, gmsgid);
1038 diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_NOTE);
1039 if (context->inhibit_notes_p)
1041 va_end (ap);
1042 return;
1044 saved_prefix = pp_get_prefix (context->printer);
1045 pp_set_prefix (context->printer,
1046 diagnostic_build_prefix (context, &diagnostic));
1047 pp_format (context->printer, &diagnostic.message);
1048 pp_output_formatted_text (context->printer);
1049 pp_destroy_prefix (context->printer);
1050 pp_set_prefix (context->printer, saved_prefix);
1051 diagnostic_show_locus (context, &richloc, DK_NOTE);
1052 va_end (ap);
1055 /* Implement emit_diagnostic, inform, inform_at_rich_loc, warning, warning_at,
1056 warning_at_rich_loc, pedwarn, permerror, permerror_at_rich_loc, error,
1057 error_at, error_at_rich_loc, sorry, fatal_error, internal_error, and
1058 internal_error_no_backtrace, as documented and defined below. */
1059 static bool
1060 diagnostic_impl (rich_location *richloc, int opt,
1061 const char *gmsgid,
1062 va_list *ap, diagnostic_t kind)
1064 diagnostic_info diagnostic;
1065 if (kind == DK_PERMERROR)
1067 diagnostic_set_info (&diagnostic, gmsgid, ap, richloc,
1068 permissive_error_kind (global_dc));
1069 diagnostic.option_index = permissive_error_option (global_dc);
1071 else
1073 diagnostic_set_info (&diagnostic, gmsgid, ap, richloc, kind);
1074 if (kind == DK_WARNING || kind == DK_PEDWARN)
1075 diagnostic.option_index = opt;
1077 return report_diagnostic (&diagnostic);
1080 /* Same as diagonostic_n_impl taking rich_location instead of location_t. */
1081 static bool
1082 diagnostic_n_impl_richloc (rich_location *richloc, int opt, int n,
1083 const char *singular_gmsgid,
1084 const char *plural_gmsgid,
1085 va_list *ap, diagnostic_t kind)
1087 diagnostic_info diagnostic;
1088 diagnostic_set_info_translated (&diagnostic,
1089 ngettext (singular_gmsgid, plural_gmsgid, n),
1090 ap, richloc, kind);
1091 if (kind == DK_WARNING)
1092 diagnostic.option_index = opt;
1093 return report_diagnostic (&diagnostic);
1096 /* Implement inform_n, warning_n, and error_n, as documented and
1097 defined below. */
1098 static bool
1099 diagnostic_n_impl (location_t location, int opt, int n,
1100 const char *singular_gmsgid,
1101 const char *plural_gmsgid,
1102 va_list *ap, diagnostic_t kind)
1104 rich_location richloc (line_table, location);
1105 return diagnostic_n_impl_richloc (&richloc, opt, n,
1106 singular_gmsgid, plural_gmsgid, ap, kind);
1109 bool
1110 emit_diagnostic (diagnostic_t kind, location_t location, int opt,
1111 const char *gmsgid, ...)
1113 va_list ap;
1114 va_start (ap, gmsgid);
1115 rich_location richloc (line_table, location);
1116 bool ret = diagnostic_impl (&richloc, opt, gmsgid, &ap, kind);
1117 va_end (ap);
1118 return ret;
1121 /* An informative note at LOCATION. Use this for additional details on an error
1122 message. */
1123 void
1124 inform (location_t location, const char *gmsgid, ...)
1126 va_list ap;
1127 va_start (ap, gmsgid);
1128 rich_location richloc (line_table, location);
1129 diagnostic_impl (&richloc, -1, gmsgid, &ap, DK_NOTE);
1130 va_end (ap);
1133 /* Same as "inform", but at RICHLOC. */
1134 void
1135 inform_at_rich_loc (rich_location *richloc, const char *gmsgid, ...)
1137 va_list ap;
1138 va_start (ap, gmsgid);
1139 diagnostic_impl (richloc, -1, gmsgid, &ap, DK_NOTE);
1140 va_end (ap);
1143 /* An informative note at LOCATION. Use this for additional details on an
1144 error message. */
1145 void
1146 inform_n (location_t location, int n, const char *singular_gmsgid,
1147 const char *plural_gmsgid, ...)
1149 va_list ap;
1150 va_start (ap, plural_gmsgid);
1151 diagnostic_n_impl (location, -1, n, singular_gmsgid, plural_gmsgid,
1152 &ap, DK_NOTE);
1153 va_end (ap);
1156 /* A warning at INPUT_LOCATION. Use this for code which is correct according
1157 to the relevant language specification but is likely to be buggy anyway.
1158 Returns true if the warning was printed, false if it was inhibited. */
1159 bool
1160 warning (int opt, const char *gmsgid, ...)
1162 va_list ap;
1163 va_start (ap, gmsgid);
1164 rich_location richloc (line_table, input_location);
1165 bool ret = diagnostic_impl (&richloc, opt, gmsgid, &ap, DK_WARNING);
1166 va_end (ap);
1167 return ret;
1170 /* A warning at LOCATION. Use this for code which is correct according to the
1171 relevant language specification but is likely to be buggy anyway.
1172 Returns true if the warning was printed, false if it was inhibited. */
1174 bool
1175 warning_at (location_t location, int opt, const char *gmsgid, ...)
1177 va_list ap;
1178 va_start (ap, gmsgid);
1179 rich_location richloc (line_table, location);
1180 bool ret = diagnostic_impl (&richloc, opt, gmsgid, &ap, DK_WARNING);
1181 va_end (ap);
1182 return ret;
1185 /* Same as warning at, but using RICHLOC. */
1187 bool
1188 warning_at_rich_loc (rich_location *richloc, int opt, const char *gmsgid, ...)
1190 va_list ap;
1191 va_start (ap, gmsgid);
1192 bool ret = diagnostic_impl (richloc, opt, gmsgid, &ap, DK_WARNING);
1193 va_end (ap);
1194 return ret;
1197 /* Same as warning_at_rich_loc but for plural variant. */
1199 bool
1200 warning_at_rich_loc_n (rich_location *richloc, int opt, int n,
1201 const char *singular_gmsgid, const char *plural_gmsgid, ...)
1203 va_list ap;
1204 va_start (ap, plural_gmsgid);
1205 bool ret = diagnostic_n_impl_richloc (richloc, opt, n,
1206 singular_gmsgid, plural_gmsgid,
1207 &ap, DK_WARNING);
1208 va_end (ap);
1209 return ret;
1212 /* A warning at LOCATION. Use this for code which is correct according to the
1213 relevant language specification but is likely to be buggy anyway.
1214 Returns true if the warning was printed, false if it was inhibited. */
1216 bool
1217 warning_n (location_t location, int opt, int n, const char *singular_gmsgid,
1218 const char *plural_gmsgid, ...)
1220 va_list ap;
1221 va_start (ap, plural_gmsgid);
1222 bool ret = diagnostic_n_impl (location, opt, n,
1223 singular_gmsgid, plural_gmsgid,
1224 &ap, DK_WARNING);
1225 va_end (ap);
1226 return ret;
1229 /* A "pedantic" warning at LOCATION: issues a warning unless
1230 -pedantic-errors was given on the command line, in which case it
1231 issues an error. Use this for diagnostics required by the relevant
1232 language standard, if you have chosen not to make them errors.
1234 Note that these diagnostics are issued independent of the setting
1235 of the -Wpedantic command-line switch. To get a warning enabled
1236 only with that switch, use either "if (pedantic) pedwarn
1237 (OPT_Wpedantic,...)" or just "pedwarn (OPT_Wpedantic,..)". To get a
1238 pedwarn independently of the -Wpedantic switch use "pedwarn (0,...)".
1240 Returns true if the warning was printed, false if it was inhibited. */
1242 bool
1243 pedwarn (location_t location, int opt, const char *gmsgid, ...)
1245 va_list ap;
1246 va_start (ap, gmsgid);
1247 rich_location richloc (line_table, location);
1248 bool ret = diagnostic_impl (&richloc, opt, gmsgid, &ap, DK_PEDWARN);
1249 va_end (ap);
1250 return ret;
1253 /* Same as pedwarn, but using RICHLOC. */
1255 bool
1256 pedwarn_at_rich_loc (rich_location *richloc, int opt, const char *gmsgid, ...)
1258 va_list ap;
1259 va_start (ap, gmsgid);
1260 bool ret = diagnostic_impl (richloc, opt, gmsgid, &ap, DK_PEDWARN);
1261 va_end (ap);
1262 return ret;
1265 /* A "permissive" error at LOCATION: issues an error unless
1266 -fpermissive was given on the command line, in which case it issues
1267 a warning. Use this for things that really should be errors but we
1268 want to support legacy code.
1270 Returns true if the warning was printed, false if it was inhibited. */
1272 bool
1273 permerror (location_t location, const char *gmsgid, ...)
1275 va_list ap;
1276 va_start (ap, gmsgid);
1277 rich_location richloc (line_table, location);
1278 bool ret = diagnostic_impl (&richloc, -1, gmsgid, &ap, DK_PERMERROR);
1279 va_end (ap);
1280 return ret;
1283 /* Same as "permerror", but at RICHLOC. */
1285 bool
1286 permerror_at_rich_loc (rich_location *richloc, const char *gmsgid, ...)
1288 va_list ap;
1289 va_start (ap, gmsgid);
1290 bool ret = diagnostic_impl (richloc, -1, gmsgid, &ap, DK_PERMERROR);
1291 va_end (ap);
1292 return ret;
1295 /* A hard error: the code is definitely ill-formed, and an object file
1296 will not be produced. */
1297 void
1298 error (const char *gmsgid, ...)
1300 va_list ap;
1301 va_start (ap, gmsgid);
1302 rich_location richloc (line_table, input_location);
1303 diagnostic_impl (&richloc, -1, gmsgid, &ap, DK_ERROR);
1304 va_end (ap);
1307 /* A hard error: the code is definitely ill-formed, and an object file
1308 will not be produced. */
1309 void
1310 error_n (location_t location, int n, const char *singular_gmsgid,
1311 const char *plural_gmsgid, ...)
1313 va_list ap;
1314 va_start (ap, plural_gmsgid);
1315 diagnostic_n_impl (location, -1, n, singular_gmsgid, plural_gmsgid,
1316 &ap, DK_ERROR);
1317 va_end (ap);
1320 /* Same as above, but use location LOC instead of input_location. */
1321 void
1322 error_at (location_t loc, const char *gmsgid, ...)
1324 va_list ap;
1325 va_start (ap, gmsgid);
1326 rich_location richloc (line_table, loc);
1327 diagnostic_impl (&richloc, -1, gmsgid, &ap, DK_ERROR);
1328 va_end (ap);
1331 /* Same as above, but use RICH_LOC. */
1333 void
1334 error_at_rich_loc (rich_location *richloc, const char *gmsgid, ...)
1336 va_list ap;
1337 va_start (ap, gmsgid);
1338 diagnostic_impl (richloc, -1, gmsgid, &ap, DK_ERROR);
1339 va_end (ap);
1342 /* "Sorry, not implemented." Use for a language feature which is
1343 required by the relevant specification but not implemented by GCC.
1344 An object file will not be produced. */
1345 void
1346 sorry (const char *gmsgid, ...)
1348 va_list ap;
1349 va_start (ap, gmsgid);
1350 rich_location richloc (line_table, input_location);
1351 diagnostic_impl (&richloc, -1, gmsgid, &ap, DK_SORRY);
1352 va_end (ap);
1355 /* Return true if an error or a "sorry" has been seen. Various
1356 processing is disabled after errors. */
1357 bool
1358 seen_error (void)
1360 return errorcount || sorrycount;
1363 /* An error which is severe enough that we make no attempt to
1364 continue. Do not use this for internal consistency checks; that's
1365 internal_error. Use of this function should be rare. */
1366 void
1367 fatal_error (location_t loc, const char *gmsgid, ...)
1369 va_list ap;
1370 va_start (ap, gmsgid);
1371 rich_location richloc (line_table, loc);
1372 diagnostic_impl (&richloc, -1, gmsgid, &ap, DK_FATAL);
1373 va_end (ap);
1375 gcc_unreachable ();
1378 /* An internal consistency check has failed. We make no attempt to
1379 continue. Note that unless there is debugging value to be had from
1380 a more specific message, or some other good reason, you should use
1381 abort () instead of calling this function directly. */
1382 void
1383 internal_error (const char *gmsgid, ...)
1385 va_list ap;
1386 va_start (ap, gmsgid);
1387 rich_location richloc (line_table, input_location);
1388 diagnostic_impl (&richloc, -1, gmsgid, &ap, DK_ICE);
1389 va_end (ap);
1391 gcc_unreachable ();
1394 /* Like internal_error, but no backtrace will be printed. Used when
1395 the internal error does not happen at the current location, but happened
1396 somewhere else. */
1397 void
1398 internal_error_no_backtrace (const char *gmsgid, ...)
1400 va_list ap;
1401 va_start (ap, gmsgid);
1402 rich_location richloc (line_table, input_location);
1403 diagnostic_impl (&richloc, -1, gmsgid, &ap, DK_ICE_NOBT);
1404 va_end (ap);
1406 gcc_unreachable ();
1409 /* Special case error functions. Most are implemented in terms of the
1410 above, or should be. */
1412 /* Print a diagnostic MSGID on FILE. This is just fprintf, except it
1413 runs its second argument through gettext. */
1414 void
1415 fnotice (FILE *file, const char *cmsgid, ...)
1417 va_list ap;
1419 va_start (ap, cmsgid);
1420 vfprintf (file, _(cmsgid), ap);
1421 va_end (ap);
1424 /* Inform the user that an error occurred while trying to report some
1425 other error. This indicates catastrophic internal inconsistencies,
1426 so give up now. But do try to flush out the previous error.
1427 This mustn't use internal_error, that will cause infinite recursion. */
1429 static void
1430 error_recursion (diagnostic_context *context)
1432 if (context->lock < 3)
1433 pp_newline_and_flush (context->printer);
1435 fnotice (stderr,
1436 "Internal compiler error: Error reporting routines re-entered.\n");
1438 /* Call diagnostic_action_after_output to get the "please submit a bug
1439 report" message. */
1440 diagnostic_action_after_output (context, DK_ICE);
1442 /* Do not use gcc_unreachable here; that goes through internal_error
1443 and therefore would cause infinite recursion. */
1444 real_abort ();
1447 /* Report an internal compiler error in a friendly manner. This is
1448 the function that gets called upon use of abort() in the source
1449 code generally, thanks to a special macro. */
1451 void
1452 fancy_abort (const char *file, int line, const char *function)
1454 internal_error ("in %s, at %s:%d", function, trim_filename (file), line);
1457 /* Really call the system 'abort'. This has to go right at the end of
1458 this file, so that there are no functions after it that call abort
1459 and get the system abort instead of our macro. */
1460 #undef abort
1461 static void
1462 real_abort (void)
1464 abort ();
1467 #if CHECKING_P
1469 namespace selftest {
1471 /* Helper function for test_print_escaped_string. */
1473 static void
1474 assert_print_escaped_string (const location &loc, const char *expected_output,
1475 const char *input)
1477 pretty_printer pp;
1478 print_escaped_string (&pp, input);
1479 ASSERT_STREQ_AT (loc, expected_output, pp_formatted_text (&pp));
1482 #define ASSERT_PRINT_ESCAPED_STRING_STREQ(EXPECTED_OUTPUT, INPUT) \
1483 assert_print_escaped_string (SELFTEST_LOCATION, EXPECTED_OUTPUT, INPUT)
1485 /* Tests of print_escaped_string. */
1487 static void
1488 test_print_escaped_string ()
1490 /* Empty string. */
1491 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"\"", "");
1493 /* Non-empty string. */
1494 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"hello world\"", "hello world");
1496 /* Various things that need to be escaped: */
1497 /* Backslash. */
1498 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\\\after\"",
1499 "before\\after");
1500 /* Tab. */
1501 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\tafter\"",
1502 "before\tafter");
1503 /* Newline. */
1504 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\nafter\"",
1505 "before\nafter");
1506 /* Double quote. */
1507 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\\"after\"",
1508 "before\"after");
1510 /* Non-printable characters: BEL: '\a': 0x07 */
1511 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\007after\"",
1512 "before\aafter");
1513 /* Non-printable characters: vertical tab: '\v': 0x0b */
1514 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\013after\"",
1515 "before\vafter");
1518 /* Tests of print_parseable_fixits. */
1520 /* Verify that print_parseable_fixits emits the empty string if there
1521 are no fixits. */
1523 static void
1524 test_print_parseable_fixits_none ()
1526 pretty_printer pp;
1527 rich_location richloc (line_table, UNKNOWN_LOCATION);
1529 print_parseable_fixits (&pp, &richloc);
1530 ASSERT_STREQ ("", pp_formatted_text (&pp));
1533 /* Verify that print_parseable_fixits does the right thing if there
1534 is an insertion fixit hint. */
1536 static void
1537 test_print_parseable_fixits_insert ()
1539 pretty_printer pp;
1540 rich_location richloc (line_table, UNKNOWN_LOCATION);
1542 linemap_add (line_table, LC_ENTER, false, "test.c", 0);
1543 linemap_line_start (line_table, 5, 100);
1544 linemap_add (line_table, LC_LEAVE, false, NULL, 0);
1545 location_t where = linemap_position_for_column (line_table, 10);
1546 richloc.add_fixit_insert_before (where, "added content");
1548 print_parseable_fixits (&pp, &richloc);
1549 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:10}:\"added content\"\n",
1550 pp_formatted_text (&pp));
1553 /* Verify that print_parseable_fixits does the right thing if there
1554 is an removal fixit hint. */
1556 static void
1557 test_print_parseable_fixits_remove ()
1559 pretty_printer pp;
1560 rich_location richloc (line_table, UNKNOWN_LOCATION);
1562 linemap_add (line_table, LC_ENTER, false, "test.c", 0);
1563 linemap_line_start (line_table, 5, 100);
1564 linemap_add (line_table, LC_LEAVE, false, NULL, 0);
1565 source_range where;
1566 where.m_start = linemap_position_for_column (line_table, 10);
1567 where.m_finish = linemap_position_for_column (line_table, 20);
1568 richloc.add_fixit_remove (where);
1570 print_parseable_fixits (&pp, &richloc);
1571 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:21}:\"\"\n",
1572 pp_formatted_text (&pp));
1575 /* Verify that print_parseable_fixits does the right thing if there
1576 is an replacement fixit hint. */
1578 static void
1579 test_print_parseable_fixits_replace ()
1581 pretty_printer pp;
1582 rich_location richloc (line_table, UNKNOWN_LOCATION);
1584 linemap_add (line_table, LC_ENTER, false, "test.c", 0);
1585 linemap_line_start (line_table, 5, 100);
1586 linemap_add (line_table, LC_LEAVE, false, NULL, 0);
1587 source_range where;
1588 where.m_start = linemap_position_for_column (line_table, 10);
1589 where.m_finish = linemap_position_for_column (line_table, 20);
1590 richloc.add_fixit_replace (where, "replacement");
1592 print_parseable_fixits (&pp, &richloc);
1593 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:21}:\"replacement\"\n",
1594 pp_formatted_text (&pp));
1597 /* Run all of the selftests within this file. */
1599 void
1600 diagnostic_c_tests ()
1602 test_print_escaped_string ();
1603 test_print_parseable_fixits_none ();
1604 test_print_parseable_fixits_insert ();
1605 test_print_parseable_fixits_remove ();
1606 test_print_parseable_fixits_replace ();
1609 } // namespace selftest
1611 #endif /* #if CHECKING_P */