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