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