ada: Fix wrong resolution for hidden discriminant in predicate
[official-gcc.git] / gcc / diagnostic.cc
blobc523f215baec25370dc4ef91b705306e687d18db
1 /* Language-independent diagnostic subroutines for the GNU Compiler Collection
2 Copyright (C) 1999-2023 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 #define INCLUDE_VECTOR
27 #include "system.h"
28 #include "coretypes.h"
29 #include "version.h"
30 #include "demangle.h"
31 #include "intl.h"
32 #include "backtrace.h"
33 #include "diagnostic.h"
34 #include "diagnostic-color.h"
35 #include "diagnostic-url.h"
36 #include "diagnostic-metadata.h"
37 #include "diagnostic-path.h"
38 #include "diagnostic-client-data-hooks.h"
39 #include "diagnostic-text-art.h"
40 #include "diagnostic-diagram.h"
41 #include "edit-context.h"
42 #include "selftest.h"
43 #include "selftest-diagnostic.h"
44 #include "opts.h"
45 #include "cpplib.h"
46 #include "text-art/theme.h"
48 #ifdef HAVE_TERMIOS_H
49 # include <termios.h>
50 #endif
52 #ifdef GWINSZ_IN_SYS_IOCTL
53 # include <sys/ioctl.h>
54 #endif
56 /* Disable warnings about quoting issues in the pp_xxx calls below
57 that (intentionally) don't follow GCC diagnostic conventions. */
58 #if __GNUC__ >= 10
59 # pragma GCC diagnostic push
60 # pragma GCC diagnostic ignored "-Wformat-diag"
61 #endif
63 #define pedantic_warning_kind(DC) \
64 ((DC)->pedantic_errors ? DK_ERROR : DK_WARNING)
65 #define permissive_error_kind(DC) ((DC)->permissive ? DK_WARNING : DK_ERROR)
66 #define permissive_error_option(DC) ((DC)->opt_permissive)
68 /* Prototypes. */
69 static bool diagnostic_impl (rich_location *, const diagnostic_metadata *,
70 int, const char *,
71 va_list *, diagnostic_t) ATTRIBUTE_GCC_DIAG(4,0);
72 static bool diagnostic_n_impl (rich_location *, const diagnostic_metadata *,
73 int, unsigned HOST_WIDE_INT,
74 const char *, const char *, va_list *,
75 diagnostic_t) ATTRIBUTE_GCC_DIAG(6,0);
77 static void error_recursion (diagnostic_context *) ATTRIBUTE_NORETURN;
78 static void real_abort (void) ATTRIBUTE_NORETURN;
80 /* Name of program invoked, sans directories. */
82 const char *progname;
84 /* A diagnostic_context surrogate for stderr. */
85 static diagnostic_context global_diagnostic_context;
86 diagnostic_context *global_dc = &global_diagnostic_context;
88 /* Return a malloc'd string containing MSG formatted a la printf. The
89 caller is responsible for freeing the memory. */
90 char *
91 build_message_string (const char *msg, ...)
93 char *str;
94 va_list ap;
96 va_start (ap, msg);
97 str = xvasprintf (msg, ap);
98 va_end (ap);
100 return str;
103 /* Same as diagnostic_build_prefix, but only the source FILE is given. */
104 char *
105 file_name_as_prefix (diagnostic_context *context, const char *f)
107 const char *locus_cs
108 = colorize_start (pp_show_color (context->printer), "locus");
109 const char *locus_ce = colorize_stop (pp_show_color (context->printer));
110 return build_message_string ("%s%s:%s ", locus_cs, f, locus_ce);
115 /* Return the value of the getenv("COLUMNS") as an integer. If the
116 value is not set to a positive integer, use ioctl to get the
117 terminal width. If it fails, return INT_MAX. */
119 get_terminal_width (void)
121 const char * s = getenv ("COLUMNS");
122 if (s != NULL) {
123 int n = atoi (s);
124 if (n > 0)
125 return n;
128 #ifdef TIOCGWINSZ
129 struct winsize w;
130 w.ws_col = 0;
131 if (ioctl (0, TIOCGWINSZ, &w) == 0 && w.ws_col > 0)
132 return w.ws_col;
133 #endif
135 return INT_MAX;
138 /* Set caret_max_width to value. */
139 void
140 diagnostic_set_caret_max_width (diagnostic_context *context, int value)
142 /* One minus to account for the leading empty space. */
143 value = value ? value - 1
144 : (isatty (fileno (pp_buffer (context->printer)->stream))
145 ? get_terminal_width () - 1: INT_MAX);
147 if (value <= 0)
148 value = INT_MAX;
150 context->caret_max_width = value;
153 /* Default implementation of final_cb. */
155 static void
156 default_diagnostic_final_cb (diagnostic_context *context)
158 /* Some of the errors may actually have been warnings. */
159 if (diagnostic_kind_count (context, DK_WERROR))
161 /* -Werror was given. */
162 if (context->warning_as_error_requested)
163 pp_verbatim (context->printer,
164 _("%s: all warnings being treated as errors"),
165 progname);
166 /* At least one -Werror= was given. */
167 else
168 pp_verbatim (context->printer,
169 _("%s: some warnings being treated as errors"),
170 progname);
171 pp_newline_and_flush (context->printer);
175 /* Initialize the diagnostic message outputting machinery. */
176 void
177 diagnostic_initialize (diagnostic_context *context, int n_opts)
179 int i;
181 /* Allocate a basic pretty-printer. Clients will replace this a
182 much more elaborated pretty-printer if they wish. */
183 context->printer = XNEW (pretty_printer);
184 new (context->printer) pretty_printer ();
186 memset (context->diagnostic_count, 0, sizeof context->diagnostic_count);
187 context->warning_as_error_requested = false;
188 context->n_opts = n_opts;
189 context->classify_diagnostic = XNEWVEC (diagnostic_t, n_opts);
190 for (i = 0; i < n_opts; i++)
191 context->classify_diagnostic[i] = DK_UNSPECIFIED;
192 context->show_caret = false;
193 diagnostic_set_caret_max_width (context, pp_line_cutoff (context->printer));
194 for (i = 0; i < rich_location::STATICALLY_ALLOCATED_RANGES; i++)
195 context->caret_chars[i] = '^';
196 context->show_cwe = false;
197 context->show_rules = false;
198 context->path_format = DPF_NONE;
199 context->show_path_depths = false;
200 context->show_option_requested = false;
201 context->abort_on_error = false;
202 context->show_column = false;
203 context->pedantic_errors = false;
204 context->permissive = false;
205 context->opt_permissive = 0;
206 context->fatal_errors = false;
207 context->dc_inhibit_warnings = false;
208 context->dc_warn_system_headers = false;
209 context->max_errors = 0;
210 context->internal_error = NULL;
211 diagnostic_starter (context) = default_diagnostic_starter;
212 context->start_span = default_diagnostic_start_span_fn;
213 diagnostic_finalizer (context) = default_diagnostic_finalizer;
214 context->option_enabled = NULL;
215 context->option_state = NULL;
216 context->option_name = NULL;
217 context->get_option_url = NULL;
218 context->last_location = UNKNOWN_LOCATION;
219 context->last_module = 0;
220 context->x_data = NULL;
221 context->lock = 0;
222 context->inhibit_notes_p = false;
223 context->colorize_source_p = false;
224 context->show_labels_p = false;
225 context->show_line_numbers_p = false;
226 context->min_margin_width = 0;
227 context->show_ruler_p = false;
228 context->report_bug = false;
230 if (const char *var = getenv ("GCC_EXTRA_DIAGNOSTIC_OUTPUT"))
232 if (!strcmp (var, "fixits-v1"))
233 context->extra_output_kind = EXTRA_DIAGNOSTIC_OUTPUT_fixits_v1;
234 else if (!strcmp (var, "fixits-v2"))
235 context->extra_output_kind = EXTRA_DIAGNOSTIC_OUTPUT_fixits_v2;
236 /* Silently ignore unrecognized values. */
238 context->column_unit = DIAGNOSTICS_COLUMN_UNIT_DISPLAY;
239 context->column_origin = 1;
240 context->tabstop = 8;
241 context->escape_format = DIAGNOSTICS_ESCAPE_FORMAT_UNICODE;
242 context->edit_context_ptr = NULL;
243 context->diagnostic_group_nesting_depth = 0;
244 context->diagnostic_group_emission_count = 0;
245 context->begin_group_cb = NULL;
246 context->end_group_cb = NULL;
247 context->final_cb = default_diagnostic_final_cb;
248 context->ice_handler_cb = NULL;
249 context->includes_seen = NULL;
250 context->m_client_data_hooks = NULL;
251 context->m_diagrams.m_theme = NULL;
252 context->m_diagrams.m_emission_cb = NULL;
253 diagnostics_text_art_charset_init (context,
254 DIAGNOSTICS_TEXT_ART_CHARSET_DEFAULT);
257 /* Maybe initialize the color support. We require clients to do this
258 explicitly, since most clients don't want color. When called
259 without a VALUE, it initializes with DIAGNOSTICS_COLOR_DEFAULT. */
261 void
262 diagnostic_color_init (diagnostic_context *context, int value /*= -1 */)
264 /* value == -1 is the default value. */
265 if (value < 0)
267 /* If DIAGNOSTICS_COLOR_DEFAULT is -1, default to
268 -fdiagnostics-color=auto if GCC_COLORS is in the environment,
269 otherwise default to -fdiagnostics-color=never, for other
270 values default to that
271 -fdiagnostics-color={never,auto,always}. */
272 if (DIAGNOSTICS_COLOR_DEFAULT == -1)
274 if (!getenv ("GCC_COLORS"))
275 return;
276 value = DIAGNOSTICS_COLOR_AUTO;
278 else
279 value = DIAGNOSTICS_COLOR_DEFAULT;
281 pp_show_color (context->printer)
282 = colorize_init ((diagnostic_color_rule_t) value);
285 /* Initialize URL support within CONTEXT based on VALUE, handling "auto". */
287 void
288 diagnostic_urls_init (diagnostic_context *context, int value /*= -1 */)
290 /* value == -1 is the default value. */
291 if (value < 0)
293 /* If DIAGNOSTICS_URLS_DEFAULT is -1, default to
294 -fdiagnostics-urls=auto if GCC_URLS or TERM_URLS is in the
295 environment, otherwise default to -fdiagnostics-urls=never,
296 for other values default to that
297 -fdiagnostics-urls={never,auto,always}. */
298 if (DIAGNOSTICS_URLS_DEFAULT == -1)
300 if (!getenv ("GCC_URLS") && !getenv ("TERM_URLS"))
301 return;
302 value = DIAGNOSTICS_URL_AUTO;
304 else
305 value = DIAGNOSTICS_URLS_DEFAULT;
308 context->printer->url_format
309 = determine_url_format ((diagnostic_url_rule_t) value);
312 /* Create the file_cache, if not already created, and tell it how to
313 translate files on input. */
314 void diagnostic_initialize_input_context (diagnostic_context *context,
315 diagnostic_input_charset_callback ccb,
316 bool should_skip_bom)
318 if (!context->m_file_cache)
319 context->m_file_cache = new file_cache;
320 context->m_file_cache->initialize_input_context (ccb, should_skip_bom);
323 /* Do any cleaning up required after the last diagnostic is emitted. */
325 void
326 diagnostic_finish (diagnostic_context *context)
328 if (context->final_cb)
329 context->final_cb (context);
331 if (context->m_diagrams.m_theme)
333 delete context->m_diagrams.m_theme;
334 context->m_diagrams.m_theme = NULL;
337 diagnostic_file_cache_fini ();
339 XDELETEVEC (context->classify_diagnostic);
340 context->classify_diagnostic = NULL;
342 /* diagnostic_initialize allocates context->printer using XNEW
343 and placement-new. */
344 context->printer->~pretty_printer ();
345 XDELETE (context->printer);
346 context->printer = NULL;
348 if (context->edit_context_ptr)
350 delete context->edit_context_ptr;
351 context->edit_context_ptr = NULL;
354 if (context->includes_seen)
356 delete context->includes_seen;
357 context->includes_seen = nullptr;
360 if (context->m_client_data_hooks)
362 delete context->m_client_data_hooks;
363 context->m_client_data_hooks = NULL;
367 /* Initialize DIAGNOSTIC, where the message MSG has already been
368 translated. */
369 void
370 diagnostic_set_info_translated (diagnostic_info *diagnostic, const char *msg,
371 va_list *args, rich_location *richloc,
372 diagnostic_t kind)
374 gcc_assert (richloc);
375 diagnostic->message.err_no = errno;
376 diagnostic->message.args_ptr = args;
377 diagnostic->message.format_spec = msg;
378 diagnostic->message.m_richloc = richloc;
379 diagnostic->richloc = richloc;
380 diagnostic->metadata = NULL;
381 diagnostic->kind = kind;
382 diagnostic->option_index = 0;
385 /* Initialize DIAGNOSTIC, where the message GMSGID has not yet been
386 translated. */
387 void
388 diagnostic_set_info (diagnostic_info *diagnostic, const char *gmsgid,
389 va_list *args, rich_location *richloc,
390 diagnostic_t kind)
392 gcc_assert (richloc);
393 diagnostic_set_info_translated (diagnostic, _(gmsgid), args, richloc, kind);
396 static const char *const diagnostic_kind_color[] = {
397 #define DEFINE_DIAGNOSTIC_KIND(K, T, C) (C),
398 #include "diagnostic.def"
399 #undef DEFINE_DIAGNOSTIC_KIND
400 NULL
403 /* Get a color name for diagnostics of type KIND
404 Result could be NULL. */
406 const char *
407 diagnostic_get_color_for_kind (diagnostic_t kind)
409 return diagnostic_kind_color[kind];
412 /* Given an expanded_location, convert the column (which is in 1-based bytes)
413 to the requested units, without converting the origin.
414 Return -1 if the column is invalid (<= 0). */
416 static int
417 convert_column_unit (enum diagnostics_column_unit column_unit,
418 int tabstop,
419 expanded_location s)
421 if (s.column <= 0)
422 return -1;
424 switch (column_unit)
426 default:
427 gcc_unreachable ();
429 case DIAGNOSTICS_COLUMN_UNIT_DISPLAY:
431 cpp_char_column_policy policy (tabstop, cpp_wcwidth);
432 return location_compute_display_column (s, policy);
435 case DIAGNOSTICS_COLUMN_UNIT_BYTE:
436 return s.column;
440 /* Given an expanded_location, convert the column (which is in 1-based bytes)
441 to the requested units and origin. Return -1 if the column is
442 invalid (<= 0). */
444 diagnostic_converted_column (diagnostic_context *context, expanded_location s)
446 int one_based_col
447 = convert_column_unit (context->column_unit, context->tabstop, s);
448 if (one_based_col <= 0)
449 return -1;
450 return one_based_col + (context->column_origin - 1);
453 /* Return a formatted line and column ':%line:%column'. Elided if
454 line == 0 or col < 0. (A column of 0 may be valid due to the
455 -fdiagnostics-column-origin option.)
456 The result is a statically allocated buffer. */
458 static const char *
459 maybe_line_and_column (int line, int col)
461 static char result[32];
463 if (line)
465 size_t l
466 = snprintf (result, sizeof (result),
467 col >= 0 ? ":%d:%d" : ":%d", line, col);
468 gcc_checking_assert (l < sizeof (result));
470 else
471 result[0] = 0;
472 return result;
475 /* Return a malloc'd string describing a location e.g. "foo.c:42:10".
476 The caller is responsible for freeing the memory. */
478 static char *
479 diagnostic_get_location_text (diagnostic_context *context,
480 expanded_location s)
482 pretty_printer *pp = context->printer;
483 const char *locus_cs = colorize_start (pp_show_color (pp), "locus");
484 const char *locus_ce = colorize_stop (pp_show_color (pp));
485 const char *file = s.file ? s.file : progname;
486 int line = 0;
487 int col = -1;
488 if (strcmp (file, special_fname_builtin ()))
490 line = s.line;
491 if (context->show_column)
492 col = diagnostic_converted_column (context, s);
495 const char *line_col = maybe_line_and_column (line, col);
496 return build_message_string ("%s%s%s:%s", locus_cs, file,
497 line_col, locus_ce);
500 static const char *const diagnostic_kind_text[] = {
501 #define DEFINE_DIAGNOSTIC_KIND(K, T, C) (T),
502 #include "diagnostic.def"
503 #undef DEFINE_DIAGNOSTIC_KIND
504 "must-not-happen"
507 /* Return a malloc'd string describing a location and the severity of the
508 diagnostic, e.g. "foo.c:42:10: error: ". The caller is responsible for
509 freeing the memory. */
510 char *
511 diagnostic_build_prefix (diagnostic_context *context,
512 const diagnostic_info *diagnostic)
514 gcc_assert (diagnostic->kind < DK_LAST_DIAGNOSTIC_KIND);
516 const char *text = _(diagnostic_kind_text[diagnostic->kind]);
517 const char *text_cs = "", *text_ce = "";
518 pretty_printer *pp = context->printer;
520 if (diagnostic_kind_color[diagnostic->kind])
522 text_cs = colorize_start (pp_show_color (pp),
523 diagnostic_kind_color[diagnostic->kind]);
524 text_ce = colorize_stop (pp_show_color (pp));
527 expanded_location s = diagnostic_expand_location (diagnostic);
528 char *location_text = diagnostic_get_location_text (context, s);
530 char *result = build_message_string ("%s %s%s%s", location_text,
531 text_cs, text, text_ce);
532 free (location_text);
533 return result;
536 /* Functions at which to stop the backtrace print. It's not
537 particularly helpful to print the callers of these functions. */
539 static const char * const bt_stop[] =
541 "main",
542 "toplev::main",
543 "execute_one_pass",
544 "compile_file",
547 /* A callback function passed to the backtrace_full function. */
549 static int
550 bt_callback (void *data, uintptr_t pc, const char *filename, int lineno,
551 const char *function)
553 int *pcount = (int *) data;
555 /* If we don't have any useful information, don't print
556 anything. */
557 if (filename == NULL && function == NULL)
558 return 0;
560 /* Skip functions in diagnostic.cc. */
561 if (*pcount == 0
562 && filename != NULL
563 && strcmp (lbasename (filename), "diagnostic.cc") == 0)
564 return 0;
566 /* Print up to 20 functions. We could make this a --param, but
567 since this is only for debugging just use a constant for now. */
568 if (*pcount >= 20)
570 /* Returning a non-zero value stops the backtrace. */
571 return 1;
573 ++*pcount;
575 char *alc = NULL;
576 if (function != NULL)
578 char *str = cplus_demangle_v3 (function,
579 (DMGL_VERBOSE | DMGL_ANSI
580 | DMGL_GNU_V3 | DMGL_PARAMS));
581 if (str != NULL)
583 alc = str;
584 function = str;
587 for (size_t i = 0; i < ARRAY_SIZE (bt_stop); ++i)
589 size_t len = strlen (bt_stop[i]);
590 if (strncmp (function, bt_stop[i], len) == 0
591 && (function[len] == '\0' || function[len] == '('))
593 if (alc != NULL)
594 free (alc);
595 /* Returning a non-zero value stops the backtrace. */
596 return 1;
601 fprintf (stderr, "0x%lx %s\n\t%s:%d\n",
602 (unsigned long) pc,
603 function == NULL ? "???" : function,
604 filename == NULL ? "???" : filename,
605 lineno);
607 if (alc != NULL)
608 free (alc);
610 return 0;
613 /* A callback function passed to the backtrace_full function. This is
614 called if backtrace_full has an error. */
616 static void
617 bt_err_callback (void *data ATTRIBUTE_UNUSED, const char *msg, int errnum)
619 if (errnum < 0)
621 /* This means that no debug info was available. Just quietly
622 skip printing backtrace info. */
623 return;
625 fprintf (stderr, "%s%s%s\n", msg, errnum == 0 ? "" : ": ",
626 errnum == 0 ? "" : xstrerror (errnum));
629 /* Check if we've met the maximum error limit, and if so fatally exit
630 with a message. CONTEXT is the context to check, and FLUSH
631 indicates whether a diagnostic_finish call is needed. */
633 void
634 diagnostic_check_max_errors (diagnostic_context *context, bool flush)
636 if (!context->max_errors)
637 return;
639 int count = (diagnostic_kind_count (context, DK_ERROR)
640 + diagnostic_kind_count (context, DK_SORRY)
641 + diagnostic_kind_count (context, DK_WERROR));
643 if (count >= context->max_errors)
645 fnotice (stderr,
646 "compilation terminated due to -fmax-errors=%u.\n",
647 context->max_errors);
648 if (flush)
649 diagnostic_finish (context);
650 exit (FATAL_EXIT_CODE);
654 /* Take any action which is expected to happen after the diagnostic
655 is written out. This function does not always return. */
656 void
657 diagnostic_action_after_output (diagnostic_context *context,
658 diagnostic_t diag_kind)
660 switch (diag_kind)
662 case DK_DEBUG:
663 case DK_NOTE:
664 case DK_ANACHRONISM:
665 case DK_WARNING:
666 break;
668 case DK_ERROR:
669 case DK_SORRY:
670 if (context->abort_on_error)
671 real_abort ();
672 if (context->fatal_errors)
674 fnotice (stderr, "compilation terminated due to -Wfatal-errors.\n");
675 diagnostic_finish (context);
676 exit (FATAL_EXIT_CODE);
678 break;
680 case DK_ICE:
681 case DK_ICE_NOBT:
683 /* Optional callback for attempting to handle ICEs gracefully. */
684 if (void (*ice_handler_cb) (diagnostic_context *)
685 = context->ice_handler_cb)
687 /* Clear the callback, to avoid potentially re-entering
688 the routine if there's a crash within the handler. */
689 context->ice_handler_cb = NULL;
690 ice_handler_cb (context);
692 /* The context might have had diagnostic_finish called on
693 it at this point. */
695 struct backtrace_state *state = NULL;
696 if (diag_kind == DK_ICE)
697 state = backtrace_create_state (NULL, 0, bt_err_callback, NULL);
698 int count = 0;
699 if (state != NULL)
700 backtrace_full (state, 2, bt_callback, bt_err_callback,
701 (void *) &count);
703 if (context->abort_on_error)
704 real_abort ();
706 if (context->report_bug)
707 fnotice (stderr, "Please submit a full bug report, "
708 "with preprocessed source.\n");
709 else
710 fnotice (stderr, "Please submit a full bug report, "
711 "with preprocessed source (by using -freport-bug).\n");
713 if (count > 0)
714 fnotice (stderr, "Please include the complete backtrace "
715 "with any bug report.\n");
716 fnotice (stderr, "See %s for instructions.\n", bug_report_url);
718 exit (ICE_EXIT_CODE);
721 case DK_FATAL:
722 if (context->abort_on_error)
723 real_abort ();
724 diagnostic_finish (context);
725 fnotice (stderr, "compilation terminated.\n");
726 exit (FATAL_EXIT_CODE);
728 default:
729 gcc_unreachable ();
733 /* True if the last module or file in which a diagnostic was reported is
734 different from the current one. */
736 static bool
737 last_module_changed_p (diagnostic_context *context,
738 const line_map_ordinary *map)
740 return context->last_module != map;
743 /* Remember the current module or file as being the last one in which we
744 report a diagnostic. */
746 static void
747 set_last_module (diagnostic_context *context, const line_map_ordinary *map)
749 context->last_module = map;
752 /* Only dump the "In file included from..." stack once for each file. */
754 static bool
755 includes_seen (diagnostic_context *context, const line_map_ordinary *map)
757 /* No include path for main. */
758 if (MAIN_FILE_P (map))
759 return true;
761 /* Always identify C++ modules, at least for now. */
762 auto probe = map;
763 if (linemap_check_ordinary (map)->reason == LC_RENAME)
764 /* The module source file shows up as LC_RENAME inside LC_MODULE. */
765 probe = linemap_included_from_linemap (line_table, map);
766 if (MAP_MODULE_P (probe))
767 return false;
769 if (!context->includes_seen)
770 context->includes_seen = new hash_set<location_t, false, location_hash>;
772 /* Hash the location of the #include directive to better handle files
773 that are included multiple times with different macros defined. */
774 return context->includes_seen->add (linemap_included_from (map));
777 void
778 diagnostic_report_current_module (diagnostic_context *context, location_t where)
780 const line_map_ordinary *map = NULL;
782 if (pp_needs_newline (context->printer))
784 pp_newline (context->printer);
785 pp_needs_newline (context->printer) = false;
788 if (where <= BUILTINS_LOCATION)
789 return;
791 linemap_resolve_location (line_table, where,
792 LRK_MACRO_DEFINITION_LOCATION,
793 &map);
795 if (map && last_module_changed_p (context, map))
797 set_last_module (context, map);
798 if (!includes_seen (context, map))
800 bool first = true, need_inc = true, was_module = MAP_MODULE_P (map);
801 expanded_location s = {};
804 where = linemap_included_from (map);
805 map = linemap_included_from_linemap (line_table, map);
806 bool is_module = MAP_MODULE_P (map);
807 s.file = LINEMAP_FILE (map);
808 s.line = SOURCE_LINE (map, where);
809 int col = -1;
810 if (first && context->show_column)
812 s.column = SOURCE_COLUMN (map, where);
813 col = diagnostic_converted_column (context, s);
815 const char *line_col = maybe_line_and_column (s.line, col);
816 static const char *const msgs[] =
818 NULL,
819 N_(" from"),
820 N_("In file included from"), /* 2 */
821 N_(" included from"),
822 N_("In module"), /* 4 */
823 N_("of module"),
824 N_("In module imported at"), /* 6 */
825 N_("imported at"),
828 unsigned index = (was_module ? 6 : is_module ? 4
829 : need_inc ? 2 : 0) + !first;
831 pp_verbatim (context->printer, "%s%s %r%s%s%R",
832 first ? "" : was_module ? ", " : ",\n",
833 _(msgs[index]),
834 "locus", s.file, line_col);
835 first = false, need_inc = was_module, was_module = is_module;
837 while (!includes_seen (context, map));
838 pp_verbatim (context->printer, ":");
839 pp_newline (context->printer);
844 /* If DIAGNOSTIC has a diagnostic_path and CONTEXT supports printing paths,
845 print the path. */
847 void
848 diagnostic_show_any_path (diagnostic_context *context,
849 diagnostic_info *diagnostic)
851 const diagnostic_path *path = diagnostic->richloc->get_path ();
852 if (!path)
853 return;
855 if (context->print_path)
856 context->print_path (context, path);
859 /* class diagnostic_event. */
861 /* struct diagnostic_event::meaning. */
863 void
864 diagnostic_event::meaning::dump_to_pp (pretty_printer *pp) const
866 bool need_comma = false;
867 pp_character (pp, '{');
868 if (const char *verb_str = maybe_get_verb_str (m_verb))
870 pp_printf (pp, "verb: %qs", verb_str);
871 need_comma = true;
873 if (const char *noun_str = maybe_get_noun_str (m_noun))
875 if (need_comma)
876 pp_string (pp, ", ");
877 pp_printf (pp, "noun: %qs", noun_str);
878 need_comma = true;
880 if (const char *property_str = maybe_get_property_str (m_property))
882 if (need_comma)
883 pp_string (pp, ", ");
884 pp_printf (pp, "property: %qs", property_str);
885 need_comma = true;
887 pp_character (pp, '}');
890 /* Get a string (or NULL) for V suitable for use within a SARIF
891 threadFlowLocation "kinds" property (SARIF v2.1.0 section 3.38.8). */
893 const char *
894 diagnostic_event::meaning::maybe_get_verb_str (enum verb v)
896 switch (v)
898 default:
899 gcc_unreachable ();
900 case VERB_unknown:
901 return NULL;
902 case VERB_acquire:
903 return "acquire";
904 case VERB_release:
905 return "release";
906 case VERB_enter:
907 return "enter";
908 case VERB_exit:
909 return "exit";
910 case VERB_call:
911 return "call";
912 case VERB_return:
913 return "return";
914 case VERB_branch:
915 return "branch";
916 case VERB_danger:
917 return "danger";
921 /* Get a string (or NULL) for N suitable for use within a SARIF
922 threadFlowLocation "kinds" property (SARIF v2.1.0 section 3.38.8). */
924 const char *
925 diagnostic_event::meaning::maybe_get_noun_str (enum noun n)
927 switch (n)
929 default:
930 gcc_unreachable ();
931 case NOUN_unknown:
932 return NULL;
933 case NOUN_taint:
934 return "taint";
935 case NOUN_sensitive:
936 return "sensitive";
937 case NOUN_function:
938 return "function";
939 case NOUN_lock:
940 return "lock";
941 case NOUN_memory:
942 return "memory";
943 case NOUN_resource:
944 return "resource";
948 /* Get a string (or NULL) for P suitable for use within a SARIF
949 threadFlowLocation "kinds" property (SARIF v2.1.0 section 3.38.8). */
951 const char *
952 diagnostic_event::meaning::maybe_get_property_str (enum property p)
954 switch (p)
956 default:
957 gcc_unreachable ();
958 case PROPERTY_unknown:
959 return NULL;
960 case PROPERTY_true:
961 return "true";
962 case PROPERTY_false:
963 return "false";
967 /* class diagnostic_path. */
969 /* Subroutint of diagnostic_path::interprocedural_p.
970 Look for the first event in this path that is within a function
971 i.e. has a non-NULL fndecl, and a non-zero stack depth.
972 If found, write its index to *OUT_IDX and return true.
973 Otherwise return false. */
975 bool
976 diagnostic_path::get_first_event_in_a_function (unsigned *out_idx) const
978 const unsigned num = num_events ();
979 for (unsigned i = 0; i < num; i++)
981 if (!(get_event (i).get_fndecl () == NULL
982 && get_event (i).get_stack_depth () == 0))
984 *out_idx = i;
985 return true;
988 return false;
991 /* Return true if the events in this path involve more than one
992 function, or false if it is purely intraprocedural. */
994 bool
995 diagnostic_path::interprocedural_p () const
997 /* Ignore leading events that are outside of any function. */
998 unsigned first_fn_event_idx;
999 if (!get_first_event_in_a_function (&first_fn_event_idx))
1000 return false;
1002 const diagnostic_event &first_fn_event = get_event (first_fn_event_idx);
1003 tree first_fndecl = first_fn_event.get_fndecl ();
1004 int first_fn_stack_depth = first_fn_event.get_stack_depth ();
1006 const unsigned num = num_events ();
1007 for (unsigned i = first_fn_event_idx + 1; i < num; i++)
1009 if (get_event (i).get_fndecl () != first_fndecl)
1010 return true;
1011 if (get_event (i).get_stack_depth () != first_fn_stack_depth)
1012 return true;
1014 return false;
1017 void
1018 default_diagnostic_starter (diagnostic_context *context,
1019 diagnostic_info *diagnostic)
1021 diagnostic_report_current_module (context, diagnostic_location (diagnostic));
1022 pp_set_prefix (context->printer, diagnostic_build_prefix (context,
1023 diagnostic));
1026 void
1027 default_diagnostic_start_span_fn (diagnostic_context *context,
1028 expanded_location exploc)
1030 char *text = diagnostic_get_location_text (context, exploc);
1031 pp_string (context->printer, text);
1032 free (text);
1033 pp_newline (context->printer);
1036 void
1037 default_diagnostic_finalizer (diagnostic_context *context,
1038 diagnostic_info *diagnostic,
1039 diagnostic_t)
1041 char *saved_prefix = pp_take_prefix (context->printer);
1042 pp_set_prefix (context->printer, NULL);
1043 pp_newline (context->printer);
1044 diagnostic_show_locus (context, diagnostic->richloc, diagnostic->kind);
1045 pp_set_prefix (context->printer, saved_prefix);
1046 pp_flush (context->printer);
1049 /* Interface to specify diagnostic kind overrides. Returns the
1050 previous setting, or DK_UNSPECIFIED if the parameters are out of
1051 range. If OPTION_INDEX is zero, the new setting is for all the
1052 diagnostics. */
1053 diagnostic_t
1054 diagnostic_classify_diagnostic (diagnostic_context *context,
1055 int option_index,
1056 diagnostic_t new_kind,
1057 location_t where)
1059 diagnostic_t old_kind;
1061 if (option_index < 0
1062 || option_index >= context->n_opts
1063 || new_kind >= DK_LAST_DIAGNOSTIC_KIND)
1064 return DK_UNSPECIFIED;
1066 old_kind = context->classify_diagnostic[option_index];
1068 /* Handle pragmas separately, since we need to keep track of *where*
1069 the pragmas were. */
1070 if (where != UNKNOWN_LOCATION)
1072 int i;
1074 /* Record the command-line status, so we can reset it back on DK_POP. */
1075 if (old_kind == DK_UNSPECIFIED)
1077 old_kind = !context->option_enabled (option_index,
1078 context->lang_mask,
1079 context->option_state)
1080 ? DK_IGNORED : (context->warning_as_error_requested
1081 ? DK_ERROR : DK_WARNING);
1082 context->classify_diagnostic[option_index] = old_kind;
1085 for (i = context->n_classification_history - 1; i >= 0; i --)
1086 if (context->classification_history[i].option == option_index)
1088 old_kind = context->classification_history[i].kind;
1089 break;
1092 i = context->n_classification_history;
1093 context->classification_history =
1094 (diagnostic_classification_change_t *) xrealloc (context->classification_history, (i + 1)
1095 * sizeof (diagnostic_classification_change_t));
1096 context->classification_history[i].location = where;
1097 context->classification_history[i].option = option_index;
1098 context->classification_history[i].kind = new_kind;
1099 context->n_classification_history ++;
1101 else
1102 context->classify_diagnostic[option_index] = new_kind;
1104 return old_kind;
1107 /* Save all diagnostic classifications in a stack. */
1108 void
1109 diagnostic_push_diagnostics (diagnostic_context *context, location_t where ATTRIBUTE_UNUSED)
1111 context->push_list = (int *) xrealloc (context->push_list, (context->n_push + 1) * sizeof (int));
1112 context->push_list[context->n_push ++] = context->n_classification_history;
1115 /* Restore the topmost classification set off the stack. If the stack
1116 is empty, revert to the state based on command line parameters. */
1117 void
1118 diagnostic_pop_diagnostics (diagnostic_context *context, location_t where)
1120 int jump_to;
1121 int i;
1123 if (context->n_push)
1124 jump_to = context->push_list [-- context->n_push];
1125 else
1126 jump_to = 0;
1128 i = context->n_classification_history;
1129 context->classification_history =
1130 (diagnostic_classification_change_t *) xrealloc (context->classification_history, (i + 1)
1131 * sizeof (diagnostic_classification_change_t));
1132 context->classification_history[i].location = where;
1133 context->classification_history[i].option = jump_to;
1134 context->classification_history[i].kind = DK_POP;
1135 context->n_classification_history ++;
1138 /* Helper function for print_parseable_fixits. Print TEXT to PP, obeying the
1139 escaping rules for -fdiagnostics-parseable-fixits. */
1141 static void
1142 print_escaped_string (pretty_printer *pp, const char *text)
1144 gcc_assert (pp);
1145 gcc_assert (text);
1147 pp_character (pp, '"');
1148 for (const char *ch = text; *ch; ch++)
1150 switch (*ch)
1152 case '\\':
1153 /* Escape backslash as two backslashes. */
1154 pp_string (pp, "\\\\");
1155 break;
1156 case '\t':
1157 /* Escape tab as "\t". */
1158 pp_string (pp, "\\t");
1159 break;
1160 case '\n':
1161 /* Escape newline as "\n". */
1162 pp_string (pp, "\\n");
1163 break;
1164 case '"':
1165 /* Escape doublequotes as \". */
1166 pp_string (pp, "\\\"");
1167 break;
1168 default:
1169 if (ISPRINT (*ch))
1170 pp_character (pp, *ch);
1171 else
1172 /* Use octal for non-printable chars. */
1174 unsigned char c = (*ch & 0xff);
1175 pp_printf (pp, "\\%o%o%o", (c / 64), (c / 8) & 007, c & 007);
1177 break;
1180 pp_character (pp, '"');
1183 /* Implementation of -fdiagnostics-parseable-fixits and
1184 GCC_EXTRA_DIAGNOSTIC_OUTPUT.
1185 Print a machine-parseable version of all fixits in RICHLOC to PP,
1186 using COLUMN_UNIT to express columns.
1187 Use TABSTOP when handling DIAGNOSTICS_COLUMN_UNIT_DISPLAY. */
1189 static void
1190 print_parseable_fixits (pretty_printer *pp, rich_location *richloc,
1191 enum diagnostics_column_unit column_unit,
1192 int tabstop)
1194 gcc_assert (pp);
1195 gcc_assert (richloc);
1197 char *saved_prefix = pp_take_prefix (pp);
1198 pp_set_prefix (pp, NULL);
1200 for (unsigned i = 0; i < richloc->get_num_fixit_hints (); i++)
1202 const fixit_hint *hint = richloc->get_fixit_hint (i);
1203 location_t start_loc = hint->get_start_loc ();
1204 expanded_location start_exploc = expand_location (start_loc);
1205 pp_string (pp, "fix-it:");
1206 print_escaped_string (pp, start_exploc.file);
1207 /* For compatibility with clang, print as a half-open range. */
1208 location_t next_loc = hint->get_next_loc ();
1209 expanded_location next_exploc = expand_location (next_loc);
1210 int start_col
1211 = convert_column_unit (column_unit, tabstop, start_exploc);
1212 int next_col
1213 = convert_column_unit (column_unit, tabstop, next_exploc);
1214 pp_printf (pp, ":{%i:%i-%i:%i}:",
1215 start_exploc.line, start_col,
1216 next_exploc.line, next_col);
1217 print_escaped_string (pp, hint->get_string ());
1218 pp_newline (pp);
1221 pp_set_prefix (pp, saved_prefix);
1224 /* Update the inlining info in CONTEXT for a DIAGNOSTIC. */
1226 static void
1227 get_any_inlining_info (diagnostic_context *context,
1228 diagnostic_info *diagnostic)
1230 auto &ilocs = diagnostic->m_iinfo.m_ilocs;
1232 if (context->set_locations_cb)
1233 /* Retrieve the locations into which the expression about to be
1234 diagnosed has been inlined, including those of all the callers
1235 all the way down the inlining stack. */
1236 context->set_locations_cb (context, diagnostic);
1237 else
1239 /* When there's no callback use just the one location provided
1240 by the caller of the diagnostic function. */
1241 location_t loc = diagnostic_location (diagnostic);
1242 ilocs.safe_push (loc);
1243 diagnostic->m_iinfo.m_allsyslocs = in_system_header_at (loc);
1247 /* Update the kind of DIAGNOSTIC based on its location(s), including
1248 any of those in its inlining stack, relative to any
1249 #pragma GCC diagnostic
1250 directives recorded within CONTEXT.
1252 Return the new kind of DIAGNOSTIC if it was updated, or DK_UNSPECIFIED
1253 otherwise. */
1255 static diagnostic_t
1256 update_effective_level_from_pragmas (diagnostic_context *context,
1257 diagnostic_info *diagnostic)
1259 if (diagnostic->m_iinfo.m_allsyslocs && !context->dc_warn_system_headers)
1261 /* Ignore the diagnostic if all the inlined locations are
1262 in system headers and -Wno-system-headers is in effect. */
1263 diagnostic->kind = DK_IGNORED;
1264 return DK_IGNORED;
1267 if (context->n_classification_history <= 0)
1268 return DK_UNSPECIFIED;
1270 /* Iterate over the locations, checking the diagnostic disposition
1271 for the diagnostic at each. If it's explicitly set as opposed
1272 to unspecified, update the disposition for this instance of
1273 the diagnostic and return it. */
1274 for (location_t loc: diagnostic->m_iinfo.m_ilocs)
1276 /* FIXME: Stupid search. Optimize later. */
1277 for (int i = context->n_classification_history - 1; i >= 0; i --)
1279 const diagnostic_classification_change_t &hist
1280 = context->classification_history[i];
1282 location_t pragloc = hist.location;
1283 if (!linemap_location_before_p (line_table, pragloc, loc))
1284 continue;
1286 if (hist.kind == (int) DK_POP)
1288 /* Move on to the next region. */
1289 i = hist.option;
1290 continue;
1293 int option = hist.option;
1294 /* The option 0 is for all the diagnostics. */
1295 if (option == 0 || option == diagnostic->option_index)
1297 diagnostic_t kind = hist.kind;
1298 if (kind != DK_UNSPECIFIED)
1299 diagnostic->kind = kind;
1300 return kind;
1305 return DK_UNSPECIFIED;
1308 /* Generate a URL string describing CWE. The caller is responsible for
1309 freeing the string. */
1311 char *
1312 get_cwe_url (int cwe)
1314 return xasprintf ("https://cwe.mitre.org/data/definitions/%i.html", cwe);
1317 /* If DIAGNOSTIC has a CWE identifier, print it.
1319 For example, if the diagnostic metadata associates it with CWE-119,
1320 " [CWE-119]" will be printed, suitably colorized, and with a URL of a
1321 description of the security issue. */
1323 static void
1324 print_any_cwe (diagnostic_context *context,
1325 const diagnostic_info *diagnostic)
1327 if (diagnostic->metadata == NULL)
1328 return;
1330 int cwe = diagnostic->metadata->get_cwe ();
1331 if (cwe)
1333 pretty_printer *pp = context->printer;
1334 char *saved_prefix = pp_take_prefix (context->printer);
1335 pp_string (pp, " [");
1336 pp_string (pp, colorize_start (pp_show_color (pp),
1337 diagnostic_kind_color[diagnostic->kind]));
1338 if (pp->url_format != URL_FORMAT_NONE)
1340 char *cwe_url = get_cwe_url (cwe);
1341 pp_begin_url (pp, cwe_url);
1342 free (cwe_url);
1344 pp_printf (pp, "CWE-%i", cwe);
1345 pp_set_prefix (context->printer, saved_prefix);
1346 if (pp->url_format != URL_FORMAT_NONE)
1347 pp_end_url (pp);
1348 pp_string (pp, colorize_stop (pp_show_color (pp)));
1349 pp_character (pp, ']');
1353 /* If DIAGNOSTIC has any rules associated with it, print them.
1355 For example, if the diagnostic metadata associates it with a rule
1356 named "STR34-C", then " [STR34-C]" will be printed, suitably colorized,
1357 with any URL provided by the rule. */
1359 static void
1360 print_any_rules (diagnostic_context *context,
1361 const diagnostic_info *diagnostic)
1363 if (diagnostic->metadata == NULL)
1364 return;
1366 for (unsigned idx = 0; idx < diagnostic->metadata->get_num_rules (); idx++)
1368 const diagnostic_metadata::rule &rule
1369 = diagnostic->metadata->get_rule (idx);
1370 if (char *desc = rule.make_description ())
1372 pretty_printer *pp = context->printer;
1373 char *saved_prefix = pp_take_prefix (context->printer);
1374 pp_string (pp, " [");
1375 pp_string (pp,
1376 colorize_start (pp_show_color (pp),
1377 diagnostic_kind_color[diagnostic->kind]));
1378 char *url = NULL;
1379 if (pp->url_format != URL_FORMAT_NONE)
1381 url = rule.make_url ();
1382 if (url)
1383 pp_begin_url (pp, url);
1385 pp_string (pp, desc);
1386 pp_set_prefix (context->printer, saved_prefix);
1387 if (pp->url_format != URL_FORMAT_NONE)
1388 if (url)
1389 pp_end_url (pp);
1390 free (url);
1391 pp_string (pp, colorize_stop (pp_show_color (pp)));
1392 pp_character (pp, ']');
1393 free (desc);
1398 /* Print any metadata about the option used to control DIAGNOSTIC to CONTEXT's
1399 printer, e.g. " [-Werror=uninitialized]".
1400 Subroutine of diagnostic_report_diagnostic. */
1402 static void
1403 print_option_information (diagnostic_context *context,
1404 const diagnostic_info *diagnostic,
1405 diagnostic_t orig_diag_kind)
1407 char *option_text;
1409 option_text = context->option_name (context, diagnostic->option_index,
1410 orig_diag_kind, diagnostic->kind);
1412 if (option_text)
1414 char *option_url = NULL;
1415 if (context->get_option_url
1416 && context->printer->url_format != URL_FORMAT_NONE)
1417 option_url = context->get_option_url (context,
1418 diagnostic->option_index);
1419 pretty_printer *pp = context->printer;
1420 pp_string (pp, " [");
1421 pp_string (pp, colorize_start (pp_show_color (pp),
1422 diagnostic_kind_color[diagnostic->kind]));
1423 if (option_url)
1424 pp_begin_url (pp, option_url);
1425 pp_string (pp, option_text);
1426 if (option_url)
1428 pp_end_url (pp);
1429 free (option_url);
1431 pp_string (pp, colorize_stop (pp_show_color (pp)));
1432 pp_character (pp, ']');
1433 free (option_text);
1437 /* Returns whether a DIAGNOSTIC should be printed, and adjusts diagnostic->kind
1438 as appropriate for #pragma GCC diagnostic and -Werror=foo. */
1440 static bool
1441 diagnostic_enabled (diagnostic_context *context,
1442 diagnostic_info *diagnostic)
1444 /* Update the inlining stack for this diagnostic. */
1445 get_any_inlining_info (context, diagnostic);
1447 /* Diagnostics with no option or -fpermissive are always enabled. */
1448 if (!diagnostic->option_index
1449 || diagnostic->option_index == permissive_error_option (context))
1450 return true;
1452 /* This tests if the user provided the appropriate -Wfoo or
1453 -Wno-foo option. */
1454 if (! context->option_enabled (diagnostic->option_index,
1455 context->lang_mask,
1456 context->option_state))
1457 return false;
1459 /* This tests for #pragma diagnostic changes. */
1460 diagnostic_t diag_class
1461 = update_effective_level_from_pragmas (context, diagnostic);
1463 /* This tests if the user provided the appropriate -Werror=foo
1464 option. */
1465 if (diag_class == DK_UNSPECIFIED
1466 && (context->classify_diagnostic[diagnostic->option_index]
1467 != DK_UNSPECIFIED))
1468 diagnostic->kind
1469 = context->classify_diagnostic[diagnostic->option_index];
1471 /* This allows for future extensions, like temporarily disabling
1472 warnings for ranges of source code. */
1473 if (diagnostic->kind == DK_IGNORED)
1474 return false;
1476 return true;
1479 /* Returns whether warning OPT is enabled at LOC. */
1481 bool
1482 warning_enabled_at (location_t loc, int opt)
1484 if (!diagnostic_report_warnings_p (global_dc, loc))
1485 return false;
1487 rich_location richloc (line_table, loc);
1488 diagnostic_info diagnostic = {};
1489 diagnostic.option_index = opt;
1490 diagnostic.richloc = &richloc;
1491 diagnostic.message.m_richloc = &richloc;
1492 diagnostic.kind = DK_WARNING;
1493 return diagnostic_enabled (global_dc, &diagnostic);
1496 /* Report a diagnostic message (an error or a warning) as specified by
1497 DC. This function is *the* subroutine in terms of which front-ends
1498 should implement their specific diagnostic handling modules. The
1499 front-end independent format specifiers are exactly those described
1500 in the documentation of output_format.
1501 Return true if a diagnostic was printed, false otherwise. */
1503 bool
1504 diagnostic_report_diagnostic (diagnostic_context *context,
1505 diagnostic_info *diagnostic)
1507 location_t location = diagnostic_location (diagnostic);
1508 diagnostic_t orig_diag_kind = diagnostic->kind;
1510 /* Give preference to being able to inhibit warnings, before they
1511 get reclassified to something else. */
1512 bool report_warning_p = true;
1513 if (diagnostic->kind == DK_WARNING || diagnostic->kind == DK_PEDWARN)
1515 if (context->dc_inhibit_warnings)
1516 return false;
1517 /* Remember the result of the overall system header warning setting
1518 but proceed to also check the inlining context. */
1519 report_warning_p = diagnostic_report_warnings_p (context, location);
1520 if (!report_warning_p && diagnostic->kind == DK_PEDWARN)
1521 return false;
1524 if (diagnostic->kind == DK_PEDWARN)
1526 diagnostic->kind = pedantic_warning_kind (context);
1527 /* We do this to avoid giving the message for -pedantic-errors. */
1528 orig_diag_kind = diagnostic->kind;
1531 if (diagnostic->kind == DK_NOTE && context->inhibit_notes_p)
1532 return false;
1534 if (context->lock > 0)
1536 /* If we're reporting an ICE in the middle of some other error,
1537 try to flush out the previous error, then let this one
1538 through. Don't do this more than once. */
1539 if ((diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT)
1540 && context->lock == 1)
1541 pp_newline_and_flush (context->printer);
1542 else
1543 error_recursion (context);
1546 /* If the user requested that warnings be treated as errors, so be
1547 it. Note that we do this before the next block so that
1548 individual warnings can be overridden back to warnings with
1549 -Wno-error=*. */
1550 if (context->warning_as_error_requested
1551 && diagnostic->kind == DK_WARNING)
1552 diagnostic->kind = DK_ERROR;
1554 diagnostic->message.x_data = &diagnostic->x_data;
1556 /* Check to see if the diagnostic is enabled at the location and
1557 not disabled by #pragma GCC diagnostic anywhere along the inlining
1558 stack. . */
1559 if (!diagnostic_enabled (context, diagnostic))
1560 return false;
1562 if (!report_warning_p && diagnostic->m_iinfo.m_allsyslocs)
1563 /* Bail if the warning is not to be reported because all locations
1564 in the inlining stack (if there is one) are in system headers. */
1565 return false;
1567 if (diagnostic->kind != DK_NOTE && diagnostic->kind != DK_ICE)
1568 diagnostic_check_max_errors (context);
1570 context->lock++;
1572 if (diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT)
1574 /* When not checking, ICEs are converted to fatal errors when an
1575 error has already occurred. This is counteracted by
1576 abort_on_error. */
1577 if (!CHECKING_P
1578 && (diagnostic_kind_count (context, DK_ERROR) > 0
1579 || diagnostic_kind_count (context, DK_SORRY) > 0)
1580 && !context->abort_on_error)
1582 expanded_location s
1583 = expand_location (diagnostic_location (diagnostic));
1584 fnotice (stderr, "%s:%d: confused by earlier errors, bailing out\n",
1585 s.file, s.line);
1586 exit (ICE_EXIT_CODE);
1588 if (context->internal_error)
1589 (*context->internal_error) (context,
1590 diagnostic->message.format_spec,
1591 diagnostic->message.args_ptr);
1593 if (diagnostic->kind == DK_ERROR && orig_diag_kind == DK_WARNING)
1594 ++diagnostic_kind_count (context, DK_WERROR);
1595 else
1596 ++diagnostic_kind_count (context, diagnostic->kind);
1598 /* Is this the initial diagnostic within the stack of groups? */
1599 if (context->diagnostic_group_emission_count == 0)
1601 if (context->begin_group_cb)
1602 context->begin_group_cb (context);
1604 context->diagnostic_group_emission_count++;
1606 pp_format (context->printer, &diagnostic->message);
1607 (*diagnostic_starter (context)) (context, diagnostic);
1608 pp_output_formatted_text (context->printer);
1609 if (context->show_cwe)
1610 print_any_cwe (context, diagnostic);
1611 if (context->show_rules)
1612 print_any_rules (context, diagnostic);
1613 if (context->show_option_requested)
1614 print_option_information (context, diagnostic, orig_diag_kind);
1615 (*diagnostic_finalizer (context)) (context, diagnostic, orig_diag_kind);
1616 switch (context->extra_output_kind)
1618 default:
1619 break;
1620 case EXTRA_DIAGNOSTIC_OUTPUT_fixits_v1:
1621 print_parseable_fixits (context->printer, diagnostic->richloc,
1622 DIAGNOSTICS_COLUMN_UNIT_BYTE,
1623 context->tabstop);
1624 pp_flush (context->printer);
1625 break;
1626 case EXTRA_DIAGNOSTIC_OUTPUT_fixits_v2:
1627 print_parseable_fixits (context->printer, diagnostic->richloc,
1628 DIAGNOSTICS_COLUMN_UNIT_DISPLAY,
1629 context->tabstop);
1630 pp_flush (context->printer);
1631 break;
1633 diagnostic_action_after_output (context, diagnostic->kind);
1634 diagnostic->x_data = NULL;
1636 if (context->edit_context_ptr)
1637 if (diagnostic->richloc->fixits_can_be_auto_applied_p ())
1638 context->edit_context_ptr->add_fixits (diagnostic->richloc);
1640 context->lock--;
1642 diagnostic_show_any_path (context, diagnostic);
1644 return true;
1647 /* Get the number of digits in the decimal representation of VALUE. */
1650 num_digits (int value)
1652 /* Perhaps simpler to use log10 for this, but doing it this way avoids
1653 using floating point. */
1654 gcc_assert (value >= 0);
1656 if (value == 0)
1657 return 1;
1659 int digits = 0;
1660 while (value > 0)
1662 digits++;
1663 value /= 10;
1665 return digits;
1668 /* Given a partial pathname as input, return another pathname that
1669 shares no directory elements with the pathname of __FILE__. This
1670 is used by fancy_abort() to print `internal compiler error in expr.cc'
1671 instead of `internal compiler error in ../../GCC/gcc/expr.cc'. */
1673 const char *
1674 trim_filename (const char *name)
1676 static const char this_file[] = __FILE__;
1677 const char *p = name, *q = this_file;
1679 /* First skip any "../" in each filename. This allows us to give a proper
1680 reference to a file in a subdirectory. */
1681 while (p[0] == '.' && p[1] == '.' && IS_DIR_SEPARATOR (p[2]))
1682 p += 3;
1684 while (q[0] == '.' && q[1] == '.' && IS_DIR_SEPARATOR (q[2]))
1685 q += 3;
1687 /* Now skip any parts the two filenames have in common. */
1688 while (*p == *q && *p != 0 && *q != 0)
1689 p++, q++;
1691 /* Now go backwards until the previous directory separator. */
1692 while (p > name && !IS_DIR_SEPARATOR (p[-1]))
1693 p--;
1695 return p;
1698 /* Standard error reporting routines in increasing order of severity.
1699 All of these take arguments like printf. */
1701 /* Text to be emitted verbatim to the error message stream; this
1702 produces no prefix and disables line-wrapping. Use rarely. */
1703 void
1704 verbatim (const char *gmsgid, ...)
1706 text_info text;
1707 va_list ap;
1709 va_start (ap, gmsgid);
1710 text.err_no = errno;
1711 text.args_ptr = &ap;
1712 text.format_spec = _(gmsgid);
1713 text.x_data = NULL;
1714 pp_format_verbatim (global_dc->printer, &text);
1715 pp_newline_and_flush (global_dc->printer);
1716 va_end (ap);
1719 /* Add a note with text GMSGID and with LOCATION to the diagnostic CONTEXT. */
1720 void
1721 diagnostic_append_note (diagnostic_context *context,
1722 location_t location,
1723 const char * gmsgid, ...)
1725 diagnostic_info diagnostic;
1726 va_list ap;
1727 rich_location richloc (line_table, location);
1729 va_start (ap, gmsgid);
1730 diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_NOTE);
1731 if (context->inhibit_notes_p)
1733 va_end (ap);
1734 return;
1736 char *saved_prefix = pp_take_prefix (context->printer);
1737 pp_set_prefix (context->printer,
1738 diagnostic_build_prefix (context, &diagnostic));
1739 pp_format (context->printer, &diagnostic.message);
1740 pp_output_formatted_text (context->printer);
1741 pp_destroy_prefix (context->printer);
1742 pp_set_prefix (context->printer, saved_prefix);
1743 pp_newline (context->printer);
1744 diagnostic_show_locus (context, &richloc, DK_NOTE);
1745 va_end (ap);
1748 /* Implement emit_diagnostic, inform, warning, warning_at, pedwarn,
1749 permerror, error, error_at, error_at, sorry, fatal_error, internal_error,
1750 and internal_error_no_backtrace, as documented and defined below. */
1751 static bool
1752 diagnostic_impl (rich_location *richloc, const diagnostic_metadata *metadata,
1753 int opt, const char *gmsgid,
1754 va_list *ap, diagnostic_t kind)
1756 diagnostic_info diagnostic;
1757 if (kind == DK_PERMERROR)
1759 diagnostic_set_info (&diagnostic, gmsgid, ap, richloc,
1760 permissive_error_kind (global_dc));
1761 diagnostic.option_index = permissive_error_option (global_dc);
1763 else
1765 diagnostic_set_info (&diagnostic, gmsgid, ap, richloc, kind);
1766 if (kind == DK_WARNING || kind == DK_PEDWARN)
1767 diagnostic.option_index = opt;
1769 diagnostic.metadata = metadata;
1770 return diagnostic_report_diagnostic (global_dc, &diagnostic);
1773 /* Implement inform_n, warning_n, and error_n, as documented and
1774 defined below. */
1775 static bool
1776 diagnostic_n_impl (rich_location *richloc, const diagnostic_metadata *metadata,
1777 int opt, unsigned HOST_WIDE_INT n,
1778 const char *singular_gmsgid,
1779 const char *plural_gmsgid,
1780 va_list *ap, diagnostic_t kind)
1782 diagnostic_info diagnostic;
1783 unsigned long gtn;
1785 if (sizeof n <= sizeof gtn)
1786 gtn = n;
1787 else
1788 /* Use the largest number ngettext can handle, otherwise
1789 preserve the six least significant decimal digits for
1790 languages where the plural form depends on them. */
1791 gtn = n <= ULONG_MAX ? n : n % 1000000LU + 1000000LU;
1793 const char *text = ngettext (singular_gmsgid, plural_gmsgid, gtn);
1794 diagnostic_set_info_translated (&diagnostic, text, ap, richloc, kind);
1795 if (kind == DK_WARNING)
1796 diagnostic.option_index = opt;
1797 diagnostic.metadata = metadata;
1798 return diagnostic_report_diagnostic (global_dc, &diagnostic);
1801 /* Wrapper around diagnostic_impl taking a variable argument list. */
1803 bool
1804 emit_diagnostic (diagnostic_t kind, location_t location, int opt,
1805 const char *gmsgid, ...)
1807 auto_diagnostic_group d;
1808 va_list ap;
1809 va_start (ap, gmsgid);
1810 rich_location richloc (line_table, location);
1811 bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, kind);
1812 va_end (ap);
1813 return ret;
1816 /* As above, but for rich_location *. */
1818 bool
1819 emit_diagnostic (diagnostic_t kind, rich_location *richloc, int opt,
1820 const char *gmsgid, ...)
1822 auto_diagnostic_group d;
1823 va_list ap;
1824 va_start (ap, gmsgid);
1825 bool ret = diagnostic_impl (richloc, NULL, opt, gmsgid, &ap, kind);
1826 va_end (ap);
1827 return ret;
1830 /* Wrapper around diagnostic_impl taking a va_list parameter. */
1832 bool
1833 emit_diagnostic_valist (diagnostic_t kind, location_t location, int opt,
1834 const char *gmsgid, va_list *ap)
1836 rich_location richloc (line_table, location);
1837 return diagnostic_impl (&richloc, NULL, opt, gmsgid, ap, kind);
1840 /* An informative note at LOCATION. Use this for additional details on an error
1841 message. */
1842 void
1843 inform (location_t location, const char *gmsgid, ...)
1845 auto_diagnostic_group d;
1846 va_list ap;
1847 va_start (ap, gmsgid);
1848 rich_location richloc (line_table, location);
1849 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_NOTE);
1850 va_end (ap);
1853 /* Same as "inform" above, but at RICHLOC. */
1854 void
1855 inform (rich_location *richloc, const char *gmsgid, ...)
1857 gcc_assert (richloc);
1859 auto_diagnostic_group d;
1860 va_list ap;
1861 va_start (ap, gmsgid);
1862 diagnostic_impl (richloc, NULL, -1, gmsgid, &ap, DK_NOTE);
1863 va_end (ap);
1866 /* An informative note at LOCATION. Use this for additional details on an
1867 error message. */
1868 void
1869 inform_n (location_t location, unsigned HOST_WIDE_INT n,
1870 const char *singular_gmsgid, const char *plural_gmsgid, ...)
1872 va_list ap;
1873 va_start (ap, plural_gmsgid);
1874 auto_diagnostic_group d;
1875 rich_location richloc (line_table, location);
1876 diagnostic_n_impl (&richloc, NULL, -1, n, singular_gmsgid, plural_gmsgid,
1877 &ap, DK_NOTE);
1878 va_end (ap);
1881 /* A warning at INPUT_LOCATION. Use this for code which is correct according
1882 to the relevant language specification but is likely to be buggy anyway.
1883 Returns true if the warning was printed, false if it was inhibited. */
1884 bool
1885 warning (int opt, const char *gmsgid, ...)
1887 auto_diagnostic_group d;
1888 va_list ap;
1889 va_start (ap, gmsgid);
1890 rich_location richloc (line_table, input_location);
1891 bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, DK_WARNING);
1892 va_end (ap);
1893 return ret;
1896 /* A warning at LOCATION. Use this for code which is correct according to the
1897 relevant language specification but is likely to be buggy anyway.
1898 Returns true if the warning was printed, false if it was inhibited. */
1900 bool
1901 warning_at (location_t location, int opt, const char *gmsgid, ...)
1903 auto_diagnostic_group d;
1904 va_list ap;
1905 va_start (ap, gmsgid);
1906 rich_location richloc (line_table, location);
1907 bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, DK_WARNING);
1908 va_end (ap);
1909 return ret;
1912 /* Same as "warning at" above, but using RICHLOC. */
1914 bool
1915 warning_at (rich_location *richloc, int opt, const char *gmsgid, ...)
1917 gcc_assert (richloc);
1919 auto_diagnostic_group d;
1920 va_list ap;
1921 va_start (ap, gmsgid);
1922 bool ret = diagnostic_impl (richloc, NULL, opt, gmsgid, &ap, DK_WARNING);
1923 va_end (ap);
1924 return ret;
1927 /* Same as "warning at" above, but using METADATA. */
1929 bool
1930 warning_meta (rich_location *richloc,
1931 const diagnostic_metadata &metadata,
1932 int opt, const char *gmsgid, ...)
1934 gcc_assert (richloc);
1936 auto_diagnostic_group d;
1937 va_list ap;
1938 va_start (ap, gmsgid);
1939 bool ret
1940 = diagnostic_impl (richloc, &metadata, opt, gmsgid, &ap,
1941 DK_WARNING);
1942 va_end (ap);
1943 return ret;
1946 /* Same as warning_n plural variant below, but using RICHLOC. */
1948 bool
1949 warning_n (rich_location *richloc, int opt, unsigned HOST_WIDE_INT n,
1950 const char *singular_gmsgid, const char *plural_gmsgid, ...)
1952 gcc_assert (richloc);
1954 auto_diagnostic_group d;
1955 va_list ap;
1956 va_start (ap, plural_gmsgid);
1957 bool ret = diagnostic_n_impl (richloc, NULL, opt, n,
1958 singular_gmsgid, plural_gmsgid,
1959 &ap, DK_WARNING);
1960 va_end (ap);
1961 return ret;
1964 /* A warning at LOCATION. Use this for code which is correct according to the
1965 relevant language specification but is likely to be buggy anyway.
1966 Returns true if the warning was printed, false if it was inhibited. */
1968 bool
1969 warning_n (location_t location, int opt, unsigned HOST_WIDE_INT n,
1970 const char *singular_gmsgid, const char *plural_gmsgid, ...)
1972 auto_diagnostic_group d;
1973 va_list ap;
1974 va_start (ap, plural_gmsgid);
1975 rich_location richloc (line_table, location);
1976 bool ret = diagnostic_n_impl (&richloc, NULL, opt, n,
1977 singular_gmsgid, plural_gmsgid,
1978 &ap, DK_WARNING);
1979 va_end (ap);
1980 return ret;
1983 /* A "pedantic" warning at LOCATION: issues a warning unless
1984 -pedantic-errors was given on the command line, in which case it
1985 issues an error. Use this for diagnostics required by the relevant
1986 language standard, if you have chosen not to make them errors.
1988 Note that these diagnostics are issued independent of the setting
1989 of the -Wpedantic command-line switch. To get a warning enabled
1990 only with that switch, use either "if (pedantic) pedwarn
1991 (OPT_Wpedantic,...)" or just "pedwarn (OPT_Wpedantic,..)". To get a
1992 pedwarn independently of the -Wpedantic switch use "pedwarn (0,...)".
1994 Returns true if the warning was printed, false if it was inhibited. */
1996 bool
1997 pedwarn (location_t location, int opt, const char *gmsgid, ...)
1999 auto_diagnostic_group d;
2000 va_list ap;
2001 va_start (ap, gmsgid);
2002 rich_location richloc (line_table, location);
2003 bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, DK_PEDWARN);
2004 va_end (ap);
2005 return ret;
2008 /* Same as pedwarn above, but using RICHLOC. */
2010 bool
2011 pedwarn (rich_location *richloc, int opt, const char *gmsgid, ...)
2013 gcc_assert (richloc);
2015 auto_diagnostic_group d;
2016 va_list ap;
2017 va_start (ap, gmsgid);
2018 bool ret = diagnostic_impl (richloc, NULL, opt, gmsgid, &ap, DK_PEDWARN);
2019 va_end (ap);
2020 return ret;
2023 /* A "permissive" error at LOCATION: issues an error unless
2024 -fpermissive was given on the command line, in which case it issues
2025 a warning. Use this for things that really should be errors but we
2026 want to support legacy code.
2028 Returns true if the warning was printed, false if it was inhibited. */
2030 bool
2031 permerror (location_t location, const char *gmsgid, ...)
2033 auto_diagnostic_group d;
2034 va_list ap;
2035 va_start (ap, gmsgid);
2036 rich_location richloc (line_table, location);
2037 bool ret = diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_PERMERROR);
2038 va_end (ap);
2039 return ret;
2042 /* Same as "permerror" above, but at RICHLOC. */
2044 bool
2045 permerror (rich_location *richloc, const char *gmsgid, ...)
2047 gcc_assert (richloc);
2049 auto_diagnostic_group d;
2050 va_list ap;
2051 va_start (ap, gmsgid);
2052 bool ret = diagnostic_impl (richloc, NULL, -1, gmsgid, &ap, DK_PERMERROR);
2053 va_end (ap);
2054 return ret;
2057 /* A hard error: the code is definitely ill-formed, and an object file
2058 will not be produced. */
2059 void
2060 error (const char *gmsgid, ...)
2062 auto_diagnostic_group d;
2063 va_list ap;
2064 va_start (ap, gmsgid);
2065 rich_location richloc (line_table, input_location);
2066 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ERROR);
2067 va_end (ap);
2070 /* A hard error: the code is definitely ill-formed, and an object file
2071 will not be produced. */
2072 void
2073 error_n (location_t location, unsigned HOST_WIDE_INT n,
2074 const char *singular_gmsgid, const char *plural_gmsgid, ...)
2076 auto_diagnostic_group d;
2077 va_list ap;
2078 va_start (ap, plural_gmsgid);
2079 rich_location richloc (line_table, location);
2080 diagnostic_n_impl (&richloc, NULL, -1, n, singular_gmsgid, plural_gmsgid,
2081 &ap, DK_ERROR);
2082 va_end (ap);
2085 /* Same as above, but use location LOC instead of input_location. */
2086 void
2087 error_at (location_t loc, const char *gmsgid, ...)
2089 auto_diagnostic_group d;
2090 va_list ap;
2091 va_start (ap, gmsgid);
2092 rich_location richloc (line_table, loc);
2093 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ERROR);
2094 va_end (ap);
2097 /* Same as above, but use RICH_LOC. */
2099 void
2100 error_at (rich_location *richloc, const char *gmsgid, ...)
2102 gcc_assert (richloc);
2104 auto_diagnostic_group d;
2105 va_list ap;
2106 va_start (ap, gmsgid);
2107 diagnostic_impl (richloc, NULL, -1, gmsgid, &ap, DK_ERROR);
2108 va_end (ap);
2111 /* "Sorry, not implemented." Use for a language feature which is
2112 required by the relevant specification but not implemented by GCC.
2113 An object file will not be produced. */
2114 void
2115 sorry (const char *gmsgid, ...)
2117 auto_diagnostic_group d;
2118 va_list ap;
2119 va_start (ap, gmsgid);
2120 rich_location richloc (line_table, input_location);
2121 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_SORRY);
2122 va_end (ap);
2125 /* Same as above, but use location LOC instead of input_location. */
2126 void
2127 sorry_at (location_t loc, const char *gmsgid, ...)
2129 auto_diagnostic_group d;
2130 va_list ap;
2131 va_start (ap, gmsgid);
2132 rich_location richloc (line_table, loc);
2133 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_SORRY);
2134 va_end (ap);
2137 /* Return true if an error or a "sorry" has been seen. Various
2138 processing is disabled after errors. */
2139 bool
2140 seen_error (void)
2142 return errorcount || sorrycount;
2145 /* An error which is severe enough that we make no attempt to
2146 continue. Do not use this for internal consistency checks; that's
2147 internal_error. Use of this function should be rare. */
2148 void
2149 fatal_error (location_t loc, const char *gmsgid, ...)
2151 auto_diagnostic_group d;
2152 va_list ap;
2153 va_start (ap, gmsgid);
2154 rich_location richloc (line_table, loc);
2155 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_FATAL);
2156 va_end (ap);
2158 gcc_unreachable ();
2161 /* An internal consistency check has failed. We make no attempt to
2162 continue. */
2163 void
2164 internal_error (const char *gmsgid, ...)
2166 auto_diagnostic_group d;
2167 va_list ap;
2168 va_start (ap, gmsgid);
2169 rich_location richloc (line_table, input_location);
2170 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ICE);
2171 va_end (ap);
2173 gcc_unreachable ();
2176 /* Like internal_error, but no backtrace will be printed. Used when
2177 the internal error does not happen at the current location, but happened
2178 somewhere else. */
2179 void
2180 internal_error_no_backtrace (const char *gmsgid, ...)
2182 auto_diagnostic_group d;
2183 va_list ap;
2184 va_start (ap, gmsgid);
2185 rich_location richloc (line_table, input_location);
2186 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ICE_NOBT);
2187 va_end (ap);
2189 gcc_unreachable ();
2192 /* Emit DIAGRAM to CONTEXT, respecting the output format. */
2194 void
2195 diagnostic_emit_diagram (diagnostic_context *context,
2196 const diagnostic_diagram &diagram)
2198 if (context->m_diagrams.m_theme == nullptr)
2199 return;
2201 if (context->m_diagrams.m_emission_cb)
2203 context->m_diagrams.m_emission_cb (context, diagram);
2204 return;
2207 /* Default implementation. */
2208 char *saved_prefix = pp_take_prefix (context->printer);
2209 pp_set_prefix (context->printer, NULL);
2210 /* Use a newline before and after and a two-space indent
2211 to make the diagram stand out a little from the wall of text. */
2212 pp_newline (context->printer);
2213 diagram.get_canvas ().print_to_pp (context->printer, " ");
2214 pp_newline (context->printer);
2215 pp_set_prefix (context->printer, saved_prefix);
2216 pp_flush (context->printer);
2219 /* Special case error functions. Most are implemented in terms of the
2220 above, or should be. */
2222 /* Print a diagnostic MSGID on FILE. This is just fprintf, except it
2223 runs its second argument through gettext. */
2224 void
2225 fnotice (FILE *file, const char *cmsgid, ...)
2227 va_list ap;
2229 va_start (ap, cmsgid);
2230 vfprintf (file, _(cmsgid), ap);
2231 va_end (ap);
2234 /* Inform the user that an error occurred while trying to report some
2235 other error. This indicates catastrophic internal inconsistencies,
2236 so give up now. But do try to flush out the previous error.
2237 This mustn't use internal_error, that will cause infinite recursion. */
2239 static void
2240 error_recursion (diagnostic_context *context)
2242 if (context->lock < 3)
2243 pp_newline_and_flush (context->printer);
2245 fnotice (stderr,
2246 "internal compiler error: error reporting routines re-entered.\n");
2248 /* Call diagnostic_action_after_output to get the "please submit a bug
2249 report" message. */
2250 diagnostic_action_after_output (context, DK_ICE);
2252 /* Do not use gcc_unreachable here; that goes through internal_error
2253 and therefore would cause infinite recursion. */
2254 real_abort ();
2257 /* Report an internal compiler error in a friendly manner. This is
2258 the function that gets called upon use of abort() in the source
2259 code generally, thanks to a special macro. */
2261 void
2262 fancy_abort (const char *file, int line, const char *function)
2264 /* If fancy_abort is called before the diagnostic subsystem is initialized,
2265 internal_error will crash internally in a way that prevents a
2266 useful message reaching the user.
2267 This can happen with libgccjit in the case of gcc_assert failures
2268 that occur outside of the libgccjit mutex that guards the rest of
2269 gcc's state, including global_dc (when global_dc may not be
2270 initialized yet, or might be in use by another thread).
2271 Handle such cases as gracefully as possible by falling back to a
2272 minimal abort handler that only relies on i18n. */
2273 if (global_dc->printer == NULL)
2275 /* Print the error message. */
2276 fnotice (stderr, diagnostic_kind_text[DK_ICE]);
2277 fnotice (stderr, "in %s, at %s:%d", function, trim_filename (file), line);
2278 fputc ('\n', stderr);
2280 /* Attempt to print a backtrace. */
2281 struct backtrace_state *state
2282 = backtrace_create_state (NULL, 0, bt_err_callback, NULL);
2283 int count = 0;
2284 if (state != NULL)
2285 backtrace_full (state, 2, bt_callback, bt_err_callback,
2286 (void *) &count);
2288 /* We can't call warn_if_plugins or emergency_dump_function as these
2289 rely on GCC state that might not be initialized, or might be in
2290 use by another thread. */
2292 /* Abort the process. */
2293 real_abort ();
2296 internal_error ("in %s, at %s:%d", function, trim_filename (file), line);
2299 /* class auto_diagnostic_group. */
2301 /* Constructor: "push" this group into global_dc. */
2303 auto_diagnostic_group::auto_diagnostic_group ()
2305 global_dc->diagnostic_group_nesting_depth++;
2308 /* Destructor: "pop" this group from global_dc. */
2310 auto_diagnostic_group::~auto_diagnostic_group ()
2312 if (--global_dc->diagnostic_group_nesting_depth == 0)
2314 /* Handle the case where we've popped the final diagnostic group.
2315 If any diagnostics were emitted, give the context a chance
2316 to do something. */
2317 if (global_dc->diagnostic_group_emission_count > 0)
2319 if (global_dc->end_group_cb)
2320 global_dc->end_group_cb (global_dc);
2322 global_dc->diagnostic_group_emission_count = 0;
2326 /* Set the output format for CONTEXT to FORMAT, using BASE_FILE_NAME for
2327 file-based output formats. */
2329 void
2330 diagnostic_output_format_init (diagnostic_context *context,
2331 const char *base_file_name,
2332 enum diagnostics_output_format format)
2334 switch (format)
2336 default:
2337 gcc_unreachable ();
2338 case DIAGNOSTICS_OUTPUT_FORMAT_TEXT:
2339 /* The default; do nothing. */
2340 break;
2342 case DIAGNOSTICS_OUTPUT_FORMAT_JSON_STDERR:
2343 diagnostic_output_format_init_json_stderr (context);
2344 break;
2346 case DIAGNOSTICS_OUTPUT_FORMAT_JSON_FILE:
2347 diagnostic_output_format_init_json_file (context, base_file_name);
2348 break;
2350 case DIAGNOSTICS_OUTPUT_FORMAT_SARIF_STDERR:
2351 diagnostic_output_format_init_sarif_stderr (context);
2352 break;
2354 case DIAGNOSTICS_OUTPUT_FORMAT_SARIF_FILE:
2355 diagnostic_output_format_init_sarif_file (context, base_file_name);
2356 break;
2360 /* Initialize CONTEXT->m_diagrams based on CHARSET.
2361 Specifically, make a text_art::theme object for m_diagrams.m_theme,
2362 (or NULL for "no diagrams"). */
2364 void
2365 diagnostics_text_art_charset_init (diagnostic_context *context,
2366 enum diagnostic_text_art_charset charset)
2368 delete context->m_diagrams.m_theme;
2369 switch (charset)
2371 default:
2372 gcc_unreachable ();
2374 case DIAGNOSTICS_TEXT_ART_CHARSET_NONE:
2375 context->m_diagrams.m_theme = NULL;
2376 break;
2378 case DIAGNOSTICS_TEXT_ART_CHARSET_ASCII:
2379 context->m_diagrams.m_theme = new text_art::ascii_theme ();
2380 break;
2382 case DIAGNOSTICS_TEXT_ART_CHARSET_UNICODE:
2383 context->m_diagrams.m_theme = new text_art::unicode_theme ();
2384 break;
2386 case DIAGNOSTICS_TEXT_ART_CHARSET_EMOJI:
2387 context->m_diagrams.m_theme = new text_art::emoji_theme ();
2388 break;
2392 /* Implementation of diagnostic_path::num_events vfunc for
2393 simple_diagnostic_path: simply get the number of events in the vec. */
2395 unsigned
2396 simple_diagnostic_path::num_events () const
2398 return m_events.length ();
2401 /* Implementation of diagnostic_path::get_event vfunc for
2402 simple_diagnostic_path: simply return the event in the vec. */
2404 const diagnostic_event &
2405 simple_diagnostic_path::get_event (int idx) const
2407 return *m_events[idx];
2410 /* Add an event to this path at LOC within function FNDECL at
2411 stack depth DEPTH.
2413 Use m_context's printer to format FMT, as the text of the new
2414 event.
2416 Return the id of the new event. */
2418 diagnostic_event_id_t
2419 simple_diagnostic_path::add_event (location_t loc, tree fndecl, int depth,
2420 const char *fmt, ...)
2422 pretty_printer *pp = m_event_pp;
2423 pp_clear_output_area (pp);
2425 text_info ti;
2426 rich_location rich_loc (line_table, UNKNOWN_LOCATION);
2428 va_list ap;
2430 va_start (ap, fmt);
2432 ti.format_spec = _(fmt);
2433 ti.args_ptr = &ap;
2434 ti.err_no = 0;
2435 ti.x_data = NULL;
2436 ti.m_richloc = &rich_loc;
2438 pp_format (pp, &ti);
2439 pp_output_formatted_text (pp);
2441 va_end (ap);
2443 simple_diagnostic_event *new_event
2444 = new simple_diagnostic_event (loc, fndecl, depth, pp_formatted_text (pp));
2445 m_events.safe_push (new_event);
2447 pp_clear_output_area (pp);
2449 return diagnostic_event_id_t (m_events.length () - 1);
2452 /* struct simple_diagnostic_event. */
2454 /* simple_diagnostic_event's ctor. */
2456 simple_diagnostic_event::simple_diagnostic_event (location_t loc,
2457 tree fndecl,
2458 int depth,
2459 const char *desc)
2460 : m_loc (loc), m_fndecl (fndecl), m_depth (depth), m_desc (xstrdup (desc))
2464 /* simple_diagnostic_event's dtor. */
2466 simple_diagnostic_event::~simple_diagnostic_event ()
2468 free (m_desc);
2471 /* Print PATH by emitting a dummy "note" associated with it. */
2473 DEBUG_FUNCTION
2474 void debug (diagnostic_path *path)
2476 rich_location richloc (line_table, UNKNOWN_LOCATION);
2477 richloc.set_path (path);
2478 inform (&richloc, "debug path");
2481 /* Really call the system 'abort'. This has to go right at the end of
2482 this file, so that there are no functions after it that call abort
2483 and get the system abort instead of our macro. */
2484 #undef abort
2485 static void
2486 real_abort (void)
2488 abort ();
2491 #if CHECKING_P
2493 namespace selftest {
2495 /* Helper function for test_print_escaped_string. */
2497 static void
2498 assert_print_escaped_string (const location &loc, const char *expected_output,
2499 const char *input)
2501 pretty_printer pp;
2502 print_escaped_string (&pp, input);
2503 ASSERT_STREQ_AT (loc, expected_output, pp_formatted_text (&pp));
2506 #define ASSERT_PRINT_ESCAPED_STRING_STREQ(EXPECTED_OUTPUT, INPUT) \
2507 assert_print_escaped_string (SELFTEST_LOCATION, EXPECTED_OUTPUT, INPUT)
2509 /* Tests of print_escaped_string. */
2511 static void
2512 test_print_escaped_string ()
2514 /* Empty string. */
2515 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"\"", "");
2517 /* Non-empty string. */
2518 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"hello world\"", "hello world");
2520 /* Various things that need to be escaped: */
2521 /* Backslash. */
2522 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\\\after\"",
2523 "before\\after");
2524 /* Tab. */
2525 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\tafter\"",
2526 "before\tafter");
2527 /* Newline. */
2528 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\nafter\"",
2529 "before\nafter");
2530 /* Double quote. */
2531 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\\"after\"",
2532 "before\"after");
2534 /* Non-printable characters: BEL: '\a': 0x07 */
2535 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\007after\"",
2536 "before\aafter");
2537 /* Non-printable characters: vertical tab: '\v': 0x0b */
2538 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\013after\"",
2539 "before\vafter");
2542 /* Tests of print_parseable_fixits. */
2544 /* Verify that print_parseable_fixits emits the empty string if there
2545 are no fixits. */
2547 static void
2548 test_print_parseable_fixits_none ()
2550 pretty_printer pp;
2551 rich_location richloc (line_table, UNKNOWN_LOCATION);
2553 print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_BYTE, 8);
2554 ASSERT_STREQ ("", pp_formatted_text (&pp));
2557 /* Verify that print_parseable_fixits does the right thing if there
2558 is an insertion fixit hint. */
2560 static void
2561 test_print_parseable_fixits_insert ()
2563 pretty_printer pp;
2564 rich_location richloc (line_table, UNKNOWN_LOCATION);
2566 linemap_add (line_table, LC_ENTER, false, "test.c", 0);
2567 linemap_line_start (line_table, 5, 100);
2568 linemap_add (line_table, LC_LEAVE, false, NULL, 0);
2569 location_t where = linemap_position_for_column (line_table, 10);
2570 richloc.add_fixit_insert_before (where, "added content");
2572 print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_BYTE, 8);
2573 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:10}:\"added content\"\n",
2574 pp_formatted_text (&pp));
2577 /* Verify that print_parseable_fixits does the right thing if there
2578 is an removal fixit hint. */
2580 static void
2581 test_print_parseable_fixits_remove ()
2583 pretty_printer pp;
2584 rich_location richloc (line_table, UNKNOWN_LOCATION);
2586 linemap_add (line_table, LC_ENTER, false, "test.c", 0);
2587 linemap_line_start (line_table, 5, 100);
2588 linemap_add (line_table, LC_LEAVE, false, NULL, 0);
2589 source_range where;
2590 where.m_start = linemap_position_for_column (line_table, 10);
2591 where.m_finish = linemap_position_for_column (line_table, 20);
2592 richloc.add_fixit_remove (where);
2594 print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_BYTE, 8);
2595 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:21}:\"\"\n",
2596 pp_formatted_text (&pp));
2599 /* Verify that print_parseable_fixits does the right thing if there
2600 is an replacement fixit hint. */
2602 static void
2603 test_print_parseable_fixits_replace ()
2605 pretty_printer pp;
2606 rich_location richloc (line_table, UNKNOWN_LOCATION);
2608 linemap_add (line_table, LC_ENTER, false, "test.c", 0);
2609 linemap_line_start (line_table, 5, 100);
2610 linemap_add (line_table, LC_LEAVE, false, NULL, 0);
2611 source_range where;
2612 where.m_start = linemap_position_for_column (line_table, 10);
2613 where.m_finish = linemap_position_for_column (line_table, 20);
2614 richloc.add_fixit_replace (where, "replacement");
2616 print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_BYTE, 8);
2617 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:21}:\"replacement\"\n",
2618 pp_formatted_text (&pp));
2621 /* Verify that print_parseable_fixits correctly handles
2622 DIAGNOSTICS_COLUMN_UNIT_BYTE vs DIAGNOSTICS_COLUMN_UNIT_COLUMN. */
2624 static void
2625 test_print_parseable_fixits_bytes_vs_display_columns ()
2627 line_table_test ltt;
2628 rich_location richloc (line_table, UNKNOWN_LOCATION);
2630 /* 1-based byte offsets: 12345677778888999900001234567. */
2631 const char *const content = "smile \xf0\x9f\x98\x82 colour\n";
2632 /* 1-based display cols: 123456[......7-8.....]9012345. */
2633 const int tabstop = 8;
2635 temp_source_file tmp (SELFTEST_LOCATION, ".c", content);
2636 const char *const fname = tmp.get_filename ();
2638 linemap_add (line_table, LC_ENTER, false, fname, 0);
2639 linemap_line_start (line_table, 1, 100);
2640 linemap_add (line_table, LC_LEAVE, false, NULL, 0);
2641 source_range where;
2642 where.m_start = linemap_position_for_column (line_table, 12);
2643 where.m_finish = linemap_position_for_column (line_table, 17);
2644 richloc.add_fixit_replace (where, "color");
2646 /* Escape fname. */
2647 pretty_printer tmp_pp;
2648 print_escaped_string (&tmp_pp, fname);
2649 char *escaped_fname = xstrdup (pp_formatted_text (&tmp_pp));
2651 const int buf_len = strlen (escaped_fname) + 100;
2652 char *const expected = XNEWVEC (char, buf_len);
2655 pretty_printer pp;
2656 print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_BYTE,
2657 tabstop);
2658 snprintf (expected, buf_len,
2659 "fix-it:%s:{1:12-1:18}:\"color\"\n", escaped_fname);
2660 ASSERT_STREQ (expected, pp_formatted_text (&pp));
2663 pretty_printer pp;
2664 print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_DISPLAY,
2665 tabstop);
2666 snprintf (expected, buf_len,
2667 "fix-it:%s:{1:10-1:16}:\"color\"\n", escaped_fname);
2668 ASSERT_STREQ (expected, pp_formatted_text (&pp));
2671 XDELETEVEC (expected);
2672 free (escaped_fname);
2675 /* Verify that
2676 diagnostic_get_location_text (..., SHOW_COLUMN)
2677 generates EXPECTED_LOC_TEXT, given FILENAME, LINE, COLUMN, with
2678 colorization disabled. */
2680 static void
2681 assert_location_text (const char *expected_loc_text,
2682 const char *filename, int line, int column,
2683 bool show_column,
2684 int origin = 1,
2685 enum diagnostics_column_unit column_unit
2686 = DIAGNOSTICS_COLUMN_UNIT_BYTE)
2688 test_diagnostic_context dc;
2689 dc.show_column = show_column;
2690 dc.column_unit = column_unit;
2691 dc.column_origin = origin;
2693 expanded_location xloc;
2694 xloc.file = filename;
2695 xloc.line = line;
2696 xloc.column = column;
2697 xloc.data = NULL;
2698 xloc.sysp = false;
2700 char *actual_loc_text = diagnostic_get_location_text (&dc, xloc);
2701 ASSERT_STREQ (expected_loc_text, actual_loc_text);
2702 free (actual_loc_text);
2705 /* Verify that diagnostic_get_location_text works as expected. */
2707 static void
2708 test_diagnostic_get_location_text ()
2710 const char *old_progname = progname;
2711 progname = "PROGNAME";
2712 assert_location_text ("PROGNAME:", NULL, 0, 0, true);
2713 char *built_in_colon = concat (special_fname_builtin (), ":", (char *) 0);
2714 assert_location_text (built_in_colon, special_fname_builtin (),
2715 42, 10, true);
2716 free (built_in_colon);
2717 assert_location_text ("foo.c:42:10:", "foo.c", 42, 10, true);
2718 assert_location_text ("foo.c:42:9:", "foo.c", 42, 10, true, 0);
2719 assert_location_text ("foo.c:42:1010:", "foo.c", 42, 10, true, 1001);
2720 for (int origin = 0; origin != 2; ++origin)
2721 assert_location_text ("foo.c:42:", "foo.c", 42, 0, true, origin);
2722 assert_location_text ("foo.c:", "foo.c", 0, 10, true);
2723 assert_location_text ("foo.c:42:", "foo.c", 42, 10, false);
2724 assert_location_text ("foo.c:", "foo.c", 0, 10, false);
2726 maybe_line_and_column (INT_MAX, INT_MAX);
2727 maybe_line_and_column (INT_MIN, INT_MIN);
2730 /* In order to test display columns vs byte columns, we need to create a
2731 file for location_get_source_line() to read. */
2733 const char *const content = "smile \xf0\x9f\x98\x82\n";
2734 const int line_bytes = strlen (content) - 1;
2735 const int def_tabstop = 8;
2736 const cpp_char_column_policy policy (def_tabstop, cpp_wcwidth);
2737 const int display_width = cpp_display_width (content, line_bytes, policy);
2738 ASSERT_EQ (line_bytes - 2, display_width);
2739 temp_source_file tmp (SELFTEST_LOCATION, ".c", content);
2740 const char *const fname = tmp.get_filename ();
2741 const int buf_len = strlen (fname) + 16;
2742 char *const expected = XNEWVEC (char, buf_len);
2744 snprintf (expected, buf_len, "%s:1:%d:", fname, line_bytes);
2745 assert_location_text (expected, fname, 1, line_bytes, true,
2746 1, DIAGNOSTICS_COLUMN_UNIT_BYTE);
2748 snprintf (expected, buf_len, "%s:1:%d:", fname, line_bytes - 1);
2749 assert_location_text (expected, fname, 1, line_bytes, true,
2750 0, DIAGNOSTICS_COLUMN_UNIT_BYTE);
2752 snprintf (expected, buf_len, "%s:1:%d:", fname, display_width);
2753 assert_location_text (expected, fname, 1, line_bytes, true,
2754 1, DIAGNOSTICS_COLUMN_UNIT_DISPLAY);
2756 snprintf (expected, buf_len, "%s:1:%d:", fname, display_width - 1);
2757 assert_location_text (expected, fname, 1, line_bytes, true,
2758 0, DIAGNOSTICS_COLUMN_UNIT_DISPLAY);
2760 XDELETEVEC (expected);
2764 progname = old_progname;
2767 /* Selftest for num_digits. */
2769 static void
2770 test_num_digits ()
2772 ASSERT_EQ (1, num_digits (0));
2773 ASSERT_EQ (1, num_digits (9));
2774 ASSERT_EQ (2, num_digits (10));
2775 ASSERT_EQ (2, num_digits (99));
2776 ASSERT_EQ (3, num_digits (100));
2777 ASSERT_EQ (3, num_digits (999));
2778 ASSERT_EQ (4, num_digits (1000));
2779 ASSERT_EQ (4, num_digits (9999));
2780 ASSERT_EQ (5, num_digits (10000));
2781 ASSERT_EQ (5, num_digits (99999));
2782 ASSERT_EQ (6, num_digits (100000));
2783 ASSERT_EQ (6, num_digits (999999));
2784 ASSERT_EQ (7, num_digits (1000000));
2785 ASSERT_EQ (7, num_digits (9999999));
2786 ASSERT_EQ (8, num_digits (10000000));
2787 ASSERT_EQ (8, num_digits (99999999));
2790 /* Run all of the selftests within this file. */
2792 void
2793 c_diagnostic_cc_tests ()
2795 test_print_escaped_string ();
2796 test_print_parseable_fixits_none ();
2797 test_print_parseable_fixits_insert ();
2798 test_print_parseable_fixits_remove ();
2799 test_print_parseable_fixits_replace ();
2800 test_print_parseable_fixits_bytes_vs_display_columns ();
2801 test_diagnostic_get_location_text ();
2802 test_num_digits ();
2806 } // namespace selftest
2808 #endif /* #if CHECKING_P */
2810 #if __GNUC__ >= 10
2811 # pragma GCC diagnostic pop
2812 #endif