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"
42 #ifdef GWINSZ_IN_SYS_IOCTL
43 # include <sys/ioctl.h>
46 /* Disable warnings about quoting issues in the pp_xxx calls below
47 that (intentionally) don't follow GCC diagnostic conventions. */
49 # pragma GCC diagnostic push
50 # pragma GCC diagnostic ignored "-Wformat-diag"
53 #define pedantic_warning_kind(DC) \
54 ((DC)->pedantic_errors ? DK_ERROR : DK_WARNING)
55 #define permissive_error_kind(DC) ((DC)->permissive ? DK_WARNING : DK_ERROR)
56 #define permissive_error_option(DC) ((DC)->opt_permissive)
59 static bool diagnostic_impl (rich_location
*, int, const char *,
60 va_list *, diagnostic_t
) ATTRIBUTE_GCC_DIAG(3,0);
61 static bool diagnostic_n_impl (rich_location
*, int, unsigned HOST_WIDE_INT
,
62 const char *, const char *, va_list *,
63 diagnostic_t
) ATTRIBUTE_GCC_DIAG(5,0);
65 static void error_recursion (diagnostic_context
*) ATTRIBUTE_NORETURN
;
66 static void real_abort (void) ATTRIBUTE_NORETURN
;
68 /* Name of program invoked, sans directories. */
72 /* A diagnostic_context surrogate for stderr. */
73 static diagnostic_context global_diagnostic_context
;
74 diagnostic_context
*global_dc
= &global_diagnostic_context
;
76 /* Return a malloc'd string containing MSG formatted a la printf. The
77 caller is responsible for freeing the memory. */
79 build_message_string (const char *msg
, ...)
85 str
= xvasprintf (msg
, ap
);
91 /* Same as diagnostic_build_prefix, but only the source FILE is given. */
93 file_name_as_prefix (diagnostic_context
*context
, const char *f
)
96 = colorize_start (pp_show_color (context
->printer
), "locus");
97 const char *locus_ce
= colorize_stop (pp_show_color (context
->printer
));
98 return build_message_string ("%s%s:%s ", locus_cs
, f
, locus_ce
);
103 /* Return the value of the getenv("COLUMNS") as an integer. If the
104 value is not set to a positive integer, use ioctl to get the
105 terminal width. If it fails, return INT_MAX. */
107 get_terminal_width (void)
109 const char * s
= getenv ("COLUMNS");
119 if (ioctl (0, TIOCGWINSZ
, &w
) == 0 && w
.ws_col
> 0)
126 /* Set caret_max_width to value. */
128 diagnostic_set_caret_max_width (diagnostic_context
*context
, int value
)
130 /* One minus to account for the leading empty space. */
131 value
= value
? value
- 1
132 : (isatty (fileno (pp_buffer (context
->printer
)->stream
))
133 ? get_terminal_width () - 1: INT_MAX
);
138 context
->caret_max_width
= value
;
141 /* Default implementation of final_cb. */
144 default_diagnostic_final_cb (diagnostic_context
*context
)
146 /* Some of the errors may actually have been warnings. */
147 if (diagnostic_kind_count (context
, DK_WERROR
))
149 /* -Werror was given. */
150 if (context
->warning_as_error_requested
)
151 pp_verbatim (context
->printer
,
152 _("%s: all warnings being treated as errors"),
154 /* At least one -Werror= was given. */
156 pp_verbatim (context
->printer
,
157 _("%s: some warnings being treated as errors"),
159 pp_newline_and_flush (context
->printer
);
163 /* Initialize the diagnostic message outputting machinery. */
165 diagnostic_initialize (diagnostic_context
*context
, int n_opts
)
169 /* Allocate a basic pretty-printer. Clients will replace this a
170 much more elaborated pretty-printer if they wish. */
171 context
->printer
= XNEW (pretty_printer
);
172 new (context
->printer
) pretty_printer ();
174 memset (context
->diagnostic_count
, 0, sizeof context
->diagnostic_count
);
175 context
->warning_as_error_requested
= false;
176 context
->n_opts
= n_opts
;
177 context
->classify_diagnostic
= XNEWVEC (diagnostic_t
, n_opts
);
178 for (i
= 0; i
< n_opts
; i
++)
179 context
->classify_diagnostic
[i
] = DK_UNSPECIFIED
;
180 context
->show_caret
= false;
181 diagnostic_set_caret_max_width (context
, pp_line_cutoff (context
->printer
));
182 for (i
= 0; i
< rich_location::STATICALLY_ALLOCATED_RANGES
; i
++)
183 context
->caret_chars
[i
] = '^';
184 context
->show_option_requested
= false;
185 context
->abort_on_error
= false;
186 context
->show_column
= false;
187 context
->pedantic_errors
= false;
188 context
->permissive
= false;
189 context
->opt_permissive
= 0;
190 context
->fatal_errors
= false;
191 context
->dc_inhibit_warnings
= false;
192 context
->dc_warn_system_headers
= false;
193 context
->max_errors
= 0;
194 context
->internal_error
= NULL
;
195 diagnostic_starter (context
) = default_diagnostic_starter
;
196 context
->start_span
= default_diagnostic_start_span_fn
;
197 diagnostic_finalizer (context
) = default_diagnostic_finalizer
;
198 context
->option_enabled
= NULL
;
199 context
->option_state
= NULL
;
200 context
->option_name
= NULL
;
201 context
->last_location
= UNKNOWN_LOCATION
;
202 context
->last_module
= 0;
203 context
->x_data
= NULL
;
205 context
->inhibit_notes_p
= false;
206 context
->colorize_source_p
= false;
207 context
->show_labels_p
= false;
208 context
->show_line_numbers_p
= false;
209 context
->min_margin_width
= 0;
210 context
->show_ruler_p
= false;
211 context
->parseable_fixits_p
= false;
212 context
->edit_context_ptr
= NULL
;
213 context
->diagnostic_group_nesting_depth
= 0;
214 context
->diagnostic_group_emission_count
= 0;
215 context
->begin_group_cb
= NULL
;
216 context
->end_group_cb
= NULL
;
217 context
->final_cb
= default_diagnostic_final_cb
;
220 /* Maybe initialize the color support. We require clients to do this
221 explicitly, since most clients don't want color. When called
222 without a VALUE, it initializes with DIAGNOSTICS_COLOR_DEFAULT. */
225 diagnostic_color_init (diagnostic_context
*context
, int value
/*= -1 */)
227 /* value == -1 is the default value. */
230 /* If DIAGNOSTICS_COLOR_DEFAULT is -1, default to
231 -fdiagnostics-color=auto if GCC_COLORS is in the environment,
232 otherwise default to -fdiagnostics-color=never, for other
233 values default to that
234 -fdiagnostics-color={never,auto,always}. */
235 if (DIAGNOSTICS_COLOR_DEFAULT
== -1)
237 if (!getenv ("GCC_COLORS"))
239 value
= DIAGNOSTICS_COLOR_AUTO
;
242 value
= DIAGNOSTICS_COLOR_DEFAULT
;
244 pp_show_color (context
->printer
)
245 = colorize_init ((diagnostic_color_rule_t
) value
);
248 /* Do any cleaning up required after the last diagnostic is emitted. */
251 diagnostic_finish (diagnostic_context
*context
)
253 if (context
->final_cb
)
254 context
->final_cb (context
);
256 diagnostic_file_cache_fini ();
258 XDELETEVEC (context
->classify_diagnostic
);
259 context
->classify_diagnostic
= NULL
;
261 /* diagnostic_initialize allocates context->printer using XNEW
262 and placement-new. */
263 context
->printer
->~pretty_printer ();
264 XDELETE (context
->printer
);
265 context
->printer
= NULL
;
267 if (context
->edit_context_ptr
)
269 delete context
->edit_context_ptr
;
270 context
->edit_context_ptr
= NULL
;
274 /* Initialize DIAGNOSTIC, where the message MSG has already been
277 diagnostic_set_info_translated (diagnostic_info
*diagnostic
, const char *msg
,
278 va_list *args
, rich_location
*richloc
,
281 gcc_assert (richloc
);
282 diagnostic
->message
.err_no
= errno
;
283 diagnostic
->message
.args_ptr
= args
;
284 diagnostic
->message
.format_spec
= msg
;
285 diagnostic
->message
.m_richloc
= richloc
;
286 diagnostic
->richloc
= richloc
;
287 diagnostic
->kind
= kind
;
288 diagnostic
->option_index
= 0;
291 /* Initialize DIAGNOSTIC, where the message GMSGID has not yet been
294 diagnostic_set_info (diagnostic_info
*diagnostic
, const char *gmsgid
,
295 va_list *args
, rich_location
*richloc
,
298 gcc_assert (richloc
);
299 diagnostic_set_info_translated (diagnostic
, _(gmsgid
), args
, richloc
, kind
);
302 static const char *const diagnostic_kind_color
[] = {
303 #define DEFINE_DIAGNOSTIC_KIND(K, T, C) (C),
304 #include "diagnostic.def"
305 #undef DEFINE_DIAGNOSTIC_KIND
309 /* Get a color name for diagnostics of type KIND
310 Result could be NULL. */
313 diagnostic_get_color_for_kind (diagnostic_t kind
)
315 return diagnostic_kind_color
[kind
];
318 /* Return a formatted line and column ':%line:%column'. Elided if
319 zero. The result is a statically allocated buffer. */
322 maybe_line_and_column (int line
, int col
)
324 static char result
[32];
328 size_t l
= snprintf (result
, sizeof (result
),
329 col
? ":%d:%d" : ":%d", line
, col
);
330 gcc_checking_assert (l
< sizeof (result
));
337 /* Return a malloc'd string describing a location e.g. "foo.c:42:10".
338 The caller is responsible for freeing the memory. */
341 diagnostic_get_location_text (diagnostic_context
*context
,
344 pretty_printer
*pp
= context
->printer
;
345 const char *locus_cs
= colorize_start (pp_show_color (pp
), "locus");
346 const char *locus_ce
= colorize_stop (pp_show_color (pp
));
347 const char *file
= s
.file
? s
.file
: progname
;
348 int line
= strcmp (file
, N_("<built-in>")) ? s
.line
: 0;
349 int col
= context
->show_column
? s
.column
: 0;
351 const char *line_col
= maybe_line_and_column (line
, col
);
352 return build_message_string ("%s%s%s:%s", locus_cs
, file
,
356 /* Return a malloc'd string describing a location and the severity of the
357 diagnostic, e.g. "foo.c:42:10: error: ". The caller is responsible for
358 freeing the memory. */
360 diagnostic_build_prefix (diagnostic_context
*context
,
361 const diagnostic_info
*diagnostic
)
363 static const char *const diagnostic_kind_text
[] = {
364 #define DEFINE_DIAGNOSTIC_KIND(K, T, C) (T),
365 #include "diagnostic.def"
366 #undef DEFINE_DIAGNOSTIC_KIND
369 gcc_assert (diagnostic
->kind
< DK_LAST_DIAGNOSTIC_KIND
);
371 const char *text
= _(diagnostic_kind_text
[diagnostic
->kind
]);
372 const char *text_cs
= "", *text_ce
= "";
373 pretty_printer
*pp
= context
->printer
;
375 if (diagnostic_kind_color
[diagnostic
->kind
])
377 text_cs
= colorize_start (pp_show_color (pp
),
378 diagnostic_kind_color
[diagnostic
->kind
]);
379 text_ce
= colorize_stop (pp_show_color (pp
));
382 expanded_location s
= diagnostic_expand_location (diagnostic
);
383 char *location_text
= diagnostic_get_location_text (context
, s
);
385 char *result
= build_message_string ("%s %s%s%s", location_text
,
386 text_cs
, text
, text_ce
);
387 free (location_text
);
391 /* Functions at which to stop the backtrace print. It's not
392 particularly helpful to print the callers of these functions. */
394 static const char * const bt_stop
[] =
402 /* A callback function passed to the backtrace_full function. */
405 bt_callback (void *data
, uintptr_t pc
, const char *filename
, int lineno
,
406 const char *function
)
408 int *pcount
= (int *) data
;
410 /* If we don't have any useful information, don't print
412 if (filename
== NULL
&& function
== NULL
)
415 /* Skip functions in diagnostic.c. */
418 && strcmp (lbasename (filename
), "diagnostic.c") == 0)
421 /* Print up to 20 functions. We could make this a --param, but
422 since this is only for debugging just use a constant for now. */
425 /* Returning a non-zero value stops the backtrace. */
431 if (function
!= NULL
)
433 char *str
= cplus_demangle_v3 (function
,
434 (DMGL_VERBOSE
| DMGL_ANSI
435 | DMGL_GNU_V3
| DMGL_PARAMS
));
442 for (size_t i
= 0; i
< ARRAY_SIZE (bt_stop
); ++i
)
444 size_t len
= strlen (bt_stop
[i
]);
445 if (strncmp (function
, bt_stop
[i
], len
) == 0
446 && (function
[len
] == '\0' || function
[len
] == '('))
450 /* Returning a non-zero value stops the backtrace. */
456 fprintf (stderr
, "0x%lx %s\n\t%s:%d\n",
458 function
== NULL
? "???" : function
,
459 filename
== NULL
? "???" : filename
,
468 /* A callback function passed to the backtrace_full function. This is
469 called if backtrace_full has an error. */
472 bt_err_callback (void *data ATTRIBUTE_UNUSED
, const char *msg
, int errnum
)
476 /* This means that no debug info was available. Just quietly
477 skip printing backtrace info. */
480 fprintf (stderr
, "%s%s%s\n", msg
, errnum
== 0 ? "" : ": ",
481 errnum
== 0 ? "" : xstrerror (errnum
));
484 /* Check if we've met the maximum error limit, and if so fatally exit
485 with a message. CONTEXT is the context to check, and FLUSH
486 indicates whether a diagnostic_finish call is needed. */
489 diagnostic_check_max_errors (diagnostic_context
*context
, bool flush
)
491 if (!context
->max_errors
)
494 int count
= (diagnostic_kind_count (context
, DK_ERROR
)
495 + diagnostic_kind_count (context
, DK_SORRY
)
496 + diagnostic_kind_count (context
, DK_WERROR
));
498 if (count
>= context
->max_errors
)
501 "compilation terminated due to -fmax-errors=%u.\n",
502 context
->max_errors
);
504 diagnostic_finish (context
);
505 exit (FATAL_EXIT_CODE
);
509 /* Take any action which is expected to happen after the diagnostic
510 is written out. This function does not always return. */
512 diagnostic_action_after_output (diagnostic_context
*context
,
513 diagnostic_t diag_kind
)
525 if (context
->abort_on_error
)
527 if (context
->fatal_errors
)
529 fnotice (stderr
, "compilation terminated due to -Wfatal-errors.\n");
530 diagnostic_finish (context
);
531 exit (FATAL_EXIT_CODE
);
538 struct backtrace_state
*state
= NULL
;
539 if (diag_kind
== DK_ICE
)
540 state
= backtrace_create_state (NULL
, 0, bt_err_callback
, NULL
);
543 backtrace_full (state
, 2, bt_callback
, bt_err_callback
,
546 if (context
->abort_on_error
)
549 fnotice (stderr
, "Please submit a full bug report,\n"
550 "with preprocessed source if appropriate.\n");
553 ("Please include the complete backtrace "
554 "with any bug report.\n"));
555 fnotice (stderr
, "See %s for instructions.\n", bug_report_url
);
557 exit (ICE_EXIT_CODE
);
561 if (context
->abort_on_error
)
563 diagnostic_finish (context
);
564 fnotice (stderr
, "compilation terminated.\n");
565 exit (FATAL_EXIT_CODE
);
572 /* True if the last module or file in which a diagnostic was reported is
573 different from the current one. */
576 last_module_changed_p (diagnostic_context
*context
,
577 const line_map_ordinary
*map
)
579 return context
->last_module
!= map
;
582 /* Remember the current module or file as being the last one in which we
583 report a diagnostic. */
586 set_last_module (diagnostic_context
*context
, const line_map_ordinary
*map
)
588 context
->last_module
= map
;
592 diagnostic_report_current_module (diagnostic_context
*context
, location_t where
)
594 const line_map_ordinary
*map
= NULL
;
596 if (pp_needs_newline (context
->printer
))
598 pp_newline (context
->printer
);
599 pp_needs_newline (context
->printer
) = false;
602 if (where
<= BUILTINS_LOCATION
)
605 linemap_resolve_location (line_table
, where
,
606 LRK_MACRO_DEFINITION_LOCATION
,
609 if (map
&& last_module_changed_p (context
, map
))
611 set_last_module (context
, map
);
612 if (! MAIN_FILE_P (map
))
617 where
= linemap_included_from (map
);
618 map
= linemap_included_from_linemap (line_table
, map
);
620 = maybe_line_and_column (SOURCE_LINE (map
, where
),
621 first
&& context
->show_column
622 ? SOURCE_COLUMN (map
, where
) : 0);
623 static const char *const msgs
[] =
625 N_("In file included from"),
628 unsigned index
= !first
;
629 pp_verbatim (context
->printer
, "%s%s %r%s%s%R",
630 first
? "" : ",\n", _(msgs
[index
]),
631 "locus", LINEMAP_FILE (map
), line_col
);
634 while (! MAIN_FILE_P (map
));
635 pp_verbatim (context
->printer
, ":");
636 pp_newline (context
->printer
);
642 default_diagnostic_starter (diagnostic_context
*context
,
643 diagnostic_info
*diagnostic
)
645 diagnostic_report_current_module (context
, diagnostic_location (diagnostic
));
646 pp_set_prefix (context
->printer
, diagnostic_build_prefix (context
,
651 default_diagnostic_start_span_fn (diagnostic_context
*context
,
652 expanded_location exploc
)
654 char *text
= diagnostic_get_location_text (context
, exploc
);
655 pp_string (context
->printer
, text
);
657 pp_newline (context
->printer
);
661 default_diagnostic_finalizer (diagnostic_context
*context
,
662 diagnostic_info
*diagnostic
,
665 diagnostic_show_locus (context
, diagnostic
->richloc
, diagnostic
->kind
);
666 pp_destroy_prefix (context
->printer
);
667 pp_flush (context
->printer
);
670 /* Interface to specify diagnostic kind overrides. Returns the
671 previous setting, or DK_UNSPECIFIED if the parameters are out of
672 range. If OPTION_INDEX is zero, the new setting is for all the
675 diagnostic_classify_diagnostic (diagnostic_context
*context
,
677 diagnostic_t new_kind
,
680 diagnostic_t old_kind
;
683 || option_index
>= context
->n_opts
684 || new_kind
>= DK_LAST_DIAGNOSTIC_KIND
)
685 return DK_UNSPECIFIED
;
687 old_kind
= context
->classify_diagnostic
[option_index
];
689 /* Handle pragmas separately, since we need to keep track of *where*
691 if (where
!= UNKNOWN_LOCATION
)
695 /* Record the command-line status, so we can reset it back on DK_POP. */
696 if (old_kind
== DK_UNSPECIFIED
)
698 old_kind
= !context
->option_enabled (option_index
,
699 context
->option_state
)
700 ? DK_IGNORED
: (context
->warning_as_error_requested
701 ? DK_ERROR
: DK_WARNING
);
702 context
->classify_diagnostic
[option_index
] = old_kind
;
705 for (i
= context
->n_classification_history
- 1; i
>= 0; i
--)
706 if (context
->classification_history
[i
].option
== option_index
)
708 old_kind
= context
->classification_history
[i
].kind
;
712 i
= context
->n_classification_history
;
713 context
->classification_history
=
714 (diagnostic_classification_change_t
*) xrealloc (context
->classification_history
, (i
+ 1)
715 * sizeof (diagnostic_classification_change_t
));
716 context
->classification_history
[i
].location
= where
;
717 context
->classification_history
[i
].option
= option_index
;
718 context
->classification_history
[i
].kind
= new_kind
;
719 context
->n_classification_history
++;
722 context
->classify_diagnostic
[option_index
] = new_kind
;
727 /* Save all diagnostic classifications in a stack. */
729 diagnostic_push_diagnostics (diagnostic_context
*context
, location_t where ATTRIBUTE_UNUSED
)
731 context
->push_list
= (int *) xrealloc (context
->push_list
, (context
->n_push
+ 1) * sizeof (int));
732 context
->push_list
[context
->n_push
++] = context
->n_classification_history
;
735 /* Restore the topmost classification set off the stack. If the stack
736 is empty, revert to the state based on command line parameters. */
738 diagnostic_pop_diagnostics (diagnostic_context
*context
, location_t where
)
744 jump_to
= context
->push_list
[-- context
->n_push
];
748 i
= context
->n_classification_history
;
749 context
->classification_history
=
750 (diagnostic_classification_change_t
*) xrealloc (context
->classification_history
, (i
+ 1)
751 * sizeof (diagnostic_classification_change_t
));
752 context
->classification_history
[i
].location
= where
;
753 context
->classification_history
[i
].option
= jump_to
;
754 context
->classification_history
[i
].kind
= DK_POP
;
755 context
->n_classification_history
++;
758 /* Helper function for print_parseable_fixits. Print TEXT to PP, obeying the
759 escaping rules for -fdiagnostics-parseable-fixits. */
762 print_escaped_string (pretty_printer
*pp
, const char *text
)
767 pp_character (pp
, '"');
768 for (const char *ch
= text
; *ch
; ch
++)
773 /* Escape backslash as two backslashes. */
774 pp_string (pp
, "\\\\");
777 /* Escape tab as "\t". */
778 pp_string (pp
, "\\t");
781 /* Escape newline as "\n". */
782 pp_string (pp
, "\\n");
785 /* Escape doublequotes as \". */
786 pp_string (pp
, "\\\"");
790 pp_character (pp
, *ch
);
792 /* Use octal for non-printable chars. */
794 unsigned char c
= (*ch
& 0xff);
795 pp_printf (pp
, "\\%o%o%o", (c
/ 64), (c
/ 8) & 007, c
& 007);
800 pp_character (pp
, '"');
803 /* Implementation of -fdiagnostics-parseable-fixits. Print a
804 machine-parseable version of all fixits in RICHLOC to PP. */
807 print_parseable_fixits (pretty_printer
*pp
, rich_location
*richloc
)
810 gcc_assert (richloc
);
812 for (unsigned i
= 0; i
< richloc
->get_num_fixit_hints (); i
++)
814 const fixit_hint
*hint
= richloc
->get_fixit_hint (i
);
815 location_t start_loc
= hint
->get_start_loc ();
816 expanded_location start_exploc
= expand_location (start_loc
);
817 pp_string (pp
, "fix-it:");
818 print_escaped_string (pp
, start_exploc
.file
);
819 /* For compatibility with clang, print as a half-open range. */
820 location_t next_loc
= hint
->get_next_loc ();
821 expanded_location next_exploc
= expand_location (next_loc
);
822 pp_printf (pp
, ":{%i:%i-%i:%i}:",
823 start_exploc
.line
, start_exploc
.column
,
824 next_exploc
.line
, next_exploc
.column
);
825 print_escaped_string (pp
, hint
->get_string ());
830 /* Update the diag_class of DIAGNOSTIC based on its location
832 #pragma GCC diagnostic
833 directives recorded within CONTEXT.
835 Return the new diag_class of DIAGNOSTIC if it was updated, or
836 DK_UNSPECIFIED otherwise. */
839 update_effective_level_from_pragmas (diagnostic_context
*context
,
840 diagnostic_info
*diagnostic
)
842 diagnostic_t diag_class
= DK_UNSPECIFIED
;
844 if (context
->n_classification_history
> 0)
846 location_t location
= diagnostic_location (diagnostic
);
848 /* FIXME: Stupid search. Optimize later. */
849 for (int i
= context
->n_classification_history
- 1; i
>= 0; i
--)
851 if (linemap_location_before_p
853 context
->classification_history
[i
].location
,
856 if (context
->classification_history
[i
].kind
== (int) DK_POP
)
858 i
= context
->classification_history
[i
].option
;
861 int option
= context
->classification_history
[i
].option
;
862 /* The option 0 is for all the diagnostics. */
863 if (option
== 0 || option
== diagnostic
->option_index
)
865 diag_class
= context
->classification_history
[i
].kind
;
866 if (diag_class
!= DK_UNSPECIFIED
)
867 diagnostic
->kind
= diag_class
;
877 /* Print any metadata about the option used to control DIAGNOSTIC to CONTEXT's
878 printer, e.g. " [-Werror=uninitialized]".
879 Subroutine of diagnostic_report_diagnostic. */
882 print_option_information (diagnostic_context
*context
,
883 const diagnostic_info
*diagnostic
,
884 diagnostic_t orig_diag_kind
)
888 option_text
= context
->option_name (context
, diagnostic
->option_index
,
889 orig_diag_kind
, diagnostic
->kind
);
893 pretty_printer
*pp
= context
->printer
;
894 pp_string (pp
, " [");
895 pp_string (pp
, colorize_start (pp_show_color (pp
),
896 diagnostic_kind_color
[diagnostic
->kind
]));
897 pp_string (pp
, option_text
);
898 pp_string (pp
, colorize_stop (pp_show_color (pp
)));
899 pp_character (pp
, ']');
904 /* Report a diagnostic message (an error or a warning) as specified by
905 DC. This function is *the* subroutine in terms of which front-ends
906 should implement their specific diagnostic handling modules. The
907 front-end independent format specifiers are exactly those described
908 in the documentation of output_format.
909 Return true if a diagnostic was printed, false otherwise. */
912 diagnostic_report_diagnostic (diagnostic_context
*context
,
913 diagnostic_info
*diagnostic
)
915 location_t location
= diagnostic_location (diagnostic
);
916 diagnostic_t orig_diag_kind
= diagnostic
->kind
;
918 /* Give preference to being able to inhibit warnings, before they
919 get reclassified to something else. */
920 if ((diagnostic
->kind
== DK_WARNING
|| diagnostic
->kind
== DK_PEDWARN
)
921 && !diagnostic_report_warnings_p (context
, location
))
924 if (diagnostic
->kind
== DK_PEDWARN
)
926 diagnostic
->kind
= pedantic_warning_kind (context
);
927 /* We do this to avoid giving the message for -pedantic-errors. */
928 orig_diag_kind
= diagnostic
->kind
;
931 if (diagnostic
->kind
== DK_NOTE
&& context
->inhibit_notes_p
)
934 if (context
->lock
> 0)
936 /* If we're reporting an ICE in the middle of some other error,
937 try to flush out the previous error, then let this one
938 through. Don't do this more than once. */
939 if ((diagnostic
->kind
== DK_ICE
|| diagnostic
->kind
== DK_ICE_NOBT
)
940 && context
->lock
== 1)
941 pp_newline_and_flush (context
->printer
);
943 error_recursion (context
);
946 /* If the user requested that warnings be treated as errors, so be
947 it. Note that we do this before the next block so that
948 individual warnings can be overridden back to warnings with
950 if (context
->warning_as_error_requested
951 && diagnostic
->kind
== DK_WARNING
)
952 diagnostic
->kind
= DK_ERROR
;
954 if (diagnostic
->option_index
955 && diagnostic
->option_index
!= permissive_error_option (context
))
957 /* This tests if the user provided the appropriate -Wfoo or
959 if (! context
->option_enabled (diagnostic
->option_index
,
960 context
->option_state
))
963 /* This tests for #pragma diagnostic changes. */
964 diagnostic_t diag_class
965 = update_effective_level_from_pragmas (context
, diagnostic
);
967 /* This tests if the user provided the appropriate -Werror=foo
969 if (diag_class
== DK_UNSPECIFIED
970 && (context
->classify_diagnostic
[diagnostic
->option_index
]
973 = context
->classify_diagnostic
[diagnostic
->option_index
];
975 /* This allows for future extensions, like temporarily disabling
976 warnings for ranges of source code. */
977 if (diagnostic
->kind
== DK_IGNORED
)
981 if (diagnostic
->kind
!= DK_NOTE
)
982 diagnostic_check_max_errors (context
);
986 if (diagnostic
->kind
== DK_ICE
|| diagnostic
->kind
== DK_ICE_NOBT
)
988 /* When not checking, ICEs are converted to fatal errors when an
989 error has already occurred. This is counteracted by
992 && (diagnostic_kind_count (context
, DK_ERROR
) > 0
993 || diagnostic_kind_count (context
, DK_SORRY
) > 0)
994 && !context
->abort_on_error
)
997 = expand_location (diagnostic_location (diagnostic
));
998 fnotice (stderr
, "%s:%d: confused by earlier errors, bailing out\n",
1000 exit (ICE_EXIT_CODE
);
1002 if (context
->internal_error
)
1003 (*context
->internal_error
) (context
,
1004 diagnostic
->message
.format_spec
,
1005 diagnostic
->message
.args_ptr
);
1007 if (diagnostic
->kind
== DK_ERROR
&& orig_diag_kind
== DK_WARNING
)
1008 ++diagnostic_kind_count (context
, DK_WERROR
);
1010 ++diagnostic_kind_count (context
, diagnostic
->kind
);
1012 /* Is this the initial diagnostic within the stack of groups? */
1013 if (context
->diagnostic_group_emission_count
== 0)
1015 if (context
->begin_group_cb
)
1016 context
->begin_group_cb (context
);
1018 context
->diagnostic_group_emission_count
++;
1020 diagnostic
->message
.x_data
= &diagnostic
->x_data
;
1021 diagnostic
->x_data
= NULL
;
1022 pp_format (context
->printer
, &diagnostic
->message
);
1023 (*diagnostic_starter (context
)) (context
, diagnostic
);
1024 pp_output_formatted_text (context
->printer
);
1025 if (context
->show_option_requested
)
1026 print_option_information (context
, diagnostic
, orig_diag_kind
);
1027 (*diagnostic_finalizer (context
)) (context
, diagnostic
, orig_diag_kind
);
1028 if (context
->parseable_fixits_p
)
1030 print_parseable_fixits (context
->printer
, diagnostic
->richloc
);
1031 pp_flush (context
->printer
);
1033 diagnostic_action_after_output (context
, diagnostic
->kind
);
1034 diagnostic
->x_data
= NULL
;
1036 if (context
->edit_context_ptr
)
1037 if (diagnostic
->richloc
->fixits_can_be_auto_applied_p ())
1038 context
->edit_context_ptr
->add_fixits (diagnostic
->richloc
);
1045 /* Get the number of digits in the decimal representation of VALUE. */
1048 num_digits (int value
)
1050 /* Perhaps simpler to use log10 for this, but doing it this way avoids
1051 using floating point. */
1052 gcc_assert (value
>= 0);
1066 /* Given a partial pathname as input, return another pathname that
1067 shares no directory elements with the pathname of __FILE__. This
1068 is used by fancy_abort() to print `Internal compiler error in expr.c'
1069 instead of `Internal compiler error in ../../GCC/gcc/expr.c'. */
1072 trim_filename (const char *name
)
1074 static const char this_file
[] = __FILE__
;
1075 const char *p
= name
, *q
= this_file
;
1077 /* First skip any "../" in each filename. This allows us to give a proper
1078 reference to a file in a subdirectory. */
1079 while (p
[0] == '.' && p
[1] == '.' && IS_DIR_SEPARATOR (p
[2]))
1082 while (q
[0] == '.' && q
[1] == '.' && IS_DIR_SEPARATOR (q
[2]))
1085 /* Now skip any parts the two filenames have in common. */
1086 while (*p
== *q
&& *p
!= 0 && *q
!= 0)
1089 /* Now go backwards until the previous directory separator. */
1090 while (p
> name
&& !IS_DIR_SEPARATOR (p
[-1]))
1096 /* Standard error reporting routines in increasing order of severity.
1097 All of these take arguments like printf. */
1099 /* Text to be emitted verbatim to the error message stream; this
1100 produces no prefix and disables line-wrapping. Use rarely. */
1102 verbatim (const char *gmsgid
, ...)
1107 va_start (ap
, gmsgid
);
1108 text
.err_no
= errno
;
1109 text
.args_ptr
= &ap
;
1110 text
.format_spec
= _(gmsgid
);
1112 pp_format_verbatim (global_dc
->printer
, &text
);
1113 pp_newline_and_flush (global_dc
->printer
);
1117 /* Add a note with text GMSGID and with LOCATION to the diagnostic CONTEXT. */
1119 diagnostic_append_note (diagnostic_context
*context
,
1120 location_t location
,
1121 const char * gmsgid
, ...)
1123 diagnostic_info diagnostic
;
1125 rich_location
richloc (line_table
, location
);
1127 va_start (ap
, gmsgid
);
1128 diagnostic_set_info (&diagnostic
, gmsgid
, &ap
, &richloc
, DK_NOTE
);
1129 if (context
->inhibit_notes_p
)
1134 char *saved_prefix
= pp_take_prefix (context
->printer
);
1135 pp_set_prefix (context
->printer
,
1136 diagnostic_build_prefix (context
, &diagnostic
));
1137 pp_format (context
->printer
, &diagnostic
.message
);
1138 pp_output_formatted_text (context
->printer
);
1139 pp_destroy_prefix (context
->printer
);
1140 pp_set_prefix (context
->printer
, saved_prefix
);
1141 diagnostic_show_locus (context
, &richloc
, DK_NOTE
);
1145 /* Implement emit_diagnostic, inform, warning, warning_at, pedwarn,
1146 permerror, error, error_at, error_at, sorry, fatal_error, internal_error,
1147 and internal_error_no_backtrace, as documented and defined below. */
1149 diagnostic_impl (rich_location
*richloc
, int opt
,
1151 va_list *ap
, diagnostic_t kind
)
1153 diagnostic_info diagnostic
;
1154 if (kind
== DK_PERMERROR
)
1156 diagnostic_set_info (&diagnostic
, gmsgid
, ap
, richloc
,
1157 permissive_error_kind (global_dc
));
1158 diagnostic
.option_index
= permissive_error_option (global_dc
);
1162 diagnostic_set_info (&diagnostic
, gmsgid
, ap
, richloc
, kind
);
1163 if (kind
== DK_WARNING
|| kind
== DK_PEDWARN
)
1164 diagnostic
.option_index
= opt
;
1166 return diagnostic_report_diagnostic (global_dc
, &diagnostic
);
1169 /* Implement inform_n, warning_n, and error_n, as documented and
1172 diagnostic_n_impl (rich_location
*richloc
, int opt
, unsigned HOST_WIDE_INT n
,
1173 const char *singular_gmsgid
,
1174 const char *plural_gmsgid
,
1175 va_list *ap
, diagnostic_t kind
)
1177 diagnostic_info diagnostic
;
1180 if (sizeof n
<= sizeof gtn
)
1183 /* Use the largest number ngettext can handle, otherwise
1184 preserve the six least significant decimal digits for
1185 languages where the plural form depends on them. */
1186 gtn
= n
<= ULONG_MAX
? n
: n
% 1000000LU + 1000000LU;
1188 const char *text
= ngettext (singular_gmsgid
, plural_gmsgid
, gtn
);
1189 diagnostic_set_info_translated (&diagnostic
, text
, ap
, richloc
, kind
);
1190 if (kind
== DK_WARNING
)
1191 diagnostic
.option_index
= opt
;
1192 return diagnostic_report_diagnostic (global_dc
, &diagnostic
);
1195 /* Wrapper around diagnostic_impl taking a variable argument list. */
1198 emit_diagnostic (diagnostic_t kind
, location_t location
, int opt
,
1199 const char *gmsgid
, ...)
1201 auto_diagnostic_group d
;
1203 va_start (ap
, gmsgid
);
1204 rich_location
richloc (line_table
, location
);
1205 bool ret
= diagnostic_impl (&richloc
, opt
, gmsgid
, &ap
, kind
);
1210 /* As above, but for rich_location *. */
1213 emit_diagnostic (diagnostic_t kind
, rich_location
*richloc
, int opt
,
1214 const char *gmsgid
, ...)
1216 auto_diagnostic_group d
;
1218 va_start (ap
, gmsgid
);
1219 bool ret
= diagnostic_impl (richloc
, opt
, gmsgid
, &ap
, kind
);
1224 /* Wrapper around diagnostic_impl taking a va_list parameter. */
1227 emit_diagnostic_valist (diagnostic_t kind
, location_t location
, int opt
,
1228 const char *gmsgid
, va_list *ap
)
1230 rich_location
richloc (line_table
, location
);
1231 return diagnostic_impl (&richloc
, opt
, gmsgid
, ap
, kind
);
1234 /* An informative note at LOCATION. Use this for additional details on an error
1237 inform (location_t location
, const char *gmsgid
, ...)
1239 auto_diagnostic_group d
;
1241 va_start (ap
, gmsgid
);
1242 rich_location
richloc (line_table
, location
);
1243 diagnostic_impl (&richloc
, -1, gmsgid
, &ap
, DK_NOTE
);
1247 /* Same as "inform" above, but at RICHLOC. */
1249 inform (rich_location
*richloc
, const char *gmsgid
, ...)
1251 gcc_assert (richloc
);
1253 auto_diagnostic_group d
;
1255 va_start (ap
, gmsgid
);
1256 diagnostic_impl (richloc
, -1, gmsgid
, &ap
, DK_NOTE
);
1260 /* An informative note at LOCATION. Use this for additional details on an
1263 inform_n (location_t location
, unsigned HOST_WIDE_INT n
,
1264 const char *singular_gmsgid
, const char *plural_gmsgid
, ...)
1267 va_start (ap
, plural_gmsgid
);
1268 auto_diagnostic_group d
;
1269 rich_location
richloc (line_table
, location
);
1270 diagnostic_n_impl (&richloc
, -1, n
, singular_gmsgid
, plural_gmsgid
,
1275 /* A warning at INPUT_LOCATION. Use this for code which is correct according
1276 to the relevant language specification but is likely to be buggy anyway.
1277 Returns true if the warning was printed, false if it was inhibited. */
1279 warning (int opt
, const char *gmsgid
, ...)
1281 auto_diagnostic_group d
;
1283 va_start (ap
, gmsgid
);
1284 rich_location
richloc (line_table
, input_location
);
1285 bool ret
= diagnostic_impl (&richloc
, opt
, gmsgid
, &ap
, DK_WARNING
);
1290 /* A warning at LOCATION. Use this for code which is correct according to the
1291 relevant language specification but is likely to be buggy anyway.
1292 Returns true if the warning was printed, false if it was inhibited. */
1295 warning_at (location_t location
, int opt
, const char *gmsgid
, ...)
1297 auto_diagnostic_group d
;
1299 va_start (ap
, gmsgid
);
1300 rich_location
richloc (line_table
, location
);
1301 bool ret
= diagnostic_impl (&richloc
, opt
, gmsgid
, &ap
, DK_WARNING
);
1306 /* Same as "warning at" above, but using RICHLOC. */
1309 warning_at (rich_location
*richloc
, int opt
, const char *gmsgid
, ...)
1311 gcc_assert (richloc
);
1313 auto_diagnostic_group d
;
1315 va_start (ap
, gmsgid
);
1316 bool ret
= diagnostic_impl (richloc
, opt
, gmsgid
, &ap
, DK_WARNING
);
1321 /* Same as warning_n plural variant below, but using RICHLOC. */
1324 warning_n (rich_location
*richloc
, int opt
, unsigned HOST_WIDE_INT n
,
1325 const char *singular_gmsgid
, const char *plural_gmsgid
, ...)
1327 gcc_assert (richloc
);
1329 auto_diagnostic_group d
;
1331 va_start (ap
, plural_gmsgid
);
1332 bool ret
= diagnostic_n_impl (richloc
, opt
, n
,
1333 singular_gmsgid
, plural_gmsgid
,
1339 /* A warning at LOCATION. Use this for code which is correct according to the
1340 relevant language specification but is likely to be buggy anyway.
1341 Returns true if the warning was printed, false if it was inhibited. */
1344 warning_n (location_t location
, int opt
, unsigned HOST_WIDE_INT n
,
1345 const char *singular_gmsgid
, const char *plural_gmsgid
, ...)
1347 auto_diagnostic_group d
;
1349 va_start (ap
, plural_gmsgid
);
1350 rich_location
richloc (line_table
, location
);
1351 bool ret
= diagnostic_n_impl (&richloc
, opt
, n
,
1352 singular_gmsgid
, plural_gmsgid
,
1358 /* A "pedantic" warning at LOCATION: issues a warning unless
1359 -pedantic-errors was given on the command line, in which case it
1360 issues an error. Use this for diagnostics required by the relevant
1361 language standard, if you have chosen not to make them errors.
1363 Note that these diagnostics are issued independent of the setting
1364 of the -Wpedantic command-line switch. To get a warning enabled
1365 only with that switch, use either "if (pedantic) pedwarn
1366 (OPT_Wpedantic,...)" or just "pedwarn (OPT_Wpedantic,..)". To get a
1367 pedwarn independently of the -Wpedantic switch use "pedwarn (0,...)".
1369 Returns true if the warning was printed, false if it was inhibited. */
1372 pedwarn (location_t location
, int opt
, const char *gmsgid
, ...)
1374 auto_diagnostic_group d
;
1376 va_start (ap
, gmsgid
);
1377 rich_location
richloc (line_table
, location
);
1378 bool ret
= diagnostic_impl (&richloc
, opt
, gmsgid
, &ap
, DK_PEDWARN
);
1383 /* Same as pedwarn above, but using RICHLOC. */
1386 pedwarn (rich_location
*richloc
, int opt
, const char *gmsgid
, ...)
1388 gcc_assert (richloc
);
1390 auto_diagnostic_group d
;
1392 va_start (ap
, gmsgid
);
1393 bool ret
= diagnostic_impl (richloc
, opt
, gmsgid
, &ap
, DK_PEDWARN
);
1398 /* A "permissive" error at LOCATION: issues an error unless
1399 -fpermissive was given on the command line, in which case it issues
1400 a warning. Use this for things that really should be errors but we
1401 want to support legacy code.
1403 Returns true if the warning was printed, false if it was inhibited. */
1406 permerror (location_t location
, const char *gmsgid
, ...)
1408 auto_diagnostic_group d
;
1410 va_start (ap
, gmsgid
);
1411 rich_location
richloc (line_table
, location
);
1412 bool ret
= diagnostic_impl (&richloc
, -1, gmsgid
, &ap
, DK_PERMERROR
);
1417 /* Same as "permerror" above, but at RICHLOC. */
1420 permerror (rich_location
*richloc
, const char *gmsgid
, ...)
1422 gcc_assert (richloc
);
1424 auto_diagnostic_group d
;
1426 va_start (ap
, gmsgid
);
1427 bool ret
= diagnostic_impl (richloc
, -1, gmsgid
, &ap
, DK_PERMERROR
);
1432 /* A hard error: the code is definitely ill-formed, and an object file
1433 will not be produced. */
1435 error (const char *gmsgid
, ...)
1437 auto_diagnostic_group d
;
1439 va_start (ap
, gmsgid
);
1440 rich_location
richloc (line_table
, input_location
);
1441 diagnostic_impl (&richloc
, -1, gmsgid
, &ap
, DK_ERROR
);
1445 /* A hard error: the code is definitely ill-formed, and an object file
1446 will not be produced. */
1448 error_n (location_t location
, unsigned HOST_WIDE_INT n
,
1449 const char *singular_gmsgid
, const char *plural_gmsgid
, ...)
1451 auto_diagnostic_group d
;
1453 va_start (ap
, plural_gmsgid
);
1454 rich_location
richloc (line_table
, location
);
1455 diagnostic_n_impl (&richloc
, -1, n
, singular_gmsgid
, plural_gmsgid
,
1460 /* Same as above, but use location LOC instead of input_location. */
1462 error_at (location_t loc
, const char *gmsgid
, ...)
1464 auto_diagnostic_group d
;
1466 va_start (ap
, gmsgid
);
1467 rich_location
richloc (line_table
, loc
);
1468 diagnostic_impl (&richloc
, -1, gmsgid
, &ap
, DK_ERROR
);
1472 /* Same as above, but use RICH_LOC. */
1475 error_at (rich_location
*richloc
, const char *gmsgid
, ...)
1477 gcc_assert (richloc
);
1479 auto_diagnostic_group d
;
1481 va_start (ap
, gmsgid
);
1482 diagnostic_impl (richloc
, -1, gmsgid
, &ap
, DK_ERROR
);
1486 /* "Sorry, not implemented." Use for a language feature which is
1487 required by the relevant specification but not implemented by GCC.
1488 An object file will not be produced. */
1490 sorry (const char *gmsgid
, ...)
1492 auto_diagnostic_group d
;
1494 va_start (ap
, gmsgid
);
1495 rich_location
richloc (line_table
, input_location
);
1496 diagnostic_impl (&richloc
, -1, gmsgid
, &ap
, DK_SORRY
);
1500 /* Same as above, but use location LOC instead of input_location. */
1502 sorry_at (location_t loc
, const char *gmsgid
, ...)
1504 auto_diagnostic_group d
;
1506 va_start (ap
, gmsgid
);
1507 rich_location
richloc (line_table
, loc
);
1508 diagnostic_impl (&richloc
, -1, gmsgid
, &ap
, DK_SORRY
);
1512 /* Return true if an error or a "sorry" has been seen. Various
1513 processing is disabled after errors. */
1517 return errorcount
|| sorrycount
;
1520 /* An error which is severe enough that we make no attempt to
1521 continue. Do not use this for internal consistency checks; that's
1522 internal_error. Use of this function should be rare. */
1524 fatal_error (location_t loc
, const char *gmsgid
, ...)
1526 auto_diagnostic_group d
;
1528 va_start (ap
, gmsgid
);
1529 rich_location
richloc (line_table
, loc
);
1530 diagnostic_impl (&richloc
, -1, gmsgid
, &ap
, DK_FATAL
);
1536 /* An internal consistency check has failed. We make no attempt to
1537 continue. Note that unless there is debugging value to be had from
1538 a more specific message, or some other good reason, you should use
1539 abort () instead of calling this function directly. */
1541 internal_error (const char *gmsgid
, ...)
1543 auto_diagnostic_group d
;
1545 va_start (ap
, gmsgid
);
1546 rich_location
richloc (line_table
, input_location
);
1547 diagnostic_impl (&richloc
, -1, gmsgid
, &ap
, DK_ICE
);
1553 /* Like internal_error, but no backtrace will be printed. Used when
1554 the internal error does not happen at the current location, but happened
1557 internal_error_no_backtrace (const char *gmsgid
, ...)
1559 auto_diagnostic_group d
;
1561 va_start (ap
, gmsgid
);
1562 rich_location
richloc (line_table
, input_location
);
1563 diagnostic_impl (&richloc
, -1, gmsgid
, &ap
, DK_ICE_NOBT
);
1569 /* Special case error functions. Most are implemented in terms of the
1570 above, or should be. */
1572 /* Print a diagnostic MSGID on FILE. This is just fprintf, except it
1573 runs its second argument through gettext. */
1575 fnotice (FILE *file
, const char *cmsgid
, ...)
1579 va_start (ap
, cmsgid
);
1580 vfprintf (file
, _(cmsgid
), ap
);
1584 /* Inform the user that an error occurred while trying to report some
1585 other error. This indicates catastrophic internal inconsistencies,
1586 so give up now. But do try to flush out the previous error.
1587 This mustn't use internal_error, that will cause infinite recursion. */
1590 error_recursion (diagnostic_context
*context
)
1592 if (context
->lock
< 3)
1593 pp_newline_and_flush (context
->printer
);
1596 "Internal compiler error: Error reporting routines re-entered.\n");
1598 /* Call diagnostic_action_after_output to get the "please submit a bug
1600 diagnostic_action_after_output (context
, DK_ICE
);
1602 /* Do not use gcc_unreachable here; that goes through internal_error
1603 and therefore would cause infinite recursion. */
1607 /* Report an internal compiler error in a friendly manner. This is
1608 the function that gets called upon use of abort() in the source
1609 code generally, thanks to a special macro. */
1612 fancy_abort (const char *file
, int line
, const char *function
)
1614 internal_error ("in %s, at %s:%d", function
, trim_filename (file
), line
);
1617 /* class auto_diagnostic_group. */
1619 /* Constructor: "push" this group into global_dc. */
1621 auto_diagnostic_group::auto_diagnostic_group ()
1623 global_dc
->diagnostic_group_nesting_depth
++;
1626 /* Destructor: "pop" this group from global_dc. */
1628 auto_diagnostic_group::~auto_diagnostic_group ()
1630 if (--global_dc
->diagnostic_group_nesting_depth
== 0)
1632 /* Handle the case where we've popped the final diagnostic group.
1633 If any diagnostics were emitted, give the context a chance
1635 if (global_dc
->diagnostic_group_emission_count
> 0)
1637 if (global_dc
->end_group_cb
)
1638 global_dc
->end_group_cb (global_dc
);
1640 global_dc
->diagnostic_group_emission_count
= 0;
1644 /* Really call the system 'abort'. This has to go right at the end of
1645 this file, so that there are no functions after it that call abort
1646 and get the system abort instead of our macro. */
1656 namespace selftest
{
1658 /* Helper function for test_print_escaped_string. */
1661 assert_print_escaped_string (const location
&loc
, const char *expected_output
,
1665 print_escaped_string (&pp
, input
);
1666 ASSERT_STREQ_AT (loc
, expected_output
, pp_formatted_text (&pp
));
1669 #define ASSERT_PRINT_ESCAPED_STRING_STREQ(EXPECTED_OUTPUT, INPUT) \
1670 assert_print_escaped_string (SELFTEST_LOCATION, EXPECTED_OUTPUT, INPUT)
1672 /* Tests of print_escaped_string. */
1675 test_print_escaped_string ()
1678 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"\"", "");
1680 /* Non-empty string. */
1681 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"hello world\"", "hello world");
1683 /* Various things that need to be escaped: */
1685 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\\\after\"",
1688 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\tafter\"",
1691 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\nafter\"",
1694 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\\"after\"",
1697 /* Non-printable characters: BEL: '\a': 0x07 */
1698 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\007after\"",
1700 /* Non-printable characters: vertical tab: '\v': 0x0b */
1701 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\013after\"",
1705 /* Tests of print_parseable_fixits. */
1707 /* Verify that print_parseable_fixits emits the empty string if there
1711 test_print_parseable_fixits_none ()
1714 rich_location
richloc (line_table
, UNKNOWN_LOCATION
);
1716 print_parseable_fixits (&pp
, &richloc
);
1717 ASSERT_STREQ ("", pp_formatted_text (&pp
));
1720 /* Verify that print_parseable_fixits does the right thing if there
1721 is an insertion fixit hint. */
1724 test_print_parseable_fixits_insert ()
1727 rich_location
richloc (line_table
, UNKNOWN_LOCATION
);
1729 linemap_add (line_table
, LC_ENTER
, false, "test.c", 0);
1730 linemap_line_start (line_table
, 5, 100);
1731 linemap_add (line_table
, LC_LEAVE
, false, NULL
, 0);
1732 location_t where
= linemap_position_for_column (line_table
, 10);
1733 richloc
.add_fixit_insert_before (where
, "added content");
1735 print_parseable_fixits (&pp
, &richloc
);
1736 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:10}:\"added content\"\n",
1737 pp_formatted_text (&pp
));
1740 /* Verify that print_parseable_fixits does the right thing if there
1741 is an removal fixit hint. */
1744 test_print_parseable_fixits_remove ()
1747 rich_location
richloc (line_table
, UNKNOWN_LOCATION
);
1749 linemap_add (line_table
, LC_ENTER
, false, "test.c", 0);
1750 linemap_line_start (line_table
, 5, 100);
1751 linemap_add (line_table
, LC_LEAVE
, false, NULL
, 0);
1753 where
.m_start
= linemap_position_for_column (line_table
, 10);
1754 where
.m_finish
= linemap_position_for_column (line_table
, 20);
1755 richloc
.add_fixit_remove (where
);
1757 print_parseable_fixits (&pp
, &richloc
);
1758 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:21}:\"\"\n",
1759 pp_formatted_text (&pp
));
1762 /* Verify that print_parseable_fixits does the right thing if there
1763 is an replacement fixit hint. */
1766 test_print_parseable_fixits_replace ()
1769 rich_location
richloc (line_table
, UNKNOWN_LOCATION
);
1771 linemap_add (line_table
, LC_ENTER
, false, "test.c", 0);
1772 linemap_line_start (line_table
, 5, 100);
1773 linemap_add (line_table
, LC_LEAVE
, false, NULL
, 0);
1775 where
.m_start
= linemap_position_for_column (line_table
, 10);
1776 where
.m_finish
= linemap_position_for_column (line_table
, 20);
1777 richloc
.add_fixit_replace (where
, "replacement");
1779 print_parseable_fixits (&pp
, &richloc
);
1780 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:21}:\"replacement\"\n",
1781 pp_formatted_text (&pp
));
1785 diagnostic_get_location_text (..., SHOW_COLUMN)
1786 generates EXPECTED_LOC_TEXT, given FILENAME, LINE, COLUMN, with
1787 colorization disabled. */
1790 assert_location_text (const char *expected_loc_text
,
1791 const char *filename
, int line
, int column
,
1794 test_diagnostic_context dc
;
1795 dc
.show_column
= show_column
;
1797 expanded_location xloc
;
1798 xloc
.file
= filename
;
1800 xloc
.column
= column
;
1804 char *actual_loc_text
= diagnostic_get_location_text (&dc
, xloc
);
1805 ASSERT_STREQ (expected_loc_text
, actual_loc_text
);
1806 free (actual_loc_text
);
1809 /* Verify that diagnostic_get_location_text works as expected. */
1812 test_diagnostic_get_location_text ()
1814 const char *old_progname
= progname
;
1815 progname
= "PROGNAME";
1816 assert_location_text ("PROGNAME:", NULL
, 0, 0, true);
1817 assert_location_text ("<built-in>:", "<built-in>", 42, 10, true);
1818 assert_location_text ("foo.c:42:10:", "foo.c", 42, 10, true);
1819 assert_location_text ("foo.c:42:", "foo.c", 42, 0, true);
1820 assert_location_text ("foo.c:", "foo.c", 0, 10, true);
1821 assert_location_text ("foo.c:42:", "foo.c", 42, 10, false);
1822 assert_location_text ("foo.c:", "foo.c", 0, 10, false);
1824 maybe_line_and_column (INT_MAX
, INT_MAX
);
1825 maybe_line_and_column (INT_MIN
, INT_MIN
);
1827 progname
= old_progname
;
1830 /* Selftest for num_digits. */
1835 ASSERT_EQ (1, num_digits (0));
1836 ASSERT_EQ (1, num_digits (9));
1837 ASSERT_EQ (2, num_digits (10));
1838 ASSERT_EQ (2, num_digits (99));
1839 ASSERT_EQ (3, num_digits (100));
1840 ASSERT_EQ (3, num_digits (999));
1841 ASSERT_EQ (4, num_digits (1000));
1842 ASSERT_EQ (4, num_digits (9999));
1843 ASSERT_EQ (5, num_digits (10000));
1844 ASSERT_EQ (5, num_digits (99999));
1845 ASSERT_EQ (6, num_digits (100000));
1846 ASSERT_EQ (6, num_digits (999999));
1847 ASSERT_EQ (7, num_digits (1000000));
1848 ASSERT_EQ (7, num_digits (9999999));
1849 ASSERT_EQ (8, num_digits (10000000));
1850 ASSERT_EQ (8, num_digits (99999999));
1853 /* Run all of the selftests within this file. */
1856 diagnostic_c_tests ()
1858 test_print_escaped_string ();
1859 test_print_parseable_fixits_none ();
1860 test_print_parseable_fixits_insert ();
1861 test_print_parseable_fixits_remove ();
1862 test_print_parseable_fixits_replace ();
1863 test_diagnostic_get_location_text ();
1868 } // namespace selftest
1870 #endif /* #if CHECKING_P */
1873 # pragma GCC diagnostic pop