]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/diagnostic.c
Add diagnostic_metadata and CWE support
[thirdparty/gcc.git] / gcc / diagnostic.c
1 /* Language-independent diagnostic subroutines for the GNU Compiler Collection
2 Copyright (C) 1999-2019 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 "edit-context.h"
37 #include "selftest.h"
38 #include "selftest-diagnostic.h"
39 #include "opts.h"
40
41 #ifdef HAVE_TERMIOS_H
42 # include <termios.h>
43 #endif
44
45 #ifdef GWINSZ_IN_SYS_IOCTL
46 # include <sys/ioctl.h>
47 #endif
48
49 /* Disable warnings about quoting issues in the pp_xxx calls below
50 that (intentionally) don't follow GCC diagnostic conventions. */
51 #if __GNUC__ >= 10
52 # pragma GCC diagnostic push
53 # pragma GCC diagnostic ignored "-Wformat-diag"
54 #endif
55
56 #define pedantic_warning_kind(DC) \
57 ((DC)->pedantic_errors ? DK_ERROR : DK_WARNING)
58 #define permissive_error_kind(DC) ((DC)->permissive ? DK_WARNING : DK_ERROR)
59 #define permissive_error_option(DC) ((DC)->opt_permissive)
60
61 /* Prototypes. */
62 static bool diagnostic_impl (rich_location *, const diagnostic_metadata *,
63 int, const char *,
64 va_list *, diagnostic_t) ATTRIBUTE_GCC_DIAG(4,0);
65 static bool diagnostic_n_impl (rich_location *, const diagnostic_metadata *,
66 int, unsigned HOST_WIDE_INT,
67 const char *, const char *, va_list *,
68 diagnostic_t) ATTRIBUTE_GCC_DIAG(6,0);
69
70 static void error_recursion (diagnostic_context *) ATTRIBUTE_NORETURN;
71 static void real_abort (void) ATTRIBUTE_NORETURN;
72
73 /* Name of program invoked, sans directories. */
74
75 const char *progname;
76
77 /* A diagnostic_context surrogate for stderr. */
78 static diagnostic_context global_diagnostic_context;
79 diagnostic_context *global_dc = &global_diagnostic_context;
80 \f
81 /* Return a malloc'd string containing MSG formatted a la printf. The
82 caller is responsible for freeing the memory. */
83 char *
84 build_message_string (const char *msg, ...)
85 {
86 char *str;
87 va_list ap;
88
89 va_start (ap, msg);
90 str = xvasprintf (msg, ap);
91 va_end (ap);
92
93 return str;
94 }
95
96 /* Same as diagnostic_build_prefix, but only the source FILE is given. */
97 char *
98 file_name_as_prefix (diagnostic_context *context, const char *f)
99 {
100 const char *locus_cs
101 = colorize_start (pp_show_color (context->printer), "locus");
102 const char *locus_ce = colorize_stop (pp_show_color (context->printer));
103 return build_message_string ("%s%s:%s ", locus_cs, f, locus_ce);
104 }
105
106
107 \f
108 /* Return the value of the getenv("COLUMNS") as an integer. If the
109 value is not set to a positive integer, use ioctl to get the
110 terminal width. If it fails, return INT_MAX. */
111 int
112 get_terminal_width (void)
113 {
114 const char * s = getenv ("COLUMNS");
115 if (s != NULL) {
116 int n = atoi (s);
117 if (n > 0)
118 return n;
119 }
120
121 #ifdef TIOCGWINSZ
122 struct winsize w;
123 w.ws_col = 0;
124 if (ioctl (0, TIOCGWINSZ, &w) == 0 && w.ws_col > 0)
125 return w.ws_col;
126 #endif
127
128 return INT_MAX;
129 }
130
131 /* Set caret_max_width to value. */
132 void
133 diagnostic_set_caret_max_width (diagnostic_context *context, int value)
134 {
135 /* One minus to account for the leading empty space. */
136 value = value ? value - 1
137 : (isatty (fileno (pp_buffer (context->printer)->stream))
138 ? get_terminal_width () - 1: INT_MAX);
139
140 if (value <= 0)
141 value = INT_MAX;
142
143 context->caret_max_width = value;
144 }
145
146 /* Default implementation of final_cb. */
147
148 static void
149 default_diagnostic_final_cb (diagnostic_context *context)
150 {
151 /* Some of the errors may actually have been warnings. */
152 if (diagnostic_kind_count (context, DK_WERROR))
153 {
154 /* -Werror was given. */
155 if (context->warning_as_error_requested)
156 pp_verbatim (context->printer,
157 _("%s: all warnings being treated as errors"),
158 progname);
159 /* At least one -Werror= was given. */
160 else
161 pp_verbatim (context->printer,
162 _("%s: some warnings being treated as errors"),
163 progname);
164 pp_newline_and_flush (context->printer);
165 }
166 }
167
168 /* Initialize the diagnostic message outputting machinery. */
169 void
170 diagnostic_initialize (diagnostic_context *context, int n_opts)
171 {
172 int i;
173
174 /* Allocate a basic pretty-printer. Clients will replace this a
175 much more elaborated pretty-printer if they wish. */
176 context->printer = XNEW (pretty_printer);
177 new (context->printer) pretty_printer ();
178
179 memset (context->diagnostic_count, 0, sizeof context->diagnostic_count);
180 context->warning_as_error_requested = false;
181 context->n_opts = n_opts;
182 context->classify_diagnostic = XNEWVEC (diagnostic_t, n_opts);
183 for (i = 0; i < n_opts; i++)
184 context->classify_diagnostic[i] = DK_UNSPECIFIED;
185 context->show_caret = false;
186 diagnostic_set_caret_max_width (context, pp_line_cutoff (context->printer));
187 for (i = 0; i < rich_location::STATICALLY_ALLOCATED_RANGES; i++)
188 context->caret_chars[i] = '^';
189 context->show_cwe = false;
190 context->show_option_requested = false;
191 context->abort_on_error = false;
192 context->show_column = false;
193 context->pedantic_errors = false;
194 context->permissive = false;
195 context->opt_permissive = 0;
196 context->fatal_errors = false;
197 context->dc_inhibit_warnings = false;
198 context->dc_warn_system_headers = false;
199 context->max_errors = 0;
200 context->internal_error = NULL;
201 diagnostic_starter (context) = default_diagnostic_starter;
202 context->start_span = default_diagnostic_start_span_fn;
203 diagnostic_finalizer (context) = default_diagnostic_finalizer;
204 context->option_enabled = NULL;
205 context->option_state = NULL;
206 context->option_name = NULL;
207 context->get_option_url = NULL;
208 context->last_location = UNKNOWN_LOCATION;
209 context->last_module = 0;
210 context->x_data = NULL;
211 context->lock = 0;
212 context->inhibit_notes_p = false;
213 context->colorize_source_p = false;
214 context->show_labels_p = false;
215 context->show_line_numbers_p = false;
216 context->min_margin_width = 0;
217 context->show_ruler_p = false;
218 context->parseable_fixits_p = false;
219 context->edit_context_ptr = NULL;
220 context->diagnostic_group_nesting_depth = 0;
221 context->diagnostic_group_emission_count = 0;
222 context->begin_group_cb = NULL;
223 context->end_group_cb = NULL;
224 context->final_cb = default_diagnostic_final_cb;
225 }
226
227 /* Maybe initialize the color support. We require clients to do this
228 explicitly, since most clients don't want color. When called
229 without a VALUE, it initializes with DIAGNOSTICS_COLOR_DEFAULT. */
230
231 void
232 diagnostic_color_init (diagnostic_context *context, int value /*= -1 */)
233 {
234 /* value == -1 is the default value. */
235 if (value < 0)
236 {
237 /* If DIAGNOSTICS_COLOR_DEFAULT is -1, default to
238 -fdiagnostics-color=auto if GCC_COLORS is in the environment,
239 otherwise default to -fdiagnostics-color=never, for other
240 values default to that
241 -fdiagnostics-color={never,auto,always}. */
242 if (DIAGNOSTICS_COLOR_DEFAULT == -1)
243 {
244 if (!getenv ("GCC_COLORS"))
245 return;
246 value = DIAGNOSTICS_COLOR_AUTO;
247 }
248 else
249 value = DIAGNOSTICS_COLOR_DEFAULT;
250 }
251 pp_show_color (context->printer)
252 = colorize_init ((diagnostic_color_rule_t) value);
253 }
254
255 /* Initialize URL support within CONTEXT based on VALUE, handling "auto". */
256
257 void
258 diagnostic_urls_init (diagnostic_context *context, int value /*= -1 */)
259 {
260 if (value < 0)
261 value = DIAGNOSTICS_COLOR_DEFAULT;
262
263 context->printer->show_urls
264 = diagnostic_urls_enabled_p ((diagnostic_url_rule_t) value);
265 }
266
267 /* Do any cleaning up required after the last diagnostic is emitted. */
268
269 void
270 diagnostic_finish (diagnostic_context *context)
271 {
272 if (context->final_cb)
273 context->final_cb (context);
274
275 diagnostic_file_cache_fini ();
276
277 XDELETEVEC (context->classify_diagnostic);
278 context->classify_diagnostic = NULL;
279
280 /* diagnostic_initialize allocates context->printer using XNEW
281 and placement-new. */
282 context->printer->~pretty_printer ();
283 XDELETE (context->printer);
284 context->printer = NULL;
285
286 if (context->edit_context_ptr)
287 {
288 delete context->edit_context_ptr;
289 context->edit_context_ptr = NULL;
290 }
291 }
292
293 /* Initialize DIAGNOSTIC, where the message MSG has already been
294 translated. */
295 void
296 diagnostic_set_info_translated (diagnostic_info *diagnostic, const char *msg,
297 va_list *args, rich_location *richloc,
298 diagnostic_t kind)
299 {
300 gcc_assert (richloc);
301 diagnostic->message.err_no = errno;
302 diagnostic->message.args_ptr = args;
303 diagnostic->message.format_spec = msg;
304 diagnostic->message.m_richloc = richloc;
305 diagnostic->richloc = richloc;
306 diagnostic->metadata = NULL;
307 diagnostic->kind = kind;
308 diagnostic->option_index = 0;
309 }
310
311 /* Initialize DIAGNOSTIC, where the message GMSGID has not yet been
312 translated. */
313 void
314 diagnostic_set_info (diagnostic_info *diagnostic, const char *gmsgid,
315 va_list *args, rich_location *richloc,
316 diagnostic_t kind)
317 {
318 gcc_assert (richloc);
319 diagnostic_set_info_translated (diagnostic, _(gmsgid), args, richloc, kind);
320 }
321
322 static const char *const diagnostic_kind_color[] = {
323 #define DEFINE_DIAGNOSTIC_KIND(K, T, C) (C),
324 #include "diagnostic.def"
325 #undef DEFINE_DIAGNOSTIC_KIND
326 NULL
327 };
328
329 /* Get a color name for diagnostics of type KIND
330 Result could be NULL. */
331
332 const char *
333 diagnostic_get_color_for_kind (diagnostic_t kind)
334 {
335 return diagnostic_kind_color[kind];
336 }
337
338 /* Return a formatted line and column ':%line:%column'. Elided if
339 zero. The result is a statically allocated buffer. */
340
341 static const char *
342 maybe_line_and_column (int line, int col)
343 {
344 static char result[32];
345
346 if (line)
347 {
348 size_t l = snprintf (result, sizeof (result),
349 col ? ":%d:%d" : ":%d", line, col);
350 gcc_checking_assert (l < sizeof (result));
351 }
352 else
353 result[0] = 0;
354 return result;
355 }
356
357 /* Return a malloc'd string describing a location e.g. "foo.c:42:10".
358 The caller is responsible for freeing the memory. */
359
360 static char *
361 diagnostic_get_location_text (diagnostic_context *context,
362 expanded_location s)
363 {
364 pretty_printer *pp = context->printer;
365 const char *locus_cs = colorize_start (pp_show_color (pp), "locus");
366 const char *locus_ce = colorize_stop (pp_show_color (pp));
367 const char *file = s.file ? s.file : progname;
368 int line = strcmp (file, N_("<built-in>")) ? s.line : 0;
369 int col = context->show_column ? s.column : 0;
370
371 const char *line_col = maybe_line_and_column (line, col);
372 return build_message_string ("%s%s%s:%s", locus_cs, file,
373 line_col, locus_ce);
374 }
375
376 /* Return a malloc'd string describing a location and the severity of the
377 diagnostic, e.g. "foo.c:42:10: error: ". The caller is responsible for
378 freeing the memory. */
379 char *
380 diagnostic_build_prefix (diagnostic_context *context,
381 const diagnostic_info *diagnostic)
382 {
383 static const char *const diagnostic_kind_text[] = {
384 #define DEFINE_DIAGNOSTIC_KIND(K, T, C) (T),
385 #include "diagnostic.def"
386 #undef DEFINE_DIAGNOSTIC_KIND
387 "must-not-happen"
388 };
389 gcc_assert (diagnostic->kind < DK_LAST_DIAGNOSTIC_KIND);
390
391 const char *text = _(diagnostic_kind_text[diagnostic->kind]);
392 const char *text_cs = "", *text_ce = "";
393 pretty_printer *pp = context->printer;
394
395 if (diagnostic_kind_color[diagnostic->kind])
396 {
397 text_cs = colorize_start (pp_show_color (pp),
398 diagnostic_kind_color[diagnostic->kind]);
399 text_ce = colorize_stop (pp_show_color (pp));
400 }
401
402 expanded_location s = diagnostic_expand_location (diagnostic);
403 char *location_text = diagnostic_get_location_text (context, s);
404
405 char *result = build_message_string ("%s %s%s%s", location_text,
406 text_cs, text, text_ce);
407 free (location_text);
408 return result;
409 }
410
411 /* Functions at which to stop the backtrace print. It's not
412 particularly helpful to print the callers of these functions. */
413
414 static const char * const bt_stop[] =
415 {
416 "main",
417 "toplev::main",
418 "execute_one_pass",
419 "compile_file",
420 };
421
422 /* A callback function passed to the backtrace_full function. */
423
424 static int
425 bt_callback (void *data, uintptr_t pc, const char *filename, int lineno,
426 const char *function)
427 {
428 int *pcount = (int *) data;
429
430 /* If we don't have any useful information, don't print
431 anything. */
432 if (filename == NULL && function == NULL)
433 return 0;
434
435 /* Skip functions in diagnostic.c. */
436 if (*pcount == 0
437 && filename != NULL
438 && strcmp (lbasename (filename), "diagnostic.c") == 0)
439 return 0;
440
441 /* Print up to 20 functions. We could make this a --param, but
442 since this is only for debugging just use a constant for now. */
443 if (*pcount >= 20)
444 {
445 /* Returning a non-zero value stops the backtrace. */
446 return 1;
447 }
448 ++*pcount;
449
450 char *alc = NULL;
451 if (function != NULL)
452 {
453 char *str = cplus_demangle_v3 (function,
454 (DMGL_VERBOSE | DMGL_ANSI
455 | DMGL_GNU_V3 | DMGL_PARAMS));
456 if (str != NULL)
457 {
458 alc = str;
459 function = str;
460 }
461
462 for (size_t i = 0; i < ARRAY_SIZE (bt_stop); ++i)
463 {
464 size_t len = strlen (bt_stop[i]);
465 if (strncmp (function, bt_stop[i], len) == 0
466 && (function[len] == '\0' || function[len] == '('))
467 {
468 if (alc != NULL)
469 free (alc);
470 /* Returning a non-zero value stops the backtrace. */
471 return 1;
472 }
473 }
474 }
475
476 fprintf (stderr, "0x%lx %s\n\t%s:%d\n",
477 (unsigned long) pc,
478 function == NULL ? "???" : function,
479 filename == NULL ? "???" : filename,
480 lineno);
481
482 if (alc != NULL)
483 free (alc);
484
485 return 0;
486 }
487
488 /* A callback function passed to the backtrace_full function. This is
489 called if backtrace_full has an error. */
490
491 static void
492 bt_err_callback (void *data ATTRIBUTE_UNUSED, const char *msg, int errnum)
493 {
494 if (errnum < 0)
495 {
496 /* This means that no debug info was available. Just quietly
497 skip printing backtrace info. */
498 return;
499 }
500 fprintf (stderr, "%s%s%s\n", msg, errnum == 0 ? "" : ": ",
501 errnum == 0 ? "" : xstrerror (errnum));
502 }
503
504 /* Check if we've met the maximum error limit, and if so fatally exit
505 with a message. CONTEXT is the context to check, and FLUSH
506 indicates whether a diagnostic_finish call is needed. */
507
508 void
509 diagnostic_check_max_errors (diagnostic_context *context, bool flush)
510 {
511 if (!context->max_errors)
512 return;
513
514 int count = (diagnostic_kind_count (context, DK_ERROR)
515 + diagnostic_kind_count (context, DK_SORRY)
516 + diagnostic_kind_count (context, DK_WERROR));
517
518 if (count >= context->max_errors)
519 {
520 fnotice (stderr,
521 "compilation terminated due to -fmax-errors=%u.\n",
522 context->max_errors);
523 if (flush)
524 diagnostic_finish (context);
525 exit (FATAL_EXIT_CODE);
526 }
527 }
528
529 /* Take any action which is expected to happen after the diagnostic
530 is written out. This function does not always return. */
531 void
532 diagnostic_action_after_output (diagnostic_context *context,
533 diagnostic_t diag_kind)
534 {
535 switch (diag_kind)
536 {
537 case DK_DEBUG:
538 case DK_NOTE:
539 case DK_ANACHRONISM:
540 case DK_WARNING:
541 break;
542
543 case DK_ERROR:
544 case DK_SORRY:
545 if (context->abort_on_error)
546 real_abort ();
547 if (context->fatal_errors)
548 {
549 fnotice (stderr, "compilation terminated due to -Wfatal-errors.\n");
550 diagnostic_finish (context);
551 exit (FATAL_EXIT_CODE);
552 }
553 break;
554
555 case DK_ICE:
556 case DK_ICE_NOBT:
557 {
558 struct backtrace_state *state = NULL;
559 if (diag_kind == DK_ICE)
560 state = backtrace_create_state (NULL, 0, bt_err_callback, NULL);
561 int count = 0;
562 if (state != NULL)
563 backtrace_full (state, 2, bt_callback, bt_err_callback,
564 (void *) &count);
565
566 if (context->abort_on_error)
567 real_abort ();
568
569 fnotice (stderr, "Please submit a full bug report,\n"
570 "with preprocessed source if appropriate.\n");
571 if (count > 0)
572 fnotice (stderr,
573 ("Please include the complete backtrace "
574 "with any bug report.\n"));
575 fnotice (stderr, "See %s for instructions.\n", bug_report_url);
576
577 exit (ICE_EXIT_CODE);
578 }
579
580 case DK_FATAL:
581 if (context->abort_on_error)
582 real_abort ();
583 diagnostic_finish (context);
584 fnotice (stderr, "compilation terminated.\n");
585 exit (FATAL_EXIT_CODE);
586
587 default:
588 gcc_unreachable ();
589 }
590 }
591
592 /* True if the last module or file in which a diagnostic was reported is
593 different from the current one. */
594
595 static bool
596 last_module_changed_p (diagnostic_context *context,
597 const line_map_ordinary *map)
598 {
599 return context->last_module != map;
600 }
601
602 /* Remember the current module or file as being the last one in which we
603 report a diagnostic. */
604
605 static void
606 set_last_module (diagnostic_context *context, const line_map_ordinary *map)
607 {
608 context->last_module = map;
609 }
610
611 void
612 diagnostic_report_current_module (diagnostic_context *context, location_t where)
613 {
614 const line_map_ordinary *map = NULL;
615
616 if (pp_needs_newline (context->printer))
617 {
618 pp_newline (context->printer);
619 pp_needs_newline (context->printer) = false;
620 }
621
622 if (where <= BUILTINS_LOCATION)
623 return;
624
625 linemap_resolve_location (line_table, where,
626 LRK_MACRO_DEFINITION_LOCATION,
627 &map);
628
629 if (map && last_module_changed_p (context, map))
630 {
631 set_last_module (context, map);
632 if (! MAIN_FILE_P (map))
633 {
634 bool first = true;
635 do
636 {
637 where = linemap_included_from (map);
638 map = linemap_included_from_linemap (line_table, map);
639 const char *line_col
640 = maybe_line_and_column (SOURCE_LINE (map, where),
641 first && context->show_column
642 ? SOURCE_COLUMN (map, where) : 0);
643 static const char *const msgs[] =
644 {
645 N_("In file included from"),
646 N_(" from"),
647 };
648 unsigned index = !first;
649 pp_verbatim (context->printer, "%s%s %r%s%s%R",
650 first ? "" : ",\n", _(msgs[index]),
651 "locus", LINEMAP_FILE (map), line_col);
652 first = false;
653 }
654 while (! MAIN_FILE_P (map));
655 pp_verbatim (context->printer, ":");
656 pp_newline (context->printer);
657 }
658 }
659 }
660
661 void
662 default_diagnostic_starter (diagnostic_context *context,
663 diagnostic_info *diagnostic)
664 {
665 diagnostic_report_current_module (context, diagnostic_location (diagnostic));
666 pp_set_prefix (context->printer, diagnostic_build_prefix (context,
667 diagnostic));
668 }
669
670 void
671 default_diagnostic_start_span_fn (diagnostic_context *context,
672 expanded_location exploc)
673 {
674 char *text = diagnostic_get_location_text (context, exploc);
675 pp_string (context->printer, text);
676 free (text);
677 pp_newline (context->printer);
678 }
679
680 void
681 default_diagnostic_finalizer (diagnostic_context *context,
682 diagnostic_info *diagnostic,
683 diagnostic_t)
684 {
685 char *saved_prefix = pp_take_prefix (context->printer);
686 pp_set_prefix (context->printer, NULL);
687 pp_newline (context->printer);
688 diagnostic_show_locus (context, diagnostic->richloc, diagnostic->kind);
689 pp_set_prefix (context->printer, saved_prefix);
690 pp_flush (context->printer);
691 }
692
693 /* Interface to specify diagnostic kind overrides. Returns the
694 previous setting, or DK_UNSPECIFIED if the parameters are out of
695 range. If OPTION_INDEX is zero, the new setting is for all the
696 diagnostics. */
697 diagnostic_t
698 diagnostic_classify_diagnostic (diagnostic_context *context,
699 int option_index,
700 diagnostic_t new_kind,
701 location_t where)
702 {
703 diagnostic_t old_kind;
704
705 if (option_index < 0
706 || option_index >= context->n_opts
707 || new_kind >= DK_LAST_DIAGNOSTIC_KIND)
708 return DK_UNSPECIFIED;
709
710 old_kind = context->classify_diagnostic[option_index];
711
712 /* Handle pragmas separately, since we need to keep track of *where*
713 the pragmas were. */
714 if (where != UNKNOWN_LOCATION)
715 {
716 int i;
717
718 /* Record the command-line status, so we can reset it back on DK_POP. */
719 if (old_kind == DK_UNSPECIFIED)
720 {
721 old_kind = !context->option_enabled (option_index,
722 context->lang_mask,
723 context->option_state)
724 ? DK_IGNORED : (context->warning_as_error_requested
725 ? DK_ERROR : DK_WARNING);
726 context->classify_diagnostic[option_index] = old_kind;
727 }
728
729 for (i = context->n_classification_history - 1; i >= 0; i --)
730 if (context->classification_history[i].option == option_index)
731 {
732 old_kind = context->classification_history[i].kind;
733 break;
734 }
735
736 i = context->n_classification_history;
737 context->classification_history =
738 (diagnostic_classification_change_t *) xrealloc (context->classification_history, (i + 1)
739 * sizeof (diagnostic_classification_change_t));
740 context->classification_history[i].location = where;
741 context->classification_history[i].option = option_index;
742 context->classification_history[i].kind = new_kind;
743 context->n_classification_history ++;
744 }
745 else
746 context->classify_diagnostic[option_index] = new_kind;
747
748 return old_kind;
749 }
750
751 /* Save all diagnostic classifications in a stack. */
752 void
753 diagnostic_push_diagnostics (diagnostic_context *context, location_t where ATTRIBUTE_UNUSED)
754 {
755 context->push_list = (int *) xrealloc (context->push_list, (context->n_push + 1) * sizeof (int));
756 context->push_list[context->n_push ++] = context->n_classification_history;
757 }
758
759 /* Restore the topmost classification set off the stack. If the stack
760 is empty, revert to the state based on command line parameters. */
761 void
762 diagnostic_pop_diagnostics (diagnostic_context *context, location_t where)
763 {
764 int jump_to;
765 int i;
766
767 if (context->n_push)
768 jump_to = context->push_list [-- context->n_push];
769 else
770 jump_to = 0;
771
772 i = context->n_classification_history;
773 context->classification_history =
774 (diagnostic_classification_change_t *) xrealloc (context->classification_history, (i + 1)
775 * sizeof (diagnostic_classification_change_t));
776 context->classification_history[i].location = where;
777 context->classification_history[i].option = jump_to;
778 context->classification_history[i].kind = DK_POP;
779 context->n_classification_history ++;
780 }
781
782 /* Helper function for print_parseable_fixits. Print TEXT to PP, obeying the
783 escaping rules for -fdiagnostics-parseable-fixits. */
784
785 static void
786 print_escaped_string (pretty_printer *pp, const char *text)
787 {
788 gcc_assert (pp);
789 gcc_assert (text);
790
791 pp_character (pp, '"');
792 for (const char *ch = text; *ch; ch++)
793 {
794 switch (*ch)
795 {
796 case '\\':
797 /* Escape backslash as two backslashes. */
798 pp_string (pp, "\\\\");
799 break;
800 case '\t':
801 /* Escape tab as "\t". */
802 pp_string (pp, "\\t");
803 break;
804 case '\n':
805 /* Escape newline as "\n". */
806 pp_string (pp, "\\n");
807 break;
808 case '"':
809 /* Escape doublequotes as \". */
810 pp_string (pp, "\\\"");
811 break;
812 default:
813 if (ISPRINT (*ch))
814 pp_character (pp, *ch);
815 else
816 /* Use octal for non-printable chars. */
817 {
818 unsigned char c = (*ch & 0xff);
819 pp_printf (pp, "\\%o%o%o", (c / 64), (c / 8) & 007, c & 007);
820 }
821 break;
822 }
823 }
824 pp_character (pp, '"');
825 }
826
827 /* Implementation of -fdiagnostics-parseable-fixits. Print a
828 machine-parseable version of all fixits in RICHLOC to PP. */
829
830 static void
831 print_parseable_fixits (pretty_printer *pp, rich_location *richloc)
832 {
833 gcc_assert (pp);
834 gcc_assert (richloc);
835
836 char *saved_prefix = pp_take_prefix (pp);
837 pp_set_prefix (pp, NULL);
838
839 for (unsigned i = 0; i < richloc->get_num_fixit_hints (); i++)
840 {
841 const fixit_hint *hint = richloc->get_fixit_hint (i);
842 location_t start_loc = hint->get_start_loc ();
843 expanded_location start_exploc = expand_location (start_loc);
844 pp_string (pp, "fix-it:");
845 print_escaped_string (pp, start_exploc.file);
846 /* For compatibility with clang, print as a half-open range. */
847 location_t next_loc = hint->get_next_loc ();
848 expanded_location next_exploc = expand_location (next_loc);
849 pp_printf (pp, ":{%i:%i-%i:%i}:",
850 start_exploc.line, start_exploc.column,
851 next_exploc.line, next_exploc.column);
852 print_escaped_string (pp, hint->get_string ());
853 pp_newline (pp);
854 }
855
856 pp_set_prefix (pp, saved_prefix);
857 }
858
859 /* Update the diag_class of DIAGNOSTIC based on its location
860 relative to any
861 #pragma GCC diagnostic
862 directives recorded within CONTEXT.
863
864 Return the new diag_class of DIAGNOSTIC if it was updated, or
865 DK_UNSPECIFIED otherwise. */
866
867 static diagnostic_t
868 update_effective_level_from_pragmas (diagnostic_context *context,
869 diagnostic_info *diagnostic)
870 {
871 diagnostic_t diag_class = DK_UNSPECIFIED;
872
873 if (context->n_classification_history > 0)
874 {
875 location_t location = diagnostic_location (diagnostic);
876
877 /* FIXME: Stupid search. Optimize later. */
878 for (int i = context->n_classification_history - 1; i >= 0; i --)
879 {
880 if (linemap_location_before_p
881 (line_table,
882 context->classification_history[i].location,
883 location))
884 {
885 if (context->classification_history[i].kind == (int) DK_POP)
886 {
887 i = context->classification_history[i].option;
888 continue;
889 }
890 int option = context->classification_history[i].option;
891 /* The option 0 is for all the diagnostics. */
892 if (option == 0 || option == diagnostic->option_index)
893 {
894 diag_class = context->classification_history[i].kind;
895 if (diag_class != DK_UNSPECIFIED)
896 diagnostic->kind = diag_class;
897 break;
898 }
899 }
900 }
901 }
902
903 return diag_class;
904 }
905
906 /* Generate a URL string describing CWE. The caller is responsible for
907 freeing the string. */
908
909 static char *
910 get_cwe_url (int cwe)
911 {
912 return xasprintf ("https://cwe.mitre.org/data/definitions/%i.html", cwe);
913 }
914
915 /* If DIAGNOSTIC has a CWE identifier, print it.
916
917 For example, if the diagnostic metadata associates it with CWE-119,
918 " [CWE-119]" will be printed, suitably colorized, and with a URL of a
919 description of the security issue. */
920
921 static void
922 print_any_cwe (diagnostic_context *context,
923 const diagnostic_info *diagnostic)
924 {
925 if (diagnostic->metadata == NULL)
926 return;
927
928 int cwe = diagnostic->metadata->get_cwe ();
929 if (cwe)
930 {
931 pretty_printer *pp = context->printer;
932 char *saved_prefix = pp_take_prefix (context->printer);
933 pp_string (pp, " [");
934 pp_string (pp, colorize_start (pp_show_color (pp),
935 diagnostic_kind_color[diagnostic->kind]));
936 char *cwe_url = get_cwe_url (cwe);
937 pp_begin_url (pp, cwe_url);
938 free (cwe_url);
939 pp_printf (pp, "CWE-%i", cwe);
940 pp_set_prefix (context->printer, saved_prefix);
941 pp_end_url (pp);
942 pp_string (pp, colorize_stop (pp_show_color (pp)));
943 pp_character (pp, ']');
944 }
945 }
946
947 /* Print any metadata about the option used to control DIAGNOSTIC to CONTEXT's
948 printer, e.g. " [-Werror=uninitialized]".
949 Subroutine of diagnostic_report_diagnostic. */
950
951 static void
952 print_option_information (diagnostic_context *context,
953 const diagnostic_info *diagnostic,
954 diagnostic_t orig_diag_kind)
955 {
956 char *option_text;
957
958 option_text = context->option_name (context, diagnostic->option_index,
959 orig_diag_kind, diagnostic->kind);
960
961 if (option_text)
962 {
963 char *option_url = NULL;
964 if (context->get_option_url)
965 option_url = context->get_option_url (context,
966 diagnostic->option_index);
967 pretty_printer *pp = context->printer;
968 pp_string (pp, " [");
969 pp_string (pp, colorize_start (pp_show_color (pp),
970 diagnostic_kind_color[diagnostic->kind]));
971 if (option_url)
972 pp_begin_url (pp, option_url);
973 pp_string (pp, option_text);
974 if (option_url)
975 {
976 pp_end_url (pp);
977 free (option_url);
978 }
979 pp_string (pp, colorize_stop (pp_show_color (pp)));
980 pp_character (pp, ']');
981 free (option_text);
982 }
983 }
984
985 /* Report a diagnostic message (an error or a warning) as specified by
986 DC. This function is *the* subroutine in terms of which front-ends
987 should implement their specific diagnostic handling modules. The
988 front-end independent format specifiers are exactly those described
989 in the documentation of output_format.
990 Return true if a diagnostic was printed, false otherwise. */
991
992 bool
993 diagnostic_report_diagnostic (diagnostic_context *context,
994 diagnostic_info *diagnostic)
995 {
996 location_t location = diagnostic_location (diagnostic);
997 diagnostic_t orig_diag_kind = diagnostic->kind;
998
999 /* Give preference to being able to inhibit warnings, before they
1000 get reclassified to something else. */
1001 if ((diagnostic->kind == DK_WARNING || diagnostic->kind == DK_PEDWARN)
1002 && !diagnostic_report_warnings_p (context, location))
1003 return false;
1004
1005 if (diagnostic->kind == DK_PEDWARN)
1006 {
1007 diagnostic->kind = pedantic_warning_kind (context);
1008 /* We do this to avoid giving the message for -pedantic-errors. */
1009 orig_diag_kind = diagnostic->kind;
1010 }
1011
1012 if (diagnostic->kind == DK_NOTE && context->inhibit_notes_p)
1013 return false;
1014
1015 if (context->lock > 0)
1016 {
1017 /* If we're reporting an ICE in the middle of some other error,
1018 try to flush out the previous error, then let this one
1019 through. Don't do this more than once. */
1020 if ((diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT)
1021 && context->lock == 1)
1022 pp_newline_and_flush (context->printer);
1023 else
1024 error_recursion (context);
1025 }
1026
1027 /* If the user requested that warnings be treated as errors, so be
1028 it. Note that we do this before the next block so that
1029 individual warnings can be overridden back to warnings with
1030 -Wno-error=*. */
1031 if (context->warning_as_error_requested
1032 && diagnostic->kind == DK_WARNING)
1033 diagnostic->kind = DK_ERROR;
1034
1035 if (diagnostic->option_index
1036 && diagnostic->option_index != permissive_error_option (context))
1037 {
1038 /* This tests if the user provided the appropriate -Wfoo or
1039 -Wno-foo option. */
1040 if (! context->option_enabled (diagnostic->option_index,
1041 context->lang_mask,
1042 context->option_state))
1043 return false;
1044
1045 /* This tests for #pragma diagnostic changes. */
1046 diagnostic_t diag_class
1047 = update_effective_level_from_pragmas (context, diagnostic);
1048
1049 /* This tests if the user provided the appropriate -Werror=foo
1050 option. */
1051 if (diag_class == DK_UNSPECIFIED
1052 && (context->classify_diagnostic[diagnostic->option_index]
1053 != DK_UNSPECIFIED))
1054 diagnostic->kind
1055 = context->classify_diagnostic[diagnostic->option_index];
1056
1057 /* This allows for future extensions, like temporarily disabling
1058 warnings for ranges of source code. */
1059 if (diagnostic->kind == DK_IGNORED)
1060 return false;
1061 }
1062
1063 if (diagnostic->kind != DK_NOTE)
1064 diagnostic_check_max_errors (context);
1065
1066 context->lock++;
1067
1068 if (diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT)
1069 {
1070 /* When not checking, ICEs are converted to fatal errors when an
1071 error has already occurred. This is counteracted by
1072 abort_on_error. */
1073 if (!CHECKING_P
1074 && (diagnostic_kind_count (context, DK_ERROR) > 0
1075 || diagnostic_kind_count (context, DK_SORRY) > 0)
1076 && !context->abort_on_error)
1077 {
1078 expanded_location s
1079 = expand_location (diagnostic_location (diagnostic));
1080 fnotice (stderr, "%s:%d: confused by earlier errors, bailing out\n",
1081 s.file, s.line);
1082 exit (ICE_EXIT_CODE);
1083 }
1084 if (context->internal_error)
1085 (*context->internal_error) (context,
1086 diagnostic->message.format_spec,
1087 diagnostic->message.args_ptr);
1088 }
1089 if (diagnostic->kind == DK_ERROR && orig_diag_kind == DK_WARNING)
1090 ++diagnostic_kind_count (context, DK_WERROR);
1091 else
1092 ++diagnostic_kind_count (context, diagnostic->kind);
1093
1094 /* Is this the initial diagnostic within the stack of groups? */
1095 if (context->diagnostic_group_emission_count == 0)
1096 {
1097 if (context->begin_group_cb)
1098 context->begin_group_cb (context);
1099 }
1100 context->diagnostic_group_emission_count++;
1101
1102 diagnostic->message.x_data = &diagnostic->x_data;
1103 diagnostic->x_data = NULL;
1104 pp_format (context->printer, &diagnostic->message);
1105 (*diagnostic_starter (context)) (context, diagnostic);
1106 pp_output_formatted_text (context->printer);
1107 if (context->show_cwe)
1108 print_any_cwe (context, diagnostic);
1109 if (context->show_option_requested)
1110 print_option_information (context, diagnostic, orig_diag_kind);
1111 (*diagnostic_finalizer (context)) (context, diagnostic, orig_diag_kind);
1112 if (context->parseable_fixits_p)
1113 {
1114 print_parseable_fixits (context->printer, diagnostic->richloc);
1115 pp_flush (context->printer);
1116 }
1117 diagnostic_action_after_output (context, diagnostic->kind);
1118 diagnostic->x_data = NULL;
1119
1120 if (context->edit_context_ptr)
1121 if (diagnostic->richloc->fixits_can_be_auto_applied_p ())
1122 context->edit_context_ptr->add_fixits (diagnostic->richloc);
1123
1124 context->lock--;
1125
1126 return true;
1127 }
1128
1129 /* Get the number of digits in the decimal representation of VALUE. */
1130
1131 int
1132 num_digits (int value)
1133 {
1134 /* Perhaps simpler to use log10 for this, but doing it this way avoids
1135 using floating point. */
1136 gcc_assert (value >= 0);
1137
1138 if (value == 0)
1139 return 1;
1140
1141 int digits = 0;
1142 while (value > 0)
1143 {
1144 digits++;
1145 value /= 10;
1146 }
1147 return digits;
1148 }
1149
1150 /* Given a partial pathname as input, return another pathname that
1151 shares no directory elements with the pathname of __FILE__. This
1152 is used by fancy_abort() to print `Internal compiler error in expr.c'
1153 instead of `Internal compiler error in ../../GCC/gcc/expr.c'. */
1154
1155 const char *
1156 trim_filename (const char *name)
1157 {
1158 static const char this_file[] = __FILE__;
1159 const char *p = name, *q = this_file;
1160
1161 /* First skip any "../" in each filename. This allows us to give a proper
1162 reference to a file in a subdirectory. */
1163 while (p[0] == '.' && p[1] == '.' && IS_DIR_SEPARATOR (p[2]))
1164 p += 3;
1165
1166 while (q[0] == '.' && q[1] == '.' && IS_DIR_SEPARATOR (q[2]))
1167 q += 3;
1168
1169 /* Now skip any parts the two filenames have in common. */
1170 while (*p == *q && *p != 0 && *q != 0)
1171 p++, q++;
1172
1173 /* Now go backwards until the previous directory separator. */
1174 while (p > name && !IS_DIR_SEPARATOR (p[-1]))
1175 p--;
1176
1177 return p;
1178 }
1179 \f
1180 /* Standard error reporting routines in increasing order of severity.
1181 All of these take arguments like printf. */
1182
1183 /* Text to be emitted verbatim to the error message stream; this
1184 produces no prefix and disables line-wrapping. Use rarely. */
1185 void
1186 verbatim (const char *gmsgid, ...)
1187 {
1188 text_info text;
1189 va_list ap;
1190
1191 va_start (ap, gmsgid);
1192 text.err_no = errno;
1193 text.args_ptr = &ap;
1194 text.format_spec = _(gmsgid);
1195 text.x_data = NULL;
1196 pp_format_verbatim (global_dc->printer, &text);
1197 pp_newline_and_flush (global_dc->printer);
1198 va_end (ap);
1199 }
1200
1201 /* Add a note with text GMSGID and with LOCATION to the diagnostic CONTEXT. */
1202 void
1203 diagnostic_append_note (diagnostic_context *context,
1204 location_t location,
1205 const char * gmsgid, ...)
1206 {
1207 diagnostic_info diagnostic;
1208 va_list ap;
1209 rich_location richloc (line_table, location);
1210
1211 va_start (ap, gmsgid);
1212 diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_NOTE);
1213 if (context->inhibit_notes_p)
1214 {
1215 va_end (ap);
1216 return;
1217 }
1218 char *saved_prefix = pp_take_prefix (context->printer);
1219 pp_set_prefix (context->printer,
1220 diagnostic_build_prefix (context, &diagnostic));
1221 pp_format (context->printer, &diagnostic.message);
1222 pp_output_formatted_text (context->printer);
1223 pp_destroy_prefix (context->printer);
1224 pp_set_prefix (context->printer, saved_prefix);
1225 pp_newline (context->printer);
1226 diagnostic_show_locus (context, &richloc, DK_NOTE);
1227 va_end (ap);
1228 }
1229
1230 /* Implement emit_diagnostic, inform, warning, warning_at, pedwarn,
1231 permerror, error, error_at, error_at, sorry, fatal_error, internal_error,
1232 and internal_error_no_backtrace, as documented and defined below. */
1233 static bool
1234 diagnostic_impl (rich_location *richloc, const diagnostic_metadata *metadata,
1235 int opt, const char *gmsgid,
1236 va_list *ap, diagnostic_t kind)
1237 {
1238 diagnostic_info diagnostic;
1239 if (kind == DK_PERMERROR)
1240 {
1241 diagnostic_set_info (&diagnostic, gmsgid, ap, richloc,
1242 permissive_error_kind (global_dc));
1243 diagnostic.option_index = permissive_error_option (global_dc);
1244 }
1245 else
1246 {
1247 diagnostic_set_info (&diagnostic, gmsgid, ap, richloc, kind);
1248 if (kind == DK_WARNING || kind == DK_PEDWARN)
1249 diagnostic.option_index = opt;
1250 }
1251 diagnostic.metadata = metadata;
1252 return diagnostic_report_diagnostic (global_dc, &diagnostic);
1253 }
1254
1255 /* Implement inform_n, warning_n, and error_n, as documented and
1256 defined below. */
1257 static bool
1258 diagnostic_n_impl (rich_location *richloc, const diagnostic_metadata *metadata,
1259 int opt, unsigned HOST_WIDE_INT n,
1260 const char *singular_gmsgid,
1261 const char *plural_gmsgid,
1262 va_list *ap, diagnostic_t kind)
1263 {
1264 diagnostic_info diagnostic;
1265 unsigned long gtn;
1266
1267 if (sizeof n <= sizeof gtn)
1268 gtn = n;
1269 else
1270 /* Use the largest number ngettext can handle, otherwise
1271 preserve the six least significant decimal digits for
1272 languages where the plural form depends on them. */
1273 gtn = n <= ULONG_MAX ? n : n % 1000000LU + 1000000LU;
1274
1275 const char *text = ngettext (singular_gmsgid, plural_gmsgid, gtn);
1276 diagnostic_set_info_translated (&diagnostic, text, ap, richloc, kind);
1277 if (kind == DK_WARNING)
1278 diagnostic.option_index = opt;
1279 diagnostic.metadata = metadata;
1280 return diagnostic_report_diagnostic (global_dc, &diagnostic);
1281 }
1282
1283 /* Wrapper around diagnostic_impl taking a variable argument list. */
1284
1285 bool
1286 emit_diagnostic (diagnostic_t kind, location_t location, int opt,
1287 const char *gmsgid, ...)
1288 {
1289 auto_diagnostic_group d;
1290 va_list ap;
1291 va_start (ap, gmsgid);
1292 rich_location richloc (line_table, location);
1293 bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, kind);
1294 va_end (ap);
1295 return ret;
1296 }
1297
1298 /* As above, but for rich_location *. */
1299
1300 bool
1301 emit_diagnostic (diagnostic_t kind, rich_location *richloc, int opt,
1302 const char *gmsgid, ...)
1303 {
1304 auto_diagnostic_group d;
1305 va_list ap;
1306 va_start (ap, gmsgid);
1307 bool ret = diagnostic_impl (richloc, NULL, opt, gmsgid, &ap, kind);
1308 va_end (ap);
1309 return ret;
1310 }
1311
1312 /* Wrapper around diagnostic_impl taking a va_list parameter. */
1313
1314 bool
1315 emit_diagnostic_valist (diagnostic_t kind, location_t location, int opt,
1316 const char *gmsgid, va_list *ap)
1317 {
1318 rich_location richloc (line_table, location);
1319 return diagnostic_impl (&richloc, NULL, opt, gmsgid, ap, kind);
1320 }
1321
1322 /* Wrapper around diagnostic_impl taking a va_list parameter. */
1323
1324 bool
1325 emit_diagnostic_valist (diagnostic_t kind, rich_location *richloc,
1326 const diagnostic_metadata *metadata,
1327 int opt,
1328 const char *gmsgid, va_list *ap)
1329 {
1330 return diagnostic_impl (richloc, metadata, opt, gmsgid, ap, kind);
1331 }
1332
1333 /* An informative note at LOCATION. Use this for additional details on an error
1334 message. */
1335 void
1336 inform (location_t location, const char *gmsgid, ...)
1337 {
1338 auto_diagnostic_group d;
1339 va_list ap;
1340 va_start (ap, gmsgid);
1341 rich_location richloc (line_table, location);
1342 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_NOTE);
1343 va_end (ap);
1344 }
1345
1346 /* Same as "inform" above, but at RICHLOC. */
1347 void
1348 inform (rich_location *richloc, const char *gmsgid, ...)
1349 {
1350 gcc_assert (richloc);
1351
1352 auto_diagnostic_group d;
1353 va_list ap;
1354 va_start (ap, gmsgid);
1355 diagnostic_impl (richloc, NULL, -1, gmsgid, &ap, DK_NOTE);
1356 va_end (ap);
1357 }
1358
1359 /* An informative note at LOCATION. Use this for additional details on an
1360 error message. */
1361 void
1362 inform_n (location_t location, unsigned HOST_WIDE_INT n,
1363 const char *singular_gmsgid, const char *plural_gmsgid, ...)
1364 {
1365 va_list ap;
1366 va_start (ap, plural_gmsgid);
1367 auto_diagnostic_group d;
1368 rich_location richloc (line_table, location);
1369 diagnostic_n_impl (&richloc, NULL, -1, n, singular_gmsgid, plural_gmsgid,
1370 &ap, DK_NOTE);
1371 va_end (ap);
1372 }
1373
1374 /* A warning at INPUT_LOCATION. Use this for code which is correct according
1375 to the relevant language specification but is likely to be buggy anyway.
1376 Returns true if the warning was printed, false if it was inhibited. */
1377 bool
1378 warning (int opt, const char *gmsgid, ...)
1379 {
1380 auto_diagnostic_group d;
1381 va_list ap;
1382 va_start (ap, gmsgid);
1383 rich_location richloc (line_table, input_location);
1384 bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, DK_WARNING);
1385 va_end (ap);
1386 return ret;
1387 }
1388
1389 /* A warning at LOCATION. Use this for code which is correct according to the
1390 relevant language specification but is likely to be buggy anyway.
1391 Returns true if the warning was printed, false if it was inhibited. */
1392
1393 bool
1394 warning_at (location_t location, int opt, const char *gmsgid, ...)
1395 {
1396 auto_diagnostic_group d;
1397 va_list ap;
1398 va_start (ap, gmsgid);
1399 rich_location richloc (line_table, location);
1400 bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, DK_WARNING);
1401 va_end (ap);
1402 return ret;
1403 }
1404
1405 /* Same as "warning at" above, but using RICHLOC. */
1406
1407 bool
1408 warning_at (rich_location *richloc, int opt, const char *gmsgid, ...)
1409 {
1410 gcc_assert (richloc);
1411
1412 auto_diagnostic_group d;
1413 va_list ap;
1414 va_start (ap, gmsgid);
1415 bool ret = diagnostic_impl (richloc, NULL, opt, gmsgid, &ap, DK_WARNING);
1416 va_end (ap);
1417 return ret;
1418 }
1419
1420 /* Same as "warning at" above, but using METADATA. */
1421
1422 bool
1423 warning_at (rich_location *richloc, const diagnostic_metadata &metadata,
1424 int opt, const char *gmsgid, ...)
1425 {
1426 gcc_assert (richloc);
1427
1428 auto_diagnostic_group d;
1429 va_list ap;
1430 va_start (ap, gmsgid);
1431 bool ret
1432 = diagnostic_impl (richloc, &metadata, opt, gmsgid, &ap,
1433 DK_WARNING);
1434 va_end (ap);
1435 return ret;
1436 }
1437
1438 /* Same as warning_n plural variant below, but using RICHLOC. */
1439
1440 bool
1441 warning_n (rich_location *richloc, int opt, unsigned HOST_WIDE_INT n,
1442 const char *singular_gmsgid, const char *plural_gmsgid, ...)
1443 {
1444 gcc_assert (richloc);
1445
1446 auto_diagnostic_group d;
1447 va_list ap;
1448 va_start (ap, plural_gmsgid);
1449 bool ret = diagnostic_n_impl (richloc, NULL, opt, n,
1450 singular_gmsgid, plural_gmsgid,
1451 &ap, DK_WARNING);
1452 va_end (ap);
1453 return ret;
1454 }
1455
1456 /* A warning at LOCATION. Use this for code which is correct according to the
1457 relevant language specification but is likely to be buggy anyway.
1458 Returns true if the warning was printed, false if it was inhibited. */
1459
1460 bool
1461 warning_n (location_t location, int opt, unsigned HOST_WIDE_INT n,
1462 const char *singular_gmsgid, const char *plural_gmsgid, ...)
1463 {
1464 auto_diagnostic_group d;
1465 va_list ap;
1466 va_start (ap, plural_gmsgid);
1467 rich_location richloc (line_table, location);
1468 bool ret = diagnostic_n_impl (&richloc, NULL, opt, n,
1469 singular_gmsgid, plural_gmsgid,
1470 &ap, DK_WARNING);
1471 va_end (ap);
1472 return ret;
1473 }
1474
1475 /* A "pedantic" warning at LOCATION: issues a warning unless
1476 -pedantic-errors was given on the command line, in which case it
1477 issues an error. Use this for diagnostics required by the relevant
1478 language standard, if you have chosen not to make them errors.
1479
1480 Note that these diagnostics are issued independent of the setting
1481 of the -Wpedantic command-line switch. To get a warning enabled
1482 only with that switch, use either "if (pedantic) pedwarn
1483 (OPT_Wpedantic,...)" or just "pedwarn (OPT_Wpedantic,..)". To get a
1484 pedwarn independently of the -Wpedantic switch use "pedwarn (0,...)".
1485
1486 Returns true if the warning was printed, false if it was inhibited. */
1487
1488 bool
1489 pedwarn (location_t location, int opt, const char *gmsgid, ...)
1490 {
1491 auto_diagnostic_group d;
1492 va_list ap;
1493 va_start (ap, gmsgid);
1494 rich_location richloc (line_table, location);
1495 bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, DK_PEDWARN);
1496 va_end (ap);
1497 return ret;
1498 }
1499
1500 /* Same as pedwarn above, but using RICHLOC. */
1501
1502 bool
1503 pedwarn (rich_location *richloc, int opt, const char *gmsgid, ...)
1504 {
1505 gcc_assert (richloc);
1506
1507 auto_diagnostic_group d;
1508 va_list ap;
1509 va_start (ap, gmsgid);
1510 bool ret = diagnostic_impl (richloc, NULL, opt, gmsgid, &ap, DK_PEDWARN);
1511 va_end (ap);
1512 return ret;
1513 }
1514
1515 /* A "permissive" error at LOCATION: issues an error unless
1516 -fpermissive was given on the command line, in which case it issues
1517 a warning. Use this for things that really should be errors but we
1518 want to support legacy code.
1519
1520 Returns true if the warning was printed, false if it was inhibited. */
1521
1522 bool
1523 permerror (location_t location, const char *gmsgid, ...)
1524 {
1525 auto_diagnostic_group d;
1526 va_list ap;
1527 va_start (ap, gmsgid);
1528 rich_location richloc (line_table, location);
1529 bool ret = diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_PERMERROR);
1530 va_end (ap);
1531 return ret;
1532 }
1533
1534 /* Same as "permerror" above, but at RICHLOC. */
1535
1536 bool
1537 permerror (rich_location *richloc, const char *gmsgid, ...)
1538 {
1539 gcc_assert (richloc);
1540
1541 auto_diagnostic_group d;
1542 va_list ap;
1543 va_start (ap, gmsgid);
1544 bool ret = diagnostic_impl (richloc, NULL, -1, gmsgid, &ap, DK_PERMERROR);
1545 va_end (ap);
1546 return ret;
1547 }
1548
1549 /* A hard error: the code is definitely ill-formed, and an object file
1550 will not be produced. */
1551 void
1552 error (const char *gmsgid, ...)
1553 {
1554 auto_diagnostic_group d;
1555 va_list ap;
1556 va_start (ap, gmsgid);
1557 rich_location richloc (line_table, input_location);
1558 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ERROR);
1559 va_end (ap);
1560 }
1561
1562 /* A hard error: the code is definitely ill-formed, and an object file
1563 will not be produced. */
1564 void
1565 error_n (location_t location, unsigned HOST_WIDE_INT n,
1566 const char *singular_gmsgid, const char *plural_gmsgid, ...)
1567 {
1568 auto_diagnostic_group d;
1569 va_list ap;
1570 va_start (ap, plural_gmsgid);
1571 rich_location richloc (line_table, location);
1572 diagnostic_n_impl (&richloc, NULL, -1, n, singular_gmsgid, plural_gmsgid,
1573 &ap, DK_ERROR);
1574 va_end (ap);
1575 }
1576
1577 /* Same as above, but use location LOC instead of input_location. */
1578 void
1579 error_at (location_t loc, const char *gmsgid, ...)
1580 {
1581 auto_diagnostic_group d;
1582 va_list ap;
1583 va_start (ap, gmsgid);
1584 rich_location richloc (line_table, loc);
1585 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ERROR);
1586 va_end (ap);
1587 }
1588
1589 /* Same as above, but use RICH_LOC. */
1590
1591 void
1592 error_at (rich_location *richloc, const char *gmsgid, ...)
1593 {
1594 gcc_assert (richloc);
1595
1596 auto_diagnostic_group d;
1597 va_list ap;
1598 va_start (ap, gmsgid);
1599 diagnostic_impl (richloc, NULL, -1, gmsgid, &ap, DK_ERROR);
1600 va_end (ap);
1601 }
1602
1603 /* "Sorry, not implemented." Use for a language feature which is
1604 required by the relevant specification but not implemented by GCC.
1605 An object file will not be produced. */
1606 void
1607 sorry (const char *gmsgid, ...)
1608 {
1609 auto_diagnostic_group d;
1610 va_list ap;
1611 va_start (ap, gmsgid);
1612 rich_location richloc (line_table, input_location);
1613 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_SORRY);
1614 va_end (ap);
1615 }
1616
1617 /* Same as above, but use location LOC instead of input_location. */
1618 void
1619 sorry_at (location_t loc, const char *gmsgid, ...)
1620 {
1621 auto_diagnostic_group d;
1622 va_list ap;
1623 va_start (ap, gmsgid);
1624 rich_location richloc (line_table, loc);
1625 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_SORRY);
1626 va_end (ap);
1627 }
1628
1629 /* Return true if an error or a "sorry" has been seen. Various
1630 processing is disabled after errors. */
1631 bool
1632 seen_error (void)
1633 {
1634 return errorcount || sorrycount;
1635 }
1636
1637 /* An error which is severe enough that we make no attempt to
1638 continue. Do not use this for internal consistency checks; that's
1639 internal_error. Use of this function should be rare. */
1640 void
1641 fatal_error (location_t loc, const char *gmsgid, ...)
1642 {
1643 auto_diagnostic_group d;
1644 va_list ap;
1645 va_start (ap, gmsgid);
1646 rich_location richloc (line_table, loc);
1647 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_FATAL);
1648 va_end (ap);
1649
1650 gcc_unreachable ();
1651 }
1652
1653 /* An internal consistency check has failed. We make no attempt to
1654 continue. Note that unless there is debugging value to be had from
1655 a more specific message, or some other good reason, you should use
1656 abort () instead of calling this function directly. */
1657 void
1658 internal_error (const char *gmsgid, ...)
1659 {
1660 auto_diagnostic_group d;
1661 va_list ap;
1662 va_start (ap, gmsgid);
1663 rich_location richloc (line_table, input_location);
1664 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ICE);
1665 va_end (ap);
1666
1667 gcc_unreachable ();
1668 }
1669
1670 /* Like internal_error, but no backtrace will be printed. Used when
1671 the internal error does not happen at the current location, but happened
1672 somewhere else. */
1673 void
1674 internal_error_no_backtrace (const char *gmsgid, ...)
1675 {
1676 auto_diagnostic_group d;
1677 va_list ap;
1678 va_start (ap, gmsgid);
1679 rich_location richloc (line_table, input_location);
1680 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ICE_NOBT);
1681 va_end (ap);
1682
1683 gcc_unreachable ();
1684 }
1685 \f
1686 /* Special case error functions. Most are implemented in terms of the
1687 above, or should be. */
1688
1689 /* Print a diagnostic MSGID on FILE. This is just fprintf, except it
1690 runs its second argument through gettext. */
1691 void
1692 fnotice (FILE *file, const char *cmsgid, ...)
1693 {
1694 va_list ap;
1695
1696 va_start (ap, cmsgid);
1697 vfprintf (file, _(cmsgid), ap);
1698 va_end (ap);
1699 }
1700
1701 /* Inform the user that an error occurred while trying to report some
1702 other error. This indicates catastrophic internal inconsistencies,
1703 so give up now. But do try to flush out the previous error.
1704 This mustn't use internal_error, that will cause infinite recursion. */
1705
1706 static void
1707 error_recursion (diagnostic_context *context)
1708 {
1709 if (context->lock < 3)
1710 pp_newline_and_flush (context->printer);
1711
1712 fnotice (stderr,
1713 "Internal compiler error: Error reporting routines re-entered.\n");
1714
1715 /* Call diagnostic_action_after_output to get the "please submit a bug
1716 report" message. */
1717 diagnostic_action_after_output (context, DK_ICE);
1718
1719 /* Do not use gcc_unreachable here; that goes through internal_error
1720 and therefore would cause infinite recursion. */
1721 real_abort ();
1722 }
1723
1724 /* Report an internal compiler error in a friendly manner. This is
1725 the function that gets called upon use of abort() in the source
1726 code generally, thanks to a special macro. */
1727
1728 void
1729 fancy_abort (const char *file, int line, const char *function)
1730 {
1731 internal_error ("in %s, at %s:%d", function, trim_filename (file), line);
1732 }
1733
1734 /* class auto_diagnostic_group. */
1735
1736 /* Constructor: "push" this group into global_dc. */
1737
1738 auto_diagnostic_group::auto_diagnostic_group ()
1739 {
1740 global_dc->diagnostic_group_nesting_depth++;
1741 }
1742
1743 /* Destructor: "pop" this group from global_dc. */
1744
1745 auto_diagnostic_group::~auto_diagnostic_group ()
1746 {
1747 if (--global_dc->diagnostic_group_nesting_depth == 0)
1748 {
1749 /* Handle the case where we've popped the final diagnostic group.
1750 If any diagnostics were emitted, give the context a chance
1751 to do something. */
1752 if (global_dc->diagnostic_group_emission_count > 0)
1753 {
1754 if (global_dc->end_group_cb)
1755 global_dc->end_group_cb (global_dc);
1756 }
1757 global_dc->diagnostic_group_emission_count = 0;
1758 }
1759 }
1760
1761 /* Really call the system 'abort'. This has to go right at the end of
1762 this file, so that there are no functions after it that call abort
1763 and get the system abort instead of our macro. */
1764 #undef abort
1765 static void
1766 real_abort (void)
1767 {
1768 abort ();
1769 }
1770
1771 #if CHECKING_P
1772
1773 namespace selftest {
1774
1775 /* Helper function for test_print_escaped_string. */
1776
1777 static void
1778 assert_print_escaped_string (const location &loc, const char *expected_output,
1779 const char *input)
1780 {
1781 pretty_printer pp;
1782 print_escaped_string (&pp, input);
1783 ASSERT_STREQ_AT (loc, expected_output, pp_formatted_text (&pp));
1784 }
1785
1786 #define ASSERT_PRINT_ESCAPED_STRING_STREQ(EXPECTED_OUTPUT, INPUT) \
1787 assert_print_escaped_string (SELFTEST_LOCATION, EXPECTED_OUTPUT, INPUT)
1788
1789 /* Tests of print_escaped_string. */
1790
1791 static void
1792 test_print_escaped_string ()
1793 {
1794 /* Empty string. */
1795 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"\"", "");
1796
1797 /* Non-empty string. */
1798 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"hello world\"", "hello world");
1799
1800 /* Various things that need to be escaped: */
1801 /* Backslash. */
1802 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\\\after\"",
1803 "before\\after");
1804 /* Tab. */
1805 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\tafter\"",
1806 "before\tafter");
1807 /* Newline. */
1808 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\nafter\"",
1809 "before\nafter");
1810 /* Double quote. */
1811 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\\"after\"",
1812 "before\"after");
1813
1814 /* Non-printable characters: BEL: '\a': 0x07 */
1815 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\007after\"",
1816 "before\aafter");
1817 /* Non-printable characters: vertical tab: '\v': 0x0b */
1818 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\013after\"",
1819 "before\vafter");
1820 }
1821
1822 /* Tests of print_parseable_fixits. */
1823
1824 /* Verify that print_parseable_fixits emits the empty string if there
1825 are no fixits. */
1826
1827 static void
1828 test_print_parseable_fixits_none ()
1829 {
1830 pretty_printer pp;
1831 rich_location richloc (line_table, UNKNOWN_LOCATION);
1832
1833 print_parseable_fixits (&pp, &richloc);
1834 ASSERT_STREQ ("", pp_formatted_text (&pp));
1835 }
1836
1837 /* Verify that print_parseable_fixits does the right thing if there
1838 is an insertion fixit hint. */
1839
1840 static void
1841 test_print_parseable_fixits_insert ()
1842 {
1843 pretty_printer pp;
1844 rich_location richloc (line_table, UNKNOWN_LOCATION);
1845
1846 linemap_add (line_table, LC_ENTER, false, "test.c", 0);
1847 linemap_line_start (line_table, 5, 100);
1848 linemap_add (line_table, LC_LEAVE, false, NULL, 0);
1849 location_t where = linemap_position_for_column (line_table, 10);
1850 richloc.add_fixit_insert_before (where, "added content");
1851
1852 print_parseable_fixits (&pp, &richloc);
1853 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:10}:\"added content\"\n",
1854 pp_formatted_text (&pp));
1855 }
1856
1857 /* Verify that print_parseable_fixits does the right thing if there
1858 is an removal fixit hint. */
1859
1860 static void
1861 test_print_parseable_fixits_remove ()
1862 {
1863 pretty_printer pp;
1864 rich_location richloc (line_table, UNKNOWN_LOCATION);
1865
1866 linemap_add (line_table, LC_ENTER, false, "test.c", 0);
1867 linemap_line_start (line_table, 5, 100);
1868 linemap_add (line_table, LC_LEAVE, false, NULL, 0);
1869 source_range where;
1870 where.m_start = linemap_position_for_column (line_table, 10);
1871 where.m_finish = linemap_position_for_column (line_table, 20);
1872 richloc.add_fixit_remove (where);
1873
1874 print_parseable_fixits (&pp, &richloc);
1875 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:21}:\"\"\n",
1876 pp_formatted_text (&pp));
1877 }
1878
1879 /* Verify that print_parseable_fixits does the right thing if there
1880 is an replacement fixit hint. */
1881
1882 static void
1883 test_print_parseable_fixits_replace ()
1884 {
1885 pretty_printer pp;
1886 rich_location richloc (line_table, UNKNOWN_LOCATION);
1887
1888 linemap_add (line_table, LC_ENTER, false, "test.c", 0);
1889 linemap_line_start (line_table, 5, 100);
1890 linemap_add (line_table, LC_LEAVE, false, NULL, 0);
1891 source_range where;
1892 where.m_start = linemap_position_for_column (line_table, 10);
1893 where.m_finish = linemap_position_for_column (line_table, 20);
1894 richloc.add_fixit_replace (where, "replacement");
1895
1896 print_parseable_fixits (&pp, &richloc);
1897 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:21}:\"replacement\"\n",
1898 pp_formatted_text (&pp));
1899 }
1900
1901 /* Verify that
1902 diagnostic_get_location_text (..., SHOW_COLUMN)
1903 generates EXPECTED_LOC_TEXT, given FILENAME, LINE, COLUMN, with
1904 colorization disabled. */
1905
1906 static void
1907 assert_location_text (const char *expected_loc_text,
1908 const char *filename, int line, int column,
1909 bool show_column)
1910 {
1911 test_diagnostic_context dc;
1912 dc.show_column = show_column;
1913
1914 expanded_location xloc;
1915 xloc.file = filename;
1916 xloc.line = line;
1917 xloc.column = column;
1918 xloc.data = NULL;
1919 xloc.sysp = false;
1920
1921 char *actual_loc_text = diagnostic_get_location_text (&dc, xloc);
1922 ASSERT_STREQ (expected_loc_text, actual_loc_text);
1923 free (actual_loc_text);
1924 }
1925
1926 /* Verify that diagnostic_get_location_text works as expected. */
1927
1928 static void
1929 test_diagnostic_get_location_text ()
1930 {
1931 const char *old_progname = progname;
1932 progname = "PROGNAME";
1933 assert_location_text ("PROGNAME:", NULL, 0, 0, true);
1934 assert_location_text ("<built-in>:", "<built-in>", 42, 10, true);
1935 assert_location_text ("foo.c:42:10:", "foo.c", 42, 10, true);
1936 assert_location_text ("foo.c:42:", "foo.c", 42, 0, true);
1937 assert_location_text ("foo.c:", "foo.c", 0, 10, true);
1938 assert_location_text ("foo.c:42:", "foo.c", 42, 10, false);
1939 assert_location_text ("foo.c:", "foo.c", 0, 10, false);
1940
1941 maybe_line_and_column (INT_MAX, INT_MAX);
1942 maybe_line_and_column (INT_MIN, INT_MIN);
1943
1944 progname = old_progname;
1945 }
1946
1947 /* Selftest for num_digits. */
1948
1949 static void
1950 test_num_digits ()
1951 {
1952 ASSERT_EQ (1, num_digits (0));
1953 ASSERT_EQ (1, num_digits (9));
1954 ASSERT_EQ (2, num_digits (10));
1955 ASSERT_EQ (2, num_digits (99));
1956 ASSERT_EQ (3, num_digits (100));
1957 ASSERT_EQ (3, num_digits (999));
1958 ASSERT_EQ (4, num_digits (1000));
1959 ASSERT_EQ (4, num_digits (9999));
1960 ASSERT_EQ (5, num_digits (10000));
1961 ASSERT_EQ (5, num_digits (99999));
1962 ASSERT_EQ (6, num_digits (100000));
1963 ASSERT_EQ (6, num_digits (999999));
1964 ASSERT_EQ (7, num_digits (1000000));
1965 ASSERT_EQ (7, num_digits (9999999));
1966 ASSERT_EQ (8, num_digits (10000000));
1967 ASSERT_EQ (8, num_digits (99999999));
1968 }
1969
1970 /* Run all of the selftests within this file. */
1971
1972 void
1973 diagnostic_c_tests ()
1974 {
1975 test_print_escaped_string ();
1976 test_print_parseable_fixits_none ();
1977 test_print_parseable_fixits_insert ();
1978 test_print_parseable_fixits_remove ();
1979 test_print_parseable_fixits_replace ();
1980 test_diagnostic_get_location_text ();
1981 test_num_digits ();
1982
1983 }
1984
1985 } // namespace selftest
1986
1987 #endif /* #if CHECKING_P */
1988
1989 #if __GNUC__ >= 10
1990 # pragma GCC diagnostic pop
1991 #endif