Fix issue for pointers to anonymous types with -fdump-ada-spec
[official-gcc.git] / gcc / diagnostic.cc
blob73324a728fe550619c2345e3ecdb0fd40b6eb257
1 /* Language-independent diagnostic subroutines for the GNU Compiler Collection
2 Copyright (C) 1999-2022 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 "diagnostic-url.h"
35 #include "diagnostic-metadata.h"
36 #include "diagnostic-path.h"
37 #include "edit-context.h"
38 #include "selftest.h"
39 #include "selftest-diagnostic.h"
40 #include "opts.h"
41 #include "cpplib.h"
43 #ifdef HAVE_TERMIOS_H
44 # include <termios.h>
45 #endif
47 #ifdef GWINSZ_IN_SYS_IOCTL
48 # include <sys/ioctl.h>
49 #endif
51 /* Disable warnings about quoting issues in the pp_xxx calls below
52 that (intentionally) don't follow GCC diagnostic conventions. */
53 #if __GNUC__ >= 10
54 # pragma GCC diagnostic push
55 # pragma GCC diagnostic ignored "-Wformat-diag"
56 #endif
58 #define pedantic_warning_kind(DC) \
59 ((DC)->pedantic_errors ? DK_ERROR : DK_WARNING)
60 #define permissive_error_kind(DC) ((DC)->permissive ? DK_WARNING : DK_ERROR)
61 #define permissive_error_option(DC) ((DC)->opt_permissive)
63 /* Prototypes. */
64 static bool diagnostic_impl (rich_location *, const diagnostic_metadata *,
65 int, const char *,
66 va_list *, diagnostic_t) ATTRIBUTE_GCC_DIAG(4,0);
67 static bool diagnostic_n_impl (rich_location *, const diagnostic_metadata *,
68 int, unsigned HOST_WIDE_INT,
69 const char *, const char *, va_list *,
70 diagnostic_t) ATTRIBUTE_GCC_DIAG(6,0);
72 static void error_recursion (diagnostic_context *) ATTRIBUTE_NORETURN;
73 static void real_abort (void) ATTRIBUTE_NORETURN;
75 /* Name of program invoked, sans directories. */
77 const char *progname;
79 /* A diagnostic_context surrogate for stderr. */
80 static diagnostic_context global_diagnostic_context;
81 diagnostic_context *global_dc = &global_diagnostic_context;
83 /* Return a malloc'd string containing MSG formatted a la printf. The
84 caller is responsible for freeing the memory. */
85 char *
86 build_message_string (const char *msg, ...)
88 char *str;
89 va_list ap;
91 va_start (ap, msg);
92 str = xvasprintf (msg, ap);
93 va_end (ap);
95 return str;
98 /* Same as diagnostic_build_prefix, but only the source FILE is given. */
99 char *
100 file_name_as_prefix (diagnostic_context *context, const char *f)
102 const char *locus_cs
103 = colorize_start (pp_show_color (context->printer), "locus");
104 const char *locus_ce = colorize_stop (pp_show_color (context->printer));
105 return build_message_string ("%s%s:%s ", locus_cs, f, locus_ce);
110 /* Return the value of the getenv("COLUMNS") as an integer. If the
111 value is not set to a positive integer, use ioctl to get the
112 terminal width. If it fails, return INT_MAX. */
114 get_terminal_width (void)
116 const char * s = getenv ("COLUMNS");
117 if (s != NULL) {
118 int n = atoi (s);
119 if (n > 0)
120 return n;
123 #ifdef TIOCGWINSZ
124 struct winsize w;
125 w.ws_col = 0;
126 if (ioctl (0, TIOCGWINSZ, &w) == 0 && w.ws_col > 0)
127 return w.ws_col;
128 #endif
130 return INT_MAX;
133 /* Set caret_max_width to value. */
134 void
135 diagnostic_set_caret_max_width (diagnostic_context *context, int value)
137 /* One minus to account for the leading empty space. */
138 value = value ? value - 1
139 : (isatty (fileno (pp_buffer (context->printer)->stream))
140 ? get_terminal_width () - 1: INT_MAX);
142 if (value <= 0)
143 value = INT_MAX;
145 context->caret_max_width = value;
148 /* Default implementation of final_cb. */
150 static void
151 default_diagnostic_final_cb (diagnostic_context *context)
153 /* Some of the errors may actually have been warnings. */
154 if (diagnostic_kind_count (context, DK_WERROR))
156 /* -Werror was given. */
157 if (context->warning_as_error_requested)
158 pp_verbatim (context->printer,
159 _("%s: all warnings being treated as errors"),
160 progname);
161 /* At least one -Werror= was given. */
162 else
163 pp_verbatim (context->printer,
164 _("%s: some warnings being treated as errors"),
165 progname);
166 pp_newline_and_flush (context->printer);
170 /* Initialize the diagnostic message outputting machinery. */
171 void
172 diagnostic_initialize (diagnostic_context *context, int n_opts)
174 int i;
176 /* Allocate a basic pretty-printer. Clients will replace this a
177 much more elaborated pretty-printer if they wish. */
178 context->printer = XNEW (pretty_printer);
179 new (context->printer) pretty_printer ();
181 memset (context->diagnostic_count, 0, sizeof context->diagnostic_count);
182 context->warning_as_error_requested = false;
183 context->n_opts = n_opts;
184 context->classify_diagnostic = XNEWVEC (diagnostic_t, n_opts);
185 for (i = 0; i < n_opts; i++)
186 context->classify_diagnostic[i] = DK_UNSPECIFIED;
187 context->show_caret = false;
188 diagnostic_set_caret_max_width (context, pp_line_cutoff (context->printer));
189 for (i = 0; i < rich_location::STATICALLY_ALLOCATED_RANGES; i++)
190 context->caret_chars[i] = '^';
191 context->show_cwe = false;
192 context->path_format = DPF_NONE;
193 context->show_path_depths = false;
194 context->show_option_requested = false;
195 context->abort_on_error = false;
196 context->show_column = false;
197 context->pedantic_errors = false;
198 context->permissive = false;
199 context->opt_permissive = 0;
200 context->fatal_errors = false;
201 context->dc_inhibit_warnings = false;
202 context->dc_warn_system_headers = false;
203 context->max_errors = 0;
204 context->internal_error = NULL;
205 diagnostic_starter (context) = default_diagnostic_starter;
206 context->start_span = default_diagnostic_start_span_fn;
207 diagnostic_finalizer (context) = default_diagnostic_finalizer;
208 context->option_enabled = NULL;
209 context->option_state = NULL;
210 context->option_name = NULL;
211 context->get_option_url = NULL;
212 context->last_location = UNKNOWN_LOCATION;
213 context->last_module = 0;
214 context->x_data = NULL;
215 context->lock = 0;
216 context->inhibit_notes_p = false;
217 context->colorize_source_p = false;
218 context->show_labels_p = false;
219 context->show_line_numbers_p = false;
220 context->min_margin_width = 0;
221 context->show_ruler_p = false;
222 context->report_bug = false;
224 if (const char *var = getenv ("GCC_EXTRA_DIAGNOSTIC_OUTPUT"))
226 if (!strcmp (var, "fixits-v1"))
227 context->extra_output_kind = EXTRA_DIAGNOSTIC_OUTPUT_fixits_v1;
228 else if (!strcmp (var, "fixits-v2"))
229 context->extra_output_kind = EXTRA_DIAGNOSTIC_OUTPUT_fixits_v2;
230 /* Silently ignore unrecognized values. */
232 context->column_unit = DIAGNOSTICS_COLUMN_UNIT_DISPLAY;
233 context->column_origin = 1;
234 context->tabstop = 8;
235 context->escape_format = DIAGNOSTICS_ESCAPE_FORMAT_UNICODE;
236 context->edit_context_ptr = NULL;
237 context->diagnostic_group_nesting_depth = 0;
238 context->diagnostic_group_emission_count = 0;
239 context->begin_group_cb = NULL;
240 context->end_group_cb = NULL;
241 context->final_cb = default_diagnostic_final_cb;
242 context->includes_seen = NULL;
245 /* Maybe initialize the color support. We require clients to do this
246 explicitly, since most clients don't want color. When called
247 without a VALUE, it initializes with DIAGNOSTICS_COLOR_DEFAULT. */
249 void
250 diagnostic_color_init (diagnostic_context *context, int value /*= -1 */)
252 /* value == -1 is the default value. */
253 if (value < 0)
255 /* If DIAGNOSTICS_COLOR_DEFAULT is -1, default to
256 -fdiagnostics-color=auto if GCC_COLORS is in the environment,
257 otherwise default to -fdiagnostics-color=never, for other
258 values default to that
259 -fdiagnostics-color={never,auto,always}. */
260 if (DIAGNOSTICS_COLOR_DEFAULT == -1)
262 if (!getenv ("GCC_COLORS"))
263 return;
264 value = DIAGNOSTICS_COLOR_AUTO;
266 else
267 value = DIAGNOSTICS_COLOR_DEFAULT;
269 pp_show_color (context->printer)
270 = colorize_init ((diagnostic_color_rule_t) value);
273 /* Initialize URL support within CONTEXT based on VALUE, handling "auto". */
275 void
276 diagnostic_urls_init (diagnostic_context *context, int value /*= -1 */)
278 /* value == -1 is the default value. */
279 if (value < 0)
281 /* If DIAGNOSTICS_URLS_DEFAULT is -1, default to
282 -fdiagnostics-urls=auto if GCC_URLS or TERM_URLS is in the
283 environment, otherwise default to -fdiagnostics-urls=never,
284 for other values default to that
285 -fdiagnostics-urls={never,auto,always}. */
286 if (DIAGNOSTICS_URLS_DEFAULT == -1)
288 if (!getenv ("GCC_URLS") && !getenv ("TERM_URLS"))
289 return;
290 value = DIAGNOSTICS_URL_AUTO;
292 else
293 value = DIAGNOSTICS_URLS_DEFAULT;
296 context->printer->url_format
297 = determine_url_format ((diagnostic_url_rule_t) value);
300 /* Create the file_cache, if not already created, and tell it how to
301 translate files on input. */
302 void diagnostic_initialize_input_context (diagnostic_context *context,
303 diagnostic_input_charset_callback ccb,
304 bool should_skip_bom)
306 if (!context->m_file_cache)
307 context->m_file_cache = new file_cache;
308 context->m_file_cache->initialize_input_context (ccb, should_skip_bom);
311 /* Do any cleaning up required after the last diagnostic is emitted. */
313 void
314 diagnostic_finish (diagnostic_context *context)
316 if (context->final_cb)
317 context->final_cb (context);
319 diagnostic_file_cache_fini ();
321 XDELETEVEC (context->classify_diagnostic);
322 context->classify_diagnostic = NULL;
324 /* diagnostic_initialize allocates context->printer using XNEW
325 and placement-new. */
326 context->printer->~pretty_printer ();
327 XDELETE (context->printer);
328 context->printer = NULL;
330 if (context->edit_context_ptr)
332 delete context->edit_context_ptr;
333 context->edit_context_ptr = NULL;
336 if (context->includes_seen)
338 delete context->includes_seen;
339 context->includes_seen = nullptr;
343 /* Initialize DIAGNOSTIC, where the message MSG has already been
344 translated. */
345 void
346 diagnostic_set_info_translated (diagnostic_info *diagnostic, const char *msg,
347 va_list *args, rich_location *richloc,
348 diagnostic_t kind)
350 gcc_assert (richloc);
351 diagnostic->message.err_no = errno;
352 diagnostic->message.args_ptr = args;
353 diagnostic->message.format_spec = msg;
354 diagnostic->message.m_richloc = richloc;
355 diagnostic->richloc = richloc;
356 diagnostic->metadata = NULL;
357 diagnostic->kind = kind;
358 diagnostic->option_index = 0;
361 /* Initialize DIAGNOSTIC, where the message GMSGID has not yet been
362 translated. */
363 void
364 diagnostic_set_info (diagnostic_info *diagnostic, const char *gmsgid,
365 va_list *args, rich_location *richloc,
366 diagnostic_t kind)
368 gcc_assert (richloc);
369 diagnostic_set_info_translated (diagnostic, _(gmsgid), args, richloc, kind);
372 static const char *const diagnostic_kind_color[] = {
373 #define DEFINE_DIAGNOSTIC_KIND(K, T, C) (C),
374 #include "diagnostic.def"
375 #undef DEFINE_DIAGNOSTIC_KIND
376 NULL
379 /* Get a color name for diagnostics of type KIND
380 Result could be NULL. */
382 const char *
383 diagnostic_get_color_for_kind (diagnostic_t kind)
385 return diagnostic_kind_color[kind];
388 /* Given an expanded_location, convert the column (which is in 1-based bytes)
389 to the requested units, without converting the origin.
390 Return -1 if the column is invalid (<= 0). */
392 static int
393 convert_column_unit (enum diagnostics_column_unit column_unit,
394 int tabstop,
395 expanded_location s)
397 if (s.column <= 0)
398 return -1;
400 switch (column_unit)
402 default:
403 gcc_unreachable ();
405 case DIAGNOSTICS_COLUMN_UNIT_DISPLAY:
407 cpp_char_column_policy policy (tabstop, cpp_wcwidth);
408 return location_compute_display_column (s, policy);
411 case DIAGNOSTICS_COLUMN_UNIT_BYTE:
412 return s.column;
416 /* Given an expanded_location, convert the column (which is in 1-based bytes)
417 to the requested units and origin. Return -1 if the column is
418 invalid (<= 0). */
420 diagnostic_converted_column (diagnostic_context *context, expanded_location s)
422 int one_based_col
423 = convert_column_unit (context->column_unit, context->tabstop, s);
424 if (one_based_col <= 0)
425 return -1;
426 return one_based_col + (context->column_origin - 1);
429 /* Return a formatted line and column ':%line:%column'. Elided if
430 line == 0 or col < 0. (A column of 0 may be valid due to the
431 -fdiagnostics-column-origin option.)
432 The result is a statically allocated buffer. */
434 static const char *
435 maybe_line_and_column (int line, int col)
437 static char result[32];
439 if (line)
441 size_t l
442 = snprintf (result, sizeof (result),
443 col >= 0 ? ":%d:%d" : ":%d", line, col);
444 gcc_checking_assert (l < sizeof (result));
446 else
447 result[0] = 0;
448 return result;
451 /* Return a malloc'd string describing a location e.g. "foo.c:42:10".
452 The caller is responsible for freeing the memory. */
454 static char *
455 diagnostic_get_location_text (diagnostic_context *context,
456 expanded_location s)
458 pretty_printer *pp = context->printer;
459 const char *locus_cs = colorize_start (pp_show_color (pp), "locus");
460 const char *locus_ce = colorize_stop (pp_show_color (pp));
461 const char *file = s.file ? s.file : progname;
462 int line = 0;
463 int col = -1;
464 if (strcmp (file, N_("<built-in>")))
466 line = s.line;
467 if (context->show_column)
468 col = diagnostic_converted_column (context, s);
471 const char *line_col = maybe_line_and_column (line, col);
472 return build_message_string ("%s%s%s:%s", locus_cs, file,
473 line_col, locus_ce);
476 static const char *const diagnostic_kind_text[] = {
477 #define DEFINE_DIAGNOSTIC_KIND(K, T, C) (T),
478 #include "diagnostic.def"
479 #undef DEFINE_DIAGNOSTIC_KIND
480 "must-not-happen"
483 /* Return a malloc'd string describing a location and the severity of the
484 diagnostic, e.g. "foo.c:42:10: error: ". The caller is responsible for
485 freeing the memory. */
486 char *
487 diagnostic_build_prefix (diagnostic_context *context,
488 const diagnostic_info *diagnostic)
490 gcc_assert (diagnostic->kind < DK_LAST_DIAGNOSTIC_KIND);
492 const char *text = _(diagnostic_kind_text[diagnostic->kind]);
493 const char *text_cs = "", *text_ce = "";
494 pretty_printer *pp = context->printer;
496 if (diagnostic_kind_color[diagnostic->kind])
498 text_cs = colorize_start (pp_show_color (pp),
499 diagnostic_kind_color[diagnostic->kind]);
500 text_ce = colorize_stop (pp_show_color (pp));
503 expanded_location s = diagnostic_expand_location (diagnostic);
504 char *location_text = diagnostic_get_location_text (context, s);
506 char *result = build_message_string ("%s %s%s%s", location_text,
507 text_cs, text, text_ce);
508 free (location_text);
509 return result;
512 /* Functions at which to stop the backtrace print. It's not
513 particularly helpful to print the callers of these functions. */
515 static const char * const bt_stop[] =
517 "main",
518 "toplev::main",
519 "execute_one_pass",
520 "compile_file",
523 /* A callback function passed to the backtrace_full function. */
525 static int
526 bt_callback (void *data, uintptr_t pc, const char *filename, int lineno,
527 const char *function)
529 int *pcount = (int *) data;
531 /* If we don't have any useful information, don't print
532 anything. */
533 if (filename == NULL && function == NULL)
534 return 0;
536 /* Skip functions in diagnostic.cc. */
537 if (*pcount == 0
538 && filename != NULL
539 && strcmp (lbasename (filename), "diagnostic.cc") == 0)
540 return 0;
542 /* Print up to 20 functions. We could make this a --param, but
543 since this is only for debugging just use a constant for now. */
544 if (*pcount >= 20)
546 /* Returning a non-zero value stops the backtrace. */
547 return 1;
549 ++*pcount;
551 char *alc = NULL;
552 if (function != NULL)
554 char *str = cplus_demangle_v3 (function,
555 (DMGL_VERBOSE | DMGL_ANSI
556 | DMGL_GNU_V3 | DMGL_PARAMS));
557 if (str != NULL)
559 alc = str;
560 function = str;
563 for (size_t i = 0; i < ARRAY_SIZE (bt_stop); ++i)
565 size_t len = strlen (bt_stop[i]);
566 if (strncmp (function, bt_stop[i], len) == 0
567 && (function[len] == '\0' || function[len] == '('))
569 if (alc != NULL)
570 free (alc);
571 /* Returning a non-zero value stops the backtrace. */
572 return 1;
577 fprintf (stderr, "0x%lx %s\n\t%s:%d\n",
578 (unsigned long) pc,
579 function == NULL ? "???" : function,
580 filename == NULL ? "???" : filename,
581 lineno);
583 if (alc != NULL)
584 free (alc);
586 return 0;
589 /* A callback function passed to the backtrace_full function. This is
590 called if backtrace_full has an error. */
592 static void
593 bt_err_callback (void *data ATTRIBUTE_UNUSED, const char *msg, int errnum)
595 if (errnum < 0)
597 /* This means that no debug info was available. Just quietly
598 skip printing backtrace info. */
599 return;
601 fprintf (stderr, "%s%s%s\n", msg, errnum == 0 ? "" : ": ",
602 errnum == 0 ? "" : xstrerror (errnum));
605 /* Check if we've met the maximum error limit, and if so fatally exit
606 with a message. CONTEXT is the context to check, and FLUSH
607 indicates whether a diagnostic_finish call is needed. */
609 void
610 diagnostic_check_max_errors (diagnostic_context *context, bool flush)
612 if (!context->max_errors)
613 return;
615 int count = (diagnostic_kind_count (context, DK_ERROR)
616 + diagnostic_kind_count (context, DK_SORRY)
617 + diagnostic_kind_count (context, DK_WERROR));
619 if (count >= context->max_errors)
621 fnotice (stderr,
622 "compilation terminated due to -fmax-errors=%u.\n",
623 context->max_errors);
624 if (flush)
625 diagnostic_finish (context);
626 exit (FATAL_EXIT_CODE);
630 /* Take any action which is expected to happen after the diagnostic
631 is written out. This function does not always return. */
632 void
633 diagnostic_action_after_output (diagnostic_context *context,
634 diagnostic_t diag_kind)
636 switch (diag_kind)
638 case DK_DEBUG:
639 case DK_NOTE:
640 case DK_ANACHRONISM:
641 case DK_WARNING:
642 break;
644 case DK_ERROR:
645 case DK_SORRY:
646 if (context->abort_on_error)
647 real_abort ();
648 if (context->fatal_errors)
650 fnotice (stderr, "compilation terminated due to -Wfatal-errors.\n");
651 diagnostic_finish (context);
652 exit (FATAL_EXIT_CODE);
654 break;
656 case DK_ICE:
657 case DK_ICE_NOBT:
659 struct backtrace_state *state = NULL;
660 if (diag_kind == DK_ICE)
661 state = backtrace_create_state (NULL, 0, bt_err_callback, NULL);
662 int count = 0;
663 if (state != NULL)
664 backtrace_full (state, 2, bt_callback, bt_err_callback,
665 (void *) &count);
667 if (context->abort_on_error)
668 real_abort ();
670 if (context->report_bug)
671 fnotice (stderr, "Please submit a full bug report, "
672 "with preprocessed source.\n");
673 else
674 fnotice (stderr, "Please submit a full bug report, "
675 "with preprocessed source (by using -freport-bug).\n");
677 if (count > 0)
678 fnotice (stderr, "Please include the complete backtrace "
679 "with any bug report.\n");
680 fnotice (stderr, "See %s for instructions.\n", bug_report_url);
682 exit (ICE_EXIT_CODE);
685 case DK_FATAL:
686 if (context->abort_on_error)
687 real_abort ();
688 diagnostic_finish (context);
689 fnotice (stderr, "compilation terminated.\n");
690 exit (FATAL_EXIT_CODE);
692 default:
693 gcc_unreachable ();
697 /* True if the last module or file in which a diagnostic was reported is
698 different from the current one. */
700 static bool
701 last_module_changed_p (diagnostic_context *context,
702 const line_map_ordinary *map)
704 return context->last_module != map;
707 /* Remember the current module or file as being the last one in which we
708 report a diagnostic. */
710 static void
711 set_last_module (diagnostic_context *context, const line_map_ordinary *map)
713 context->last_module = map;
716 /* Only dump the "In file included from..." stack once for each file. */
718 static bool
719 includes_seen (diagnostic_context *context, const line_map_ordinary *map)
721 /* No include path for main. */
722 if (MAIN_FILE_P (map))
723 return true;
725 /* Always identify C++ modules, at least for now. */
726 auto probe = map;
727 if (linemap_check_ordinary (map)->reason == LC_RENAME)
728 /* The module source file shows up as LC_RENAME inside LC_MODULE. */
729 probe = linemap_included_from_linemap (line_table, map);
730 if (MAP_MODULE_P (probe))
731 return false;
733 if (!context->includes_seen)
734 context->includes_seen = new hash_set<location_t, false, location_hash>;
736 /* Hash the location of the #include directive to better handle files
737 that are included multiple times with different macros defined. */
738 return context->includes_seen->add (linemap_included_from (map));
741 void
742 diagnostic_report_current_module (diagnostic_context *context, location_t where)
744 const line_map_ordinary *map = NULL;
746 if (pp_needs_newline (context->printer))
748 pp_newline (context->printer);
749 pp_needs_newline (context->printer) = false;
752 if (where <= BUILTINS_LOCATION)
753 return;
755 linemap_resolve_location (line_table, where,
756 LRK_MACRO_DEFINITION_LOCATION,
757 &map);
759 if (map && last_module_changed_p (context, map))
761 set_last_module (context, map);
762 if (!includes_seen (context, map))
764 bool first = true, need_inc = true, was_module = MAP_MODULE_P (map);
765 expanded_location s = {};
768 where = linemap_included_from (map);
769 map = linemap_included_from_linemap (line_table, map);
770 bool is_module = MAP_MODULE_P (map);
771 s.file = LINEMAP_FILE (map);
772 s.line = SOURCE_LINE (map, where);
773 int col = -1;
774 if (first && context->show_column)
776 s.column = SOURCE_COLUMN (map, where);
777 col = diagnostic_converted_column (context, s);
779 const char *line_col = maybe_line_and_column (s.line, col);
780 static const char *const msgs[] =
782 NULL,
783 N_(" from"),
784 N_("In file included from"), /* 2 */
785 N_(" included from"),
786 N_("In module"), /* 4 */
787 N_("of module"),
788 N_("In module imported at"), /* 6 */
789 N_("imported at"),
792 unsigned index = (was_module ? 6 : is_module ? 4
793 : need_inc ? 2 : 0) + !first;
795 pp_verbatim (context->printer, "%s%s %r%s%s%R",
796 first ? "" : was_module ? ", " : ",\n",
797 _(msgs[index]),
798 "locus", s.file, line_col);
799 first = false, need_inc = was_module, was_module = is_module;
801 while (!includes_seen (context, map));
802 pp_verbatim (context->printer, ":");
803 pp_newline (context->printer);
808 /* If DIAGNOSTIC has a diagnostic_path and CONTEXT supports printing paths,
809 print the path. */
811 void
812 diagnostic_show_any_path (diagnostic_context *context,
813 diagnostic_info *diagnostic)
815 const diagnostic_path *path = diagnostic->richloc->get_path ();
816 if (!path)
817 return;
819 if (context->print_path)
820 context->print_path (context, path);
823 /* Return true if the events in this path involve more than one
824 function, or false if it is purely intraprocedural. */
826 bool
827 diagnostic_path::interprocedural_p () const
829 const unsigned num = num_events ();
830 for (unsigned i = 0; i < num; i++)
832 if (get_event (i).get_fndecl () != get_event (0).get_fndecl ())
833 return true;
834 if (get_event (i).get_stack_depth () != get_event (0).get_stack_depth ())
835 return true;
837 return false;
840 void
841 default_diagnostic_starter (diagnostic_context *context,
842 diagnostic_info *diagnostic)
844 diagnostic_report_current_module (context, diagnostic_location (diagnostic));
845 pp_set_prefix (context->printer, diagnostic_build_prefix (context,
846 diagnostic));
849 void
850 default_diagnostic_start_span_fn (diagnostic_context *context,
851 expanded_location exploc)
853 char *text = diagnostic_get_location_text (context, exploc);
854 pp_string (context->printer, text);
855 free (text);
856 pp_newline (context->printer);
859 void
860 default_diagnostic_finalizer (diagnostic_context *context,
861 diagnostic_info *diagnostic,
862 diagnostic_t)
864 char *saved_prefix = pp_take_prefix (context->printer);
865 pp_set_prefix (context->printer, NULL);
866 pp_newline (context->printer);
867 diagnostic_show_locus (context, diagnostic->richloc, diagnostic->kind);
868 pp_set_prefix (context->printer, saved_prefix);
869 pp_flush (context->printer);
872 /* Interface to specify diagnostic kind overrides. Returns the
873 previous setting, or DK_UNSPECIFIED if the parameters are out of
874 range. If OPTION_INDEX is zero, the new setting is for all the
875 diagnostics. */
876 diagnostic_t
877 diagnostic_classify_diagnostic (diagnostic_context *context,
878 int option_index,
879 diagnostic_t new_kind,
880 location_t where)
882 diagnostic_t old_kind;
884 if (option_index < 0
885 || option_index >= context->n_opts
886 || new_kind >= DK_LAST_DIAGNOSTIC_KIND)
887 return DK_UNSPECIFIED;
889 old_kind = context->classify_diagnostic[option_index];
891 /* Handle pragmas separately, since we need to keep track of *where*
892 the pragmas were. */
893 if (where != UNKNOWN_LOCATION)
895 int i;
897 /* Record the command-line status, so we can reset it back on DK_POP. */
898 if (old_kind == DK_UNSPECIFIED)
900 old_kind = !context->option_enabled (option_index,
901 context->lang_mask,
902 context->option_state)
903 ? DK_IGNORED : (context->warning_as_error_requested
904 ? DK_ERROR : DK_WARNING);
905 context->classify_diagnostic[option_index] = old_kind;
908 for (i = context->n_classification_history - 1; i >= 0; i --)
909 if (context->classification_history[i].option == option_index)
911 old_kind = context->classification_history[i].kind;
912 break;
915 i = context->n_classification_history;
916 context->classification_history =
917 (diagnostic_classification_change_t *) xrealloc (context->classification_history, (i + 1)
918 * sizeof (diagnostic_classification_change_t));
919 context->classification_history[i].location = where;
920 context->classification_history[i].option = option_index;
921 context->classification_history[i].kind = new_kind;
922 context->n_classification_history ++;
924 else
925 context->classify_diagnostic[option_index] = new_kind;
927 return old_kind;
930 /* Save all diagnostic classifications in a stack. */
931 void
932 diagnostic_push_diagnostics (diagnostic_context *context, location_t where ATTRIBUTE_UNUSED)
934 context->push_list = (int *) xrealloc (context->push_list, (context->n_push + 1) * sizeof (int));
935 context->push_list[context->n_push ++] = context->n_classification_history;
938 /* Restore the topmost classification set off the stack. If the stack
939 is empty, revert to the state based on command line parameters. */
940 void
941 diagnostic_pop_diagnostics (diagnostic_context *context, location_t where)
943 int jump_to;
944 int i;
946 if (context->n_push)
947 jump_to = context->push_list [-- context->n_push];
948 else
949 jump_to = 0;
951 i = context->n_classification_history;
952 context->classification_history =
953 (diagnostic_classification_change_t *) xrealloc (context->classification_history, (i + 1)
954 * sizeof (diagnostic_classification_change_t));
955 context->classification_history[i].location = where;
956 context->classification_history[i].option = jump_to;
957 context->classification_history[i].kind = DK_POP;
958 context->n_classification_history ++;
961 /* Helper function for print_parseable_fixits. Print TEXT to PP, obeying the
962 escaping rules for -fdiagnostics-parseable-fixits. */
964 static void
965 print_escaped_string (pretty_printer *pp, const char *text)
967 gcc_assert (pp);
968 gcc_assert (text);
970 pp_character (pp, '"');
971 for (const char *ch = text; *ch; ch++)
973 switch (*ch)
975 case '\\':
976 /* Escape backslash as two backslashes. */
977 pp_string (pp, "\\\\");
978 break;
979 case '\t':
980 /* Escape tab as "\t". */
981 pp_string (pp, "\\t");
982 break;
983 case '\n':
984 /* Escape newline as "\n". */
985 pp_string (pp, "\\n");
986 break;
987 case '"':
988 /* Escape doublequotes as \". */
989 pp_string (pp, "\\\"");
990 break;
991 default:
992 if (ISPRINT (*ch))
993 pp_character (pp, *ch);
994 else
995 /* Use octal for non-printable chars. */
997 unsigned char c = (*ch & 0xff);
998 pp_printf (pp, "\\%o%o%o", (c / 64), (c / 8) & 007, c & 007);
1000 break;
1003 pp_character (pp, '"');
1006 /* Implementation of -fdiagnostics-parseable-fixits and
1007 GCC_EXTRA_DIAGNOSTIC_OUTPUT.
1008 Print a machine-parseable version of all fixits in RICHLOC to PP,
1009 using COLUMN_UNIT to express columns.
1010 Use TABSTOP when handling DIAGNOSTICS_COLUMN_UNIT_DISPLAY. */
1012 static void
1013 print_parseable_fixits (pretty_printer *pp, rich_location *richloc,
1014 enum diagnostics_column_unit column_unit,
1015 int tabstop)
1017 gcc_assert (pp);
1018 gcc_assert (richloc);
1020 char *saved_prefix = pp_take_prefix (pp);
1021 pp_set_prefix (pp, NULL);
1023 for (unsigned i = 0; i < richloc->get_num_fixit_hints (); i++)
1025 const fixit_hint *hint = richloc->get_fixit_hint (i);
1026 location_t start_loc = hint->get_start_loc ();
1027 expanded_location start_exploc = expand_location (start_loc);
1028 pp_string (pp, "fix-it:");
1029 print_escaped_string (pp, start_exploc.file);
1030 /* For compatibility with clang, print as a half-open range. */
1031 location_t next_loc = hint->get_next_loc ();
1032 expanded_location next_exploc = expand_location (next_loc);
1033 int start_col
1034 = convert_column_unit (column_unit, tabstop, start_exploc);
1035 int next_col
1036 = convert_column_unit (column_unit, tabstop, next_exploc);
1037 pp_printf (pp, ":{%i:%i-%i:%i}:",
1038 start_exploc.line, start_col,
1039 next_exploc.line, next_col);
1040 print_escaped_string (pp, hint->get_string ());
1041 pp_newline (pp);
1044 pp_set_prefix (pp, saved_prefix);
1047 /* Update the inlining info in CONTEXT for a DIAGNOSTIC. */
1049 static void
1050 get_any_inlining_info (diagnostic_context *context,
1051 diagnostic_info *diagnostic)
1053 auto &ilocs = diagnostic->m_iinfo.m_ilocs;
1055 if (context->set_locations_cb)
1056 /* Retrieve the locations into which the expression about to be
1057 diagnosed has been inlined, including those of all the callers
1058 all the way down the inlining stack. */
1059 context->set_locations_cb (context, diagnostic);
1060 else
1062 /* When there's no callback use just the one location provided
1063 by the caller of the diagnostic function. */
1064 location_t loc = diagnostic_location (diagnostic);
1065 ilocs.safe_push (loc);
1066 diagnostic->m_iinfo.m_allsyslocs = in_system_header_at (loc);
1070 /* Update the kind of DIAGNOSTIC based on its location(s), including
1071 any of those in its inlining stack, relative to any
1072 #pragma GCC diagnostic
1073 directives recorded within CONTEXT.
1075 Return the new kind of DIAGNOSTIC if it was updated, or DK_UNSPECIFIED
1076 otherwise. */
1078 static diagnostic_t
1079 update_effective_level_from_pragmas (diagnostic_context *context,
1080 diagnostic_info *diagnostic)
1082 if (diagnostic->m_iinfo.m_allsyslocs && !context->dc_warn_system_headers)
1084 /* Ignore the diagnostic if all the inlined locations are
1085 in system headers and -Wno-system-headers is in effect. */
1086 diagnostic->kind = DK_IGNORED;
1087 return DK_IGNORED;
1090 if (context->n_classification_history <= 0)
1091 return DK_UNSPECIFIED;
1093 /* Iterate over the locations, checking the diagnostic disposition
1094 for the diagnostic at each. If it's explicitly set as opposed
1095 to unspecified, update the disposition for this instance of
1096 the diagnostic and return it. */
1097 for (location_t loc: diagnostic->m_iinfo.m_ilocs)
1099 /* FIXME: Stupid search. Optimize later. */
1100 for (int i = context->n_classification_history - 1; i >= 0; i --)
1102 const diagnostic_classification_change_t &hist
1103 = context->classification_history[i];
1105 location_t pragloc = hist.location;
1106 if (!linemap_location_before_p (line_table, pragloc, loc))
1107 continue;
1109 if (hist.kind == (int) DK_POP)
1111 /* Move on to the next region. */
1112 i = hist.option;
1113 continue;
1116 int option = hist.option;
1117 /* The option 0 is for all the diagnostics. */
1118 if (option == 0 || option == diagnostic->option_index)
1120 diagnostic_t kind = hist.kind;
1121 if (kind != DK_UNSPECIFIED)
1122 diagnostic->kind = kind;
1123 return kind;
1128 return DK_UNSPECIFIED;
1131 /* Generate a URL string describing CWE. The caller is responsible for
1132 freeing the string. */
1134 static char *
1135 get_cwe_url (int cwe)
1137 return xasprintf ("https://cwe.mitre.org/data/definitions/%i.html", cwe);
1140 /* If DIAGNOSTIC has a CWE identifier, print it.
1142 For example, if the diagnostic metadata associates it with CWE-119,
1143 " [CWE-119]" will be printed, suitably colorized, and with a URL of a
1144 description of the security issue. */
1146 static void
1147 print_any_cwe (diagnostic_context *context,
1148 const diagnostic_info *diagnostic)
1150 if (diagnostic->metadata == NULL)
1151 return;
1153 int cwe = diagnostic->metadata->get_cwe ();
1154 if (cwe)
1156 pretty_printer *pp = context->printer;
1157 char *saved_prefix = pp_take_prefix (context->printer);
1158 pp_string (pp, " [");
1159 pp_string (pp, colorize_start (pp_show_color (pp),
1160 diagnostic_kind_color[diagnostic->kind]));
1161 if (pp->url_format != URL_FORMAT_NONE)
1163 char *cwe_url = get_cwe_url (cwe);
1164 pp_begin_url (pp, cwe_url);
1165 free (cwe_url);
1167 pp_printf (pp, "CWE-%i", cwe);
1168 pp_set_prefix (context->printer, saved_prefix);
1169 if (pp->url_format != URL_FORMAT_NONE)
1170 pp_end_url (pp);
1171 pp_string (pp, colorize_stop (pp_show_color (pp)));
1172 pp_character (pp, ']');
1176 /* Print any metadata about the option used to control DIAGNOSTIC to CONTEXT's
1177 printer, e.g. " [-Werror=uninitialized]".
1178 Subroutine of diagnostic_report_diagnostic. */
1180 static void
1181 print_option_information (diagnostic_context *context,
1182 const diagnostic_info *diagnostic,
1183 diagnostic_t orig_diag_kind)
1185 char *option_text;
1187 option_text = context->option_name (context, diagnostic->option_index,
1188 orig_diag_kind, diagnostic->kind);
1190 if (option_text)
1192 char *option_url = NULL;
1193 if (context->get_option_url
1194 && context->printer->url_format != URL_FORMAT_NONE)
1195 option_url = context->get_option_url (context,
1196 diagnostic->option_index);
1197 pretty_printer *pp = context->printer;
1198 pp_string (pp, " [");
1199 pp_string (pp, colorize_start (pp_show_color (pp),
1200 diagnostic_kind_color[diagnostic->kind]));
1201 if (option_url)
1202 pp_begin_url (pp, option_url);
1203 pp_string (pp, option_text);
1204 if (option_url)
1206 pp_end_url (pp);
1207 free (option_url);
1209 pp_string (pp, colorize_stop (pp_show_color (pp)));
1210 pp_character (pp, ']');
1211 free (option_text);
1215 /* Returns whether a DIAGNOSTIC should be printed, and adjusts diagnostic->kind
1216 as appropriate for #pragma GCC diagnostic and -Werror=foo. */
1218 static bool
1219 diagnostic_enabled (diagnostic_context *context,
1220 diagnostic_info *diagnostic)
1222 /* Update the inlining stack for this diagnostic. */
1223 get_any_inlining_info (context, diagnostic);
1225 /* Diagnostics with no option or -fpermissive are always enabled. */
1226 if (!diagnostic->option_index
1227 || diagnostic->option_index == permissive_error_option (context))
1228 return true;
1230 /* This tests if the user provided the appropriate -Wfoo or
1231 -Wno-foo option. */
1232 if (! context->option_enabled (diagnostic->option_index,
1233 context->lang_mask,
1234 context->option_state))
1235 return false;
1237 /* This tests for #pragma diagnostic changes. */
1238 diagnostic_t diag_class
1239 = update_effective_level_from_pragmas (context, diagnostic);
1241 /* This tests if the user provided the appropriate -Werror=foo
1242 option. */
1243 if (diag_class == DK_UNSPECIFIED
1244 && (context->classify_diagnostic[diagnostic->option_index]
1245 != DK_UNSPECIFIED))
1246 diagnostic->kind
1247 = context->classify_diagnostic[diagnostic->option_index];
1249 /* This allows for future extensions, like temporarily disabling
1250 warnings for ranges of source code. */
1251 if (diagnostic->kind == DK_IGNORED)
1252 return false;
1254 return true;
1257 /* Returns whether warning OPT is enabled at LOC. */
1259 bool
1260 warning_enabled_at (location_t loc, int opt)
1262 if (!diagnostic_report_warnings_p (global_dc, loc))
1263 return false;
1265 rich_location richloc (line_table, loc);
1266 diagnostic_info diagnostic = {};
1267 diagnostic.option_index = opt;
1268 diagnostic.richloc = &richloc;
1269 diagnostic.message.m_richloc = &richloc;
1270 diagnostic.kind = DK_WARNING;
1271 return diagnostic_enabled (global_dc, &diagnostic);
1274 /* Report a diagnostic message (an error or a warning) as specified by
1275 DC. This function is *the* subroutine in terms of which front-ends
1276 should implement their specific diagnostic handling modules. The
1277 front-end independent format specifiers are exactly those described
1278 in the documentation of output_format.
1279 Return true if a diagnostic was printed, false otherwise. */
1281 bool
1282 diagnostic_report_diagnostic (diagnostic_context *context,
1283 diagnostic_info *diagnostic)
1285 location_t location = diagnostic_location (diagnostic);
1286 diagnostic_t orig_diag_kind = diagnostic->kind;
1288 /* Give preference to being able to inhibit warnings, before they
1289 get reclassified to something else. */
1290 bool report_warning_p = true;
1291 if (diagnostic->kind == DK_WARNING || diagnostic->kind == DK_PEDWARN)
1293 if (context->dc_inhibit_warnings)
1294 return false;
1295 /* Remember the result of the overall system header warning setting
1296 but proceed to also check the inlining context. */
1297 report_warning_p = diagnostic_report_warnings_p (context, location);
1298 if (!report_warning_p && diagnostic->kind == DK_PEDWARN)
1299 return false;
1302 if (diagnostic->kind == DK_PEDWARN)
1304 diagnostic->kind = pedantic_warning_kind (context);
1305 /* We do this to avoid giving the message for -pedantic-errors. */
1306 orig_diag_kind = diagnostic->kind;
1309 if (diagnostic->kind == DK_NOTE && context->inhibit_notes_p)
1310 return false;
1312 if (context->lock > 0)
1314 /* If we're reporting an ICE in the middle of some other error,
1315 try to flush out the previous error, then let this one
1316 through. Don't do this more than once. */
1317 if ((diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT)
1318 && context->lock == 1)
1319 pp_newline_and_flush (context->printer);
1320 else
1321 error_recursion (context);
1324 /* If the user requested that warnings be treated as errors, so be
1325 it. Note that we do this before the next block so that
1326 individual warnings can be overridden back to warnings with
1327 -Wno-error=*. */
1328 if (context->warning_as_error_requested
1329 && diagnostic->kind == DK_WARNING)
1330 diagnostic->kind = DK_ERROR;
1332 diagnostic->message.x_data = &diagnostic->x_data;
1334 /* Check to see if the diagnostic is enabled at the location and
1335 not disabled by #pragma GCC diagnostic anywhere along the inlining
1336 stack. . */
1337 if (!diagnostic_enabled (context, diagnostic))
1338 return false;
1340 if (!report_warning_p && diagnostic->m_iinfo.m_allsyslocs)
1341 /* Bail if the warning is not to be reported because all locations
1342 in the inlining stack (if there is one) are in system headers. */
1343 return false;
1345 if (diagnostic->kind != DK_NOTE && diagnostic->kind != DK_ICE)
1346 diagnostic_check_max_errors (context);
1348 context->lock++;
1350 if (diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT)
1352 /* When not checking, ICEs are converted to fatal errors when an
1353 error has already occurred. This is counteracted by
1354 abort_on_error. */
1355 if (!CHECKING_P
1356 && (diagnostic_kind_count (context, DK_ERROR) > 0
1357 || diagnostic_kind_count (context, DK_SORRY) > 0)
1358 && !context->abort_on_error)
1360 expanded_location s
1361 = expand_location (diagnostic_location (diagnostic));
1362 fnotice (stderr, "%s:%d: confused by earlier errors, bailing out\n",
1363 s.file, s.line);
1364 exit (ICE_EXIT_CODE);
1366 if (context->internal_error)
1367 (*context->internal_error) (context,
1368 diagnostic->message.format_spec,
1369 diagnostic->message.args_ptr);
1371 if (diagnostic->kind == DK_ERROR && orig_diag_kind == DK_WARNING)
1372 ++diagnostic_kind_count (context, DK_WERROR);
1373 else
1374 ++diagnostic_kind_count (context, diagnostic->kind);
1376 /* Is this the initial diagnostic within the stack of groups? */
1377 if (context->diagnostic_group_emission_count == 0)
1379 if (context->begin_group_cb)
1380 context->begin_group_cb (context);
1382 context->diagnostic_group_emission_count++;
1384 pp_format (context->printer, &diagnostic->message);
1385 (*diagnostic_starter (context)) (context, diagnostic);
1386 pp_output_formatted_text (context->printer);
1387 if (context->show_cwe)
1388 print_any_cwe (context, diagnostic);
1389 if (context->show_option_requested)
1390 print_option_information (context, diagnostic, orig_diag_kind);
1391 (*diagnostic_finalizer (context)) (context, diagnostic, orig_diag_kind);
1392 switch (context->extra_output_kind)
1394 default:
1395 break;
1396 case EXTRA_DIAGNOSTIC_OUTPUT_fixits_v1:
1397 print_parseable_fixits (context->printer, diagnostic->richloc,
1398 DIAGNOSTICS_COLUMN_UNIT_BYTE,
1399 context->tabstop);
1400 pp_flush (context->printer);
1401 break;
1402 case EXTRA_DIAGNOSTIC_OUTPUT_fixits_v2:
1403 print_parseable_fixits (context->printer, diagnostic->richloc,
1404 DIAGNOSTICS_COLUMN_UNIT_DISPLAY,
1405 context->tabstop);
1406 pp_flush (context->printer);
1407 break;
1409 diagnostic_action_after_output (context, diagnostic->kind);
1410 diagnostic->x_data = NULL;
1412 if (context->edit_context_ptr)
1413 if (diagnostic->richloc->fixits_can_be_auto_applied_p ())
1414 context->edit_context_ptr->add_fixits (diagnostic->richloc);
1416 context->lock--;
1418 diagnostic_show_any_path (context, diagnostic);
1420 return true;
1423 /* Get the number of digits in the decimal representation of VALUE. */
1426 num_digits (int value)
1428 /* Perhaps simpler to use log10 for this, but doing it this way avoids
1429 using floating point. */
1430 gcc_assert (value >= 0);
1432 if (value == 0)
1433 return 1;
1435 int digits = 0;
1436 while (value > 0)
1438 digits++;
1439 value /= 10;
1441 return digits;
1444 /* Given a partial pathname as input, return another pathname that
1445 shares no directory elements with the pathname of __FILE__. This
1446 is used by fancy_abort() to print `internal compiler error in expr.cc'
1447 instead of `internal compiler error in ../../GCC/gcc/expr.cc'. */
1449 const char *
1450 trim_filename (const char *name)
1452 static const char this_file[] = __FILE__;
1453 const char *p = name, *q = this_file;
1455 /* First skip any "../" in each filename. This allows us to give a proper
1456 reference to a file in a subdirectory. */
1457 while (p[0] == '.' && p[1] == '.' && IS_DIR_SEPARATOR (p[2]))
1458 p += 3;
1460 while (q[0] == '.' && q[1] == '.' && IS_DIR_SEPARATOR (q[2]))
1461 q += 3;
1463 /* Now skip any parts the two filenames have in common. */
1464 while (*p == *q && *p != 0 && *q != 0)
1465 p++, q++;
1467 /* Now go backwards until the previous directory separator. */
1468 while (p > name && !IS_DIR_SEPARATOR (p[-1]))
1469 p--;
1471 return p;
1474 /* Standard error reporting routines in increasing order of severity.
1475 All of these take arguments like printf. */
1477 /* Text to be emitted verbatim to the error message stream; this
1478 produces no prefix and disables line-wrapping. Use rarely. */
1479 void
1480 verbatim (const char *gmsgid, ...)
1482 text_info text;
1483 va_list ap;
1485 va_start (ap, gmsgid);
1486 text.err_no = errno;
1487 text.args_ptr = &ap;
1488 text.format_spec = _(gmsgid);
1489 text.x_data = NULL;
1490 pp_format_verbatim (global_dc->printer, &text);
1491 pp_newline_and_flush (global_dc->printer);
1492 va_end (ap);
1495 /* Add a note with text GMSGID and with LOCATION to the diagnostic CONTEXT. */
1496 void
1497 diagnostic_append_note (diagnostic_context *context,
1498 location_t location,
1499 const char * gmsgid, ...)
1501 diagnostic_info diagnostic;
1502 va_list ap;
1503 rich_location richloc (line_table, location);
1505 va_start (ap, gmsgid);
1506 diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_NOTE);
1507 if (context->inhibit_notes_p)
1509 va_end (ap);
1510 return;
1512 char *saved_prefix = pp_take_prefix (context->printer);
1513 pp_set_prefix (context->printer,
1514 diagnostic_build_prefix (context, &diagnostic));
1515 pp_format (context->printer, &diagnostic.message);
1516 pp_output_formatted_text (context->printer);
1517 pp_destroy_prefix (context->printer);
1518 pp_set_prefix (context->printer, saved_prefix);
1519 pp_newline (context->printer);
1520 diagnostic_show_locus (context, &richloc, DK_NOTE);
1521 va_end (ap);
1524 /* Implement emit_diagnostic, inform, warning, warning_at, pedwarn,
1525 permerror, error, error_at, error_at, sorry, fatal_error, internal_error,
1526 and internal_error_no_backtrace, as documented and defined below. */
1527 static bool
1528 diagnostic_impl (rich_location *richloc, const diagnostic_metadata *metadata,
1529 int opt, const char *gmsgid,
1530 va_list *ap, diagnostic_t kind)
1532 diagnostic_info diagnostic;
1533 if (kind == DK_PERMERROR)
1535 diagnostic_set_info (&diagnostic, gmsgid, ap, richloc,
1536 permissive_error_kind (global_dc));
1537 diagnostic.option_index = permissive_error_option (global_dc);
1539 else
1541 diagnostic_set_info (&diagnostic, gmsgid, ap, richloc, kind);
1542 if (kind == DK_WARNING || kind == DK_PEDWARN)
1543 diagnostic.option_index = opt;
1545 diagnostic.metadata = metadata;
1546 return diagnostic_report_diagnostic (global_dc, &diagnostic);
1549 /* Implement inform_n, warning_n, and error_n, as documented and
1550 defined below. */
1551 static bool
1552 diagnostic_n_impl (rich_location *richloc, const diagnostic_metadata *metadata,
1553 int opt, unsigned HOST_WIDE_INT n,
1554 const char *singular_gmsgid,
1555 const char *plural_gmsgid,
1556 va_list *ap, diagnostic_t kind)
1558 diagnostic_info diagnostic;
1559 unsigned long gtn;
1561 if (sizeof n <= sizeof gtn)
1562 gtn = n;
1563 else
1564 /* Use the largest number ngettext can handle, otherwise
1565 preserve the six least significant decimal digits for
1566 languages where the plural form depends on them. */
1567 gtn = n <= ULONG_MAX ? n : n % 1000000LU + 1000000LU;
1569 const char *text = ngettext (singular_gmsgid, plural_gmsgid, gtn);
1570 diagnostic_set_info_translated (&diagnostic, text, ap, richloc, kind);
1571 if (kind == DK_WARNING)
1572 diagnostic.option_index = opt;
1573 diagnostic.metadata = metadata;
1574 return diagnostic_report_diagnostic (global_dc, &diagnostic);
1577 /* Wrapper around diagnostic_impl taking a variable argument list. */
1579 bool
1580 emit_diagnostic (diagnostic_t kind, location_t location, int opt,
1581 const char *gmsgid, ...)
1583 auto_diagnostic_group d;
1584 va_list ap;
1585 va_start (ap, gmsgid);
1586 rich_location richloc (line_table, location);
1587 bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, kind);
1588 va_end (ap);
1589 return ret;
1592 /* As above, but for rich_location *. */
1594 bool
1595 emit_diagnostic (diagnostic_t kind, rich_location *richloc, int opt,
1596 const char *gmsgid, ...)
1598 auto_diagnostic_group d;
1599 va_list ap;
1600 va_start (ap, gmsgid);
1601 bool ret = diagnostic_impl (richloc, NULL, opt, gmsgid, &ap, kind);
1602 va_end (ap);
1603 return ret;
1606 /* Wrapper around diagnostic_impl taking a va_list parameter. */
1608 bool
1609 emit_diagnostic_valist (diagnostic_t kind, location_t location, int opt,
1610 const char *gmsgid, va_list *ap)
1612 rich_location richloc (line_table, location);
1613 return diagnostic_impl (&richloc, NULL, opt, gmsgid, ap, kind);
1616 /* An informative note at LOCATION. Use this for additional details on an error
1617 message. */
1618 void
1619 inform (location_t location, const char *gmsgid, ...)
1621 auto_diagnostic_group d;
1622 va_list ap;
1623 va_start (ap, gmsgid);
1624 rich_location richloc (line_table, location);
1625 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_NOTE);
1626 va_end (ap);
1629 /* Same as "inform" above, but at RICHLOC. */
1630 void
1631 inform (rich_location *richloc, const char *gmsgid, ...)
1633 gcc_assert (richloc);
1635 auto_diagnostic_group d;
1636 va_list ap;
1637 va_start (ap, gmsgid);
1638 diagnostic_impl (richloc, NULL, -1, gmsgid, &ap, DK_NOTE);
1639 va_end (ap);
1642 /* An informative note at LOCATION. Use this for additional details on an
1643 error message. */
1644 void
1645 inform_n (location_t location, unsigned HOST_WIDE_INT n,
1646 const char *singular_gmsgid, const char *plural_gmsgid, ...)
1648 va_list ap;
1649 va_start (ap, plural_gmsgid);
1650 auto_diagnostic_group d;
1651 rich_location richloc (line_table, location);
1652 diagnostic_n_impl (&richloc, NULL, -1, n, singular_gmsgid, plural_gmsgid,
1653 &ap, DK_NOTE);
1654 va_end (ap);
1657 /* A warning at INPUT_LOCATION. Use this for code which is correct according
1658 to the relevant language specification but is likely to be buggy anyway.
1659 Returns true if the warning was printed, false if it was inhibited. */
1660 bool
1661 warning (int opt, const char *gmsgid, ...)
1663 auto_diagnostic_group d;
1664 va_list ap;
1665 va_start (ap, gmsgid);
1666 rich_location richloc (line_table, input_location);
1667 bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, DK_WARNING);
1668 va_end (ap);
1669 return ret;
1672 /* A warning at LOCATION. Use this for code which is correct according to the
1673 relevant language specification but is likely to be buggy anyway.
1674 Returns true if the warning was printed, false if it was inhibited. */
1676 bool
1677 warning_at (location_t location, int opt, const char *gmsgid, ...)
1679 auto_diagnostic_group d;
1680 va_list ap;
1681 va_start (ap, gmsgid);
1682 rich_location richloc (line_table, location);
1683 bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, DK_WARNING);
1684 va_end (ap);
1685 return ret;
1688 /* Same as "warning at" above, but using RICHLOC. */
1690 bool
1691 warning_at (rich_location *richloc, int opt, const char *gmsgid, ...)
1693 gcc_assert (richloc);
1695 auto_diagnostic_group d;
1696 va_list ap;
1697 va_start (ap, gmsgid);
1698 bool ret = diagnostic_impl (richloc, NULL, opt, gmsgid, &ap, DK_WARNING);
1699 va_end (ap);
1700 return ret;
1703 /* Same as "warning at" above, but using METADATA. */
1705 bool
1706 warning_meta (rich_location *richloc,
1707 const diagnostic_metadata &metadata,
1708 int opt, const char *gmsgid, ...)
1710 gcc_assert (richloc);
1712 auto_diagnostic_group d;
1713 va_list ap;
1714 va_start (ap, gmsgid);
1715 bool ret
1716 = diagnostic_impl (richloc, &metadata, opt, gmsgid, &ap,
1717 DK_WARNING);
1718 va_end (ap);
1719 return ret;
1722 /* Same as warning_n plural variant below, but using RICHLOC. */
1724 bool
1725 warning_n (rich_location *richloc, int opt, unsigned HOST_WIDE_INT n,
1726 const char *singular_gmsgid, const char *plural_gmsgid, ...)
1728 gcc_assert (richloc);
1730 auto_diagnostic_group d;
1731 va_list ap;
1732 va_start (ap, plural_gmsgid);
1733 bool ret = diagnostic_n_impl (richloc, NULL, opt, n,
1734 singular_gmsgid, plural_gmsgid,
1735 &ap, DK_WARNING);
1736 va_end (ap);
1737 return ret;
1740 /* A warning at LOCATION. Use this for code which is correct according to the
1741 relevant language specification but is likely to be buggy anyway.
1742 Returns true if the warning was printed, false if it was inhibited. */
1744 bool
1745 warning_n (location_t location, int opt, unsigned HOST_WIDE_INT n,
1746 const char *singular_gmsgid, const char *plural_gmsgid, ...)
1748 auto_diagnostic_group d;
1749 va_list ap;
1750 va_start (ap, plural_gmsgid);
1751 rich_location richloc (line_table, location);
1752 bool ret = diagnostic_n_impl (&richloc, NULL, opt, n,
1753 singular_gmsgid, plural_gmsgid,
1754 &ap, DK_WARNING);
1755 va_end (ap);
1756 return ret;
1759 /* A "pedantic" warning at LOCATION: issues a warning unless
1760 -pedantic-errors was given on the command line, in which case it
1761 issues an error. Use this for diagnostics required by the relevant
1762 language standard, if you have chosen not to make them errors.
1764 Note that these diagnostics are issued independent of the setting
1765 of the -Wpedantic command-line switch. To get a warning enabled
1766 only with that switch, use either "if (pedantic) pedwarn
1767 (OPT_Wpedantic,...)" or just "pedwarn (OPT_Wpedantic,..)". To get a
1768 pedwarn independently of the -Wpedantic switch use "pedwarn (0,...)".
1770 Returns true if the warning was printed, false if it was inhibited. */
1772 bool
1773 pedwarn (location_t location, int opt, const char *gmsgid, ...)
1775 auto_diagnostic_group d;
1776 va_list ap;
1777 va_start (ap, gmsgid);
1778 rich_location richloc (line_table, location);
1779 bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, DK_PEDWARN);
1780 va_end (ap);
1781 return ret;
1784 /* Same as pedwarn above, but using RICHLOC. */
1786 bool
1787 pedwarn (rich_location *richloc, int opt, const char *gmsgid, ...)
1789 gcc_assert (richloc);
1791 auto_diagnostic_group d;
1792 va_list ap;
1793 va_start (ap, gmsgid);
1794 bool ret = diagnostic_impl (richloc, NULL, opt, gmsgid, &ap, DK_PEDWARN);
1795 va_end (ap);
1796 return ret;
1799 /* A "permissive" error at LOCATION: issues an error unless
1800 -fpermissive was given on the command line, in which case it issues
1801 a warning. Use this for things that really should be errors but we
1802 want to support legacy code.
1804 Returns true if the warning was printed, false if it was inhibited. */
1806 bool
1807 permerror (location_t location, const char *gmsgid, ...)
1809 auto_diagnostic_group d;
1810 va_list ap;
1811 va_start (ap, gmsgid);
1812 rich_location richloc (line_table, location);
1813 bool ret = diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_PERMERROR);
1814 va_end (ap);
1815 return ret;
1818 /* Same as "permerror" above, but at RICHLOC. */
1820 bool
1821 permerror (rich_location *richloc, const char *gmsgid, ...)
1823 gcc_assert (richloc);
1825 auto_diagnostic_group d;
1826 va_list ap;
1827 va_start (ap, gmsgid);
1828 bool ret = diagnostic_impl (richloc, NULL, -1, gmsgid, &ap, DK_PERMERROR);
1829 va_end (ap);
1830 return ret;
1833 /* A hard error: the code is definitely ill-formed, and an object file
1834 will not be produced. */
1835 void
1836 error (const char *gmsgid, ...)
1838 auto_diagnostic_group d;
1839 va_list ap;
1840 va_start (ap, gmsgid);
1841 rich_location richloc (line_table, input_location);
1842 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ERROR);
1843 va_end (ap);
1846 /* A hard error: the code is definitely ill-formed, and an object file
1847 will not be produced. */
1848 void
1849 error_n (location_t location, unsigned HOST_WIDE_INT n,
1850 const char *singular_gmsgid, const char *plural_gmsgid, ...)
1852 auto_diagnostic_group d;
1853 va_list ap;
1854 va_start (ap, plural_gmsgid);
1855 rich_location richloc (line_table, location);
1856 diagnostic_n_impl (&richloc, NULL, -1, n, singular_gmsgid, plural_gmsgid,
1857 &ap, DK_ERROR);
1858 va_end (ap);
1861 /* Same as above, but use location LOC instead of input_location. */
1862 void
1863 error_at (location_t loc, const char *gmsgid, ...)
1865 auto_diagnostic_group d;
1866 va_list ap;
1867 va_start (ap, gmsgid);
1868 rich_location richloc (line_table, loc);
1869 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ERROR);
1870 va_end (ap);
1873 /* Same as above, but use RICH_LOC. */
1875 void
1876 error_at (rich_location *richloc, const char *gmsgid, ...)
1878 gcc_assert (richloc);
1880 auto_diagnostic_group d;
1881 va_list ap;
1882 va_start (ap, gmsgid);
1883 diagnostic_impl (richloc, NULL, -1, gmsgid, &ap, DK_ERROR);
1884 va_end (ap);
1887 /* "Sorry, not implemented." Use for a language feature which is
1888 required by the relevant specification but not implemented by GCC.
1889 An object file will not be produced. */
1890 void
1891 sorry (const char *gmsgid, ...)
1893 auto_diagnostic_group d;
1894 va_list ap;
1895 va_start (ap, gmsgid);
1896 rich_location richloc (line_table, input_location);
1897 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_SORRY);
1898 va_end (ap);
1901 /* Same as above, but use location LOC instead of input_location. */
1902 void
1903 sorry_at (location_t loc, const char *gmsgid, ...)
1905 auto_diagnostic_group d;
1906 va_list ap;
1907 va_start (ap, gmsgid);
1908 rich_location richloc (line_table, loc);
1909 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_SORRY);
1910 va_end (ap);
1913 /* Return true if an error or a "sorry" has been seen. Various
1914 processing is disabled after errors. */
1915 bool
1916 seen_error (void)
1918 return errorcount || sorrycount;
1921 /* An error which is severe enough that we make no attempt to
1922 continue. Do not use this for internal consistency checks; that's
1923 internal_error. Use of this function should be rare. */
1924 void
1925 fatal_error (location_t loc, const char *gmsgid, ...)
1927 auto_diagnostic_group d;
1928 va_list ap;
1929 va_start (ap, gmsgid);
1930 rich_location richloc (line_table, loc);
1931 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_FATAL);
1932 va_end (ap);
1934 gcc_unreachable ();
1937 /* An internal consistency check has failed. We make no attempt to
1938 continue. Note that unless there is debugging value to be had from
1939 a more specific message, or some other good reason, you should use
1940 abort () instead of calling this function directly. */
1941 void
1942 internal_error (const char *gmsgid, ...)
1944 auto_diagnostic_group d;
1945 va_list ap;
1946 va_start (ap, gmsgid);
1947 rich_location richloc (line_table, input_location);
1948 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ICE);
1949 va_end (ap);
1951 gcc_unreachable ();
1954 /* Like internal_error, but no backtrace will be printed. Used when
1955 the internal error does not happen at the current location, but happened
1956 somewhere else. */
1957 void
1958 internal_error_no_backtrace (const char *gmsgid, ...)
1960 auto_diagnostic_group d;
1961 va_list ap;
1962 va_start (ap, gmsgid);
1963 rich_location richloc (line_table, input_location);
1964 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ICE_NOBT);
1965 va_end (ap);
1967 gcc_unreachable ();
1970 /* Special case error functions. Most are implemented in terms of the
1971 above, or should be. */
1973 /* Print a diagnostic MSGID on FILE. This is just fprintf, except it
1974 runs its second argument through gettext. */
1975 void
1976 fnotice (FILE *file, const char *cmsgid, ...)
1978 va_list ap;
1980 va_start (ap, cmsgid);
1981 vfprintf (file, _(cmsgid), ap);
1982 va_end (ap);
1985 /* Inform the user that an error occurred while trying to report some
1986 other error. This indicates catastrophic internal inconsistencies,
1987 so give up now. But do try to flush out the previous error.
1988 This mustn't use internal_error, that will cause infinite recursion. */
1990 static void
1991 error_recursion (diagnostic_context *context)
1993 if (context->lock < 3)
1994 pp_newline_and_flush (context->printer);
1996 fnotice (stderr,
1997 "internal compiler error: error reporting routines re-entered.\n");
1999 /* Call diagnostic_action_after_output to get the "please submit a bug
2000 report" message. */
2001 diagnostic_action_after_output (context, DK_ICE);
2003 /* Do not use gcc_unreachable here; that goes through internal_error
2004 and therefore would cause infinite recursion. */
2005 real_abort ();
2008 /* Report an internal compiler error in a friendly manner. This is
2009 the function that gets called upon use of abort() in the source
2010 code generally, thanks to a special macro. */
2012 void
2013 fancy_abort (const char *file, int line, const char *function)
2015 /* If fancy_abort is called before the diagnostic subsystem is initialized,
2016 internal_error will crash internally in a way that prevents a
2017 useful message reaching the user.
2018 This can happen with libgccjit in the case of gcc_assert failures
2019 that occur outside of the libgccjit mutex that guards the rest of
2020 gcc's state, including global_dc (when global_dc may not be
2021 initialized yet, or might be in use by another thread).
2022 Handle such cases as gracefully as possible by falling back to a
2023 minimal abort handler that only relies on i18n. */
2024 if (global_dc->printer == NULL)
2026 /* Print the error message. */
2027 fnotice (stderr, diagnostic_kind_text[DK_ICE]);
2028 fnotice (stderr, "in %s, at %s:%d", function, trim_filename (file), line);
2029 fputc ('\n', stderr);
2031 /* Attempt to print a backtrace. */
2032 struct backtrace_state *state
2033 = backtrace_create_state (NULL, 0, bt_err_callback, NULL);
2034 int count = 0;
2035 if (state != NULL)
2036 backtrace_full (state, 2, bt_callback, bt_err_callback,
2037 (void *) &count);
2039 /* We can't call warn_if_plugins or emergency_dump_function as these
2040 rely on GCC state that might not be initialized, or might be in
2041 use by another thread. */
2043 /* Abort the process. */
2044 real_abort ();
2047 internal_error ("in %s, at %s:%d", function, trim_filename (file), line);
2050 /* class auto_diagnostic_group. */
2052 /* Constructor: "push" this group into global_dc. */
2054 auto_diagnostic_group::auto_diagnostic_group ()
2056 global_dc->diagnostic_group_nesting_depth++;
2059 /* Destructor: "pop" this group from global_dc. */
2061 auto_diagnostic_group::~auto_diagnostic_group ()
2063 if (--global_dc->diagnostic_group_nesting_depth == 0)
2065 /* Handle the case where we've popped the final diagnostic group.
2066 If any diagnostics were emitted, give the context a chance
2067 to do something. */
2068 if (global_dc->diagnostic_group_emission_count > 0)
2070 if (global_dc->end_group_cb)
2071 global_dc->end_group_cb (global_dc);
2073 global_dc->diagnostic_group_emission_count = 0;
2077 /* Implementation of diagnostic_path::num_events vfunc for
2078 simple_diagnostic_path: simply get the number of events in the vec. */
2080 unsigned
2081 simple_diagnostic_path::num_events () const
2083 return m_events.length ();
2086 /* Implementation of diagnostic_path::get_event vfunc for
2087 simple_diagnostic_path: simply return the event in the vec. */
2089 const diagnostic_event &
2090 simple_diagnostic_path::get_event (int idx) const
2092 return *m_events[idx];
2095 /* Add an event to this path at LOC within function FNDECL at
2096 stack depth DEPTH.
2098 Use m_context's printer to format FMT, as the text of the new
2099 event.
2101 Return the id of the new event. */
2103 diagnostic_event_id_t
2104 simple_diagnostic_path::add_event (location_t loc, tree fndecl, int depth,
2105 const char *fmt, ...)
2107 pretty_printer *pp = m_event_pp;
2108 pp_clear_output_area (pp);
2110 text_info ti;
2111 rich_location rich_loc (line_table, UNKNOWN_LOCATION);
2113 va_list ap;
2115 va_start (ap, fmt);
2117 ti.format_spec = _(fmt);
2118 ti.args_ptr = &ap;
2119 ti.err_no = 0;
2120 ti.x_data = NULL;
2121 ti.m_richloc = &rich_loc;
2123 pp_format (pp, &ti);
2124 pp_output_formatted_text (pp);
2126 va_end (ap);
2128 simple_diagnostic_event *new_event
2129 = new simple_diagnostic_event (loc, fndecl, depth, pp_formatted_text (pp));
2130 m_events.safe_push (new_event);
2132 pp_clear_output_area (pp);
2134 return diagnostic_event_id_t (m_events.length () - 1);
2137 /* struct simple_diagnostic_event. */
2139 /* simple_diagnostic_event's ctor. */
2141 simple_diagnostic_event::simple_diagnostic_event (location_t loc,
2142 tree fndecl,
2143 int depth,
2144 const char *desc)
2145 : m_loc (loc), m_fndecl (fndecl), m_depth (depth), m_desc (xstrdup (desc))
2149 /* simple_diagnostic_event's dtor. */
2151 simple_diagnostic_event::~simple_diagnostic_event ()
2153 free (m_desc);
2156 /* Print PATH by emitting a dummy "note" associated with it. */
2158 DEBUG_FUNCTION
2159 void debug (diagnostic_path *path)
2161 rich_location richloc (line_table, UNKNOWN_LOCATION);
2162 richloc.set_path (path);
2163 inform (&richloc, "debug path");
2166 /* Really call the system 'abort'. This has to go right at the end of
2167 this file, so that there are no functions after it that call abort
2168 and get the system abort instead of our macro. */
2169 #undef abort
2170 static void
2171 real_abort (void)
2173 abort ();
2176 #if CHECKING_P
2178 namespace selftest {
2180 /* Helper function for test_print_escaped_string. */
2182 static void
2183 assert_print_escaped_string (const location &loc, const char *expected_output,
2184 const char *input)
2186 pretty_printer pp;
2187 print_escaped_string (&pp, input);
2188 ASSERT_STREQ_AT (loc, expected_output, pp_formatted_text (&pp));
2191 #define ASSERT_PRINT_ESCAPED_STRING_STREQ(EXPECTED_OUTPUT, INPUT) \
2192 assert_print_escaped_string (SELFTEST_LOCATION, EXPECTED_OUTPUT, INPUT)
2194 /* Tests of print_escaped_string. */
2196 static void
2197 test_print_escaped_string ()
2199 /* Empty string. */
2200 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"\"", "");
2202 /* Non-empty string. */
2203 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"hello world\"", "hello world");
2205 /* Various things that need to be escaped: */
2206 /* Backslash. */
2207 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\\\after\"",
2208 "before\\after");
2209 /* Tab. */
2210 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\tafter\"",
2211 "before\tafter");
2212 /* Newline. */
2213 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\nafter\"",
2214 "before\nafter");
2215 /* Double quote. */
2216 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\\"after\"",
2217 "before\"after");
2219 /* Non-printable characters: BEL: '\a': 0x07 */
2220 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\007after\"",
2221 "before\aafter");
2222 /* Non-printable characters: vertical tab: '\v': 0x0b */
2223 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\013after\"",
2224 "before\vafter");
2227 /* Tests of print_parseable_fixits. */
2229 /* Verify that print_parseable_fixits emits the empty string if there
2230 are no fixits. */
2232 static void
2233 test_print_parseable_fixits_none ()
2235 pretty_printer pp;
2236 rich_location richloc (line_table, UNKNOWN_LOCATION);
2238 print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_BYTE, 8);
2239 ASSERT_STREQ ("", pp_formatted_text (&pp));
2242 /* Verify that print_parseable_fixits does the right thing if there
2243 is an insertion fixit hint. */
2245 static void
2246 test_print_parseable_fixits_insert ()
2248 pretty_printer pp;
2249 rich_location richloc (line_table, UNKNOWN_LOCATION);
2251 linemap_add (line_table, LC_ENTER, false, "test.c", 0);
2252 linemap_line_start (line_table, 5, 100);
2253 linemap_add (line_table, LC_LEAVE, false, NULL, 0);
2254 location_t where = linemap_position_for_column (line_table, 10);
2255 richloc.add_fixit_insert_before (where, "added content");
2257 print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_BYTE, 8);
2258 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:10}:\"added content\"\n",
2259 pp_formatted_text (&pp));
2262 /* Verify that print_parseable_fixits does the right thing if there
2263 is an removal fixit hint. */
2265 static void
2266 test_print_parseable_fixits_remove ()
2268 pretty_printer pp;
2269 rich_location richloc (line_table, UNKNOWN_LOCATION);
2271 linemap_add (line_table, LC_ENTER, false, "test.c", 0);
2272 linemap_line_start (line_table, 5, 100);
2273 linemap_add (line_table, LC_LEAVE, false, NULL, 0);
2274 source_range where;
2275 where.m_start = linemap_position_for_column (line_table, 10);
2276 where.m_finish = linemap_position_for_column (line_table, 20);
2277 richloc.add_fixit_remove (where);
2279 print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_BYTE, 8);
2280 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:21}:\"\"\n",
2281 pp_formatted_text (&pp));
2284 /* Verify that print_parseable_fixits does the right thing if there
2285 is an replacement fixit hint. */
2287 static void
2288 test_print_parseable_fixits_replace ()
2290 pretty_printer pp;
2291 rich_location richloc (line_table, UNKNOWN_LOCATION);
2293 linemap_add (line_table, LC_ENTER, false, "test.c", 0);
2294 linemap_line_start (line_table, 5, 100);
2295 linemap_add (line_table, LC_LEAVE, false, NULL, 0);
2296 source_range where;
2297 where.m_start = linemap_position_for_column (line_table, 10);
2298 where.m_finish = linemap_position_for_column (line_table, 20);
2299 richloc.add_fixit_replace (where, "replacement");
2301 print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_BYTE, 8);
2302 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:21}:\"replacement\"\n",
2303 pp_formatted_text (&pp));
2306 /* Verify that print_parseable_fixits correctly handles
2307 DIAGNOSTICS_COLUMN_UNIT_BYTE vs DIAGNOSTICS_COLUMN_UNIT_COLUMN. */
2309 static void
2310 test_print_parseable_fixits_bytes_vs_display_columns ()
2312 line_table_test ltt;
2313 rich_location richloc (line_table, UNKNOWN_LOCATION);
2315 /* 1-based byte offsets: 12345677778888999900001234567. */
2316 const char *const content = "smile \xf0\x9f\x98\x82 colour\n";
2317 /* 1-based display cols: 123456[......7-8.....]9012345. */
2318 const int tabstop = 8;
2320 temp_source_file tmp (SELFTEST_LOCATION, ".c", content);
2321 const char *const fname = tmp.get_filename ();
2323 linemap_add (line_table, LC_ENTER, false, fname, 0);
2324 linemap_line_start (line_table, 1, 100);
2325 linemap_add (line_table, LC_LEAVE, false, NULL, 0);
2326 source_range where;
2327 where.m_start = linemap_position_for_column (line_table, 12);
2328 where.m_finish = linemap_position_for_column (line_table, 17);
2329 richloc.add_fixit_replace (where, "color");
2331 /* Escape fname. */
2332 pretty_printer tmp_pp;
2333 print_escaped_string (&tmp_pp, fname);
2334 char *escaped_fname = xstrdup (pp_formatted_text (&tmp_pp));
2336 const int buf_len = strlen (escaped_fname) + 100;
2337 char *const expected = XNEWVEC (char, buf_len);
2340 pretty_printer pp;
2341 print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_BYTE,
2342 tabstop);
2343 snprintf (expected, buf_len,
2344 "fix-it:%s:{1:12-1:18}:\"color\"\n", escaped_fname);
2345 ASSERT_STREQ (expected, pp_formatted_text (&pp));
2348 pretty_printer pp;
2349 print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_DISPLAY,
2350 tabstop);
2351 snprintf (expected, buf_len,
2352 "fix-it:%s:{1:10-1:16}:\"color\"\n", escaped_fname);
2353 ASSERT_STREQ (expected, pp_formatted_text (&pp));
2356 XDELETEVEC (expected);
2357 free (escaped_fname);
2360 /* Verify that
2361 diagnostic_get_location_text (..., SHOW_COLUMN)
2362 generates EXPECTED_LOC_TEXT, given FILENAME, LINE, COLUMN, with
2363 colorization disabled. */
2365 static void
2366 assert_location_text (const char *expected_loc_text,
2367 const char *filename, int line, int column,
2368 bool show_column,
2369 int origin = 1,
2370 enum diagnostics_column_unit column_unit
2371 = DIAGNOSTICS_COLUMN_UNIT_BYTE)
2373 test_diagnostic_context dc;
2374 dc.show_column = show_column;
2375 dc.column_unit = column_unit;
2376 dc.column_origin = origin;
2378 expanded_location xloc;
2379 xloc.file = filename;
2380 xloc.line = line;
2381 xloc.column = column;
2382 xloc.data = NULL;
2383 xloc.sysp = false;
2385 char *actual_loc_text = diagnostic_get_location_text (&dc, xloc);
2386 ASSERT_STREQ (expected_loc_text, actual_loc_text);
2387 free (actual_loc_text);
2390 /* Verify that diagnostic_get_location_text works as expected. */
2392 static void
2393 test_diagnostic_get_location_text ()
2395 const char *old_progname = progname;
2396 progname = "PROGNAME";
2397 assert_location_text ("PROGNAME:", NULL, 0, 0, true);
2398 assert_location_text ("<built-in>:", "<built-in>", 42, 10, true);
2399 assert_location_text ("foo.c:42:10:", "foo.c", 42, 10, true);
2400 assert_location_text ("foo.c:42:9:", "foo.c", 42, 10, true, 0);
2401 assert_location_text ("foo.c:42:1010:", "foo.c", 42, 10, true, 1001);
2402 for (int origin = 0; origin != 2; ++origin)
2403 assert_location_text ("foo.c:42:", "foo.c", 42, 0, true, origin);
2404 assert_location_text ("foo.c:", "foo.c", 0, 10, true);
2405 assert_location_text ("foo.c:42:", "foo.c", 42, 10, false);
2406 assert_location_text ("foo.c:", "foo.c", 0, 10, false);
2408 maybe_line_and_column (INT_MAX, INT_MAX);
2409 maybe_line_and_column (INT_MIN, INT_MIN);
2412 /* In order to test display columns vs byte columns, we need to create a
2413 file for location_get_source_line() to read. */
2415 const char *const content = "smile \xf0\x9f\x98\x82\n";
2416 const int line_bytes = strlen (content) - 1;
2417 const int def_tabstop = 8;
2418 const cpp_char_column_policy policy (def_tabstop, cpp_wcwidth);
2419 const int display_width = cpp_display_width (content, line_bytes, policy);
2420 ASSERT_EQ (line_bytes - 2, display_width);
2421 temp_source_file tmp (SELFTEST_LOCATION, ".c", content);
2422 const char *const fname = tmp.get_filename ();
2423 const int buf_len = strlen (fname) + 16;
2424 char *const expected = XNEWVEC (char, buf_len);
2426 snprintf (expected, buf_len, "%s:1:%d:", fname, line_bytes);
2427 assert_location_text (expected, fname, 1, line_bytes, true,
2428 1, DIAGNOSTICS_COLUMN_UNIT_BYTE);
2430 snprintf (expected, buf_len, "%s:1:%d:", fname, line_bytes - 1);
2431 assert_location_text (expected, fname, 1, line_bytes, true,
2432 0, DIAGNOSTICS_COLUMN_UNIT_BYTE);
2434 snprintf (expected, buf_len, "%s:1:%d:", fname, display_width);
2435 assert_location_text (expected, fname, 1, line_bytes, true,
2436 1, DIAGNOSTICS_COLUMN_UNIT_DISPLAY);
2438 snprintf (expected, buf_len, "%s:1:%d:", fname, display_width - 1);
2439 assert_location_text (expected, fname, 1, line_bytes, true,
2440 0, DIAGNOSTICS_COLUMN_UNIT_DISPLAY);
2442 XDELETEVEC (expected);
2446 progname = old_progname;
2449 /* Selftest for num_digits. */
2451 static void
2452 test_num_digits ()
2454 ASSERT_EQ (1, num_digits (0));
2455 ASSERT_EQ (1, num_digits (9));
2456 ASSERT_EQ (2, num_digits (10));
2457 ASSERT_EQ (2, num_digits (99));
2458 ASSERT_EQ (3, num_digits (100));
2459 ASSERT_EQ (3, num_digits (999));
2460 ASSERT_EQ (4, num_digits (1000));
2461 ASSERT_EQ (4, num_digits (9999));
2462 ASSERT_EQ (5, num_digits (10000));
2463 ASSERT_EQ (5, num_digits (99999));
2464 ASSERT_EQ (6, num_digits (100000));
2465 ASSERT_EQ (6, num_digits (999999));
2466 ASSERT_EQ (7, num_digits (1000000));
2467 ASSERT_EQ (7, num_digits (9999999));
2468 ASSERT_EQ (8, num_digits (10000000));
2469 ASSERT_EQ (8, num_digits (99999999));
2472 /* Run all of the selftests within this file. */
2474 void
2475 c_diagnostic_cc_tests ()
2477 test_print_escaped_string ();
2478 test_print_parseable_fixits_none ();
2479 test_print_parseable_fixits_insert ();
2480 test_print_parseable_fixits_remove ();
2481 test_print_parseable_fixits_replace ();
2482 test_print_parseable_fixits_bytes_vs_display_columns ();
2483 test_diagnostic_get_location_text ();
2484 test_num_digits ();
2488 } // namespace selftest
2490 #endif /* #if CHECKING_P */
2492 #if __GNUC__ >= 10
2493 # pragma GCC diagnostic pop
2494 #endif