1 /* Language-independent diagnostic subroutines for the GNU Compiler Collection
2 Copyright (C) 1999-2019 Free Software Foundation, Inc.
3 Contributed by Gabriel Dos Reis <gdr@codesourcery.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
22 /* This file implements the language independent aspect of diagnostic
27 #include "coretypes.h"
31 #include "backtrace.h"
32 #include "diagnostic.h"
33 #include "diagnostic-color.h"
34 #include "edit-context.h"
36 #include "selftest-diagnostic.h"
43 #ifdef GWINSZ_IN_SYS_IOCTL
44 # include <sys/ioctl.h>
47 /* Disable warnings about quoting issues in the pp_xxx calls below
48 that (intentionally) don't follow GCC diagnostic conventions. */
50 # pragma GCC diagnostic push
51 # pragma GCC diagnostic ignored "-Wformat-diag"
54 #define pedantic_warning_kind(DC) \
55 ((DC)->pedantic_errors ? DK_ERROR : DK_WARNING)
56 #define permissive_error_kind(DC) ((DC)->permissive ? DK_WARNING : DK_ERROR)
57 #define permissive_error_option(DC) ((DC)->opt_permissive)
60 static bool diagnostic_impl (rich_location
*, int, const char *,
61 va_list *, diagnostic_t
) ATTRIBUTE_GCC_DIAG(3,0);
62 static bool diagnostic_n_impl (rich_location
*, int, unsigned HOST_WIDE_INT
,
63 const char *, const char *, va_list *,
64 diagnostic_t
) ATTRIBUTE_GCC_DIAG(5,0);
66 static void error_recursion (diagnostic_context
*) ATTRIBUTE_NORETURN
;
67 static void real_abort (void) ATTRIBUTE_NORETURN
;
69 /* Name of program invoked, sans directories. */
73 /* A diagnostic_context surrogate for stderr. */
74 static diagnostic_context global_diagnostic_context
;
75 diagnostic_context
*global_dc
= &global_diagnostic_context
;
77 /* Return a malloc'd string containing MSG formatted a la printf. The
78 caller is responsible for freeing the memory. */
80 build_message_string (const char *msg
, ...)
86 str
= xvasprintf (msg
, ap
);
92 /* Same as diagnostic_build_prefix, but only the source FILE is given. */
94 file_name_as_prefix (diagnostic_context
*context
, const char *f
)
97 = colorize_start (pp_show_color (context
->printer
), "locus");
98 const char *locus_ce
= colorize_stop (pp_show_color (context
->printer
));
99 return build_message_string ("%s%s:%s ", locus_cs
, f
, locus_ce
);
104 /* Return the value of the getenv("COLUMNS") as an integer. If the
105 value is not set to a positive integer, use ioctl to get the
106 terminal width. If it fails, return INT_MAX. */
108 get_terminal_width (void)
110 const char * s
= getenv ("COLUMNS");
120 if (ioctl (0, TIOCGWINSZ
, &w
) == 0 && w
.ws_col
> 0)
127 /* Set caret_max_width to value. */
129 diagnostic_set_caret_max_width (diagnostic_context
*context
, int value
)
131 /* One minus to account for the leading empty space. */
132 value
= value
? value
- 1
133 : (isatty (fileno (pp_buffer (context
->printer
)->stream
))
134 ? get_terminal_width () - 1: INT_MAX
);
139 context
->caret_max_width
= value
;
142 /* Default implementation of final_cb. */
145 default_diagnostic_final_cb (diagnostic_context
*context
)
147 /* Some of the errors may actually have been warnings. */
148 if (diagnostic_kind_count (context
, DK_WERROR
))
150 /* -Werror was given. */
151 if (context
->warning_as_error_requested
)
152 pp_verbatim (context
->printer
,
153 _("%s: all warnings being treated as errors"),
155 /* At least one -Werror= was given. */
157 pp_verbatim (context
->printer
,
158 _("%s: some warnings being treated as errors"),
160 pp_newline_and_flush (context
->printer
);
164 /* Initialize the diagnostic message outputting machinery. */
166 diagnostic_initialize (diagnostic_context
*context
, int n_opts
)
170 /* Allocate a basic pretty-printer. Clients will replace this a
171 much more elaborated pretty-printer if they wish. */
172 context
->printer
= XNEW (pretty_printer
);
173 new (context
->printer
) pretty_printer ();
175 memset (context
->diagnostic_count
, 0, sizeof context
->diagnostic_count
);
176 context
->warning_as_error_requested
= false;
177 context
->n_opts
= n_opts
;
178 context
->classify_diagnostic
= XNEWVEC (diagnostic_t
, n_opts
);
179 for (i
= 0; i
< n_opts
; i
++)
180 context
->classify_diagnostic
[i
] = DK_UNSPECIFIED
;
181 context
->show_caret
= false;
182 diagnostic_set_caret_max_width (context
, pp_line_cutoff (context
->printer
));
183 for (i
= 0; i
< rich_location::STATICALLY_ALLOCATED_RANGES
; i
++)
184 context
->caret_chars
[i
] = '^';
185 context
->show_option_requested
= false;
186 context
->abort_on_error
= false;
187 context
->show_column
= false;
188 context
->pedantic_errors
= false;
189 context
->permissive
= false;
190 context
->opt_permissive
= 0;
191 context
->fatal_errors
= false;
192 context
->dc_inhibit_warnings
= false;
193 context
->dc_warn_system_headers
= false;
194 context
->max_errors
= 0;
195 context
->internal_error
= NULL
;
196 diagnostic_starter (context
) = default_diagnostic_starter
;
197 context
->start_span
= default_diagnostic_start_span_fn
;
198 diagnostic_finalizer (context
) = default_diagnostic_finalizer
;
199 context
->option_enabled
= NULL
;
200 context
->option_state
= NULL
;
201 context
->option_name
= NULL
;
202 context
->last_location
= UNKNOWN_LOCATION
;
203 context
->last_module
= 0;
204 context
->x_data
= NULL
;
206 context
->inhibit_notes_p
= false;
207 context
->colorize_source_p
= false;
208 context
->show_labels_p
= false;
209 context
->show_line_numbers_p
= false;
210 context
->min_margin_width
= 0;
211 context
->show_ruler_p
= false;
212 context
->parseable_fixits_p
= false;
213 context
->edit_context_ptr
= NULL
;
214 context
->diagnostic_group_nesting_depth
= 0;
215 context
->diagnostic_group_emission_count
= 0;
216 context
->begin_group_cb
= NULL
;
217 context
->end_group_cb
= NULL
;
218 context
->final_cb
= default_diagnostic_final_cb
;
221 /* Maybe initialize the color support. We require clients to do this
222 explicitly, since most clients don't want color. When called
223 without a VALUE, it initializes with DIAGNOSTICS_COLOR_DEFAULT. */
226 diagnostic_color_init (diagnostic_context
*context
, int value
/*= -1 */)
228 /* value == -1 is the default value. */
231 /* If DIAGNOSTICS_COLOR_DEFAULT is -1, default to
232 -fdiagnostics-color=auto if GCC_COLORS is in the environment,
233 otherwise default to -fdiagnostics-color=never, for other
234 values default to that
235 -fdiagnostics-color={never,auto,always}. */
236 if (DIAGNOSTICS_COLOR_DEFAULT
== -1)
238 if (!getenv ("GCC_COLORS"))
240 value
= DIAGNOSTICS_COLOR_AUTO
;
243 value
= DIAGNOSTICS_COLOR_DEFAULT
;
245 pp_show_color (context
->printer
)
246 = colorize_init ((diagnostic_color_rule_t
) value
);
249 /* Do any cleaning up required after the last diagnostic is emitted. */
252 diagnostic_finish (diagnostic_context
*context
)
254 if (context
->final_cb
)
255 context
->final_cb (context
);
257 diagnostic_file_cache_fini ();
259 XDELETEVEC (context
->classify_diagnostic
);
260 context
->classify_diagnostic
= NULL
;
262 /* diagnostic_initialize allocates context->printer using XNEW
263 and placement-new. */
264 context
->printer
->~pretty_printer ();
265 XDELETE (context
->printer
);
266 context
->printer
= NULL
;
268 if (context
->edit_context_ptr
)
270 delete context
->edit_context_ptr
;
271 context
->edit_context_ptr
= NULL
;
275 /* Initialize DIAGNOSTIC, where the message MSG has already been
278 diagnostic_set_info_translated (diagnostic_info
*diagnostic
, const char *msg
,
279 va_list *args
, rich_location
*richloc
,
282 gcc_assert (richloc
);
283 diagnostic
->message
.err_no
= errno
;
284 diagnostic
->message
.args_ptr
= args
;
285 diagnostic
->message
.format_spec
= msg
;
286 diagnostic
->message
.m_richloc
= richloc
;
287 diagnostic
->richloc
= richloc
;
288 diagnostic
->kind
= kind
;
289 diagnostic
->option_index
= 0;
292 /* Initialize DIAGNOSTIC, where the message GMSGID has not yet been
295 diagnostic_set_info (diagnostic_info
*diagnostic
, const char *gmsgid
,
296 va_list *args
, rich_location
*richloc
,
299 gcc_assert (richloc
);
300 diagnostic_set_info_translated (diagnostic
, _(gmsgid
), args
, richloc
, kind
);
303 static const char *const diagnostic_kind_color
[] = {
304 #define DEFINE_DIAGNOSTIC_KIND(K, T, C) (C),
305 #include "diagnostic.def"
306 #undef DEFINE_DIAGNOSTIC_KIND
310 /* Get a color name for diagnostics of type KIND
311 Result could be NULL. */
314 diagnostic_get_color_for_kind (diagnostic_t kind
)
316 return diagnostic_kind_color
[kind
];
319 /* Return a formatted line and column ':%line:%column'. Elided if
320 zero. The result is a statically allocated buffer. */
323 maybe_line_and_column (int line
, int col
)
325 static char result
[32];
329 size_t l
= snprintf (result
, sizeof (result
),
330 col
? ":%d:%d" : ":%d", line
, col
);
331 gcc_checking_assert (l
< sizeof (result
));
338 /* Return a malloc'd string describing a location e.g. "foo.c:42:10".
339 The caller is responsible for freeing the memory. */
342 diagnostic_get_location_text (diagnostic_context
*context
,
345 pretty_printer
*pp
= context
->printer
;
346 const char *locus_cs
= colorize_start (pp_show_color (pp
), "locus");
347 const char *locus_ce
= colorize_stop (pp_show_color (pp
));
348 const char *file
= s
.file
? s
.file
: progname
;
349 int line
= strcmp (file
, N_("<built-in>")) ? s
.line
: 0;
350 int col
= context
->show_column
? s
.column
: 0;
352 const char *line_col
= maybe_line_and_column (line
, col
);
353 return build_message_string ("%s%s%s:%s", locus_cs
, file
,
357 /* Return a malloc'd string describing a location and the severity of the
358 diagnostic, e.g. "foo.c:42:10: error: ". The caller is responsible for
359 freeing the memory. */
361 diagnostic_build_prefix (diagnostic_context
*context
,
362 const diagnostic_info
*diagnostic
)
364 static const char *const diagnostic_kind_text
[] = {
365 #define DEFINE_DIAGNOSTIC_KIND(K, T, C) (T),
366 #include "diagnostic.def"
367 #undef DEFINE_DIAGNOSTIC_KIND
370 gcc_assert (diagnostic
->kind
< DK_LAST_DIAGNOSTIC_KIND
);
372 const char *text
= _(diagnostic_kind_text
[diagnostic
->kind
]);
373 const char *text_cs
= "", *text_ce
= "";
374 pretty_printer
*pp
= context
->printer
;
376 if (diagnostic_kind_color
[diagnostic
->kind
])
378 text_cs
= colorize_start (pp_show_color (pp
),
379 diagnostic_kind_color
[diagnostic
->kind
]);
380 text_ce
= colorize_stop (pp_show_color (pp
));
383 expanded_location s
= diagnostic_expand_location (diagnostic
);
384 char *location_text
= diagnostic_get_location_text (context
, s
);
386 char *result
= build_message_string ("%s %s%s%s", location_text
,
387 text_cs
, text
, text_ce
);
388 free (location_text
);
392 /* Functions at which to stop the backtrace print. It's not
393 particularly helpful to print the callers of these functions. */
395 static const char * const bt_stop
[] =
403 /* A callback function passed to the backtrace_full function. */
406 bt_callback (void *data
, uintptr_t pc
, const char *filename
, int lineno
,
407 const char *function
)
409 int *pcount
= (int *) data
;
411 /* If we don't have any useful information, don't print
413 if (filename
== NULL
&& function
== NULL
)
416 /* Skip functions in diagnostic.c. */
419 && strcmp (lbasename (filename
), "diagnostic.c") == 0)
422 /* Print up to 20 functions. We could make this a --param, but
423 since this is only for debugging just use a constant for now. */
426 /* Returning a non-zero value stops the backtrace. */
432 if (function
!= NULL
)
434 char *str
= cplus_demangle_v3 (function
,
435 (DMGL_VERBOSE
| DMGL_ANSI
436 | DMGL_GNU_V3
| DMGL_PARAMS
));
443 for (size_t i
= 0; i
< ARRAY_SIZE (bt_stop
); ++i
)
445 size_t len
= strlen (bt_stop
[i
]);
446 if (strncmp (function
, bt_stop
[i
], len
) == 0
447 && (function
[len
] == '\0' || function
[len
] == '('))
451 /* Returning a non-zero value stops the backtrace. */
457 fprintf (stderr
, "0x%lx %s\n\t%s:%d\n",
459 function
== NULL
? "???" : function
,
460 filename
== NULL
? "???" : filename
,
469 /* A callback function passed to the backtrace_full function. This is
470 called if backtrace_full has an error. */
473 bt_err_callback (void *data ATTRIBUTE_UNUSED
, const char *msg
, int errnum
)
477 /* This means that no debug info was available. Just quietly
478 skip printing backtrace info. */
481 fprintf (stderr
, "%s%s%s\n", msg
, errnum
== 0 ? "" : ": ",
482 errnum
== 0 ? "" : xstrerror (errnum
));
485 /* Check if we've met the maximum error limit, and if so fatally exit
486 with a message. CONTEXT is the context to check, and FLUSH
487 indicates whether a diagnostic_finish call is needed. */
490 diagnostic_check_max_errors (diagnostic_context
*context
, bool flush
)
492 if (!context
->max_errors
)
495 int count
= (diagnostic_kind_count (context
, DK_ERROR
)
496 + diagnostic_kind_count (context
, DK_SORRY
)
497 + diagnostic_kind_count (context
, DK_WERROR
));
499 if (count
>= context
->max_errors
)
502 "compilation terminated due to -fmax-errors=%u.\n",
503 context
->max_errors
);
505 diagnostic_finish (context
);
506 exit (FATAL_EXIT_CODE
);
510 /* Take any action which is expected to happen after the diagnostic
511 is written out. This function does not always return. */
513 diagnostic_action_after_output (diagnostic_context
*context
,
514 diagnostic_t diag_kind
)
526 if (context
->abort_on_error
)
528 if (context
->fatal_errors
)
530 fnotice (stderr
, "compilation terminated due to -Wfatal-errors.\n");
531 diagnostic_finish (context
);
532 exit (FATAL_EXIT_CODE
);
539 struct backtrace_state
*state
= NULL
;
540 if (diag_kind
== DK_ICE
)
541 state
= backtrace_create_state (NULL
, 0, bt_err_callback
, NULL
);
544 backtrace_full (state
, 2, bt_callback
, bt_err_callback
,
547 if (context
->abort_on_error
)
550 fnotice (stderr
, "Please submit a full bug report,\n"
551 "with preprocessed source if appropriate.\n");
554 ("Please include the complete backtrace "
555 "with any bug report.\n"));
556 fnotice (stderr
, "See %s for instructions.\n", bug_report_url
);
558 exit (ICE_EXIT_CODE
);
562 if (context
->abort_on_error
)
564 diagnostic_finish (context
);
565 fnotice (stderr
, "compilation terminated.\n");
566 exit (FATAL_EXIT_CODE
);
573 /* True if the last module or file in which a diagnostic was reported is
574 different from the current one. */
577 last_module_changed_p (diagnostic_context
*context
,
578 const line_map_ordinary
*map
)
580 return context
->last_module
!= map
;
583 /* Remember the current module or file as being the last one in which we
584 report a diagnostic. */
587 set_last_module (diagnostic_context
*context
, const line_map_ordinary
*map
)
589 context
->last_module
= map
;
593 diagnostic_report_current_module (diagnostic_context
*context
, location_t where
)
595 const line_map_ordinary
*map
= NULL
;
597 if (pp_needs_newline (context
->printer
))
599 pp_newline (context
->printer
);
600 pp_needs_newline (context
->printer
) = false;
603 if (where
<= BUILTINS_LOCATION
)
606 linemap_resolve_location (line_table
, where
,
607 LRK_MACRO_DEFINITION_LOCATION
,
610 if (map
&& last_module_changed_p (context
, map
))
612 set_last_module (context
, map
);
613 if (! MAIN_FILE_P (map
))
618 where
= linemap_included_from (map
);
619 map
= linemap_included_from_linemap (line_table
, map
);
621 = maybe_line_and_column (SOURCE_LINE (map
, where
),
622 first
&& context
->show_column
623 ? SOURCE_COLUMN (map
, where
) : 0);
624 static const char *const msgs
[] =
626 N_("In file included from"),
629 unsigned index
= !first
;
630 pp_verbatim (context
->printer
, "%s%s %r%s%s%R",
631 first
? "" : ",\n", _(msgs
[index
]),
632 "locus", LINEMAP_FILE (map
), line_col
);
635 while (! MAIN_FILE_P (map
));
636 pp_verbatim (context
->printer
, ":");
637 pp_newline (context
->printer
);
643 default_diagnostic_starter (diagnostic_context
*context
,
644 diagnostic_info
*diagnostic
)
646 diagnostic_report_current_module (context
, diagnostic_location (diagnostic
));
647 pp_set_prefix (context
->printer
, diagnostic_build_prefix (context
,
652 default_diagnostic_start_span_fn (diagnostic_context
*context
,
653 expanded_location exploc
)
655 char *text
= diagnostic_get_location_text (context
, exploc
);
656 pp_string (context
->printer
, text
);
658 pp_newline (context
->printer
);
662 default_diagnostic_finalizer (diagnostic_context
*context
,
663 diagnostic_info
*diagnostic
,
666 diagnostic_show_locus (context
, diagnostic
->richloc
, diagnostic
->kind
);
667 pp_destroy_prefix (context
->printer
);
668 pp_flush (context
->printer
);
671 /* Interface to specify diagnostic kind overrides. Returns the
672 previous setting, or DK_UNSPECIFIED if the parameters are out of
673 range. If OPTION_INDEX is zero, the new setting is for all the
676 diagnostic_classify_diagnostic (diagnostic_context
*context
,
678 diagnostic_t new_kind
,
681 diagnostic_t old_kind
;
684 || option_index
>= context
->n_opts
685 || new_kind
>= DK_LAST_DIAGNOSTIC_KIND
)
686 return DK_UNSPECIFIED
;
688 old_kind
= context
->classify_diagnostic
[option_index
];
690 /* Handle pragmas separately, since we need to keep track of *where*
692 if (where
!= UNKNOWN_LOCATION
)
696 /* Record the command-line status, so we can reset it back on DK_POP. */
697 if (old_kind
== DK_UNSPECIFIED
)
699 old_kind
= !context
->option_enabled (option_index
,
701 context
->option_state
)
702 ? DK_IGNORED
: (context
->warning_as_error_requested
703 ? DK_ERROR
: DK_WARNING
);
704 context
->classify_diagnostic
[option_index
] = old_kind
;
707 for (i
= context
->n_classification_history
- 1; i
>= 0; i
--)
708 if (context
->classification_history
[i
].option
== option_index
)
710 old_kind
= context
->classification_history
[i
].kind
;
714 i
= context
->n_classification_history
;
715 context
->classification_history
=
716 (diagnostic_classification_change_t
*) xrealloc (context
->classification_history
, (i
+ 1)
717 * sizeof (diagnostic_classification_change_t
));
718 context
->classification_history
[i
].location
= where
;
719 context
->classification_history
[i
].option
= option_index
;
720 context
->classification_history
[i
].kind
= new_kind
;
721 context
->n_classification_history
++;
724 context
->classify_diagnostic
[option_index
] = new_kind
;
729 /* Save all diagnostic classifications in a stack. */
731 diagnostic_push_diagnostics (diagnostic_context
*context
, location_t where ATTRIBUTE_UNUSED
)
733 context
->push_list
= (int *) xrealloc (context
->push_list
, (context
->n_push
+ 1) * sizeof (int));
734 context
->push_list
[context
->n_push
++] = context
->n_classification_history
;
737 /* Restore the topmost classification set off the stack. If the stack
738 is empty, revert to the state based on command line parameters. */
740 diagnostic_pop_diagnostics (diagnostic_context
*context
, location_t where
)
746 jump_to
= context
->push_list
[-- context
->n_push
];
750 i
= context
->n_classification_history
;
751 context
->classification_history
=
752 (diagnostic_classification_change_t
*) xrealloc (context
->classification_history
, (i
+ 1)
753 * sizeof (diagnostic_classification_change_t
));
754 context
->classification_history
[i
].location
= where
;
755 context
->classification_history
[i
].option
= jump_to
;
756 context
->classification_history
[i
].kind
= DK_POP
;
757 context
->n_classification_history
++;
760 /* Helper function for print_parseable_fixits. Print TEXT to PP, obeying the
761 escaping rules for -fdiagnostics-parseable-fixits. */
764 print_escaped_string (pretty_printer
*pp
, const char *text
)
769 pp_character (pp
, '"');
770 for (const char *ch
= text
; *ch
; ch
++)
775 /* Escape backslash as two backslashes. */
776 pp_string (pp
, "\\\\");
779 /* Escape tab as "\t". */
780 pp_string (pp
, "\\t");
783 /* Escape newline as "\n". */
784 pp_string (pp
, "\\n");
787 /* Escape doublequotes as \". */
788 pp_string (pp
, "\\\"");
792 pp_character (pp
, *ch
);
794 /* Use octal for non-printable chars. */
796 unsigned char c
= (*ch
& 0xff);
797 pp_printf (pp
, "\\%o%o%o", (c
/ 64), (c
/ 8) & 007, c
& 007);
802 pp_character (pp
, '"');
805 /* Implementation of -fdiagnostics-parseable-fixits. Print a
806 machine-parseable version of all fixits in RICHLOC to PP. */
809 print_parseable_fixits (pretty_printer
*pp
, rich_location
*richloc
)
812 gcc_assert (richloc
);
814 for (unsigned i
= 0; i
< richloc
->get_num_fixit_hints (); i
++)
816 const fixit_hint
*hint
= richloc
->get_fixit_hint (i
);
817 location_t start_loc
= hint
->get_start_loc ();
818 expanded_location start_exploc
= expand_location (start_loc
);
819 pp_string (pp
, "fix-it:");
820 print_escaped_string (pp
, start_exploc
.file
);
821 /* For compatibility with clang, print as a half-open range. */
822 location_t next_loc
= hint
->get_next_loc ();
823 expanded_location next_exploc
= expand_location (next_loc
);
824 pp_printf (pp
, ":{%i:%i-%i:%i}:",
825 start_exploc
.line
, start_exploc
.column
,
826 next_exploc
.line
, next_exploc
.column
);
827 print_escaped_string (pp
, hint
->get_string ());
832 /* Update the diag_class of DIAGNOSTIC based on its location
834 #pragma GCC diagnostic
835 directives recorded within CONTEXT.
837 Return the new diag_class of DIAGNOSTIC if it was updated, or
838 DK_UNSPECIFIED otherwise. */
841 update_effective_level_from_pragmas (diagnostic_context
*context
,
842 diagnostic_info
*diagnostic
)
844 diagnostic_t diag_class
= DK_UNSPECIFIED
;
846 if (context
->n_classification_history
> 0)
848 location_t location
= diagnostic_location (diagnostic
);
850 /* FIXME: Stupid search. Optimize later. */
851 for (int i
= context
->n_classification_history
- 1; i
>= 0; i
--)
853 if (linemap_location_before_p
855 context
->classification_history
[i
].location
,
858 if (context
->classification_history
[i
].kind
== (int) DK_POP
)
860 i
= context
->classification_history
[i
].option
;
863 int option
= context
->classification_history
[i
].option
;
864 /* The option 0 is for all the diagnostics. */
865 if (option
== 0 || option
== diagnostic
->option_index
)
867 diag_class
= context
->classification_history
[i
].kind
;
868 if (diag_class
!= DK_UNSPECIFIED
)
869 diagnostic
->kind
= diag_class
;
879 /* Print any metadata about the option used to control DIAGNOSTIC to CONTEXT's
880 printer, e.g. " [-Werror=uninitialized]".
881 Subroutine of diagnostic_report_diagnostic. */
884 print_option_information (diagnostic_context
*context
,
885 const diagnostic_info
*diagnostic
,
886 diagnostic_t orig_diag_kind
)
890 option_text
= context
->option_name (context
, diagnostic
->option_index
,
891 orig_diag_kind
, diagnostic
->kind
);
895 pretty_printer
*pp
= context
->printer
;
896 pp_string (pp
, " [");
897 pp_string (pp
, colorize_start (pp_show_color (pp
),
898 diagnostic_kind_color
[diagnostic
->kind
]));
899 pp_string (pp
, option_text
);
900 pp_string (pp
, colorize_stop (pp_show_color (pp
)));
901 pp_character (pp
, ']');
906 /* Report a diagnostic message (an error or a warning) as specified by
907 DC. This function is *the* subroutine in terms of which front-ends
908 should implement their specific diagnostic handling modules. The
909 front-end independent format specifiers are exactly those described
910 in the documentation of output_format.
911 Return true if a diagnostic was printed, false otherwise. */
914 diagnostic_report_diagnostic (diagnostic_context
*context
,
915 diagnostic_info
*diagnostic
)
917 location_t location
= diagnostic_location (diagnostic
);
918 diagnostic_t orig_diag_kind
= diagnostic
->kind
;
920 /* Give preference to being able to inhibit warnings, before they
921 get reclassified to something else. */
922 if ((diagnostic
->kind
== DK_WARNING
|| diagnostic
->kind
== DK_PEDWARN
)
923 && !diagnostic_report_warnings_p (context
, location
))
926 if (diagnostic
->kind
== DK_PEDWARN
)
928 diagnostic
->kind
= pedantic_warning_kind (context
);
929 /* We do this to avoid giving the message for -pedantic-errors. */
930 orig_diag_kind
= diagnostic
->kind
;
933 if (diagnostic
->kind
== DK_NOTE
&& context
->inhibit_notes_p
)
936 if (context
->lock
> 0)
938 /* If we're reporting an ICE in the middle of some other error,
939 try to flush out the previous error, then let this one
940 through. Don't do this more than once. */
941 if ((diagnostic
->kind
== DK_ICE
|| diagnostic
->kind
== DK_ICE_NOBT
)
942 && context
->lock
== 1)
943 pp_newline_and_flush (context
->printer
);
945 error_recursion (context
);
948 /* If the user requested that warnings be treated as errors, so be
949 it. Note that we do this before the next block so that
950 individual warnings can be overridden back to warnings with
952 if (context
->warning_as_error_requested
953 && diagnostic
->kind
== DK_WARNING
)
954 diagnostic
->kind
= DK_ERROR
;
956 if (diagnostic
->option_index
957 && diagnostic
->option_index
!= permissive_error_option (context
))
959 /* This tests if the user provided the appropriate -Wfoo or
961 if (! context
->option_enabled (diagnostic
->option_index
,
963 context
->option_state
))
966 /* This tests for #pragma diagnostic changes. */
967 diagnostic_t diag_class
968 = update_effective_level_from_pragmas (context
, diagnostic
);
970 /* This tests if the user provided the appropriate -Werror=foo
972 if (diag_class
== DK_UNSPECIFIED
973 && (context
->classify_diagnostic
[diagnostic
->option_index
]
976 = context
->classify_diagnostic
[diagnostic
->option_index
];
978 /* This allows for future extensions, like temporarily disabling
979 warnings for ranges of source code. */
980 if (diagnostic
->kind
== DK_IGNORED
)
984 if (diagnostic
->kind
!= DK_NOTE
)
985 diagnostic_check_max_errors (context
);
989 if (diagnostic
->kind
== DK_ICE
|| diagnostic
->kind
== DK_ICE_NOBT
)
991 /* When not checking, ICEs are converted to fatal errors when an
992 error has already occurred. This is counteracted by
995 && (diagnostic_kind_count (context
, DK_ERROR
) > 0
996 || diagnostic_kind_count (context
, DK_SORRY
) > 0)
997 && !context
->abort_on_error
)
1000 = expand_location (diagnostic_location (diagnostic
));
1001 fnotice (stderr
, "%s:%d: confused by earlier errors, bailing out\n",
1003 exit (ICE_EXIT_CODE
);
1005 if (context
->internal_error
)
1006 (*context
->internal_error
) (context
,
1007 diagnostic
->message
.format_spec
,
1008 diagnostic
->message
.args_ptr
);
1010 if (diagnostic
->kind
== DK_ERROR
&& orig_diag_kind
== DK_WARNING
)
1011 ++diagnostic_kind_count (context
, DK_WERROR
);
1013 ++diagnostic_kind_count (context
, diagnostic
->kind
);
1015 /* Is this the initial diagnostic within the stack of groups? */
1016 if (context
->diagnostic_group_emission_count
== 0)
1018 if (context
->begin_group_cb
)
1019 context
->begin_group_cb (context
);
1021 context
->diagnostic_group_emission_count
++;
1023 diagnostic
->message
.x_data
= &diagnostic
->x_data
;
1024 diagnostic
->x_data
= NULL
;
1025 pp_format (context
->printer
, &diagnostic
->message
);
1026 (*diagnostic_starter (context
)) (context
, diagnostic
);
1027 pp_output_formatted_text (context
->printer
);
1028 if (context
->show_option_requested
)
1029 print_option_information (context
, diagnostic
, orig_diag_kind
);
1030 (*diagnostic_finalizer (context
)) (context
, diagnostic
, orig_diag_kind
);
1031 if (context
->parseable_fixits_p
)
1033 print_parseable_fixits (context
->printer
, diagnostic
->richloc
);
1034 pp_flush (context
->printer
);
1036 diagnostic_action_after_output (context
, diagnostic
->kind
);
1037 diagnostic
->x_data
= NULL
;
1039 if (context
->edit_context_ptr
)
1040 if (diagnostic
->richloc
->fixits_can_be_auto_applied_p ())
1041 context
->edit_context_ptr
->add_fixits (diagnostic
->richloc
);
1048 /* Get the number of digits in the decimal representation of VALUE. */
1051 num_digits (int value
)
1053 /* Perhaps simpler to use log10 for this, but doing it this way avoids
1054 using floating point. */
1055 gcc_assert (value
>= 0);
1069 /* Given a partial pathname as input, return another pathname that
1070 shares no directory elements with the pathname of __FILE__. This
1071 is used by fancy_abort() to print `Internal compiler error in expr.c'
1072 instead of `Internal compiler error in ../../GCC/gcc/expr.c'. */
1075 trim_filename (const char *name
)
1077 static const char this_file
[] = __FILE__
;
1078 const char *p
= name
, *q
= this_file
;
1080 /* First skip any "../" in each filename. This allows us to give a proper
1081 reference to a file in a subdirectory. */
1082 while (p
[0] == '.' && p
[1] == '.' && IS_DIR_SEPARATOR (p
[2]))
1085 while (q
[0] == '.' && q
[1] == '.' && IS_DIR_SEPARATOR (q
[2]))
1088 /* Now skip any parts the two filenames have in common. */
1089 while (*p
== *q
&& *p
!= 0 && *q
!= 0)
1092 /* Now go backwards until the previous directory separator. */
1093 while (p
> name
&& !IS_DIR_SEPARATOR (p
[-1]))
1099 /* Standard error reporting routines in increasing order of severity.
1100 All of these take arguments like printf. */
1102 /* Text to be emitted verbatim to the error message stream; this
1103 produces no prefix and disables line-wrapping. Use rarely. */
1105 verbatim (const char *gmsgid
, ...)
1110 va_start (ap
, gmsgid
);
1111 text
.err_no
= errno
;
1112 text
.args_ptr
= &ap
;
1113 text
.format_spec
= _(gmsgid
);
1115 pp_format_verbatim (global_dc
->printer
, &text
);
1116 pp_newline_and_flush (global_dc
->printer
);
1120 /* Add a note with text GMSGID and with LOCATION to the diagnostic CONTEXT. */
1122 diagnostic_append_note (diagnostic_context
*context
,
1123 location_t location
,
1124 const char * gmsgid
, ...)
1126 diagnostic_info diagnostic
;
1128 rich_location
richloc (line_table
, location
);
1130 va_start (ap
, gmsgid
);
1131 diagnostic_set_info (&diagnostic
, gmsgid
, &ap
, &richloc
, DK_NOTE
);
1132 if (context
->inhibit_notes_p
)
1137 char *saved_prefix
= pp_take_prefix (context
->printer
);
1138 pp_set_prefix (context
->printer
,
1139 diagnostic_build_prefix (context
, &diagnostic
));
1140 pp_format (context
->printer
, &diagnostic
.message
);
1141 pp_output_formatted_text (context
->printer
);
1142 pp_destroy_prefix (context
->printer
);
1143 pp_set_prefix (context
->printer
, saved_prefix
);
1144 diagnostic_show_locus (context
, &richloc
, DK_NOTE
);
1148 /* Implement emit_diagnostic, inform, warning, warning_at, pedwarn,
1149 permerror, error, error_at, error_at, sorry, fatal_error, internal_error,
1150 and internal_error_no_backtrace, as documented and defined below. */
1152 diagnostic_impl (rich_location
*richloc
, int opt
,
1154 va_list *ap
, diagnostic_t kind
)
1156 diagnostic_info diagnostic
;
1157 if (kind
== DK_PERMERROR
)
1159 diagnostic_set_info (&diagnostic
, gmsgid
, ap
, richloc
,
1160 permissive_error_kind (global_dc
));
1161 diagnostic
.option_index
= permissive_error_option (global_dc
);
1165 diagnostic_set_info (&diagnostic
, gmsgid
, ap
, richloc
, kind
);
1166 if (kind
== DK_WARNING
|| kind
== DK_PEDWARN
)
1167 diagnostic
.option_index
= opt
;
1169 return diagnostic_report_diagnostic (global_dc
, &diagnostic
);
1172 /* Implement inform_n, warning_n, and error_n, as documented and
1175 diagnostic_n_impl (rich_location
*richloc
, int opt
, unsigned HOST_WIDE_INT n
,
1176 const char *singular_gmsgid
,
1177 const char *plural_gmsgid
,
1178 va_list *ap
, diagnostic_t kind
)
1180 diagnostic_info diagnostic
;
1183 if (sizeof n
<= sizeof gtn
)
1186 /* Use the largest number ngettext can handle, otherwise
1187 preserve the six least significant decimal digits for
1188 languages where the plural form depends on them. */
1189 gtn
= n
<= ULONG_MAX
? n
: n
% 1000000LU + 1000000LU;
1191 const char *text
= ngettext (singular_gmsgid
, plural_gmsgid
, gtn
);
1192 diagnostic_set_info_translated (&diagnostic
, text
, ap
, richloc
, kind
);
1193 if (kind
== DK_WARNING
)
1194 diagnostic
.option_index
= opt
;
1195 return diagnostic_report_diagnostic (global_dc
, &diagnostic
);
1198 /* Wrapper around diagnostic_impl taking a variable argument list. */
1201 emit_diagnostic (diagnostic_t kind
, location_t location
, int opt
,
1202 const char *gmsgid
, ...)
1204 auto_diagnostic_group d
;
1206 va_start (ap
, gmsgid
);
1207 rich_location
richloc (line_table
, location
);
1208 bool ret
= diagnostic_impl (&richloc
, opt
, gmsgid
, &ap
, kind
);
1213 /* As above, but for rich_location *. */
1216 emit_diagnostic (diagnostic_t kind
, rich_location
*richloc
, int opt
,
1217 const char *gmsgid
, ...)
1219 auto_diagnostic_group d
;
1221 va_start (ap
, gmsgid
);
1222 bool ret
= diagnostic_impl (richloc
, opt
, gmsgid
, &ap
, kind
);
1227 /* Wrapper around diagnostic_impl taking a va_list parameter. */
1230 emit_diagnostic_valist (diagnostic_t kind
, location_t location
, int opt
,
1231 const char *gmsgid
, va_list *ap
)
1233 rich_location
richloc (line_table
, location
);
1234 return diagnostic_impl (&richloc
, opt
, gmsgid
, ap
, kind
);
1237 /* An informative note at LOCATION. Use this for additional details on an error
1240 inform (location_t location
, const char *gmsgid
, ...)
1242 auto_diagnostic_group d
;
1244 va_start (ap
, gmsgid
);
1245 rich_location
richloc (line_table
, location
);
1246 diagnostic_impl (&richloc
, -1, gmsgid
, &ap
, DK_NOTE
);
1250 /* Same as "inform" above, but at RICHLOC. */
1252 inform (rich_location
*richloc
, const char *gmsgid
, ...)
1254 gcc_assert (richloc
);
1256 auto_diagnostic_group d
;
1258 va_start (ap
, gmsgid
);
1259 diagnostic_impl (richloc
, -1, gmsgid
, &ap
, DK_NOTE
);
1263 /* An informative note at LOCATION. Use this for additional details on an
1266 inform_n (location_t location
, unsigned HOST_WIDE_INT n
,
1267 const char *singular_gmsgid
, const char *plural_gmsgid
, ...)
1270 va_start (ap
, plural_gmsgid
);
1271 auto_diagnostic_group d
;
1272 rich_location
richloc (line_table
, location
);
1273 diagnostic_n_impl (&richloc
, -1, n
, singular_gmsgid
, plural_gmsgid
,
1278 /* A warning at INPUT_LOCATION. Use this for code which is correct according
1279 to the relevant language specification but is likely to be buggy anyway.
1280 Returns true if the warning was printed, false if it was inhibited. */
1282 warning (int opt
, const char *gmsgid
, ...)
1284 auto_diagnostic_group d
;
1286 va_start (ap
, gmsgid
);
1287 rich_location
richloc (line_table
, input_location
);
1288 bool ret
= diagnostic_impl (&richloc
, opt
, gmsgid
, &ap
, DK_WARNING
);
1293 /* A warning at LOCATION. Use this for code which is correct according to the
1294 relevant language specification but is likely to be buggy anyway.
1295 Returns true if the warning was printed, false if it was inhibited. */
1298 warning_at (location_t location
, int opt
, const char *gmsgid
, ...)
1300 auto_diagnostic_group d
;
1302 va_start (ap
, gmsgid
);
1303 rich_location
richloc (line_table
, location
);
1304 bool ret
= diagnostic_impl (&richloc
, opt
, gmsgid
, &ap
, DK_WARNING
);
1309 /* Same as "warning at" above, but using RICHLOC. */
1312 warning_at (rich_location
*richloc
, int opt
, const char *gmsgid
, ...)
1314 gcc_assert (richloc
);
1316 auto_diagnostic_group d
;
1318 va_start (ap
, gmsgid
);
1319 bool ret
= diagnostic_impl (richloc
, opt
, gmsgid
, &ap
, DK_WARNING
);
1324 /* Same as warning_n plural variant below, but using RICHLOC. */
1327 warning_n (rich_location
*richloc
, int opt
, unsigned HOST_WIDE_INT n
,
1328 const char *singular_gmsgid
, const char *plural_gmsgid
, ...)
1330 gcc_assert (richloc
);
1332 auto_diagnostic_group d
;
1334 va_start (ap
, plural_gmsgid
);
1335 bool ret
= diagnostic_n_impl (richloc
, opt
, n
,
1336 singular_gmsgid
, plural_gmsgid
,
1342 /* A warning at LOCATION. Use this for code which is correct according to the
1343 relevant language specification but is likely to be buggy anyway.
1344 Returns true if the warning was printed, false if it was inhibited. */
1347 warning_n (location_t location
, int opt
, unsigned HOST_WIDE_INT n
,
1348 const char *singular_gmsgid
, const char *plural_gmsgid
, ...)
1350 auto_diagnostic_group d
;
1352 va_start (ap
, plural_gmsgid
);
1353 rich_location
richloc (line_table
, location
);
1354 bool ret
= diagnostic_n_impl (&richloc
, opt
, n
,
1355 singular_gmsgid
, plural_gmsgid
,
1361 /* A "pedantic" warning at LOCATION: issues a warning unless
1362 -pedantic-errors was given on the command line, in which case it
1363 issues an error. Use this for diagnostics required by the relevant
1364 language standard, if you have chosen not to make them errors.
1366 Note that these diagnostics are issued independent of the setting
1367 of the -Wpedantic command-line switch. To get a warning enabled
1368 only with that switch, use either "if (pedantic) pedwarn
1369 (OPT_Wpedantic,...)" or just "pedwarn (OPT_Wpedantic,..)". To get a
1370 pedwarn independently of the -Wpedantic switch use "pedwarn (0,...)".
1372 Returns true if the warning was printed, false if it was inhibited. */
1375 pedwarn (location_t location
, int opt
, const char *gmsgid
, ...)
1377 auto_diagnostic_group d
;
1379 va_start (ap
, gmsgid
);
1380 rich_location
richloc (line_table
, location
);
1381 bool ret
= diagnostic_impl (&richloc
, opt
, gmsgid
, &ap
, DK_PEDWARN
);
1386 /* Same as pedwarn above, but using RICHLOC. */
1389 pedwarn (rich_location
*richloc
, int opt
, const char *gmsgid
, ...)
1391 gcc_assert (richloc
);
1393 auto_diagnostic_group d
;
1395 va_start (ap
, gmsgid
);
1396 bool ret
= diagnostic_impl (richloc
, opt
, gmsgid
, &ap
, DK_PEDWARN
);
1401 /* A "permissive" error at LOCATION: issues an error unless
1402 -fpermissive was given on the command line, in which case it issues
1403 a warning. Use this for things that really should be errors but we
1404 want to support legacy code.
1406 Returns true if the warning was printed, false if it was inhibited. */
1409 permerror (location_t location
, const char *gmsgid
, ...)
1411 auto_diagnostic_group d
;
1413 va_start (ap
, gmsgid
);
1414 rich_location
richloc (line_table
, location
);
1415 bool ret
= diagnostic_impl (&richloc
, -1, gmsgid
, &ap
, DK_PERMERROR
);
1420 /* Same as "permerror" above, but at RICHLOC. */
1423 permerror (rich_location
*richloc
, const char *gmsgid
, ...)
1425 gcc_assert (richloc
);
1427 auto_diagnostic_group d
;
1429 va_start (ap
, gmsgid
);
1430 bool ret
= diagnostic_impl (richloc
, -1, gmsgid
, &ap
, DK_PERMERROR
);
1435 /* A hard error: the code is definitely ill-formed, and an object file
1436 will not be produced. */
1438 error (const char *gmsgid
, ...)
1440 auto_diagnostic_group d
;
1442 va_start (ap
, gmsgid
);
1443 rich_location
richloc (line_table
, input_location
);
1444 diagnostic_impl (&richloc
, -1, gmsgid
, &ap
, DK_ERROR
);
1448 /* A hard error: the code is definitely ill-formed, and an object file
1449 will not be produced. */
1451 error_n (location_t location
, unsigned HOST_WIDE_INT n
,
1452 const char *singular_gmsgid
, const char *plural_gmsgid
, ...)
1454 auto_diagnostic_group d
;
1456 va_start (ap
, plural_gmsgid
);
1457 rich_location
richloc (line_table
, location
);
1458 diagnostic_n_impl (&richloc
, -1, n
, singular_gmsgid
, plural_gmsgid
,
1463 /* Same as above, but use location LOC instead of input_location. */
1465 error_at (location_t loc
, const char *gmsgid
, ...)
1467 auto_diagnostic_group d
;
1469 va_start (ap
, gmsgid
);
1470 rich_location
richloc (line_table
, loc
);
1471 diagnostic_impl (&richloc
, -1, gmsgid
, &ap
, DK_ERROR
);
1475 /* Same as above, but use RICH_LOC. */
1478 error_at (rich_location
*richloc
, const char *gmsgid
, ...)
1480 gcc_assert (richloc
);
1482 auto_diagnostic_group d
;
1484 va_start (ap
, gmsgid
);
1485 diagnostic_impl (richloc
, -1, gmsgid
, &ap
, DK_ERROR
);
1489 /* "Sorry, not implemented." Use for a language feature which is
1490 required by the relevant specification but not implemented by GCC.
1491 An object file will not be produced. */
1493 sorry (const char *gmsgid
, ...)
1495 auto_diagnostic_group d
;
1497 va_start (ap
, gmsgid
);
1498 rich_location
richloc (line_table
, input_location
);
1499 diagnostic_impl (&richloc
, -1, gmsgid
, &ap
, DK_SORRY
);
1503 /* Same as above, but use location LOC instead of input_location. */
1505 sorry_at (location_t loc
, const char *gmsgid
, ...)
1507 auto_diagnostic_group d
;
1509 va_start (ap
, gmsgid
);
1510 rich_location
richloc (line_table
, loc
);
1511 diagnostic_impl (&richloc
, -1, gmsgid
, &ap
, DK_SORRY
);
1515 /* Return true if an error or a "sorry" has been seen. Various
1516 processing is disabled after errors. */
1520 return errorcount
|| sorrycount
;
1523 /* An error which is severe enough that we make no attempt to
1524 continue. Do not use this for internal consistency checks; that's
1525 internal_error. Use of this function should be rare. */
1527 fatal_error (location_t loc
, const char *gmsgid
, ...)
1529 auto_diagnostic_group d
;
1531 va_start (ap
, gmsgid
);
1532 rich_location
richloc (line_table
, loc
);
1533 diagnostic_impl (&richloc
, -1, gmsgid
, &ap
, DK_FATAL
);
1539 /* An internal consistency check has failed. We make no attempt to
1540 continue. Note that unless there is debugging value to be had from
1541 a more specific message, or some other good reason, you should use
1542 abort () instead of calling this function directly. */
1544 internal_error (const char *gmsgid
, ...)
1546 auto_diagnostic_group d
;
1548 va_start (ap
, gmsgid
);
1549 rich_location
richloc (line_table
, input_location
);
1550 diagnostic_impl (&richloc
, -1, gmsgid
, &ap
, DK_ICE
);
1556 /* Like internal_error, but no backtrace will be printed. Used when
1557 the internal error does not happen at the current location, but happened
1560 internal_error_no_backtrace (const char *gmsgid
, ...)
1562 auto_diagnostic_group d
;
1564 va_start (ap
, gmsgid
);
1565 rich_location
richloc (line_table
, input_location
);
1566 diagnostic_impl (&richloc
, -1, gmsgid
, &ap
, DK_ICE_NOBT
);
1572 /* Special case error functions. Most are implemented in terms of the
1573 above, or should be. */
1575 /* Print a diagnostic MSGID on FILE. This is just fprintf, except it
1576 runs its second argument through gettext. */
1578 fnotice (FILE *file
, const char *cmsgid
, ...)
1582 va_start (ap
, cmsgid
);
1583 vfprintf (file
, _(cmsgid
), ap
);
1587 /* Inform the user that an error occurred while trying to report some
1588 other error. This indicates catastrophic internal inconsistencies,
1589 so give up now. But do try to flush out the previous error.
1590 This mustn't use internal_error, that will cause infinite recursion. */
1593 error_recursion (diagnostic_context
*context
)
1595 if (context
->lock
< 3)
1596 pp_newline_and_flush (context
->printer
);
1599 "Internal compiler error: Error reporting routines re-entered.\n");
1601 /* Call diagnostic_action_after_output to get the "please submit a bug
1603 diagnostic_action_after_output (context
, DK_ICE
);
1605 /* Do not use gcc_unreachable here; that goes through internal_error
1606 and therefore would cause infinite recursion. */
1610 /* Report an internal compiler error in a friendly manner. This is
1611 the function that gets called upon use of abort() in the source
1612 code generally, thanks to a special macro. */
1615 fancy_abort (const char *file
, int line
, const char *function
)
1617 internal_error ("in %s, at %s:%d", function
, trim_filename (file
), line
);
1620 /* class auto_diagnostic_group. */
1622 /* Constructor: "push" this group into global_dc. */
1624 auto_diagnostic_group::auto_diagnostic_group ()
1626 global_dc
->diagnostic_group_nesting_depth
++;
1629 /* Destructor: "pop" this group from global_dc. */
1631 auto_diagnostic_group::~auto_diagnostic_group ()
1633 if (--global_dc
->diagnostic_group_nesting_depth
== 0)
1635 /* Handle the case where we've popped the final diagnostic group.
1636 If any diagnostics were emitted, give the context a chance
1638 if (global_dc
->diagnostic_group_emission_count
> 0)
1640 if (global_dc
->end_group_cb
)
1641 global_dc
->end_group_cb (global_dc
);
1643 global_dc
->diagnostic_group_emission_count
= 0;
1647 /* Really call the system 'abort'. This has to go right at the end of
1648 this file, so that there are no functions after it that call abort
1649 and get the system abort instead of our macro. */
1659 namespace selftest
{
1661 /* Helper function for test_print_escaped_string. */
1664 assert_print_escaped_string (const location
&loc
, const char *expected_output
,
1668 print_escaped_string (&pp
, input
);
1669 ASSERT_STREQ_AT (loc
, expected_output
, pp_formatted_text (&pp
));
1672 #define ASSERT_PRINT_ESCAPED_STRING_STREQ(EXPECTED_OUTPUT, INPUT) \
1673 assert_print_escaped_string (SELFTEST_LOCATION, EXPECTED_OUTPUT, INPUT)
1675 /* Tests of print_escaped_string. */
1678 test_print_escaped_string ()
1681 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"\"", "");
1683 /* Non-empty string. */
1684 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"hello world\"", "hello world");
1686 /* Various things that need to be escaped: */
1688 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\\\after\"",
1691 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\tafter\"",
1694 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\nafter\"",
1697 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\\"after\"",
1700 /* Non-printable characters: BEL: '\a': 0x07 */
1701 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\007after\"",
1703 /* Non-printable characters: vertical tab: '\v': 0x0b */
1704 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\013after\"",
1708 /* Tests of print_parseable_fixits. */
1710 /* Verify that print_parseable_fixits emits the empty string if there
1714 test_print_parseable_fixits_none ()
1717 rich_location
richloc (line_table
, UNKNOWN_LOCATION
);
1719 print_parseable_fixits (&pp
, &richloc
);
1720 ASSERT_STREQ ("", pp_formatted_text (&pp
));
1723 /* Verify that print_parseable_fixits does the right thing if there
1724 is an insertion fixit hint. */
1727 test_print_parseable_fixits_insert ()
1730 rich_location
richloc (line_table
, UNKNOWN_LOCATION
);
1732 linemap_add (line_table
, LC_ENTER
, false, "test.c", 0);
1733 linemap_line_start (line_table
, 5, 100);
1734 linemap_add (line_table
, LC_LEAVE
, false, NULL
, 0);
1735 location_t where
= linemap_position_for_column (line_table
, 10);
1736 richloc
.add_fixit_insert_before (where
, "added content");
1738 print_parseable_fixits (&pp
, &richloc
);
1739 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:10}:\"added content\"\n",
1740 pp_formatted_text (&pp
));
1743 /* Verify that print_parseable_fixits does the right thing if there
1744 is an removal fixit hint. */
1747 test_print_parseable_fixits_remove ()
1750 rich_location
richloc (line_table
, UNKNOWN_LOCATION
);
1752 linemap_add (line_table
, LC_ENTER
, false, "test.c", 0);
1753 linemap_line_start (line_table
, 5, 100);
1754 linemap_add (line_table
, LC_LEAVE
, false, NULL
, 0);
1756 where
.m_start
= linemap_position_for_column (line_table
, 10);
1757 where
.m_finish
= linemap_position_for_column (line_table
, 20);
1758 richloc
.add_fixit_remove (where
);
1760 print_parseable_fixits (&pp
, &richloc
);
1761 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:21}:\"\"\n",
1762 pp_formatted_text (&pp
));
1765 /* Verify that print_parseable_fixits does the right thing if there
1766 is an replacement fixit hint. */
1769 test_print_parseable_fixits_replace ()
1772 rich_location
richloc (line_table
, UNKNOWN_LOCATION
);
1774 linemap_add (line_table
, LC_ENTER
, false, "test.c", 0);
1775 linemap_line_start (line_table
, 5, 100);
1776 linemap_add (line_table
, LC_LEAVE
, false, NULL
, 0);
1778 where
.m_start
= linemap_position_for_column (line_table
, 10);
1779 where
.m_finish
= linemap_position_for_column (line_table
, 20);
1780 richloc
.add_fixit_replace (where
, "replacement");
1782 print_parseable_fixits (&pp
, &richloc
);
1783 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:21}:\"replacement\"\n",
1784 pp_formatted_text (&pp
));
1788 diagnostic_get_location_text (..., SHOW_COLUMN)
1789 generates EXPECTED_LOC_TEXT, given FILENAME, LINE, COLUMN, with
1790 colorization disabled. */
1793 assert_location_text (const char *expected_loc_text
,
1794 const char *filename
, int line
, int column
,
1797 test_diagnostic_context dc
;
1798 dc
.show_column
= show_column
;
1800 expanded_location xloc
;
1801 xloc
.file
= filename
;
1803 xloc
.column
= column
;
1807 char *actual_loc_text
= diagnostic_get_location_text (&dc
, xloc
);
1808 ASSERT_STREQ (expected_loc_text
, actual_loc_text
);
1809 free (actual_loc_text
);
1812 /* Verify that diagnostic_get_location_text works as expected. */
1815 test_diagnostic_get_location_text ()
1817 const char *old_progname
= progname
;
1818 progname
= "PROGNAME";
1819 assert_location_text ("PROGNAME:", NULL
, 0, 0, true);
1820 assert_location_text ("<built-in>:", "<built-in>", 42, 10, true);
1821 assert_location_text ("foo.c:42:10:", "foo.c", 42, 10, true);
1822 assert_location_text ("foo.c:42:", "foo.c", 42, 0, true);
1823 assert_location_text ("foo.c:", "foo.c", 0, 10, true);
1824 assert_location_text ("foo.c:42:", "foo.c", 42, 10, false);
1825 assert_location_text ("foo.c:", "foo.c", 0, 10, false);
1827 maybe_line_and_column (INT_MAX
, INT_MAX
);
1828 maybe_line_and_column (INT_MIN
, INT_MIN
);
1830 progname
= old_progname
;
1833 /* Selftest for num_digits. */
1838 ASSERT_EQ (1, num_digits (0));
1839 ASSERT_EQ (1, num_digits (9));
1840 ASSERT_EQ (2, num_digits (10));
1841 ASSERT_EQ (2, num_digits (99));
1842 ASSERT_EQ (3, num_digits (100));
1843 ASSERT_EQ (3, num_digits (999));
1844 ASSERT_EQ (4, num_digits (1000));
1845 ASSERT_EQ (4, num_digits (9999));
1846 ASSERT_EQ (5, num_digits (10000));
1847 ASSERT_EQ (5, num_digits (99999));
1848 ASSERT_EQ (6, num_digits (100000));
1849 ASSERT_EQ (6, num_digits (999999));
1850 ASSERT_EQ (7, num_digits (1000000));
1851 ASSERT_EQ (7, num_digits (9999999));
1852 ASSERT_EQ (8, num_digits (10000000));
1853 ASSERT_EQ (8, num_digits (99999999));
1856 /* Run all of the selftests within this file. */
1859 diagnostic_c_tests ()
1861 test_print_escaped_string ();
1862 test_print_parseable_fixits_none ();
1863 test_print_parseable_fixits_insert ();
1864 test_print_parseable_fixits_remove ();
1865 test_print_parseable_fixits_replace ();
1866 test_diagnostic_get_location_text ();
1871 } // namespace selftest
1873 #endif /* #if CHECKING_P */
1876 # pragma GCC diagnostic pop