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