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