]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/diagnostic.cc
docs: Fix expected diagnostics URL [PR107599]
[thirdparty/gcc.git] / gcc / diagnostic.cc
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>
4
5 This file is part of GCC.
6
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.
11
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.
16
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/>. */
20
21
22 /* This file implements the language independent aspect of diagnostic
23 message module. */
24
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 "diagnostic-client-data-hooks.h"
38 #include "edit-context.h"
39 #include "selftest.h"
40 #include "selftest-diagnostic.h"
41 #include "opts.h"
42 #include "cpplib.h"
43
44 #ifdef HAVE_TERMIOS_H
45 # include <termios.h>
46 #endif
47
48 #ifdef GWINSZ_IN_SYS_IOCTL
49 # include <sys/ioctl.h>
50 #endif
51
52 /* Disable warnings about quoting issues in the pp_xxx calls below
53 that (intentionally) don't follow GCC diagnostic conventions. */
54 #if __GNUC__ >= 10
55 # pragma GCC diagnostic push
56 # pragma GCC diagnostic ignored "-Wformat-diag"
57 #endif
58
59 #define pedantic_warning_kind(DC) \
60 ((DC)->pedantic_errors ? DK_ERROR : DK_WARNING)
61 #define permissive_error_kind(DC) ((DC)->permissive ? DK_WARNING : DK_ERROR)
62 #define permissive_error_option(DC) ((DC)->opt_permissive)
63
64 /* Prototypes. */
65 static bool diagnostic_impl (rich_location *, const diagnostic_metadata *,
66 int, const char *,
67 va_list *, diagnostic_t) ATTRIBUTE_GCC_DIAG(4,0);
68 static bool diagnostic_n_impl (rich_location *, const diagnostic_metadata *,
69 int, unsigned HOST_WIDE_INT,
70 const char *, const char *, va_list *,
71 diagnostic_t) ATTRIBUTE_GCC_DIAG(6,0);
72
73 static void error_recursion (diagnostic_context *) ATTRIBUTE_NORETURN;
74 static void real_abort (void) ATTRIBUTE_NORETURN;
75
76 /* Name of program invoked, sans directories. */
77
78 const char *progname;
79
80 /* A diagnostic_context surrogate for stderr. */
81 static diagnostic_context global_diagnostic_context;
82 diagnostic_context *global_dc = &global_diagnostic_context;
83 \f
84 /* Return a malloc'd string containing MSG formatted a la printf. The
85 caller is responsible for freeing the memory. */
86 char *
87 build_message_string (const char *msg, ...)
88 {
89 char *str;
90 va_list ap;
91
92 va_start (ap, msg);
93 str = xvasprintf (msg, ap);
94 va_end (ap);
95
96 return str;
97 }
98
99 /* Same as diagnostic_build_prefix, but only the source FILE is given. */
100 char *
101 file_name_as_prefix (diagnostic_context *context, const char *f)
102 {
103 const char *locus_cs
104 = colorize_start (pp_show_color (context->printer), "locus");
105 const char *locus_ce = colorize_stop (pp_show_color (context->printer));
106 return build_message_string ("%s%s:%s ", locus_cs, f, locus_ce);
107 }
108
109
110 \f
111 /* Return the value of the getenv("COLUMNS") as an integer. If the
112 value is not set to a positive integer, use ioctl to get the
113 terminal width. If it fails, return INT_MAX. */
114 int
115 get_terminal_width (void)
116 {
117 const char * s = getenv ("COLUMNS");
118 if (s != NULL) {
119 int n = atoi (s);
120 if (n > 0)
121 return n;
122 }
123
124 #ifdef TIOCGWINSZ
125 struct winsize w;
126 w.ws_col = 0;
127 if (ioctl (0, TIOCGWINSZ, &w) == 0 && w.ws_col > 0)
128 return w.ws_col;
129 #endif
130
131 return INT_MAX;
132 }
133
134 /* Set caret_max_width to value. */
135 void
136 diagnostic_set_caret_max_width (diagnostic_context *context, int value)
137 {
138 /* One minus to account for the leading empty space. */
139 value = value ? value - 1
140 : (isatty (fileno (pp_buffer (context->printer)->stream))
141 ? get_terminal_width () - 1: INT_MAX);
142
143 if (value <= 0)
144 value = INT_MAX;
145
146 context->caret_max_width = value;
147 }
148
149 /* Default implementation of final_cb. */
150
151 static void
152 default_diagnostic_final_cb (diagnostic_context *context)
153 {
154 /* Some of the errors may actually have been warnings. */
155 if (diagnostic_kind_count (context, DK_WERROR))
156 {
157 /* -Werror was given. */
158 if (context->warning_as_error_requested)
159 pp_verbatim (context->printer,
160 _("%s: all warnings being treated as errors"),
161 progname);
162 /* At least one -Werror= was given. */
163 else
164 pp_verbatim (context->printer,
165 _("%s: some warnings being treated as errors"),
166 progname);
167 pp_newline_and_flush (context->printer);
168 }
169 }
170
171 /* Initialize the diagnostic message outputting machinery. */
172 void
173 diagnostic_initialize (diagnostic_context *context, int n_opts)
174 {
175 int i;
176
177 /* Allocate a basic pretty-printer. Clients will replace this a
178 much more elaborated pretty-printer if they wish. */
179 context->printer = XNEW (pretty_printer);
180 new (context->printer) pretty_printer ();
181
182 memset (context->diagnostic_count, 0, sizeof context->diagnostic_count);
183 context->warning_as_error_requested = false;
184 context->n_opts = n_opts;
185 context->classify_diagnostic = XNEWVEC (diagnostic_t, n_opts);
186 for (i = 0; i < n_opts; i++)
187 context->classify_diagnostic[i] = DK_UNSPECIFIED;
188 context->show_caret = false;
189 diagnostic_set_caret_max_width (context, pp_line_cutoff (context->printer));
190 for (i = 0; i < rich_location::STATICALLY_ALLOCATED_RANGES; i++)
191 context->caret_chars[i] = '^';
192 context->show_cwe = false;
193 context->show_rules = false;
194 context->path_format = DPF_NONE;
195 context->show_path_depths = false;
196 context->show_option_requested = false;
197 context->abort_on_error = false;
198 context->show_column = false;
199 context->pedantic_errors = false;
200 context->permissive = false;
201 context->opt_permissive = 0;
202 context->fatal_errors = false;
203 context->dc_inhibit_warnings = false;
204 context->dc_warn_system_headers = false;
205 context->max_errors = 0;
206 context->internal_error = NULL;
207 diagnostic_starter (context) = default_diagnostic_starter;
208 context->start_span = default_diagnostic_start_span_fn;
209 diagnostic_finalizer (context) = default_diagnostic_finalizer;
210 context->option_enabled = NULL;
211 context->option_state = NULL;
212 context->option_name = NULL;
213 context->get_option_url = NULL;
214 context->last_location = UNKNOWN_LOCATION;
215 context->last_module = 0;
216 context->x_data = NULL;
217 context->lock = 0;
218 context->inhibit_notes_p = false;
219 context->colorize_source_p = false;
220 context->show_labels_p = false;
221 context->show_line_numbers_p = false;
222 context->min_margin_width = 0;
223 context->show_ruler_p = false;
224 context->report_bug = false;
225
226 if (const char *var = getenv ("GCC_EXTRA_DIAGNOSTIC_OUTPUT"))
227 {
228 if (!strcmp (var, "fixits-v1"))
229 context->extra_output_kind = EXTRA_DIAGNOSTIC_OUTPUT_fixits_v1;
230 else if (!strcmp (var, "fixits-v2"))
231 context->extra_output_kind = EXTRA_DIAGNOSTIC_OUTPUT_fixits_v2;
232 /* Silently ignore unrecognized values. */
233 }
234 context->column_unit = DIAGNOSTICS_COLUMN_UNIT_DISPLAY;
235 context->column_origin = 1;
236 context->tabstop = 8;
237 context->escape_format = DIAGNOSTICS_ESCAPE_FORMAT_UNICODE;
238 context->edit_context_ptr = NULL;
239 context->diagnostic_group_nesting_depth = 0;
240 context->diagnostic_group_emission_count = 0;
241 context->begin_group_cb = NULL;
242 context->end_group_cb = NULL;
243 context->final_cb = default_diagnostic_final_cb;
244 context->includes_seen = NULL;
245 context->m_client_data_hooks = NULL;
246 }
247
248 /* Maybe initialize the color support. We require clients to do this
249 explicitly, since most clients don't want color. When called
250 without a VALUE, it initializes with DIAGNOSTICS_COLOR_DEFAULT. */
251
252 void
253 diagnostic_color_init (diagnostic_context *context, int value /*= -1 */)
254 {
255 /* value == -1 is the default value. */
256 if (value < 0)
257 {
258 /* If DIAGNOSTICS_COLOR_DEFAULT is -1, default to
259 -fdiagnostics-color=auto if GCC_COLORS is in the environment,
260 otherwise default to -fdiagnostics-color=never, for other
261 values default to that
262 -fdiagnostics-color={never,auto,always}. */
263 if (DIAGNOSTICS_COLOR_DEFAULT == -1)
264 {
265 if (!getenv ("GCC_COLORS"))
266 return;
267 value = DIAGNOSTICS_COLOR_AUTO;
268 }
269 else
270 value = DIAGNOSTICS_COLOR_DEFAULT;
271 }
272 pp_show_color (context->printer)
273 = colorize_init ((diagnostic_color_rule_t) value);
274 }
275
276 /* Initialize URL support within CONTEXT based on VALUE, handling "auto". */
277
278 void
279 diagnostic_urls_init (diagnostic_context *context, int value /*= -1 */)
280 {
281 /* value == -1 is the default value. */
282 if (value < 0)
283 {
284 /* If DIAGNOSTICS_URLS_DEFAULT is -1, default to
285 -fdiagnostics-urls=auto if GCC_URLS or TERM_URLS is in the
286 environment, otherwise default to -fdiagnostics-urls=never,
287 for other values default to that
288 -fdiagnostics-urls={never,auto,always}. */
289 if (DIAGNOSTICS_URLS_DEFAULT == -1)
290 {
291 if (!getenv ("GCC_URLS") && !getenv ("TERM_URLS"))
292 return;
293 value = DIAGNOSTICS_URL_AUTO;
294 }
295 else
296 value = DIAGNOSTICS_URLS_DEFAULT;
297 }
298
299 context->printer->url_format
300 = determine_url_format ((diagnostic_url_rule_t) value);
301 }
302
303 /* Create the file_cache, if not already created, and tell it how to
304 translate files on input. */
305 void diagnostic_initialize_input_context (diagnostic_context *context,
306 diagnostic_input_charset_callback ccb,
307 bool should_skip_bom)
308 {
309 if (!context->m_file_cache)
310 context->m_file_cache = new file_cache;
311 context->m_file_cache->initialize_input_context (ccb, should_skip_bom);
312 }
313
314 /* Do any cleaning up required after the last diagnostic is emitted. */
315
316 void
317 diagnostic_finish (diagnostic_context *context)
318 {
319 if (context->final_cb)
320 context->final_cb (context);
321
322 diagnostic_file_cache_fini ();
323
324 XDELETEVEC (context->classify_diagnostic);
325 context->classify_diagnostic = NULL;
326
327 /* diagnostic_initialize allocates context->printer using XNEW
328 and placement-new. */
329 context->printer->~pretty_printer ();
330 XDELETE (context->printer);
331 context->printer = NULL;
332
333 if (context->edit_context_ptr)
334 {
335 delete context->edit_context_ptr;
336 context->edit_context_ptr = NULL;
337 }
338
339 if (context->includes_seen)
340 {
341 delete context->includes_seen;
342 context->includes_seen = nullptr;
343 }
344
345 if (context->m_client_data_hooks)
346 {
347 delete context->m_client_data_hooks;
348 context->m_client_data_hooks = NULL;
349 }
350 }
351
352 /* Initialize DIAGNOSTIC, where the message MSG has already been
353 translated. */
354 void
355 diagnostic_set_info_translated (diagnostic_info *diagnostic, const char *msg,
356 va_list *args, rich_location *richloc,
357 diagnostic_t kind)
358 {
359 gcc_assert (richloc);
360 diagnostic->message.err_no = errno;
361 diagnostic->message.args_ptr = args;
362 diagnostic->message.format_spec = msg;
363 diagnostic->message.m_richloc = richloc;
364 diagnostic->richloc = richloc;
365 diagnostic->metadata = NULL;
366 diagnostic->kind = kind;
367 diagnostic->option_index = 0;
368 }
369
370 /* Initialize DIAGNOSTIC, where the message GMSGID has not yet been
371 translated. */
372 void
373 diagnostic_set_info (diagnostic_info *diagnostic, const char *gmsgid,
374 va_list *args, rich_location *richloc,
375 diagnostic_t kind)
376 {
377 gcc_assert (richloc);
378 diagnostic_set_info_translated (diagnostic, _(gmsgid), args, richloc, kind);
379 }
380
381 static const char *const diagnostic_kind_color[] = {
382 #define DEFINE_DIAGNOSTIC_KIND(K, T, C) (C),
383 #include "diagnostic.def"
384 #undef DEFINE_DIAGNOSTIC_KIND
385 NULL
386 };
387
388 /* Get a color name for diagnostics of type KIND
389 Result could be NULL. */
390
391 const char *
392 diagnostic_get_color_for_kind (diagnostic_t kind)
393 {
394 return diagnostic_kind_color[kind];
395 }
396
397 /* Given an expanded_location, convert the column (which is in 1-based bytes)
398 to the requested units, without converting the origin.
399 Return -1 if the column is invalid (<= 0). */
400
401 static int
402 convert_column_unit (enum diagnostics_column_unit column_unit,
403 int tabstop,
404 expanded_location s)
405 {
406 if (s.column <= 0)
407 return -1;
408
409 switch (column_unit)
410 {
411 default:
412 gcc_unreachable ();
413
414 case DIAGNOSTICS_COLUMN_UNIT_DISPLAY:
415 {
416 cpp_char_column_policy policy (tabstop, cpp_wcwidth);
417 return location_compute_display_column (s, policy);
418 }
419
420 case DIAGNOSTICS_COLUMN_UNIT_BYTE:
421 return s.column;
422 }
423 }
424
425 /* Given an expanded_location, convert the column (which is in 1-based bytes)
426 to the requested units and origin. Return -1 if the column is
427 invalid (<= 0). */
428 int
429 diagnostic_converted_column (diagnostic_context *context, expanded_location s)
430 {
431 int one_based_col
432 = convert_column_unit (context->column_unit, context->tabstop, s);
433 if (one_based_col <= 0)
434 return -1;
435 return one_based_col + (context->column_origin - 1);
436 }
437
438 /* Return a formatted line and column ':%line:%column'. Elided if
439 line == 0 or col < 0. (A column of 0 may be valid due to the
440 -fdiagnostics-column-origin option.)
441 The result is a statically allocated buffer. */
442
443 static const char *
444 maybe_line_and_column (int line, int col)
445 {
446 static char result[32];
447
448 if (line)
449 {
450 size_t l
451 = snprintf (result, sizeof (result),
452 col >= 0 ? ":%d:%d" : ":%d", line, col);
453 gcc_checking_assert (l < sizeof (result));
454 }
455 else
456 result[0] = 0;
457 return result;
458 }
459
460 /* Return a malloc'd string describing a location e.g. "foo.c:42:10".
461 The caller is responsible for freeing the memory. */
462
463 static char *
464 diagnostic_get_location_text (diagnostic_context *context,
465 expanded_location s)
466 {
467 pretty_printer *pp = context->printer;
468 const char *locus_cs = colorize_start (pp_show_color (pp), "locus");
469 const char *locus_ce = colorize_stop (pp_show_color (pp));
470 const char *file = s.file ? s.file : progname;
471 int line = 0;
472 int col = -1;
473 if (strcmp (file, N_("<built-in>")))
474 {
475 line = s.line;
476 if (context->show_column)
477 col = diagnostic_converted_column (context, s);
478 }
479
480 const char *line_col = maybe_line_and_column (line, col);
481 return build_message_string ("%s%s%s:%s", locus_cs, file,
482 line_col, locus_ce);
483 }
484
485 static const char *const diagnostic_kind_text[] = {
486 #define DEFINE_DIAGNOSTIC_KIND(K, T, C) (T),
487 #include "diagnostic.def"
488 #undef DEFINE_DIAGNOSTIC_KIND
489 "must-not-happen"
490 };
491
492 /* Return a malloc'd string describing a location and the severity of the
493 diagnostic, e.g. "foo.c:42:10: error: ". The caller is responsible for
494 freeing the memory. */
495 char *
496 diagnostic_build_prefix (diagnostic_context *context,
497 const diagnostic_info *diagnostic)
498 {
499 gcc_assert (diagnostic->kind < DK_LAST_DIAGNOSTIC_KIND);
500
501 const char *text = _(diagnostic_kind_text[diagnostic->kind]);
502 const char *text_cs = "", *text_ce = "";
503 pretty_printer *pp = context->printer;
504
505 if (diagnostic_kind_color[diagnostic->kind])
506 {
507 text_cs = colorize_start (pp_show_color (pp),
508 diagnostic_kind_color[diagnostic->kind]);
509 text_ce = colorize_stop (pp_show_color (pp));
510 }
511
512 expanded_location s = diagnostic_expand_location (diagnostic);
513 char *location_text = diagnostic_get_location_text (context, s);
514
515 char *result = build_message_string ("%s %s%s%s", location_text,
516 text_cs, text, text_ce);
517 free (location_text);
518 return result;
519 }
520
521 /* Functions at which to stop the backtrace print. It's not
522 particularly helpful to print the callers of these functions. */
523
524 static const char * const bt_stop[] =
525 {
526 "main",
527 "toplev::main",
528 "execute_one_pass",
529 "compile_file",
530 };
531
532 /* A callback function passed to the backtrace_full function. */
533
534 static int
535 bt_callback (void *data, uintptr_t pc, const char *filename, int lineno,
536 const char *function)
537 {
538 int *pcount = (int *) data;
539
540 /* If we don't have any useful information, don't print
541 anything. */
542 if (filename == NULL && function == NULL)
543 return 0;
544
545 /* Skip functions in diagnostic.cc. */
546 if (*pcount == 0
547 && filename != NULL
548 && strcmp (lbasename (filename), "diagnostic.cc") == 0)
549 return 0;
550
551 /* Print up to 20 functions. We could make this a --param, but
552 since this is only for debugging just use a constant for now. */
553 if (*pcount >= 20)
554 {
555 /* Returning a non-zero value stops the backtrace. */
556 return 1;
557 }
558 ++*pcount;
559
560 char *alc = NULL;
561 if (function != NULL)
562 {
563 char *str = cplus_demangle_v3 (function,
564 (DMGL_VERBOSE | DMGL_ANSI
565 | DMGL_GNU_V3 | DMGL_PARAMS));
566 if (str != NULL)
567 {
568 alc = str;
569 function = str;
570 }
571
572 for (size_t i = 0; i < ARRAY_SIZE (bt_stop); ++i)
573 {
574 size_t len = strlen (bt_stop[i]);
575 if (strncmp (function, bt_stop[i], len) == 0
576 && (function[len] == '\0' || function[len] == '('))
577 {
578 if (alc != NULL)
579 free (alc);
580 /* Returning a non-zero value stops the backtrace. */
581 return 1;
582 }
583 }
584 }
585
586 fprintf (stderr, "0x%lx %s\n\t%s:%d\n",
587 (unsigned long) pc,
588 function == NULL ? "???" : function,
589 filename == NULL ? "???" : filename,
590 lineno);
591
592 if (alc != NULL)
593 free (alc);
594
595 return 0;
596 }
597
598 /* A callback function passed to the backtrace_full function. This is
599 called if backtrace_full has an error. */
600
601 static void
602 bt_err_callback (void *data ATTRIBUTE_UNUSED, const char *msg, int errnum)
603 {
604 if (errnum < 0)
605 {
606 /* This means that no debug info was available. Just quietly
607 skip printing backtrace info. */
608 return;
609 }
610 fprintf (stderr, "%s%s%s\n", msg, errnum == 0 ? "" : ": ",
611 errnum == 0 ? "" : xstrerror (errnum));
612 }
613
614 /* Check if we've met the maximum error limit, and if so fatally exit
615 with a message. CONTEXT is the context to check, and FLUSH
616 indicates whether a diagnostic_finish call is needed. */
617
618 void
619 diagnostic_check_max_errors (diagnostic_context *context, bool flush)
620 {
621 if (!context->max_errors)
622 return;
623
624 int count = (diagnostic_kind_count (context, DK_ERROR)
625 + diagnostic_kind_count (context, DK_SORRY)
626 + diagnostic_kind_count (context, DK_WERROR));
627
628 if (count >= context->max_errors)
629 {
630 fnotice (stderr,
631 "compilation terminated due to -fmax-errors=%u.\n",
632 context->max_errors);
633 if (flush)
634 diagnostic_finish (context);
635 exit (FATAL_EXIT_CODE);
636 }
637 }
638
639 /* Take any action which is expected to happen after the diagnostic
640 is written out. This function does not always return. */
641 void
642 diagnostic_action_after_output (diagnostic_context *context,
643 diagnostic_t diag_kind)
644 {
645 switch (diag_kind)
646 {
647 case DK_DEBUG:
648 case DK_NOTE:
649 case DK_ANACHRONISM:
650 case DK_WARNING:
651 break;
652
653 case DK_ERROR:
654 case DK_SORRY:
655 if (context->abort_on_error)
656 real_abort ();
657 if (context->fatal_errors)
658 {
659 fnotice (stderr, "compilation terminated due to -Wfatal-errors.\n");
660 diagnostic_finish (context);
661 exit (FATAL_EXIT_CODE);
662 }
663 break;
664
665 case DK_ICE:
666 case DK_ICE_NOBT:
667 {
668 struct backtrace_state *state = NULL;
669 if (diag_kind == DK_ICE)
670 state = backtrace_create_state (NULL, 0, bt_err_callback, NULL);
671 int count = 0;
672 if (state != NULL)
673 backtrace_full (state, 2, bt_callback, bt_err_callback,
674 (void *) &count);
675
676 if (context->abort_on_error)
677 real_abort ();
678
679 if (context->report_bug)
680 fnotice (stderr, "Please submit a full bug report, "
681 "with preprocessed source.\n");
682 else
683 fnotice (stderr, "Please submit a full bug report, "
684 "with preprocessed source (by using -freport-bug).\n");
685
686 if (count > 0)
687 fnotice (stderr, "Please include the complete backtrace "
688 "with any bug report.\n");
689 fnotice (stderr, "See %s for instructions.\n", bug_report_url);
690
691 exit (ICE_EXIT_CODE);
692 }
693
694 case DK_FATAL:
695 if (context->abort_on_error)
696 real_abort ();
697 diagnostic_finish (context);
698 fnotice (stderr, "compilation terminated.\n");
699 exit (FATAL_EXIT_CODE);
700
701 default:
702 gcc_unreachable ();
703 }
704 }
705
706 /* True if the last module or file in which a diagnostic was reported is
707 different from the current one. */
708
709 static bool
710 last_module_changed_p (diagnostic_context *context,
711 const line_map_ordinary *map)
712 {
713 return context->last_module != map;
714 }
715
716 /* Remember the current module or file as being the last one in which we
717 report a diagnostic. */
718
719 static void
720 set_last_module (diagnostic_context *context, const line_map_ordinary *map)
721 {
722 context->last_module = map;
723 }
724
725 /* Only dump the "In file included from..." stack once for each file. */
726
727 static bool
728 includes_seen (diagnostic_context *context, const line_map_ordinary *map)
729 {
730 /* No include path for main. */
731 if (MAIN_FILE_P (map))
732 return true;
733
734 /* Always identify C++ modules, at least for now. */
735 auto probe = map;
736 if (linemap_check_ordinary (map)->reason == LC_RENAME)
737 /* The module source file shows up as LC_RENAME inside LC_MODULE. */
738 probe = linemap_included_from_linemap (line_table, map);
739 if (MAP_MODULE_P (probe))
740 return false;
741
742 if (!context->includes_seen)
743 context->includes_seen = new hash_set<location_t, false, location_hash>;
744
745 /* Hash the location of the #include directive to better handle files
746 that are included multiple times with different macros defined. */
747 return context->includes_seen->add (linemap_included_from (map));
748 }
749
750 void
751 diagnostic_report_current_module (diagnostic_context *context, location_t where)
752 {
753 const line_map_ordinary *map = NULL;
754
755 if (pp_needs_newline (context->printer))
756 {
757 pp_newline (context->printer);
758 pp_needs_newline (context->printer) = false;
759 }
760
761 if (where <= BUILTINS_LOCATION)
762 return;
763
764 linemap_resolve_location (line_table, where,
765 LRK_MACRO_DEFINITION_LOCATION,
766 &map);
767
768 if (map && last_module_changed_p (context, map))
769 {
770 set_last_module (context, map);
771 if (!includes_seen (context, map))
772 {
773 bool first = true, need_inc = true, was_module = MAP_MODULE_P (map);
774 expanded_location s = {};
775 do
776 {
777 where = linemap_included_from (map);
778 map = linemap_included_from_linemap (line_table, map);
779 bool is_module = MAP_MODULE_P (map);
780 s.file = LINEMAP_FILE (map);
781 s.line = SOURCE_LINE (map, where);
782 int col = -1;
783 if (first && context->show_column)
784 {
785 s.column = SOURCE_COLUMN (map, where);
786 col = diagnostic_converted_column (context, s);
787 }
788 const char *line_col = maybe_line_and_column (s.line, col);
789 static const char *const msgs[] =
790 {
791 NULL,
792 N_(" from"),
793 N_("In file included from"), /* 2 */
794 N_(" included from"),
795 N_("In module"), /* 4 */
796 N_("of module"),
797 N_("In module imported at"), /* 6 */
798 N_("imported at"),
799 };
800
801 unsigned index = (was_module ? 6 : is_module ? 4
802 : need_inc ? 2 : 0) + !first;
803
804 pp_verbatim (context->printer, "%s%s %r%s%s%R",
805 first ? "" : was_module ? ", " : ",\n",
806 _(msgs[index]),
807 "locus", s.file, line_col);
808 first = false, need_inc = was_module, was_module = is_module;
809 }
810 while (!includes_seen (context, map));
811 pp_verbatim (context->printer, ":");
812 pp_newline (context->printer);
813 }
814 }
815 }
816
817 /* If DIAGNOSTIC has a diagnostic_path and CONTEXT supports printing paths,
818 print the path. */
819
820 void
821 diagnostic_show_any_path (diagnostic_context *context,
822 diagnostic_info *diagnostic)
823 {
824 const diagnostic_path *path = diagnostic->richloc->get_path ();
825 if (!path)
826 return;
827
828 if (context->print_path)
829 context->print_path (context, path);
830 }
831
832 /* class diagnostic_event. */
833
834 /* struct diagnostic_event::meaning. */
835
836 void
837 diagnostic_event::meaning::dump_to_pp (pretty_printer *pp) const
838 {
839 bool need_comma = false;
840 pp_character (pp, '{');
841 if (const char *verb_str = maybe_get_verb_str (m_verb))
842 {
843 pp_printf (pp, "verb: %qs", verb_str);
844 need_comma = true;
845 }
846 if (const char *noun_str = maybe_get_noun_str (m_noun))
847 {
848 if (need_comma)
849 pp_string (pp, ", ");
850 pp_printf (pp, "noun: %qs", noun_str);
851 need_comma = true;
852 }
853 if (const char *property_str = maybe_get_property_str (m_property))
854 {
855 if (need_comma)
856 pp_string (pp, ", ");
857 pp_printf (pp, "property: %qs", property_str);
858 need_comma = true;
859 }
860 pp_character (pp, '}');
861 }
862
863 /* Get a string (or NULL) for V suitable for use within a SARIF
864 threadFlowLocation "kinds" property (SARIF v2.1.0 section 3.38.8). */
865
866 const char *
867 diagnostic_event::meaning::maybe_get_verb_str (enum verb v)
868 {
869 switch (v)
870 {
871 default:
872 gcc_unreachable ();
873 case VERB_unknown:
874 return NULL;
875 case VERB_acquire:
876 return "acquire";
877 case VERB_release:
878 return "release";
879 case VERB_enter:
880 return "enter";
881 case VERB_exit:
882 return "exit";
883 case VERB_call:
884 return "call";
885 case VERB_return:
886 return "return";
887 case VERB_branch:
888 return "branch";
889 case VERB_danger:
890 return "danger";
891 }
892 }
893
894 /* Get a string (or NULL) for N suitable for use within a SARIF
895 threadFlowLocation "kinds" property (SARIF v2.1.0 section 3.38.8). */
896
897 const char *
898 diagnostic_event::meaning::maybe_get_noun_str (enum noun n)
899 {
900 switch (n)
901 {
902 default:
903 gcc_unreachable ();
904 case NOUN_unknown:
905 return NULL;
906 case NOUN_taint:
907 return "taint";
908 case NOUN_sensitive:
909 return "sensitive";
910 case NOUN_function:
911 return "function";
912 case NOUN_lock:
913 return "lock";
914 case NOUN_memory:
915 return "memory";
916 case NOUN_resource:
917 return "resource";
918 }
919 }
920
921 /* Get a string (or NULL) for P suitable for use within a SARIF
922 threadFlowLocation "kinds" property (SARIF v2.1.0 section 3.38.8). */
923
924 const char *
925 diagnostic_event::meaning::maybe_get_property_str (enum property p)
926 {
927 switch (p)
928 {
929 default:
930 gcc_unreachable ();
931 case PROPERTY_unknown:
932 return NULL;
933 case PROPERTY_true:
934 return "true";
935 case PROPERTY_false:
936 return "false";
937 }
938 }
939
940 /* class diagnostic_path. */
941
942 /* Return true if the events in this path involve more than one
943 function, or false if it is purely intraprocedural. */
944
945 bool
946 diagnostic_path::interprocedural_p () const
947 {
948 const unsigned num = num_events ();
949 for (unsigned i = 0; i < num; i++)
950 {
951 if (get_event (i).get_fndecl () != get_event (0).get_fndecl ())
952 return true;
953 if (get_event (i).get_stack_depth () != get_event (0).get_stack_depth ())
954 return true;
955 }
956 return false;
957 }
958
959 void
960 default_diagnostic_starter (diagnostic_context *context,
961 diagnostic_info *diagnostic)
962 {
963 diagnostic_report_current_module (context, diagnostic_location (diagnostic));
964 pp_set_prefix (context->printer, diagnostic_build_prefix (context,
965 diagnostic));
966 }
967
968 void
969 default_diagnostic_start_span_fn (diagnostic_context *context,
970 expanded_location exploc)
971 {
972 char *text = diagnostic_get_location_text (context, exploc);
973 pp_string (context->printer, text);
974 free (text);
975 pp_newline (context->printer);
976 }
977
978 void
979 default_diagnostic_finalizer (diagnostic_context *context,
980 diagnostic_info *diagnostic,
981 diagnostic_t)
982 {
983 char *saved_prefix = pp_take_prefix (context->printer);
984 pp_set_prefix (context->printer, NULL);
985 pp_newline (context->printer);
986 diagnostic_show_locus (context, diagnostic->richloc, diagnostic->kind);
987 pp_set_prefix (context->printer, saved_prefix);
988 pp_flush (context->printer);
989 }
990
991 /* Interface to specify diagnostic kind overrides. Returns the
992 previous setting, or DK_UNSPECIFIED if the parameters are out of
993 range. If OPTION_INDEX is zero, the new setting is for all the
994 diagnostics. */
995 diagnostic_t
996 diagnostic_classify_diagnostic (diagnostic_context *context,
997 int option_index,
998 diagnostic_t new_kind,
999 location_t where)
1000 {
1001 diagnostic_t old_kind;
1002
1003 if (option_index < 0
1004 || option_index >= context->n_opts
1005 || new_kind >= DK_LAST_DIAGNOSTIC_KIND)
1006 return DK_UNSPECIFIED;
1007
1008 old_kind = context->classify_diagnostic[option_index];
1009
1010 /* Handle pragmas separately, since we need to keep track of *where*
1011 the pragmas were. */
1012 if (where != UNKNOWN_LOCATION)
1013 {
1014 int i;
1015
1016 /* Record the command-line status, so we can reset it back on DK_POP. */
1017 if (old_kind == DK_UNSPECIFIED)
1018 {
1019 old_kind = !context->option_enabled (option_index,
1020 context->lang_mask,
1021 context->option_state)
1022 ? DK_IGNORED : (context->warning_as_error_requested
1023 ? DK_ERROR : DK_WARNING);
1024 context->classify_diagnostic[option_index] = old_kind;
1025 }
1026
1027 for (i = context->n_classification_history - 1; i >= 0; i --)
1028 if (context->classification_history[i].option == option_index)
1029 {
1030 old_kind = context->classification_history[i].kind;
1031 break;
1032 }
1033
1034 i = context->n_classification_history;
1035 context->classification_history =
1036 (diagnostic_classification_change_t *) xrealloc (context->classification_history, (i + 1)
1037 * sizeof (diagnostic_classification_change_t));
1038 context->classification_history[i].location = where;
1039 context->classification_history[i].option = option_index;
1040 context->classification_history[i].kind = new_kind;
1041 context->n_classification_history ++;
1042 }
1043 else
1044 context->classify_diagnostic[option_index] = new_kind;
1045
1046 return old_kind;
1047 }
1048
1049 /* Save all diagnostic classifications in a stack. */
1050 void
1051 diagnostic_push_diagnostics (diagnostic_context *context, location_t where ATTRIBUTE_UNUSED)
1052 {
1053 context->push_list = (int *) xrealloc (context->push_list, (context->n_push + 1) * sizeof (int));
1054 context->push_list[context->n_push ++] = context->n_classification_history;
1055 }
1056
1057 /* Restore the topmost classification set off the stack. If the stack
1058 is empty, revert to the state based on command line parameters. */
1059 void
1060 diagnostic_pop_diagnostics (diagnostic_context *context, location_t where)
1061 {
1062 int jump_to;
1063 int i;
1064
1065 if (context->n_push)
1066 jump_to = context->push_list [-- context->n_push];
1067 else
1068 jump_to = 0;
1069
1070 i = context->n_classification_history;
1071 context->classification_history =
1072 (diagnostic_classification_change_t *) xrealloc (context->classification_history, (i + 1)
1073 * sizeof (diagnostic_classification_change_t));
1074 context->classification_history[i].location = where;
1075 context->classification_history[i].option = jump_to;
1076 context->classification_history[i].kind = DK_POP;
1077 context->n_classification_history ++;
1078 }
1079
1080 /* Helper function for print_parseable_fixits. Print TEXT to PP, obeying the
1081 escaping rules for -fdiagnostics-parseable-fixits. */
1082
1083 static void
1084 print_escaped_string (pretty_printer *pp, const char *text)
1085 {
1086 gcc_assert (pp);
1087 gcc_assert (text);
1088
1089 pp_character (pp, '"');
1090 for (const char *ch = text; *ch; ch++)
1091 {
1092 switch (*ch)
1093 {
1094 case '\\':
1095 /* Escape backslash as two backslashes. */
1096 pp_string (pp, "\\\\");
1097 break;
1098 case '\t':
1099 /* Escape tab as "\t". */
1100 pp_string (pp, "\\t");
1101 break;
1102 case '\n':
1103 /* Escape newline as "\n". */
1104 pp_string (pp, "\\n");
1105 break;
1106 case '"':
1107 /* Escape doublequotes as \". */
1108 pp_string (pp, "\\\"");
1109 break;
1110 default:
1111 if (ISPRINT (*ch))
1112 pp_character (pp, *ch);
1113 else
1114 /* Use octal for non-printable chars. */
1115 {
1116 unsigned char c = (*ch & 0xff);
1117 pp_printf (pp, "\\%o%o%o", (c / 64), (c / 8) & 007, c & 007);
1118 }
1119 break;
1120 }
1121 }
1122 pp_character (pp, '"');
1123 }
1124
1125 /* Implementation of -fdiagnostics-parseable-fixits and
1126 GCC_EXTRA_DIAGNOSTIC_OUTPUT.
1127 Print a machine-parseable version of all fixits in RICHLOC to PP,
1128 using COLUMN_UNIT to express columns.
1129 Use TABSTOP when handling DIAGNOSTICS_COLUMN_UNIT_DISPLAY. */
1130
1131 static void
1132 print_parseable_fixits (pretty_printer *pp, rich_location *richloc,
1133 enum diagnostics_column_unit column_unit,
1134 int tabstop)
1135 {
1136 gcc_assert (pp);
1137 gcc_assert (richloc);
1138
1139 char *saved_prefix = pp_take_prefix (pp);
1140 pp_set_prefix (pp, NULL);
1141
1142 for (unsigned i = 0; i < richloc->get_num_fixit_hints (); i++)
1143 {
1144 const fixit_hint *hint = richloc->get_fixit_hint (i);
1145 location_t start_loc = hint->get_start_loc ();
1146 expanded_location start_exploc = expand_location (start_loc);
1147 pp_string (pp, "fix-it:");
1148 print_escaped_string (pp, start_exploc.file);
1149 /* For compatibility with clang, print as a half-open range. */
1150 location_t next_loc = hint->get_next_loc ();
1151 expanded_location next_exploc = expand_location (next_loc);
1152 int start_col
1153 = convert_column_unit (column_unit, tabstop, start_exploc);
1154 int next_col
1155 = convert_column_unit (column_unit, tabstop, next_exploc);
1156 pp_printf (pp, ":{%i:%i-%i:%i}:",
1157 start_exploc.line, start_col,
1158 next_exploc.line, next_col);
1159 print_escaped_string (pp, hint->get_string ());
1160 pp_newline (pp);
1161 }
1162
1163 pp_set_prefix (pp, saved_prefix);
1164 }
1165
1166 /* Update the inlining info in CONTEXT for a DIAGNOSTIC. */
1167
1168 static void
1169 get_any_inlining_info (diagnostic_context *context,
1170 diagnostic_info *diagnostic)
1171 {
1172 auto &ilocs = diagnostic->m_iinfo.m_ilocs;
1173
1174 if (context->set_locations_cb)
1175 /* Retrieve the locations into which the expression about to be
1176 diagnosed has been inlined, including those of all the callers
1177 all the way down the inlining stack. */
1178 context->set_locations_cb (context, diagnostic);
1179 else
1180 {
1181 /* When there's no callback use just the one location provided
1182 by the caller of the diagnostic function. */
1183 location_t loc = diagnostic_location (diagnostic);
1184 ilocs.safe_push (loc);
1185 diagnostic->m_iinfo.m_allsyslocs = in_system_header_at (loc);
1186 }
1187 }
1188
1189 /* Update the kind of DIAGNOSTIC based on its location(s), including
1190 any of those in its inlining stack, relative to any
1191 #pragma GCC diagnostic
1192 directives recorded within CONTEXT.
1193
1194 Return the new kind of DIAGNOSTIC if it was updated, or DK_UNSPECIFIED
1195 otherwise. */
1196
1197 static diagnostic_t
1198 update_effective_level_from_pragmas (diagnostic_context *context,
1199 diagnostic_info *diagnostic)
1200 {
1201 if (diagnostic->m_iinfo.m_allsyslocs && !context->dc_warn_system_headers)
1202 {
1203 /* Ignore the diagnostic if all the inlined locations are
1204 in system headers and -Wno-system-headers is in effect. */
1205 diagnostic->kind = DK_IGNORED;
1206 return DK_IGNORED;
1207 }
1208
1209 if (context->n_classification_history <= 0)
1210 return DK_UNSPECIFIED;
1211
1212 /* Iterate over the locations, checking the diagnostic disposition
1213 for the diagnostic at each. If it's explicitly set as opposed
1214 to unspecified, update the disposition for this instance of
1215 the diagnostic and return it. */
1216 for (location_t loc: diagnostic->m_iinfo.m_ilocs)
1217 {
1218 /* FIXME: Stupid search. Optimize later. */
1219 for (int i = context->n_classification_history - 1; i >= 0; i --)
1220 {
1221 const diagnostic_classification_change_t &hist
1222 = context->classification_history[i];
1223
1224 location_t pragloc = hist.location;
1225 if (!linemap_location_before_p (line_table, pragloc, loc))
1226 continue;
1227
1228 if (hist.kind == (int) DK_POP)
1229 {
1230 /* Move on to the next region. */
1231 i = hist.option;
1232 continue;
1233 }
1234
1235 int option = hist.option;
1236 /* The option 0 is for all the diagnostics. */
1237 if (option == 0 || option == diagnostic->option_index)
1238 {
1239 diagnostic_t kind = hist.kind;
1240 if (kind != DK_UNSPECIFIED)
1241 diagnostic->kind = kind;
1242 return kind;
1243 }
1244 }
1245 }
1246
1247 return DK_UNSPECIFIED;
1248 }
1249
1250 /* Generate a URL string describing CWE. The caller is responsible for
1251 freeing the string. */
1252
1253 char *
1254 get_cwe_url (int cwe)
1255 {
1256 return xasprintf ("https://cwe.mitre.org/data/definitions/%i.html", cwe);
1257 }
1258
1259 /* If DIAGNOSTIC has a CWE identifier, print it.
1260
1261 For example, if the diagnostic metadata associates it with CWE-119,
1262 " [CWE-119]" will be printed, suitably colorized, and with a URL of a
1263 description of the security issue. */
1264
1265 static void
1266 print_any_cwe (diagnostic_context *context,
1267 const diagnostic_info *diagnostic)
1268 {
1269 if (diagnostic->metadata == NULL)
1270 return;
1271
1272 int cwe = diagnostic->metadata->get_cwe ();
1273 if (cwe)
1274 {
1275 pretty_printer *pp = context->printer;
1276 char *saved_prefix = pp_take_prefix (context->printer);
1277 pp_string (pp, " [");
1278 pp_string (pp, colorize_start (pp_show_color (pp),
1279 diagnostic_kind_color[diagnostic->kind]));
1280 if (pp->url_format != URL_FORMAT_NONE)
1281 {
1282 char *cwe_url = get_cwe_url (cwe);
1283 pp_begin_url (pp, cwe_url);
1284 free (cwe_url);
1285 }
1286 pp_printf (pp, "CWE-%i", cwe);
1287 pp_set_prefix (context->printer, saved_prefix);
1288 if (pp->url_format != URL_FORMAT_NONE)
1289 pp_end_url (pp);
1290 pp_string (pp, colorize_stop (pp_show_color (pp)));
1291 pp_character (pp, ']');
1292 }
1293 }
1294
1295 /* If DIAGNOSTIC has any rules associated with it, print them.
1296
1297 For example, if the diagnostic metadata associates it with a rule
1298 named "STR34-C", then " [STR34-C]" will be printed, suitably colorized,
1299 with any URL provided by the rule. */
1300
1301 static void
1302 print_any_rules (diagnostic_context *context,
1303 const diagnostic_info *diagnostic)
1304 {
1305 if (diagnostic->metadata == NULL)
1306 return;
1307
1308 for (unsigned idx = 0; idx < diagnostic->metadata->get_num_rules (); idx++)
1309 {
1310 const diagnostic_metadata::rule &rule
1311 = diagnostic->metadata->get_rule (idx);
1312 if (char *desc = rule.make_description ())
1313 {
1314 pretty_printer *pp = context->printer;
1315 char *saved_prefix = pp_take_prefix (context->printer);
1316 pp_string (pp, " [");
1317 pp_string (pp,
1318 colorize_start (pp_show_color (pp),
1319 diagnostic_kind_color[diagnostic->kind]));
1320 char *url = NULL;
1321 if (pp->url_format != URL_FORMAT_NONE)
1322 {
1323 url = rule.make_url ();
1324 if (url)
1325 pp_begin_url (pp, url);
1326 }
1327 pp_string (pp, desc);
1328 pp_set_prefix (context->printer, saved_prefix);
1329 if (pp->url_format != URL_FORMAT_NONE)
1330 if (url)
1331 pp_end_url (pp);
1332 free (url);
1333 pp_string (pp, colorize_stop (pp_show_color (pp)));
1334 pp_character (pp, ']');
1335 free (desc);
1336 }
1337 }
1338 }
1339
1340 /* Print any metadata about the option used to control DIAGNOSTIC to CONTEXT's
1341 printer, e.g. " [-Werror=uninitialized]".
1342 Subroutine of diagnostic_report_diagnostic. */
1343
1344 static void
1345 print_option_information (diagnostic_context *context,
1346 const diagnostic_info *diagnostic,
1347 diagnostic_t orig_diag_kind)
1348 {
1349 char *option_text;
1350
1351 option_text = context->option_name (context, diagnostic->option_index,
1352 orig_diag_kind, diagnostic->kind);
1353
1354 if (option_text)
1355 {
1356 char *option_url = NULL;
1357 if (context->get_option_url
1358 && context->printer->url_format != URL_FORMAT_NONE)
1359 option_url = context->get_option_url (context,
1360 diagnostic->option_index);
1361 pretty_printer *pp = context->printer;
1362 pp_string (pp, " [");
1363 pp_string (pp, colorize_start (pp_show_color (pp),
1364 diagnostic_kind_color[diagnostic->kind]));
1365 if (option_url)
1366 pp_begin_url (pp, option_url);
1367 pp_string (pp, option_text);
1368 if (option_url)
1369 {
1370 pp_end_url (pp);
1371 free (option_url);
1372 }
1373 pp_string (pp, colorize_stop (pp_show_color (pp)));
1374 pp_character (pp, ']');
1375 free (option_text);
1376 }
1377 }
1378
1379 /* Returns whether a DIAGNOSTIC should be printed, and adjusts diagnostic->kind
1380 as appropriate for #pragma GCC diagnostic and -Werror=foo. */
1381
1382 static bool
1383 diagnostic_enabled (diagnostic_context *context,
1384 diagnostic_info *diagnostic)
1385 {
1386 /* Update the inlining stack for this diagnostic. */
1387 get_any_inlining_info (context, diagnostic);
1388
1389 /* Diagnostics with no option or -fpermissive are always enabled. */
1390 if (!diagnostic->option_index
1391 || diagnostic->option_index == permissive_error_option (context))
1392 return true;
1393
1394 /* This tests if the user provided the appropriate -Wfoo or
1395 -Wno-foo option. */
1396 if (! context->option_enabled (diagnostic->option_index,
1397 context->lang_mask,
1398 context->option_state))
1399 return false;
1400
1401 /* This tests for #pragma diagnostic changes. */
1402 diagnostic_t diag_class
1403 = update_effective_level_from_pragmas (context, diagnostic);
1404
1405 /* This tests if the user provided the appropriate -Werror=foo
1406 option. */
1407 if (diag_class == DK_UNSPECIFIED
1408 && (context->classify_diagnostic[diagnostic->option_index]
1409 != DK_UNSPECIFIED))
1410 diagnostic->kind
1411 = context->classify_diagnostic[diagnostic->option_index];
1412
1413 /* This allows for future extensions, like temporarily disabling
1414 warnings for ranges of source code. */
1415 if (diagnostic->kind == DK_IGNORED)
1416 return false;
1417
1418 return true;
1419 }
1420
1421 /* Returns whether warning OPT is enabled at LOC. */
1422
1423 bool
1424 warning_enabled_at (location_t loc, int opt)
1425 {
1426 if (!diagnostic_report_warnings_p (global_dc, loc))
1427 return false;
1428
1429 rich_location richloc (line_table, loc);
1430 diagnostic_info diagnostic = {};
1431 diagnostic.option_index = opt;
1432 diagnostic.richloc = &richloc;
1433 diagnostic.message.m_richloc = &richloc;
1434 diagnostic.kind = DK_WARNING;
1435 return diagnostic_enabled (global_dc, &diagnostic);
1436 }
1437
1438 /* Report a diagnostic message (an error or a warning) as specified by
1439 DC. This function is *the* subroutine in terms of which front-ends
1440 should implement their specific diagnostic handling modules. The
1441 front-end independent format specifiers are exactly those described
1442 in the documentation of output_format.
1443 Return true if a diagnostic was printed, false otherwise. */
1444
1445 bool
1446 diagnostic_report_diagnostic (diagnostic_context *context,
1447 diagnostic_info *diagnostic)
1448 {
1449 location_t location = diagnostic_location (diagnostic);
1450 diagnostic_t orig_diag_kind = diagnostic->kind;
1451
1452 /* Give preference to being able to inhibit warnings, before they
1453 get reclassified to something else. */
1454 bool report_warning_p = true;
1455 if (diagnostic->kind == DK_WARNING || diagnostic->kind == DK_PEDWARN)
1456 {
1457 if (context->dc_inhibit_warnings)
1458 return false;
1459 /* Remember the result of the overall system header warning setting
1460 but proceed to also check the inlining context. */
1461 report_warning_p = diagnostic_report_warnings_p (context, location);
1462 if (!report_warning_p && diagnostic->kind == DK_PEDWARN)
1463 return false;
1464 }
1465
1466 if (diagnostic->kind == DK_PEDWARN)
1467 {
1468 diagnostic->kind = pedantic_warning_kind (context);
1469 /* We do this to avoid giving the message for -pedantic-errors. */
1470 orig_diag_kind = diagnostic->kind;
1471 }
1472
1473 if (diagnostic->kind == DK_NOTE && context->inhibit_notes_p)
1474 return false;
1475
1476 if (context->lock > 0)
1477 {
1478 /* If we're reporting an ICE in the middle of some other error,
1479 try to flush out the previous error, then let this one
1480 through. Don't do this more than once. */
1481 if ((diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT)
1482 && context->lock == 1)
1483 pp_newline_and_flush (context->printer);
1484 else
1485 error_recursion (context);
1486 }
1487
1488 /* If the user requested that warnings be treated as errors, so be
1489 it. Note that we do this before the next block so that
1490 individual warnings can be overridden back to warnings with
1491 -Wno-error=*. */
1492 if (context->warning_as_error_requested
1493 && diagnostic->kind == DK_WARNING)
1494 diagnostic->kind = DK_ERROR;
1495
1496 diagnostic->message.x_data = &diagnostic->x_data;
1497
1498 /* Check to see if the diagnostic is enabled at the location and
1499 not disabled by #pragma GCC diagnostic anywhere along the inlining
1500 stack. . */
1501 if (!diagnostic_enabled (context, diagnostic))
1502 return false;
1503
1504 if (!report_warning_p && diagnostic->m_iinfo.m_allsyslocs)
1505 /* Bail if the warning is not to be reported because all locations
1506 in the inlining stack (if there is one) are in system headers. */
1507 return false;
1508
1509 if (diagnostic->kind != DK_NOTE && diagnostic->kind != DK_ICE)
1510 diagnostic_check_max_errors (context);
1511
1512 context->lock++;
1513
1514 if (diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT)
1515 {
1516 /* When not checking, ICEs are converted to fatal errors when an
1517 error has already occurred. This is counteracted by
1518 abort_on_error. */
1519 if (!CHECKING_P
1520 && (diagnostic_kind_count (context, DK_ERROR) > 0
1521 || diagnostic_kind_count (context, DK_SORRY) > 0)
1522 && !context->abort_on_error)
1523 {
1524 expanded_location s
1525 = expand_location (diagnostic_location (diagnostic));
1526 fnotice (stderr, "%s:%d: confused by earlier errors, bailing out\n",
1527 s.file, s.line);
1528 exit (ICE_EXIT_CODE);
1529 }
1530 if (context->internal_error)
1531 (*context->internal_error) (context,
1532 diagnostic->message.format_spec,
1533 diagnostic->message.args_ptr);
1534 }
1535 if (diagnostic->kind == DK_ERROR && orig_diag_kind == DK_WARNING)
1536 ++diagnostic_kind_count (context, DK_WERROR);
1537 else
1538 ++diagnostic_kind_count (context, diagnostic->kind);
1539
1540 /* Is this the initial diagnostic within the stack of groups? */
1541 if (context->diagnostic_group_emission_count == 0)
1542 {
1543 if (context->begin_group_cb)
1544 context->begin_group_cb (context);
1545 }
1546 context->diagnostic_group_emission_count++;
1547
1548 pp_format (context->printer, &diagnostic->message);
1549 (*diagnostic_starter (context)) (context, diagnostic);
1550 pp_output_formatted_text (context->printer);
1551 if (context->show_cwe)
1552 print_any_cwe (context, diagnostic);
1553 if (context->show_rules)
1554 print_any_rules (context, diagnostic);
1555 if (context->show_option_requested)
1556 print_option_information (context, diagnostic, orig_diag_kind);
1557 (*diagnostic_finalizer (context)) (context, diagnostic, orig_diag_kind);
1558 switch (context->extra_output_kind)
1559 {
1560 default:
1561 break;
1562 case EXTRA_DIAGNOSTIC_OUTPUT_fixits_v1:
1563 print_parseable_fixits (context->printer, diagnostic->richloc,
1564 DIAGNOSTICS_COLUMN_UNIT_BYTE,
1565 context->tabstop);
1566 pp_flush (context->printer);
1567 break;
1568 case EXTRA_DIAGNOSTIC_OUTPUT_fixits_v2:
1569 print_parseable_fixits (context->printer, diagnostic->richloc,
1570 DIAGNOSTICS_COLUMN_UNIT_DISPLAY,
1571 context->tabstop);
1572 pp_flush (context->printer);
1573 break;
1574 }
1575 diagnostic_action_after_output (context, diagnostic->kind);
1576 diagnostic->x_data = NULL;
1577
1578 if (context->edit_context_ptr)
1579 if (diagnostic->richloc->fixits_can_be_auto_applied_p ())
1580 context->edit_context_ptr->add_fixits (diagnostic->richloc);
1581
1582 context->lock--;
1583
1584 diagnostic_show_any_path (context, diagnostic);
1585
1586 return true;
1587 }
1588
1589 /* Get the number of digits in the decimal representation of VALUE. */
1590
1591 int
1592 num_digits (int value)
1593 {
1594 /* Perhaps simpler to use log10 for this, but doing it this way avoids
1595 using floating point. */
1596 gcc_assert (value >= 0);
1597
1598 if (value == 0)
1599 return 1;
1600
1601 int digits = 0;
1602 while (value > 0)
1603 {
1604 digits++;
1605 value /= 10;
1606 }
1607 return digits;
1608 }
1609
1610 /* Given a partial pathname as input, return another pathname that
1611 shares no directory elements with the pathname of __FILE__. This
1612 is used by fancy_abort() to print `internal compiler error in expr.cc'
1613 instead of `internal compiler error in ../../GCC/gcc/expr.cc'. */
1614
1615 const char *
1616 trim_filename (const char *name)
1617 {
1618 static const char this_file[] = __FILE__;
1619 const char *p = name, *q = this_file;
1620
1621 /* First skip any "../" in each filename. This allows us to give a proper
1622 reference to a file in a subdirectory. */
1623 while (p[0] == '.' && p[1] == '.' && IS_DIR_SEPARATOR (p[2]))
1624 p += 3;
1625
1626 while (q[0] == '.' && q[1] == '.' && IS_DIR_SEPARATOR (q[2]))
1627 q += 3;
1628
1629 /* Now skip any parts the two filenames have in common. */
1630 while (*p == *q && *p != 0 && *q != 0)
1631 p++, q++;
1632
1633 /* Now go backwards until the previous directory separator. */
1634 while (p > name && !IS_DIR_SEPARATOR (p[-1]))
1635 p--;
1636
1637 return p;
1638 }
1639 \f
1640 /* Standard error reporting routines in increasing order of severity.
1641 All of these take arguments like printf. */
1642
1643 /* Text to be emitted verbatim to the error message stream; this
1644 produces no prefix and disables line-wrapping. Use rarely. */
1645 void
1646 verbatim (const char *gmsgid, ...)
1647 {
1648 text_info text;
1649 va_list ap;
1650
1651 va_start (ap, gmsgid);
1652 text.err_no = errno;
1653 text.args_ptr = &ap;
1654 text.format_spec = _(gmsgid);
1655 text.x_data = NULL;
1656 pp_format_verbatim (global_dc->printer, &text);
1657 pp_newline_and_flush (global_dc->printer);
1658 va_end (ap);
1659 }
1660
1661 /* Add a note with text GMSGID and with LOCATION to the diagnostic CONTEXT. */
1662 void
1663 diagnostic_append_note (diagnostic_context *context,
1664 location_t location,
1665 const char * gmsgid, ...)
1666 {
1667 diagnostic_info diagnostic;
1668 va_list ap;
1669 rich_location richloc (line_table, location);
1670
1671 va_start (ap, gmsgid);
1672 diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_NOTE);
1673 if (context->inhibit_notes_p)
1674 {
1675 va_end (ap);
1676 return;
1677 }
1678 char *saved_prefix = pp_take_prefix (context->printer);
1679 pp_set_prefix (context->printer,
1680 diagnostic_build_prefix (context, &diagnostic));
1681 pp_format (context->printer, &diagnostic.message);
1682 pp_output_formatted_text (context->printer);
1683 pp_destroy_prefix (context->printer);
1684 pp_set_prefix (context->printer, saved_prefix);
1685 pp_newline (context->printer);
1686 diagnostic_show_locus (context, &richloc, DK_NOTE);
1687 va_end (ap);
1688 }
1689
1690 /* Implement emit_diagnostic, inform, warning, warning_at, pedwarn,
1691 permerror, error, error_at, error_at, sorry, fatal_error, internal_error,
1692 and internal_error_no_backtrace, as documented and defined below. */
1693 static bool
1694 diagnostic_impl (rich_location *richloc, const diagnostic_metadata *metadata,
1695 int opt, const char *gmsgid,
1696 va_list *ap, diagnostic_t kind)
1697 {
1698 diagnostic_info diagnostic;
1699 if (kind == DK_PERMERROR)
1700 {
1701 diagnostic_set_info (&diagnostic, gmsgid, ap, richloc,
1702 permissive_error_kind (global_dc));
1703 diagnostic.option_index = permissive_error_option (global_dc);
1704 }
1705 else
1706 {
1707 diagnostic_set_info (&diagnostic, gmsgid, ap, richloc, kind);
1708 if (kind == DK_WARNING || kind == DK_PEDWARN)
1709 diagnostic.option_index = opt;
1710 }
1711 diagnostic.metadata = metadata;
1712 return diagnostic_report_diagnostic (global_dc, &diagnostic);
1713 }
1714
1715 /* Implement inform_n, warning_n, and error_n, as documented and
1716 defined below. */
1717 static bool
1718 diagnostic_n_impl (rich_location *richloc, const diagnostic_metadata *metadata,
1719 int opt, unsigned HOST_WIDE_INT n,
1720 const char *singular_gmsgid,
1721 const char *plural_gmsgid,
1722 va_list *ap, diagnostic_t kind)
1723 {
1724 diagnostic_info diagnostic;
1725 unsigned long gtn;
1726
1727 if (sizeof n <= sizeof gtn)
1728 gtn = n;
1729 else
1730 /* Use the largest number ngettext can handle, otherwise
1731 preserve the six least significant decimal digits for
1732 languages where the plural form depends on them. */
1733 gtn = n <= ULONG_MAX ? n : n % 1000000LU + 1000000LU;
1734
1735 const char *text = ngettext (singular_gmsgid, plural_gmsgid, gtn);
1736 diagnostic_set_info_translated (&diagnostic, text, ap, richloc, kind);
1737 if (kind == DK_WARNING)
1738 diagnostic.option_index = opt;
1739 diagnostic.metadata = metadata;
1740 return diagnostic_report_diagnostic (global_dc, &diagnostic);
1741 }
1742
1743 /* Wrapper around diagnostic_impl taking a variable argument list. */
1744
1745 bool
1746 emit_diagnostic (diagnostic_t kind, location_t location, int opt,
1747 const char *gmsgid, ...)
1748 {
1749 auto_diagnostic_group d;
1750 va_list ap;
1751 va_start (ap, gmsgid);
1752 rich_location richloc (line_table, location);
1753 bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, kind);
1754 va_end (ap);
1755 return ret;
1756 }
1757
1758 /* As above, but for rich_location *. */
1759
1760 bool
1761 emit_diagnostic (diagnostic_t kind, rich_location *richloc, int opt,
1762 const char *gmsgid, ...)
1763 {
1764 auto_diagnostic_group d;
1765 va_list ap;
1766 va_start (ap, gmsgid);
1767 bool ret = diagnostic_impl (richloc, NULL, opt, gmsgid, &ap, kind);
1768 va_end (ap);
1769 return ret;
1770 }
1771
1772 /* Wrapper around diagnostic_impl taking a va_list parameter. */
1773
1774 bool
1775 emit_diagnostic_valist (diagnostic_t kind, location_t location, int opt,
1776 const char *gmsgid, va_list *ap)
1777 {
1778 rich_location richloc (line_table, location);
1779 return diagnostic_impl (&richloc, NULL, opt, gmsgid, ap, kind);
1780 }
1781
1782 /* An informative note at LOCATION. Use this for additional details on an error
1783 message. */
1784 void
1785 inform (location_t location, const char *gmsgid, ...)
1786 {
1787 auto_diagnostic_group d;
1788 va_list ap;
1789 va_start (ap, gmsgid);
1790 rich_location richloc (line_table, location);
1791 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_NOTE);
1792 va_end (ap);
1793 }
1794
1795 /* Same as "inform" above, but at RICHLOC. */
1796 void
1797 inform (rich_location *richloc, const char *gmsgid, ...)
1798 {
1799 gcc_assert (richloc);
1800
1801 auto_diagnostic_group d;
1802 va_list ap;
1803 va_start (ap, gmsgid);
1804 diagnostic_impl (richloc, NULL, -1, gmsgid, &ap, DK_NOTE);
1805 va_end (ap);
1806 }
1807
1808 /* An informative note at LOCATION. Use this for additional details on an
1809 error message. */
1810 void
1811 inform_n (location_t location, unsigned HOST_WIDE_INT n,
1812 const char *singular_gmsgid, const char *plural_gmsgid, ...)
1813 {
1814 va_list ap;
1815 va_start (ap, plural_gmsgid);
1816 auto_diagnostic_group d;
1817 rich_location richloc (line_table, location);
1818 diagnostic_n_impl (&richloc, NULL, -1, n, singular_gmsgid, plural_gmsgid,
1819 &ap, DK_NOTE);
1820 va_end (ap);
1821 }
1822
1823 /* A warning at INPUT_LOCATION. Use this for code which is correct according
1824 to the relevant language specification but is likely to be buggy anyway.
1825 Returns true if the warning was printed, false if it was inhibited. */
1826 bool
1827 warning (int opt, const char *gmsgid, ...)
1828 {
1829 auto_diagnostic_group d;
1830 va_list ap;
1831 va_start (ap, gmsgid);
1832 rich_location richloc (line_table, input_location);
1833 bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, DK_WARNING);
1834 va_end (ap);
1835 return ret;
1836 }
1837
1838 /* A warning at LOCATION. Use this for code which is correct according to the
1839 relevant language specification but is likely to be buggy anyway.
1840 Returns true if the warning was printed, false if it was inhibited. */
1841
1842 bool
1843 warning_at (location_t location, int opt, const char *gmsgid, ...)
1844 {
1845 auto_diagnostic_group d;
1846 va_list ap;
1847 va_start (ap, gmsgid);
1848 rich_location richloc (line_table, location);
1849 bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, DK_WARNING);
1850 va_end (ap);
1851 return ret;
1852 }
1853
1854 /* Same as "warning at" above, but using RICHLOC. */
1855
1856 bool
1857 warning_at (rich_location *richloc, int opt, const char *gmsgid, ...)
1858 {
1859 gcc_assert (richloc);
1860
1861 auto_diagnostic_group d;
1862 va_list ap;
1863 va_start (ap, gmsgid);
1864 bool ret = diagnostic_impl (richloc, NULL, opt, gmsgid, &ap, DK_WARNING);
1865 va_end (ap);
1866 return ret;
1867 }
1868
1869 /* Same as "warning at" above, but using METADATA. */
1870
1871 bool
1872 warning_meta (rich_location *richloc,
1873 const diagnostic_metadata &metadata,
1874 int opt, const char *gmsgid, ...)
1875 {
1876 gcc_assert (richloc);
1877
1878 auto_diagnostic_group d;
1879 va_list ap;
1880 va_start (ap, gmsgid);
1881 bool ret
1882 = diagnostic_impl (richloc, &metadata, opt, gmsgid, &ap,
1883 DK_WARNING);
1884 va_end (ap);
1885 return ret;
1886 }
1887
1888 /* Same as warning_n plural variant below, but using RICHLOC. */
1889
1890 bool
1891 warning_n (rich_location *richloc, int opt, unsigned HOST_WIDE_INT n,
1892 const char *singular_gmsgid, const char *plural_gmsgid, ...)
1893 {
1894 gcc_assert (richloc);
1895
1896 auto_diagnostic_group d;
1897 va_list ap;
1898 va_start (ap, plural_gmsgid);
1899 bool ret = diagnostic_n_impl (richloc, NULL, opt, n,
1900 singular_gmsgid, plural_gmsgid,
1901 &ap, DK_WARNING);
1902 va_end (ap);
1903 return ret;
1904 }
1905
1906 /* A warning at LOCATION. Use this for code which is correct according to the
1907 relevant language specification but is likely to be buggy anyway.
1908 Returns true if the warning was printed, false if it was inhibited. */
1909
1910 bool
1911 warning_n (location_t location, int opt, unsigned HOST_WIDE_INT n,
1912 const char *singular_gmsgid, const char *plural_gmsgid, ...)
1913 {
1914 auto_diagnostic_group d;
1915 va_list ap;
1916 va_start (ap, plural_gmsgid);
1917 rich_location richloc (line_table, location);
1918 bool ret = diagnostic_n_impl (&richloc, NULL, opt, n,
1919 singular_gmsgid, plural_gmsgid,
1920 &ap, DK_WARNING);
1921 va_end (ap);
1922 return ret;
1923 }
1924
1925 /* A "pedantic" warning at LOCATION: issues a warning unless
1926 -pedantic-errors was given on the command line, in which case it
1927 issues an error. Use this for diagnostics required by the relevant
1928 language standard, if you have chosen not to make them errors.
1929
1930 Note that these diagnostics are issued independent of the setting
1931 of the -Wpedantic command-line switch. To get a warning enabled
1932 only with that switch, use either "if (pedantic) pedwarn
1933 (OPT_Wpedantic,...)" or just "pedwarn (OPT_Wpedantic,..)". To get a
1934 pedwarn independently of the -Wpedantic switch use "pedwarn (0,...)".
1935
1936 Returns true if the warning was printed, false if it was inhibited. */
1937
1938 bool
1939 pedwarn (location_t location, int opt, const char *gmsgid, ...)
1940 {
1941 auto_diagnostic_group d;
1942 va_list ap;
1943 va_start (ap, gmsgid);
1944 rich_location richloc (line_table, location);
1945 bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, DK_PEDWARN);
1946 va_end (ap);
1947 return ret;
1948 }
1949
1950 /* Same as pedwarn above, but using RICHLOC. */
1951
1952 bool
1953 pedwarn (rich_location *richloc, int opt, const char *gmsgid, ...)
1954 {
1955 gcc_assert (richloc);
1956
1957 auto_diagnostic_group d;
1958 va_list ap;
1959 va_start (ap, gmsgid);
1960 bool ret = diagnostic_impl (richloc, NULL, opt, gmsgid, &ap, DK_PEDWARN);
1961 va_end (ap);
1962 return ret;
1963 }
1964
1965 /* A "permissive" error at LOCATION: issues an error unless
1966 -fpermissive was given on the command line, in which case it issues
1967 a warning. Use this for things that really should be errors but we
1968 want to support legacy code.
1969
1970 Returns true if the warning was printed, false if it was inhibited. */
1971
1972 bool
1973 permerror (location_t location, const char *gmsgid, ...)
1974 {
1975 auto_diagnostic_group d;
1976 va_list ap;
1977 va_start (ap, gmsgid);
1978 rich_location richloc (line_table, location);
1979 bool ret = diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_PERMERROR);
1980 va_end (ap);
1981 return ret;
1982 }
1983
1984 /* Same as "permerror" above, but at RICHLOC. */
1985
1986 bool
1987 permerror (rich_location *richloc, const char *gmsgid, ...)
1988 {
1989 gcc_assert (richloc);
1990
1991 auto_diagnostic_group d;
1992 va_list ap;
1993 va_start (ap, gmsgid);
1994 bool ret = diagnostic_impl (richloc, NULL, -1, gmsgid, &ap, DK_PERMERROR);
1995 va_end (ap);
1996 return ret;
1997 }
1998
1999 /* A hard error: the code is definitely ill-formed, and an object file
2000 will not be produced. */
2001 void
2002 error (const char *gmsgid, ...)
2003 {
2004 auto_diagnostic_group d;
2005 va_list ap;
2006 va_start (ap, gmsgid);
2007 rich_location richloc (line_table, input_location);
2008 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ERROR);
2009 va_end (ap);
2010 }
2011
2012 /* A hard error: the code is definitely ill-formed, and an object file
2013 will not be produced. */
2014 void
2015 error_n (location_t location, unsigned HOST_WIDE_INT n,
2016 const char *singular_gmsgid, const char *plural_gmsgid, ...)
2017 {
2018 auto_diagnostic_group d;
2019 va_list ap;
2020 va_start (ap, plural_gmsgid);
2021 rich_location richloc (line_table, location);
2022 diagnostic_n_impl (&richloc, NULL, -1, n, singular_gmsgid, plural_gmsgid,
2023 &ap, DK_ERROR);
2024 va_end (ap);
2025 }
2026
2027 /* Same as above, but use location LOC instead of input_location. */
2028 void
2029 error_at (location_t loc, const char *gmsgid, ...)
2030 {
2031 auto_diagnostic_group d;
2032 va_list ap;
2033 va_start (ap, gmsgid);
2034 rich_location richloc (line_table, loc);
2035 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ERROR);
2036 va_end (ap);
2037 }
2038
2039 /* Same as above, but use RICH_LOC. */
2040
2041 void
2042 error_at (rich_location *richloc, const char *gmsgid, ...)
2043 {
2044 gcc_assert (richloc);
2045
2046 auto_diagnostic_group d;
2047 va_list ap;
2048 va_start (ap, gmsgid);
2049 diagnostic_impl (richloc, NULL, -1, gmsgid, &ap, DK_ERROR);
2050 va_end (ap);
2051 }
2052
2053 /* "Sorry, not implemented." Use for a language feature which is
2054 required by the relevant specification but not implemented by GCC.
2055 An object file will not be produced. */
2056 void
2057 sorry (const char *gmsgid, ...)
2058 {
2059 auto_diagnostic_group d;
2060 va_list ap;
2061 va_start (ap, gmsgid);
2062 rich_location richloc (line_table, input_location);
2063 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_SORRY);
2064 va_end (ap);
2065 }
2066
2067 /* Same as above, but use location LOC instead of input_location. */
2068 void
2069 sorry_at (location_t loc, const char *gmsgid, ...)
2070 {
2071 auto_diagnostic_group d;
2072 va_list ap;
2073 va_start (ap, gmsgid);
2074 rich_location richloc (line_table, loc);
2075 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_SORRY);
2076 va_end (ap);
2077 }
2078
2079 /* Return true if an error or a "sorry" has been seen. Various
2080 processing is disabled after errors. */
2081 bool
2082 seen_error (void)
2083 {
2084 return errorcount || sorrycount;
2085 }
2086
2087 /* An error which is severe enough that we make no attempt to
2088 continue. Do not use this for internal consistency checks; that's
2089 internal_error. Use of this function should be rare. */
2090 void
2091 fatal_error (location_t loc, const char *gmsgid, ...)
2092 {
2093 auto_diagnostic_group d;
2094 va_list ap;
2095 va_start (ap, gmsgid);
2096 rich_location richloc (line_table, loc);
2097 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_FATAL);
2098 va_end (ap);
2099
2100 gcc_unreachable ();
2101 }
2102
2103 /* An internal consistency check has failed. We make no attempt to
2104 continue. */
2105 void
2106 internal_error (const char *gmsgid, ...)
2107 {
2108 auto_diagnostic_group d;
2109 va_list ap;
2110 va_start (ap, gmsgid);
2111 rich_location richloc (line_table, input_location);
2112 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ICE);
2113 va_end (ap);
2114
2115 gcc_unreachable ();
2116 }
2117
2118 /* Like internal_error, but no backtrace will be printed. Used when
2119 the internal error does not happen at the current location, but happened
2120 somewhere else. */
2121 void
2122 internal_error_no_backtrace (const char *gmsgid, ...)
2123 {
2124 auto_diagnostic_group d;
2125 va_list ap;
2126 va_start (ap, gmsgid);
2127 rich_location richloc (line_table, input_location);
2128 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ICE_NOBT);
2129 va_end (ap);
2130
2131 gcc_unreachable ();
2132 }
2133 \f
2134 /* Special case error functions. Most are implemented in terms of the
2135 above, or should be. */
2136
2137 /* Print a diagnostic MSGID on FILE. This is just fprintf, except it
2138 runs its second argument through gettext. */
2139 void
2140 fnotice (FILE *file, const char *cmsgid, ...)
2141 {
2142 va_list ap;
2143
2144 va_start (ap, cmsgid);
2145 vfprintf (file, _(cmsgid), ap);
2146 va_end (ap);
2147 }
2148
2149 /* Inform the user that an error occurred while trying to report some
2150 other error. This indicates catastrophic internal inconsistencies,
2151 so give up now. But do try to flush out the previous error.
2152 This mustn't use internal_error, that will cause infinite recursion. */
2153
2154 static void
2155 error_recursion (diagnostic_context *context)
2156 {
2157 if (context->lock < 3)
2158 pp_newline_and_flush (context->printer);
2159
2160 fnotice (stderr,
2161 "internal compiler error: error reporting routines re-entered.\n");
2162
2163 /* Call diagnostic_action_after_output to get the "please submit a bug
2164 report" message. */
2165 diagnostic_action_after_output (context, DK_ICE);
2166
2167 /* Do not use gcc_unreachable here; that goes through internal_error
2168 and therefore would cause infinite recursion. */
2169 real_abort ();
2170 }
2171
2172 /* Report an internal compiler error in a friendly manner. This is
2173 the function that gets called upon use of abort() in the source
2174 code generally, thanks to a special macro. */
2175
2176 void
2177 fancy_abort (const char *file, int line, const char *function)
2178 {
2179 /* If fancy_abort is called before the diagnostic subsystem is initialized,
2180 internal_error will crash internally in a way that prevents a
2181 useful message reaching the user.
2182 This can happen with libgccjit in the case of gcc_assert failures
2183 that occur outside of the libgccjit mutex that guards the rest of
2184 gcc's state, including global_dc (when global_dc may not be
2185 initialized yet, or might be in use by another thread).
2186 Handle such cases as gracefully as possible by falling back to a
2187 minimal abort handler that only relies on i18n. */
2188 if (global_dc->printer == NULL)
2189 {
2190 /* Print the error message. */
2191 fnotice (stderr, diagnostic_kind_text[DK_ICE]);
2192 fnotice (stderr, "in %s, at %s:%d", function, trim_filename (file), line);
2193 fputc ('\n', stderr);
2194
2195 /* Attempt to print a backtrace. */
2196 struct backtrace_state *state
2197 = backtrace_create_state (NULL, 0, bt_err_callback, NULL);
2198 int count = 0;
2199 if (state != NULL)
2200 backtrace_full (state, 2, bt_callback, bt_err_callback,
2201 (void *) &count);
2202
2203 /* We can't call warn_if_plugins or emergency_dump_function as these
2204 rely on GCC state that might not be initialized, or might be in
2205 use by another thread. */
2206
2207 /* Abort the process. */
2208 real_abort ();
2209 }
2210
2211 internal_error ("in %s, at %s:%d", function, trim_filename (file), line);
2212 }
2213
2214 /* class auto_diagnostic_group. */
2215
2216 /* Constructor: "push" this group into global_dc. */
2217
2218 auto_diagnostic_group::auto_diagnostic_group ()
2219 {
2220 global_dc->diagnostic_group_nesting_depth++;
2221 }
2222
2223 /* Destructor: "pop" this group from global_dc. */
2224
2225 auto_diagnostic_group::~auto_diagnostic_group ()
2226 {
2227 if (--global_dc->diagnostic_group_nesting_depth == 0)
2228 {
2229 /* Handle the case where we've popped the final diagnostic group.
2230 If any diagnostics were emitted, give the context a chance
2231 to do something. */
2232 if (global_dc->diagnostic_group_emission_count > 0)
2233 {
2234 if (global_dc->end_group_cb)
2235 global_dc->end_group_cb (global_dc);
2236 }
2237 global_dc->diagnostic_group_emission_count = 0;
2238 }
2239 }
2240
2241 /* Set the output format for CONTEXT to FORMAT, using BASE_FILE_NAME for
2242 file-based output formats. */
2243
2244 void
2245 diagnostic_output_format_init (diagnostic_context *context,
2246 const char *base_file_name,
2247 enum diagnostics_output_format format)
2248 {
2249 switch (format)
2250 {
2251 default:
2252 gcc_unreachable ();
2253 case DIAGNOSTICS_OUTPUT_FORMAT_TEXT:
2254 /* The default; do nothing. */
2255 break;
2256
2257 case DIAGNOSTICS_OUTPUT_FORMAT_JSON_STDERR:
2258 diagnostic_output_format_init_json_stderr (context);
2259 break;
2260
2261 case DIAGNOSTICS_OUTPUT_FORMAT_JSON_FILE:
2262 diagnostic_output_format_init_json_file (context, base_file_name);
2263 break;
2264
2265 case DIAGNOSTICS_OUTPUT_FORMAT_SARIF_STDERR:
2266 diagnostic_output_format_init_sarif_stderr (context);
2267 break;
2268
2269 case DIAGNOSTICS_OUTPUT_FORMAT_SARIF_FILE:
2270 diagnostic_output_format_init_sarif_file (context, base_file_name);
2271 break;
2272 }
2273 }
2274
2275 /* Implementation of diagnostic_path::num_events vfunc for
2276 simple_diagnostic_path: simply get the number of events in the vec. */
2277
2278 unsigned
2279 simple_diagnostic_path::num_events () const
2280 {
2281 return m_events.length ();
2282 }
2283
2284 /* Implementation of diagnostic_path::get_event vfunc for
2285 simple_diagnostic_path: simply return the event in the vec. */
2286
2287 const diagnostic_event &
2288 simple_diagnostic_path::get_event (int idx) const
2289 {
2290 return *m_events[idx];
2291 }
2292
2293 /* Add an event to this path at LOC within function FNDECL at
2294 stack depth DEPTH.
2295
2296 Use m_context's printer to format FMT, as the text of the new
2297 event.
2298
2299 Return the id of the new event. */
2300
2301 diagnostic_event_id_t
2302 simple_diagnostic_path::add_event (location_t loc, tree fndecl, int depth,
2303 const char *fmt, ...)
2304 {
2305 pretty_printer *pp = m_event_pp;
2306 pp_clear_output_area (pp);
2307
2308 text_info ti;
2309 rich_location rich_loc (line_table, UNKNOWN_LOCATION);
2310
2311 va_list ap;
2312
2313 va_start (ap, fmt);
2314
2315 ti.format_spec = _(fmt);
2316 ti.args_ptr = &ap;
2317 ti.err_no = 0;
2318 ti.x_data = NULL;
2319 ti.m_richloc = &rich_loc;
2320
2321 pp_format (pp, &ti);
2322 pp_output_formatted_text (pp);
2323
2324 va_end (ap);
2325
2326 simple_diagnostic_event *new_event
2327 = new simple_diagnostic_event (loc, fndecl, depth, pp_formatted_text (pp));
2328 m_events.safe_push (new_event);
2329
2330 pp_clear_output_area (pp);
2331
2332 return diagnostic_event_id_t (m_events.length () - 1);
2333 }
2334
2335 /* struct simple_diagnostic_event. */
2336
2337 /* simple_diagnostic_event's ctor. */
2338
2339 simple_diagnostic_event::simple_diagnostic_event (location_t loc,
2340 tree fndecl,
2341 int depth,
2342 const char *desc)
2343 : m_loc (loc), m_fndecl (fndecl), m_depth (depth), m_desc (xstrdup (desc))
2344 {
2345 }
2346
2347 /* simple_diagnostic_event's dtor. */
2348
2349 simple_diagnostic_event::~simple_diagnostic_event ()
2350 {
2351 free (m_desc);
2352 }
2353
2354 /* Print PATH by emitting a dummy "note" associated with it. */
2355
2356 DEBUG_FUNCTION
2357 void debug (diagnostic_path *path)
2358 {
2359 rich_location richloc (line_table, UNKNOWN_LOCATION);
2360 richloc.set_path (path);
2361 inform (&richloc, "debug path");
2362 }
2363
2364 /* Really call the system 'abort'. This has to go right at the end of
2365 this file, so that there are no functions after it that call abort
2366 and get the system abort instead of our macro. */
2367 #undef abort
2368 static void
2369 real_abort (void)
2370 {
2371 abort ();
2372 }
2373
2374 #if CHECKING_P
2375
2376 namespace selftest {
2377
2378 /* Helper function for test_print_escaped_string. */
2379
2380 static void
2381 assert_print_escaped_string (const location &loc, const char *expected_output,
2382 const char *input)
2383 {
2384 pretty_printer pp;
2385 print_escaped_string (&pp, input);
2386 ASSERT_STREQ_AT (loc, expected_output, pp_formatted_text (&pp));
2387 }
2388
2389 #define ASSERT_PRINT_ESCAPED_STRING_STREQ(EXPECTED_OUTPUT, INPUT) \
2390 assert_print_escaped_string (SELFTEST_LOCATION, EXPECTED_OUTPUT, INPUT)
2391
2392 /* Tests of print_escaped_string. */
2393
2394 static void
2395 test_print_escaped_string ()
2396 {
2397 /* Empty string. */
2398 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"\"", "");
2399
2400 /* Non-empty string. */
2401 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"hello world\"", "hello world");
2402
2403 /* Various things that need to be escaped: */
2404 /* Backslash. */
2405 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\\\after\"",
2406 "before\\after");
2407 /* Tab. */
2408 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\tafter\"",
2409 "before\tafter");
2410 /* Newline. */
2411 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\nafter\"",
2412 "before\nafter");
2413 /* Double quote. */
2414 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\\"after\"",
2415 "before\"after");
2416
2417 /* Non-printable characters: BEL: '\a': 0x07 */
2418 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\007after\"",
2419 "before\aafter");
2420 /* Non-printable characters: vertical tab: '\v': 0x0b */
2421 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\013after\"",
2422 "before\vafter");
2423 }
2424
2425 /* Tests of print_parseable_fixits. */
2426
2427 /* Verify that print_parseable_fixits emits the empty string if there
2428 are no fixits. */
2429
2430 static void
2431 test_print_parseable_fixits_none ()
2432 {
2433 pretty_printer pp;
2434 rich_location richloc (line_table, UNKNOWN_LOCATION);
2435
2436 print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_BYTE, 8);
2437 ASSERT_STREQ ("", pp_formatted_text (&pp));
2438 }
2439
2440 /* Verify that print_parseable_fixits does the right thing if there
2441 is an insertion fixit hint. */
2442
2443 static void
2444 test_print_parseable_fixits_insert ()
2445 {
2446 pretty_printer pp;
2447 rich_location richloc (line_table, UNKNOWN_LOCATION);
2448
2449 linemap_add (line_table, LC_ENTER, false, "test.c", 0);
2450 linemap_line_start (line_table, 5, 100);
2451 linemap_add (line_table, LC_LEAVE, false, NULL, 0);
2452 location_t where = linemap_position_for_column (line_table, 10);
2453 richloc.add_fixit_insert_before (where, "added content");
2454
2455 print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_BYTE, 8);
2456 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:10}:\"added content\"\n",
2457 pp_formatted_text (&pp));
2458 }
2459
2460 /* Verify that print_parseable_fixits does the right thing if there
2461 is an removal fixit hint. */
2462
2463 static void
2464 test_print_parseable_fixits_remove ()
2465 {
2466 pretty_printer pp;
2467 rich_location richloc (line_table, UNKNOWN_LOCATION);
2468
2469 linemap_add (line_table, LC_ENTER, false, "test.c", 0);
2470 linemap_line_start (line_table, 5, 100);
2471 linemap_add (line_table, LC_LEAVE, false, NULL, 0);
2472 source_range where;
2473 where.m_start = linemap_position_for_column (line_table, 10);
2474 where.m_finish = linemap_position_for_column (line_table, 20);
2475 richloc.add_fixit_remove (where);
2476
2477 print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_BYTE, 8);
2478 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:21}:\"\"\n",
2479 pp_formatted_text (&pp));
2480 }
2481
2482 /* Verify that print_parseable_fixits does the right thing if there
2483 is an replacement fixit hint. */
2484
2485 static void
2486 test_print_parseable_fixits_replace ()
2487 {
2488 pretty_printer pp;
2489 rich_location richloc (line_table, UNKNOWN_LOCATION);
2490
2491 linemap_add (line_table, LC_ENTER, false, "test.c", 0);
2492 linemap_line_start (line_table, 5, 100);
2493 linemap_add (line_table, LC_LEAVE, false, NULL, 0);
2494 source_range where;
2495 where.m_start = linemap_position_for_column (line_table, 10);
2496 where.m_finish = linemap_position_for_column (line_table, 20);
2497 richloc.add_fixit_replace (where, "replacement");
2498
2499 print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_BYTE, 8);
2500 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:21}:\"replacement\"\n",
2501 pp_formatted_text (&pp));
2502 }
2503
2504 /* Verify that print_parseable_fixits correctly handles
2505 DIAGNOSTICS_COLUMN_UNIT_BYTE vs DIAGNOSTICS_COLUMN_UNIT_COLUMN. */
2506
2507 static void
2508 test_print_parseable_fixits_bytes_vs_display_columns ()
2509 {
2510 line_table_test ltt;
2511 rich_location richloc (line_table, UNKNOWN_LOCATION);
2512
2513 /* 1-based byte offsets: 12345677778888999900001234567. */
2514 const char *const content = "smile \xf0\x9f\x98\x82 colour\n";
2515 /* 1-based display cols: 123456[......7-8.....]9012345. */
2516 const int tabstop = 8;
2517
2518 temp_source_file tmp (SELFTEST_LOCATION, ".c", content);
2519 const char *const fname = tmp.get_filename ();
2520
2521 linemap_add (line_table, LC_ENTER, false, fname, 0);
2522 linemap_line_start (line_table, 1, 100);
2523 linemap_add (line_table, LC_LEAVE, false, NULL, 0);
2524 source_range where;
2525 where.m_start = linemap_position_for_column (line_table, 12);
2526 where.m_finish = linemap_position_for_column (line_table, 17);
2527 richloc.add_fixit_replace (where, "color");
2528
2529 /* Escape fname. */
2530 pretty_printer tmp_pp;
2531 print_escaped_string (&tmp_pp, fname);
2532 char *escaped_fname = xstrdup (pp_formatted_text (&tmp_pp));
2533
2534 const int buf_len = strlen (escaped_fname) + 100;
2535 char *const expected = XNEWVEC (char, buf_len);
2536
2537 {
2538 pretty_printer pp;
2539 print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_BYTE,
2540 tabstop);
2541 snprintf (expected, buf_len,
2542 "fix-it:%s:{1:12-1:18}:\"color\"\n", escaped_fname);
2543 ASSERT_STREQ (expected, pp_formatted_text (&pp));
2544 }
2545 {
2546 pretty_printer pp;
2547 print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_DISPLAY,
2548 tabstop);
2549 snprintf (expected, buf_len,
2550 "fix-it:%s:{1:10-1:16}:\"color\"\n", escaped_fname);
2551 ASSERT_STREQ (expected, pp_formatted_text (&pp));
2552 }
2553
2554 XDELETEVEC (expected);
2555 free (escaped_fname);
2556 }
2557
2558 /* Verify that
2559 diagnostic_get_location_text (..., SHOW_COLUMN)
2560 generates EXPECTED_LOC_TEXT, given FILENAME, LINE, COLUMN, with
2561 colorization disabled. */
2562
2563 static void
2564 assert_location_text (const char *expected_loc_text,
2565 const char *filename, int line, int column,
2566 bool show_column,
2567 int origin = 1,
2568 enum diagnostics_column_unit column_unit
2569 = DIAGNOSTICS_COLUMN_UNIT_BYTE)
2570 {
2571 test_diagnostic_context dc;
2572 dc.show_column = show_column;
2573 dc.column_unit = column_unit;
2574 dc.column_origin = origin;
2575
2576 expanded_location xloc;
2577 xloc.file = filename;
2578 xloc.line = line;
2579 xloc.column = column;
2580 xloc.data = NULL;
2581 xloc.sysp = false;
2582
2583 char *actual_loc_text = diagnostic_get_location_text (&dc, xloc);
2584 ASSERT_STREQ (expected_loc_text, actual_loc_text);
2585 free (actual_loc_text);
2586 }
2587
2588 /* Verify that diagnostic_get_location_text works as expected. */
2589
2590 static void
2591 test_diagnostic_get_location_text ()
2592 {
2593 const char *old_progname = progname;
2594 progname = "PROGNAME";
2595 assert_location_text ("PROGNAME:", NULL, 0, 0, true);
2596 assert_location_text ("<built-in>:", "<built-in>", 42, 10, true);
2597 assert_location_text ("foo.c:42:10:", "foo.c", 42, 10, true);
2598 assert_location_text ("foo.c:42:9:", "foo.c", 42, 10, true, 0);
2599 assert_location_text ("foo.c:42:1010:", "foo.c", 42, 10, true, 1001);
2600 for (int origin = 0; origin != 2; ++origin)
2601 assert_location_text ("foo.c:42:", "foo.c", 42, 0, true, origin);
2602 assert_location_text ("foo.c:", "foo.c", 0, 10, true);
2603 assert_location_text ("foo.c:42:", "foo.c", 42, 10, false);
2604 assert_location_text ("foo.c:", "foo.c", 0, 10, false);
2605
2606 maybe_line_and_column (INT_MAX, INT_MAX);
2607 maybe_line_and_column (INT_MIN, INT_MIN);
2608
2609 {
2610 /* In order to test display columns vs byte columns, we need to create a
2611 file for location_get_source_line() to read. */
2612
2613 const char *const content = "smile \xf0\x9f\x98\x82\n";
2614 const int line_bytes = strlen (content) - 1;
2615 const int def_tabstop = 8;
2616 const cpp_char_column_policy policy (def_tabstop, cpp_wcwidth);
2617 const int display_width = cpp_display_width (content, line_bytes, policy);
2618 ASSERT_EQ (line_bytes - 2, display_width);
2619 temp_source_file tmp (SELFTEST_LOCATION, ".c", content);
2620 const char *const fname = tmp.get_filename ();
2621 const int buf_len = strlen (fname) + 16;
2622 char *const expected = XNEWVEC (char, buf_len);
2623
2624 snprintf (expected, buf_len, "%s:1:%d:", fname, line_bytes);
2625 assert_location_text (expected, fname, 1, line_bytes, true,
2626 1, DIAGNOSTICS_COLUMN_UNIT_BYTE);
2627
2628 snprintf (expected, buf_len, "%s:1:%d:", fname, line_bytes - 1);
2629 assert_location_text (expected, fname, 1, line_bytes, true,
2630 0, DIAGNOSTICS_COLUMN_UNIT_BYTE);
2631
2632 snprintf (expected, buf_len, "%s:1:%d:", fname, display_width);
2633 assert_location_text (expected, fname, 1, line_bytes, true,
2634 1, DIAGNOSTICS_COLUMN_UNIT_DISPLAY);
2635
2636 snprintf (expected, buf_len, "%s:1:%d:", fname, display_width - 1);
2637 assert_location_text (expected, fname, 1, line_bytes, true,
2638 0, DIAGNOSTICS_COLUMN_UNIT_DISPLAY);
2639
2640 XDELETEVEC (expected);
2641 }
2642
2643
2644 progname = old_progname;
2645 }
2646
2647 /* Selftest for num_digits. */
2648
2649 static void
2650 test_num_digits ()
2651 {
2652 ASSERT_EQ (1, num_digits (0));
2653 ASSERT_EQ (1, num_digits (9));
2654 ASSERT_EQ (2, num_digits (10));
2655 ASSERT_EQ (2, num_digits (99));
2656 ASSERT_EQ (3, num_digits (100));
2657 ASSERT_EQ (3, num_digits (999));
2658 ASSERT_EQ (4, num_digits (1000));
2659 ASSERT_EQ (4, num_digits (9999));
2660 ASSERT_EQ (5, num_digits (10000));
2661 ASSERT_EQ (5, num_digits (99999));
2662 ASSERT_EQ (6, num_digits (100000));
2663 ASSERT_EQ (6, num_digits (999999));
2664 ASSERT_EQ (7, num_digits (1000000));
2665 ASSERT_EQ (7, num_digits (9999999));
2666 ASSERT_EQ (8, num_digits (10000000));
2667 ASSERT_EQ (8, num_digits (99999999));
2668 }
2669
2670 /* Run all of the selftests within this file. */
2671
2672 void
2673 c_diagnostic_cc_tests ()
2674 {
2675 test_print_escaped_string ();
2676 test_print_parseable_fixits_none ();
2677 test_print_parseable_fixits_insert ();
2678 test_print_parseable_fixits_remove ();
2679 test_print_parseable_fixits_replace ();
2680 test_print_parseable_fixits_bytes_vs_display_columns ();
2681 test_diagnostic_get_location_text ();
2682 test_num_digits ();
2683
2684 }
2685
2686 } // namespace selftest
2687
2688 #endif /* #if CHECKING_P */
2689
2690 #if __GNUC__ >= 10
2691 # pragma GCC diagnostic pop
2692 #endif