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