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