1 /* Language-independent diagnostic subroutines for the GNU Compiler Collection
2 Copyright (C) 1999-2021 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 "diagnostic-url.h"
35 #include "diagnostic-metadata.h"
36 #include "diagnostic-path.h"
37 #include "edit-context.h"
39 #include "selftest-diagnostic.h"
47 #ifdef GWINSZ_IN_SYS_IOCTL
48 # include <sys/ioctl.h>
51 /* Disable warnings about quoting issues in the pp_xxx calls below
52 that (intentionally) don't follow GCC diagnostic conventions. */
54 # pragma GCC diagnostic push
55 # pragma GCC diagnostic ignored "-Wformat-diag"
58 #define pedantic_warning_kind(DC) \
59 ((DC)->pedantic_errors ? DK_ERROR : DK_WARNING)
60 #define permissive_error_kind(DC) ((DC)->permissive ? DK_WARNING : DK_ERROR)
61 #define permissive_error_option(DC) ((DC)->opt_permissive)
64 static bool diagnostic_impl (rich_location
*, const diagnostic_metadata
*,
66 va_list *, diagnostic_t
) ATTRIBUTE_GCC_DIAG(4,0);
67 static bool diagnostic_n_impl (rich_location
*, const diagnostic_metadata
*,
68 int, unsigned HOST_WIDE_INT
,
69 const char *, const char *, va_list *,
70 diagnostic_t
) ATTRIBUTE_GCC_DIAG(6,0);
72 static void error_recursion (diagnostic_context
*) ATTRIBUTE_NORETURN
;
73 static void real_abort (void) ATTRIBUTE_NORETURN
;
75 /* Name of program invoked, sans directories. */
79 /* A diagnostic_context surrogate for stderr. */
80 static diagnostic_context global_diagnostic_context
;
81 diagnostic_context
*global_dc
= &global_diagnostic_context
;
83 /* Return a malloc'd string containing MSG formatted a la printf. The
84 caller is responsible for freeing the memory. */
86 build_message_string (const char *msg
, ...)
92 str
= xvasprintf (msg
, ap
);
98 /* Same as diagnostic_build_prefix, but only the source FILE is given. */
100 file_name_as_prefix (diagnostic_context
*context
, const char *f
)
103 = colorize_start (pp_show_color (context
->printer
), "locus");
104 const char *locus_ce
= colorize_stop (pp_show_color (context
->printer
));
105 return build_message_string ("%s%s:%s ", locus_cs
, f
, locus_ce
);
110 /* Return the value of the getenv("COLUMNS") as an integer. If the
111 value is not set to a positive integer, use ioctl to get the
112 terminal width. If it fails, return INT_MAX. */
114 get_terminal_width (void)
116 const char * s
= getenv ("COLUMNS");
126 if (ioctl (0, TIOCGWINSZ
, &w
) == 0 && w
.ws_col
> 0)
133 /* Set caret_max_width to value. */
135 diagnostic_set_caret_max_width (diagnostic_context
*context
, int value
)
137 /* One minus to account for the leading empty space. */
138 value
= value
? value
- 1
139 : (isatty (fileno (pp_buffer (context
->printer
)->stream
))
140 ? get_terminal_width () - 1: INT_MAX
);
145 context
->caret_max_width
= value
;
148 /* Default implementation of final_cb. */
151 default_diagnostic_final_cb (diagnostic_context
*context
)
153 /* Some of the errors may actually have been warnings. */
154 if (diagnostic_kind_count (context
, DK_WERROR
))
156 /* -Werror was given. */
157 if (context
->warning_as_error_requested
)
158 pp_verbatim (context
->printer
,
159 _("%s: all warnings being treated as errors"),
161 /* At least one -Werror= was given. */
163 pp_verbatim (context
->printer
,
164 _("%s: some warnings being treated as errors"),
166 pp_newline_and_flush (context
->printer
);
170 /* Initialize the diagnostic message outputting machinery. */
172 diagnostic_initialize (diagnostic_context
*context
, int n_opts
)
176 /* Allocate a basic pretty-printer. Clients will replace this a
177 much more elaborated pretty-printer if they wish. */
178 context
->printer
= XNEW (pretty_printer
);
179 new (context
->printer
) pretty_printer ();
181 memset (context
->diagnostic_count
, 0, sizeof context
->diagnostic_count
);
182 context
->warning_as_error_requested
= false;
183 context
->n_opts
= n_opts
;
184 context
->classify_diagnostic
= XNEWVEC (diagnostic_t
, n_opts
);
185 for (i
= 0; i
< n_opts
; i
++)
186 context
->classify_diagnostic
[i
] = DK_UNSPECIFIED
;
187 context
->show_caret
= false;
188 diagnostic_set_caret_max_width (context
, pp_line_cutoff (context
->printer
));
189 for (i
= 0; i
< rich_location::STATICALLY_ALLOCATED_RANGES
; i
++)
190 context
->caret_chars
[i
] = '^';
191 context
->show_cwe
= false;
192 context
->path_format
= DPF_NONE
;
193 context
->show_path_depths
= false;
194 context
->show_option_requested
= false;
195 context
->abort_on_error
= false;
196 context
->show_column
= false;
197 context
->pedantic_errors
= false;
198 context
->permissive
= false;
199 context
->opt_permissive
= 0;
200 context
->fatal_errors
= false;
201 context
->dc_inhibit_warnings
= false;
202 context
->dc_warn_system_headers
= false;
203 context
->max_errors
= 0;
204 context
->internal_error
= NULL
;
205 diagnostic_starter (context
) = default_diagnostic_starter
;
206 context
->start_span
= default_diagnostic_start_span_fn
;
207 diagnostic_finalizer (context
) = default_diagnostic_finalizer
;
208 context
->option_enabled
= NULL
;
209 context
->option_state
= NULL
;
210 context
->option_name
= NULL
;
211 context
->get_option_url
= NULL
;
212 context
->last_location
= UNKNOWN_LOCATION
;
213 context
->last_module
= 0;
214 context
->x_data
= NULL
;
216 context
->inhibit_notes_p
= false;
217 context
->colorize_source_p
= false;
218 context
->show_labels_p
= false;
219 context
->show_line_numbers_p
= false;
220 context
->min_margin_width
= 0;
221 context
->show_ruler_p
= false;
222 if (const char *var
= getenv ("GCC_EXTRA_DIAGNOSTIC_OUTPUT"))
224 if (!strcmp (var
, "fixits-v1"))
225 context
->extra_output_kind
= EXTRA_DIAGNOSTIC_OUTPUT_fixits_v1
;
226 else if (!strcmp (var
, "fixits-v2"))
227 context
->extra_output_kind
= EXTRA_DIAGNOSTIC_OUTPUT_fixits_v2
;
228 /* Silently ignore unrecognized values. */
230 context
->column_unit
= DIAGNOSTICS_COLUMN_UNIT_DISPLAY
;
231 context
->column_origin
= 1;
232 context
->tabstop
= 8;
233 context
->escape_format
= DIAGNOSTICS_ESCAPE_FORMAT_UNICODE
;
234 context
->edit_context_ptr
= NULL
;
235 context
->diagnostic_group_nesting_depth
= 0;
236 context
->diagnostic_group_emission_count
= 0;
237 context
->begin_group_cb
= NULL
;
238 context
->end_group_cb
= NULL
;
239 context
->final_cb
= default_diagnostic_final_cb
;
242 /* Maybe initialize the color support. We require clients to do this
243 explicitly, since most clients don't want color. When called
244 without a VALUE, it initializes with DIAGNOSTICS_COLOR_DEFAULT. */
247 diagnostic_color_init (diagnostic_context
*context
, int value
/*= -1 */)
249 /* value == -1 is the default value. */
252 /* If DIAGNOSTICS_COLOR_DEFAULT is -1, default to
253 -fdiagnostics-color=auto if GCC_COLORS is in the environment,
254 otherwise default to -fdiagnostics-color=never, for other
255 values default to that
256 -fdiagnostics-color={never,auto,always}. */
257 if (DIAGNOSTICS_COLOR_DEFAULT
== -1)
259 if (!getenv ("GCC_COLORS"))
261 value
= DIAGNOSTICS_COLOR_AUTO
;
264 value
= DIAGNOSTICS_COLOR_DEFAULT
;
266 pp_show_color (context
->printer
)
267 = colorize_init ((diagnostic_color_rule_t
) value
);
270 /* Initialize URL support within CONTEXT based on VALUE, handling "auto". */
273 diagnostic_urls_init (diagnostic_context
*context
, int value
/*= -1 */)
275 /* value == -1 is the default value. */
278 /* If DIAGNOSTICS_URLS_DEFAULT is -1, default to
279 -fdiagnostics-urls=auto if GCC_URLS or TERM_URLS is in the
280 environment, otherwise default to -fdiagnostics-urls=never,
281 for other values default to that
282 -fdiagnostics-urls={never,auto,always}. */
283 if (DIAGNOSTICS_URLS_DEFAULT
== -1)
285 if (!getenv ("GCC_URLS") && !getenv ("TERM_URLS"))
287 value
= DIAGNOSTICS_URL_AUTO
;
290 value
= DIAGNOSTICS_URLS_DEFAULT
;
293 context
->printer
->url_format
294 = determine_url_format ((diagnostic_url_rule_t
) value
);
297 /* Create the file_cache, if not already created, and tell it how to
298 translate files on input. */
299 void diagnostic_initialize_input_context (diagnostic_context
*context
,
300 diagnostic_input_charset_callback ccb
,
301 bool should_skip_bom
)
303 if (!context
->m_file_cache
)
304 context
->m_file_cache
= new file_cache
;
305 context
->m_file_cache
->initialize_input_context (ccb
, should_skip_bom
);
308 /* Do any cleaning up required after the last diagnostic is emitted. */
311 diagnostic_finish (diagnostic_context
*context
)
313 if (context
->final_cb
)
314 context
->final_cb (context
);
316 diagnostic_file_cache_fini ();
318 XDELETEVEC (context
->classify_diagnostic
);
319 context
->classify_diagnostic
= NULL
;
321 /* diagnostic_initialize allocates context->printer using XNEW
322 and placement-new. */
323 context
->printer
->~pretty_printer ();
324 XDELETE (context
->printer
);
325 context
->printer
= NULL
;
327 if (context
->edit_context_ptr
)
329 delete context
->edit_context_ptr
;
330 context
->edit_context_ptr
= NULL
;
334 /* Initialize DIAGNOSTIC, where the message MSG has already been
337 diagnostic_set_info_translated (diagnostic_info
*diagnostic
, const char *msg
,
338 va_list *args
, rich_location
*richloc
,
341 gcc_assert (richloc
);
342 diagnostic
->message
.err_no
= errno
;
343 diagnostic
->message
.args_ptr
= args
;
344 diagnostic
->message
.format_spec
= msg
;
345 diagnostic
->message
.m_richloc
= richloc
;
346 diagnostic
->richloc
= richloc
;
347 diagnostic
->metadata
= NULL
;
348 diagnostic
->kind
= kind
;
349 diagnostic
->option_index
= 0;
352 /* Initialize DIAGNOSTIC, where the message GMSGID has not yet been
355 diagnostic_set_info (diagnostic_info
*diagnostic
, const char *gmsgid
,
356 va_list *args
, rich_location
*richloc
,
359 gcc_assert (richloc
);
360 diagnostic_set_info_translated (diagnostic
, _(gmsgid
), args
, richloc
, kind
);
363 static const char *const diagnostic_kind_color
[] = {
364 #define DEFINE_DIAGNOSTIC_KIND(K, T, C) (C),
365 #include "diagnostic.def"
366 #undef DEFINE_DIAGNOSTIC_KIND
370 /* Get a color name for diagnostics of type KIND
371 Result could be NULL. */
374 diagnostic_get_color_for_kind (diagnostic_t kind
)
376 return diagnostic_kind_color
[kind
];
379 /* Given an expanded_location, convert the column (which is in 1-based bytes)
380 to the requested units, without converting the origin.
381 Return -1 if the column is invalid (<= 0). */
384 convert_column_unit (enum diagnostics_column_unit column_unit
,
396 case DIAGNOSTICS_COLUMN_UNIT_DISPLAY
:
398 cpp_char_column_policy
policy (tabstop
, cpp_wcwidth
);
399 return location_compute_display_column (s
, policy
);
402 case DIAGNOSTICS_COLUMN_UNIT_BYTE
:
407 /* Given an expanded_location, convert the column (which is in 1-based bytes)
408 to the requested units and origin. Return -1 if the column is
411 diagnostic_converted_column (diagnostic_context
*context
, expanded_location s
)
414 = convert_column_unit (context
->column_unit
, context
->tabstop
, s
);
415 if (one_based_col
<= 0)
417 return one_based_col
+ (context
->column_origin
- 1);
420 /* Return a formatted line and column ':%line:%column'. Elided if
421 line == 0 or col < 0. (A column of 0 may be valid due to the
422 -fdiagnostics-column-origin option.)
423 The result is a statically allocated buffer. */
426 maybe_line_and_column (int line
, int col
)
428 static char result
[32];
433 = snprintf (result
, sizeof (result
),
434 col
>= 0 ? ":%d:%d" : ":%d", line
, col
);
435 gcc_checking_assert (l
< sizeof (result
));
442 /* Return a malloc'd string describing a location e.g. "foo.c:42:10".
443 The caller is responsible for freeing the memory. */
446 diagnostic_get_location_text (diagnostic_context
*context
,
449 pretty_printer
*pp
= context
->printer
;
450 const char *locus_cs
= colorize_start (pp_show_color (pp
), "locus");
451 const char *locus_ce
= colorize_stop (pp_show_color (pp
));
452 const char *file
= s
.file
? s
.file
: progname
;
455 if (strcmp (file
, N_("<built-in>")))
458 if (context
->show_column
)
459 col
= diagnostic_converted_column (context
, s
);
462 const char *line_col
= maybe_line_and_column (line
, col
);
463 return build_message_string ("%s%s%s:%s", locus_cs
, file
,
467 static const char *const diagnostic_kind_text
[] = {
468 #define DEFINE_DIAGNOSTIC_KIND(K, T, C) (T),
469 #include "diagnostic.def"
470 #undef DEFINE_DIAGNOSTIC_KIND
474 /* Return a malloc'd string describing a location and the severity of the
475 diagnostic, e.g. "foo.c:42:10: error: ". The caller is responsible for
476 freeing the memory. */
478 diagnostic_build_prefix (diagnostic_context
*context
,
479 const diagnostic_info
*diagnostic
)
481 gcc_assert (diagnostic
->kind
< DK_LAST_DIAGNOSTIC_KIND
);
483 const char *text
= _(diagnostic_kind_text
[diagnostic
->kind
]);
484 const char *text_cs
= "", *text_ce
= "";
485 pretty_printer
*pp
= context
->printer
;
487 if (diagnostic_kind_color
[diagnostic
->kind
])
489 text_cs
= colorize_start (pp_show_color (pp
),
490 diagnostic_kind_color
[diagnostic
->kind
]);
491 text_ce
= colorize_stop (pp_show_color (pp
));
494 expanded_location s
= diagnostic_expand_location (diagnostic
);
495 char *location_text
= diagnostic_get_location_text (context
, s
);
497 char *result
= build_message_string ("%s %s%s%s", location_text
,
498 text_cs
, text
, text_ce
);
499 free (location_text
);
503 /* Functions at which to stop the backtrace print. It's not
504 particularly helpful to print the callers of these functions. */
506 static const char * const bt_stop
[] =
514 /* A callback function passed to the backtrace_full function. */
517 bt_callback (void *data
, uintptr_t pc
, const char *filename
, int lineno
,
518 const char *function
)
520 int *pcount
= (int *) data
;
522 /* If we don't have any useful information, don't print
524 if (filename
== NULL
&& function
== NULL
)
527 /* Skip functions in diagnostic.c. */
530 && strcmp (lbasename (filename
), "diagnostic.c") == 0)
533 /* Print up to 20 functions. We could make this a --param, but
534 since this is only for debugging just use a constant for now. */
537 /* Returning a non-zero value stops the backtrace. */
543 if (function
!= NULL
)
545 char *str
= cplus_demangle_v3 (function
,
546 (DMGL_VERBOSE
| DMGL_ANSI
547 | DMGL_GNU_V3
| DMGL_PARAMS
));
554 for (size_t i
= 0; i
< ARRAY_SIZE (bt_stop
); ++i
)
556 size_t len
= strlen (bt_stop
[i
]);
557 if (strncmp (function
, bt_stop
[i
], len
) == 0
558 && (function
[len
] == '\0' || function
[len
] == '('))
562 /* Returning a non-zero value stops the backtrace. */
568 fprintf (stderr
, "0x%lx %s\n\t%s:%d\n",
570 function
== NULL
? "???" : function
,
571 filename
== NULL
? "???" : filename
,
580 /* A callback function passed to the backtrace_full function. This is
581 called if backtrace_full has an error. */
584 bt_err_callback (void *data ATTRIBUTE_UNUSED
, const char *msg
, int errnum
)
588 /* This means that no debug info was available. Just quietly
589 skip printing backtrace info. */
592 fprintf (stderr
, "%s%s%s\n", msg
, errnum
== 0 ? "" : ": ",
593 errnum
== 0 ? "" : xstrerror (errnum
));
596 /* Check if we've met the maximum error limit, and if so fatally exit
597 with a message. CONTEXT is the context to check, and FLUSH
598 indicates whether a diagnostic_finish call is needed. */
601 diagnostic_check_max_errors (diagnostic_context
*context
, bool flush
)
603 if (!context
->max_errors
)
606 int count
= (diagnostic_kind_count (context
, DK_ERROR
)
607 + diagnostic_kind_count (context
, DK_SORRY
)
608 + diagnostic_kind_count (context
, DK_WERROR
));
610 if (count
>= context
->max_errors
)
613 "compilation terminated due to -fmax-errors=%u.\n",
614 context
->max_errors
);
616 diagnostic_finish (context
);
617 exit (FATAL_EXIT_CODE
);
621 /* Take any action which is expected to happen after the diagnostic
622 is written out. This function does not always return. */
624 diagnostic_action_after_output (diagnostic_context
*context
,
625 diagnostic_t diag_kind
)
637 if (context
->abort_on_error
)
639 if (context
->fatal_errors
)
641 fnotice (stderr
, "compilation terminated due to -Wfatal-errors.\n");
642 diagnostic_finish (context
);
643 exit (FATAL_EXIT_CODE
);
650 struct backtrace_state
*state
= NULL
;
651 if (diag_kind
== DK_ICE
)
652 state
= backtrace_create_state (NULL
, 0, bt_err_callback
, NULL
);
655 backtrace_full (state
, 2, bt_callback
, bt_err_callback
,
658 if (context
->abort_on_error
)
661 fnotice (stderr
, "Please submit a full bug report,\n"
662 "with preprocessed source if appropriate.\n");
665 ("Please include the complete backtrace "
666 "with any bug report.\n"));
667 fnotice (stderr
, "See %s for instructions.\n", bug_report_url
);
669 exit (ICE_EXIT_CODE
);
673 if (context
->abort_on_error
)
675 diagnostic_finish (context
);
676 fnotice (stderr
, "compilation terminated.\n");
677 exit (FATAL_EXIT_CODE
);
684 /* True if the last module or file in which a diagnostic was reported is
685 different from the current one. */
688 last_module_changed_p (diagnostic_context
*context
,
689 const line_map_ordinary
*map
)
691 return context
->last_module
!= map
;
694 /* Remember the current module or file as being the last one in which we
695 report a diagnostic. */
698 set_last_module (diagnostic_context
*context
, const line_map_ordinary
*map
)
700 context
->last_module
= map
;
704 diagnostic_report_current_module (diagnostic_context
*context
, location_t where
)
706 const line_map_ordinary
*map
= NULL
;
708 if (pp_needs_newline (context
->printer
))
710 pp_newline (context
->printer
);
711 pp_needs_newline (context
->printer
) = false;
714 if (where
<= BUILTINS_LOCATION
)
717 linemap_resolve_location (line_table
, where
,
718 LRK_MACRO_DEFINITION_LOCATION
,
721 if (map
&& last_module_changed_p (context
, map
))
723 set_last_module (context
, map
);
724 if (! MAIN_FILE_P (map
))
726 bool first
= true, need_inc
= true, was_module
= MAP_MODULE_P (map
);
727 expanded_location s
= {};
730 where
= linemap_included_from (map
);
731 map
= linemap_included_from_linemap (line_table
, map
);
732 bool is_module
= MAP_MODULE_P (map
);
733 s
.file
= LINEMAP_FILE (map
);
734 s
.line
= SOURCE_LINE (map
, where
);
736 if (first
&& context
->show_column
)
738 s
.column
= SOURCE_COLUMN (map
, where
);
739 col
= diagnostic_converted_column (context
, s
);
741 const char *line_col
= maybe_line_and_column (s
.line
, col
);
742 static const char *const msgs
[] =
746 N_("In file included from"), /* 2 */
747 N_(" included from"),
748 N_("In module"), /* 4 */
750 N_("In module imported at"), /* 6 */
754 unsigned index
= (was_module
? 6 : is_module
? 4
755 : need_inc
? 2 : 0) + !first
;
757 pp_verbatim (context
->printer
, "%s%s %r%s%s%R",
758 first
? "" : was_module
? ", " : ",\n",
760 "locus", s
.file
, line_col
);
761 first
= false, need_inc
= was_module
, was_module
= is_module
;
763 while (! MAIN_FILE_P (map
));
764 pp_verbatim (context
->printer
, ":");
765 pp_newline (context
->printer
);
770 /* If DIAGNOSTIC has a diagnostic_path and CONTEXT supports printing paths,
774 diagnostic_show_any_path (diagnostic_context
*context
,
775 diagnostic_info
*diagnostic
)
777 const diagnostic_path
*path
= diagnostic
->richloc
->get_path ();
781 if (context
->print_path
)
782 context
->print_path (context
, path
);
785 /* Return true if the events in this path involve more than one
786 function, or false if it is purely intraprocedural. */
789 diagnostic_path::interprocedural_p () const
791 const unsigned num
= num_events ();
792 for (unsigned i
= 0; i
< num
; i
++)
794 if (get_event (i
).get_fndecl () != get_event (0).get_fndecl ())
796 if (get_event (i
).get_stack_depth () != get_event (0).get_stack_depth ())
803 default_diagnostic_starter (diagnostic_context
*context
,
804 diagnostic_info
*diagnostic
)
806 diagnostic_report_current_module (context
, diagnostic_location (diagnostic
));
807 pp_set_prefix (context
->printer
, diagnostic_build_prefix (context
,
812 default_diagnostic_start_span_fn (diagnostic_context
*context
,
813 expanded_location exploc
)
815 char *text
= diagnostic_get_location_text (context
, exploc
);
816 pp_string (context
->printer
, text
);
818 pp_newline (context
->printer
);
822 default_diagnostic_finalizer (diagnostic_context
*context
,
823 diagnostic_info
*diagnostic
,
826 char *saved_prefix
= pp_take_prefix (context
->printer
);
827 pp_set_prefix (context
->printer
, NULL
);
828 pp_newline (context
->printer
);
829 diagnostic_show_locus (context
, diagnostic
->richloc
, diagnostic
->kind
);
830 pp_set_prefix (context
->printer
, saved_prefix
);
831 pp_flush (context
->printer
);
834 /* Interface to specify diagnostic kind overrides. Returns the
835 previous setting, or DK_UNSPECIFIED if the parameters are out of
836 range. If OPTION_INDEX is zero, the new setting is for all the
839 diagnostic_classify_diagnostic (diagnostic_context
*context
,
841 diagnostic_t new_kind
,
844 diagnostic_t old_kind
;
847 || option_index
>= context
->n_opts
848 || new_kind
>= DK_LAST_DIAGNOSTIC_KIND
)
849 return DK_UNSPECIFIED
;
851 old_kind
= context
->classify_diagnostic
[option_index
];
853 /* Handle pragmas separately, since we need to keep track of *where*
855 if (where
!= UNKNOWN_LOCATION
)
859 /* Record the command-line status, so we can reset it back on DK_POP. */
860 if (old_kind
== DK_UNSPECIFIED
)
862 old_kind
= !context
->option_enabled (option_index
,
864 context
->option_state
)
865 ? DK_IGNORED
: (context
->warning_as_error_requested
866 ? DK_ERROR
: DK_WARNING
);
867 context
->classify_diagnostic
[option_index
] = old_kind
;
870 for (i
= context
->n_classification_history
- 1; i
>= 0; i
--)
871 if (context
->classification_history
[i
].option
== option_index
)
873 old_kind
= context
->classification_history
[i
].kind
;
877 i
= context
->n_classification_history
;
878 context
->classification_history
=
879 (diagnostic_classification_change_t
*) xrealloc (context
->classification_history
, (i
+ 1)
880 * sizeof (diagnostic_classification_change_t
));
881 context
->classification_history
[i
].location
= where
;
882 context
->classification_history
[i
].option
= option_index
;
883 context
->classification_history
[i
].kind
= new_kind
;
884 context
->n_classification_history
++;
887 context
->classify_diagnostic
[option_index
] = new_kind
;
892 /* Save all diagnostic classifications in a stack. */
894 diagnostic_push_diagnostics (diagnostic_context
*context
, location_t where ATTRIBUTE_UNUSED
)
896 context
->push_list
= (int *) xrealloc (context
->push_list
, (context
->n_push
+ 1) * sizeof (int));
897 context
->push_list
[context
->n_push
++] = context
->n_classification_history
;
900 /* Restore the topmost classification set off the stack. If the stack
901 is empty, revert to the state based on command line parameters. */
903 diagnostic_pop_diagnostics (diagnostic_context
*context
, location_t where
)
909 jump_to
= context
->push_list
[-- context
->n_push
];
913 i
= context
->n_classification_history
;
914 context
->classification_history
=
915 (diagnostic_classification_change_t
*) xrealloc (context
->classification_history
, (i
+ 1)
916 * sizeof (diagnostic_classification_change_t
));
917 context
->classification_history
[i
].location
= where
;
918 context
->classification_history
[i
].option
= jump_to
;
919 context
->classification_history
[i
].kind
= DK_POP
;
920 context
->n_classification_history
++;
923 /* Helper function for print_parseable_fixits. Print TEXT to PP, obeying the
924 escaping rules for -fdiagnostics-parseable-fixits. */
927 print_escaped_string (pretty_printer
*pp
, const char *text
)
932 pp_character (pp
, '"');
933 for (const char *ch
= text
; *ch
; ch
++)
938 /* Escape backslash as two backslashes. */
939 pp_string (pp
, "\\\\");
942 /* Escape tab as "\t". */
943 pp_string (pp
, "\\t");
946 /* Escape newline as "\n". */
947 pp_string (pp
, "\\n");
950 /* Escape doublequotes as \". */
951 pp_string (pp
, "\\\"");
955 pp_character (pp
, *ch
);
957 /* Use octal for non-printable chars. */
959 unsigned char c
= (*ch
& 0xff);
960 pp_printf (pp
, "\\%o%o%o", (c
/ 64), (c
/ 8) & 007, c
& 007);
965 pp_character (pp
, '"');
968 /* Implementation of -fdiagnostics-parseable-fixits and
969 GCC_EXTRA_DIAGNOSTIC_OUTPUT.
970 Print a machine-parseable version of all fixits in RICHLOC to PP,
971 using COLUMN_UNIT to express columns.
972 Use TABSTOP when handling DIAGNOSTICS_COLUMN_UNIT_DISPLAY. */
975 print_parseable_fixits (pretty_printer
*pp
, rich_location
*richloc
,
976 enum diagnostics_column_unit column_unit
,
980 gcc_assert (richloc
);
982 char *saved_prefix
= pp_take_prefix (pp
);
983 pp_set_prefix (pp
, NULL
);
985 for (unsigned i
= 0; i
< richloc
->get_num_fixit_hints (); i
++)
987 const fixit_hint
*hint
= richloc
->get_fixit_hint (i
);
988 location_t start_loc
= hint
->get_start_loc ();
989 expanded_location start_exploc
= expand_location (start_loc
);
990 pp_string (pp
, "fix-it:");
991 print_escaped_string (pp
, start_exploc
.file
);
992 /* For compatibility with clang, print as a half-open range. */
993 location_t next_loc
= hint
->get_next_loc ();
994 expanded_location next_exploc
= expand_location (next_loc
);
996 = convert_column_unit (column_unit
, tabstop
, start_exploc
);
998 = convert_column_unit (column_unit
, tabstop
, next_exploc
);
999 pp_printf (pp
, ":{%i:%i-%i:%i}:",
1000 start_exploc
.line
, start_col
,
1001 next_exploc
.line
, next_col
);
1002 print_escaped_string (pp
, hint
->get_string ());
1006 pp_set_prefix (pp
, saved_prefix
);
1009 /* Update the inlining info in CONTEXT for a DIAGNOSTIC. */
1012 get_any_inlining_info (diagnostic_context
*context
,
1013 diagnostic_info
*diagnostic
)
1015 auto &ilocs
= diagnostic
->m_iinfo
.m_ilocs
;
1017 if (context
->set_locations_cb
)
1018 /* Retrieve the locations into which the expression about to be
1019 diagnosed has been inlined, including those of all the callers
1020 all the way down the inlining stack. */
1021 context
->set_locations_cb (context
, diagnostic
);
1024 /* When there's no callback use just the one location provided
1025 by the caller of the diagnostic function. */
1026 location_t loc
= diagnostic_location (diagnostic
);
1027 ilocs
.safe_push (loc
);
1028 diagnostic
->m_iinfo
.m_allsyslocs
= in_system_header_at (loc
);
1032 /* Update the kind of DIAGNOSTIC based on its location(s), including
1033 any of those in its inlining stack, relative to any
1034 #pragma GCC diagnostic
1035 directives recorded within CONTEXT.
1037 Return the new kind of DIAGNOSTIC if it was updated, or DK_UNSPECIFIED
1041 update_effective_level_from_pragmas (diagnostic_context
*context
,
1042 diagnostic_info
*diagnostic
)
1044 if (diagnostic
->m_iinfo
.m_allsyslocs
&& !context
->dc_warn_system_headers
)
1046 /* Ignore the diagnostic if all the inlined locations are
1047 in system headers and -Wno-system-headers is in effect. */
1048 diagnostic
->kind
= DK_IGNORED
;
1052 if (context
->n_classification_history
<= 0)
1053 return DK_UNSPECIFIED
;
1055 /* Iterate over the locations, checking the diagnostic disposition
1056 for the diagnostic at each. If it's explicitly set as opposed
1057 to unspecified, update the disposition for this instance of
1058 the diagnostic and return it. */
1059 for (location_t loc
: diagnostic
->m_iinfo
.m_ilocs
)
1061 /* FIXME: Stupid search. Optimize later. */
1062 for (int i
= context
->n_classification_history
- 1; i
>= 0; i
--)
1064 const diagnostic_classification_change_t
&hist
1065 = context
->classification_history
[i
];
1067 location_t pragloc
= hist
.location
;
1068 if (!linemap_location_before_p (line_table
, pragloc
, loc
))
1071 if (hist
.kind
== (int) DK_POP
)
1073 /* Move on to the next region. */
1078 int option
= hist
.option
;
1079 /* The option 0 is for all the diagnostics. */
1080 if (option
== 0 || option
== diagnostic
->option_index
)
1082 diagnostic_t kind
= hist
.kind
;
1083 if (kind
!= DK_UNSPECIFIED
)
1084 diagnostic
->kind
= kind
;
1090 return DK_UNSPECIFIED
;
1093 /* Generate a URL string describing CWE. The caller is responsible for
1094 freeing the string. */
1097 get_cwe_url (int cwe
)
1099 return xasprintf ("https://cwe.mitre.org/data/definitions/%i.html", cwe
);
1102 /* If DIAGNOSTIC has a CWE identifier, print it.
1104 For example, if the diagnostic metadata associates it with CWE-119,
1105 " [CWE-119]" will be printed, suitably colorized, and with a URL of a
1106 description of the security issue. */
1109 print_any_cwe (diagnostic_context
*context
,
1110 const diagnostic_info
*diagnostic
)
1112 if (diagnostic
->metadata
== NULL
)
1115 int cwe
= diagnostic
->metadata
->get_cwe ();
1118 pretty_printer
*pp
= context
->printer
;
1119 char *saved_prefix
= pp_take_prefix (context
->printer
);
1120 pp_string (pp
, " [");
1121 pp_string (pp
, colorize_start (pp_show_color (pp
),
1122 diagnostic_kind_color
[diagnostic
->kind
]));
1123 if (pp
->url_format
!= URL_FORMAT_NONE
)
1125 char *cwe_url
= get_cwe_url (cwe
);
1126 pp_begin_url (pp
, cwe_url
);
1129 pp_printf (pp
, "CWE-%i", cwe
);
1130 pp_set_prefix (context
->printer
, saved_prefix
);
1131 if (pp
->url_format
!= URL_FORMAT_NONE
)
1133 pp_string (pp
, colorize_stop (pp_show_color (pp
)));
1134 pp_character (pp
, ']');
1138 /* Print any metadata about the option used to control DIAGNOSTIC to CONTEXT's
1139 printer, e.g. " [-Werror=uninitialized]".
1140 Subroutine of diagnostic_report_diagnostic. */
1143 print_option_information (diagnostic_context
*context
,
1144 const diagnostic_info
*diagnostic
,
1145 diagnostic_t orig_diag_kind
)
1149 option_text
= context
->option_name (context
, diagnostic
->option_index
,
1150 orig_diag_kind
, diagnostic
->kind
);
1154 char *option_url
= NULL
;
1155 if (context
->get_option_url
1156 && context
->printer
->url_format
!= URL_FORMAT_NONE
)
1157 option_url
= context
->get_option_url (context
,
1158 diagnostic
->option_index
);
1159 pretty_printer
*pp
= context
->printer
;
1160 pp_string (pp
, " [");
1161 pp_string (pp
, colorize_start (pp_show_color (pp
),
1162 diagnostic_kind_color
[diagnostic
->kind
]));
1164 pp_begin_url (pp
, option_url
);
1165 pp_string (pp
, option_text
);
1171 pp_string (pp
, colorize_stop (pp_show_color (pp
)));
1172 pp_character (pp
, ']');
1177 /* Returns whether a DIAGNOSTIC should be printed, and adjusts diagnostic->kind
1178 as appropriate for #pragma GCC diagnostic and -Werror=foo. */
1181 diagnostic_enabled (diagnostic_context
*context
,
1182 diagnostic_info
*diagnostic
)
1184 /* Update the inlining stack for this diagnostic. */
1185 get_any_inlining_info (context
, diagnostic
);
1187 /* Diagnostics with no option or -fpermissive are always enabled. */
1188 if (!diagnostic
->option_index
1189 || diagnostic
->option_index
== permissive_error_option (context
))
1192 /* This tests if the user provided the appropriate -Wfoo or
1194 if (! context
->option_enabled (diagnostic
->option_index
,
1196 context
->option_state
))
1199 /* This tests for #pragma diagnostic changes. */
1200 diagnostic_t diag_class
1201 = update_effective_level_from_pragmas (context
, diagnostic
);
1203 /* This tests if the user provided the appropriate -Werror=foo
1205 if (diag_class
== DK_UNSPECIFIED
1206 && (context
->classify_diagnostic
[diagnostic
->option_index
]
1209 = context
->classify_diagnostic
[diagnostic
->option_index
];
1211 /* This allows for future extensions, like temporarily disabling
1212 warnings for ranges of source code. */
1213 if (diagnostic
->kind
== DK_IGNORED
)
1219 /* Returns whether warning OPT is enabled at LOC. */
1222 warning_enabled_at (location_t loc
, int opt
)
1224 if (!diagnostic_report_warnings_p (global_dc
, loc
))
1227 rich_location
richloc (line_table
, loc
);
1228 diagnostic_info diagnostic
= {};
1229 diagnostic
.option_index
= opt
;
1230 diagnostic
.richloc
= &richloc
;
1231 diagnostic
.message
.m_richloc
= &richloc
;
1232 diagnostic
.kind
= DK_WARNING
;
1233 return diagnostic_enabled (global_dc
, &diagnostic
);
1236 /* Report a diagnostic message (an error or a warning) as specified by
1237 DC. This function is *the* subroutine in terms of which front-ends
1238 should implement their specific diagnostic handling modules. The
1239 front-end independent format specifiers are exactly those described
1240 in the documentation of output_format.
1241 Return true if a diagnostic was printed, false otherwise. */
1244 diagnostic_report_diagnostic (diagnostic_context
*context
,
1245 diagnostic_info
*diagnostic
)
1247 location_t location
= diagnostic_location (diagnostic
);
1248 diagnostic_t orig_diag_kind
= diagnostic
->kind
;
1250 /* Give preference to being able to inhibit warnings, before they
1251 get reclassified to something else. */
1252 bool report_warning_p
= true;
1253 if (diagnostic
->kind
== DK_WARNING
|| diagnostic
->kind
== DK_PEDWARN
)
1255 if (context
->dc_inhibit_warnings
)
1257 /* Remember the result of the overall system header warning setting
1258 but proceed to also check the inlining context. */
1259 report_warning_p
= diagnostic_report_warnings_p (context
, location
);
1260 if (!report_warning_p
&& diagnostic
->kind
== DK_PEDWARN
)
1264 if (diagnostic
->kind
== DK_PEDWARN
)
1266 diagnostic
->kind
= pedantic_warning_kind (context
);
1267 /* We do this to avoid giving the message for -pedantic-errors. */
1268 orig_diag_kind
= diagnostic
->kind
;
1271 if (diagnostic
->kind
== DK_NOTE
&& context
->inhibit_notes_p
)
1274 if (context
->lock
> 0)
1276 /* If we're reporting an ICE in the middle of some other error,
1277 try to flush out the previous error, then let this one
1278 through. Don't do this more than once. */
1279 if ((diagnostic
->kind
== DK_ICE
|| diagnostic
->kind
== DK_ICE_NOBT
)
1280 && context
->lock
== 1)
1281 pp_newline_and_flush (context
->printer
);
1283 error_recursion (context
);
1286 /* If the user requested that warnings be treated as errors, so be
1287 it. Note that we do this before the next block so that
1288 individual warnings can be overridden back to warnings with
1290 if (context
->warning_as_error_requested
1291 && diagnostic
->kind
== DK_WARNING
)
1292 diagnostic
->kind
= DK_ERROR
;
1294 diagnostic
->message
.x_data
= &diagnostic
->x_data
;
1296 /* Check to see if the diagnostic is enabled at the location and
1297 not disabled by #pragma GCC diagnostic anywhere along the inlining
1299 if (!diagnostic_enabled (context
, diagnostic
))
1302 if (!report_warning_p
&& diagnostic
->m_iinfo
.m_allsyslocs
)
1303 /* Bail if the warning is not to be reported because all locations
1304 in the inlining stack (if there is one) are in system headers. */
1307 if (diagnostic
->kind
!= DK_NOTE
&& diagnostic
->kind
!= DK_ICE
)
1308 diagnostic_check_max_errors (context
);
1312 if (diagnostic
->kind
== DK_ICE
|| diagnostic
->kind
== DK_ICE_NOBT
)
1314 /* When not checking, ICEs are converted to fatal errors when an
1315 error has already occurred. This is counteracted by
1318 && (diagnostic_kind_count (context
, DK_ERROR
) > 0
1319 || diagnostic_kind_count (context
, DK_SORRY
) > 0)
1320 && !context
->abort_on_error
)
1323 = expand_location (diagnostic_location (diagnostic
));
1324 fnotice (stderr
, "%s:%d: confused by earlier errors, bailing out\n",
1326 exit (ICE_EXIT_CODE
);
1328 if (context
->internal_error
)
1329 (*context
->internal_error
) (context
,
1330 diagnostic
->message
.format_spec
,
1331 diagnostic
->message
.args_ptr
);
1333 if (diagnostic
->kind
== DK_ERROR
&& orig_diag_kind
== DK_WARNING
)
1334 ++diagnostic_kind_count (context
, DK_WERROR
);
1336 ++diagnostic_kind_count (context
, diagnostic
->kind
);
1338 /* Is this the initial diagnostic within the stack of groups? */
1339 if (context
->diagnostic_group_emission_count
== 0)
1341 if (context
->begin_group_cb
)
1342 context
->begin_group_cb (context
);
1344 context
->diagnostic_group_emission_count
++;
1346 pp_format (context
->printer
, &diagnostic
->message
);
1347 (*diagnostic_starter (context
)) (context
, diagnostic
);
1348 pp_output_formatted_text (context
->printer
);
1349 if (context
->show_cwe
)
1350 print_any_cwe (context
, diagnostic
);
1351 if (context
->show_option_requested
)
1352 print_option_information (context
, diagnostic
, orig_diag_kind
);
1353 (*diagnostic_finalizer (context
)) (context
, diagnostic
, orig_diag_kind
);
1354 switch (context
->extra_output_kind
)
1358 case EXTRA_DIAGNOSTIC_OUTPUT_fixits_v1
:
1359 print_parseable_fixits (context
->printer
, diagnostic
->richloc
,
1360 DIAGNOSTICS_COLUMN_UNIT_BYTE
,
1362 pp_flush (context
->printer
);
1364 case EXTRA_DIAGNOSTIC_OUTPUT_fixits_v2
:
1365 print_parseable_fixits (context
->printer
, diagnostic
->richloc
,
1366 DIAGNOSTICS_COLUMN_UNIT_DISPLAY
,
1368 pp_flush (context
->printer
);
1371 diagnostic_action_after_output (context
, diagnostic
->kind
);
1372 diagnostic
->x_data
= NULL
;
1374 if (context
->edit_context_ptr
)
1375 if (diagnostic
->richloc
->fixits_can_be_auto_applied_p ())
1376 context
->edit_context_ptr
->add_fixits (diagnostic
->richloc
);
1380 diagnostic_show_any_path (context
, diagnostic
);
1385 /* Get the number of digits in the decimal representation of VALUE. */
1388 num_digits (int value
)
1390 /* Perhaps simpler to use log10 for this, but doing it this way avoids
1391 using floating point. */
1392 gcc_assert (value
>= 0);
1406 /* Given a partial pathname as input, return another pathname that
1407 shares no directory elements with the pathname of __FILE__. This
1408 is used by fancy_abort() to print `Internal compiler error in expr.c'
1409 instead of `Internal compiler error in ../../GCC/gcc/expr.c'. */
1412 trim_filename (const char *name
)
1414 static const char this_file
[] = __FILE__
;
1415 const char *p
= name
, *q
= this_file
;
1417 /* First skip any "../" in each filename. This allows us to give a proper
1418 reference to a file in a subdirectory. */
1419 while (p
[0] == '.' && p
[1] == '.' && IS_DIR_SEPARATOR (p
[2]))
1422 while (q
[0] == '.' && q
[1] == '.' && IS_DIR_SEPARATOR (q
[2]))
1425 /* Now skip any parts the two filenames have in common. */
1426 while (*p
== *q
&& *p
!= 0 && *q
!= 0)
1429 /* Now go backwards until the previous directory separator. */
1430 while (p
> name
&& !IS_DIR_SEPARATOR (p
[-1]))
1436 /* Standard error reporting routines in increasing order of severity.
1437 All of these take arguments like printf. */
1439 /* Text to be emitted verbatim to the error message stream; this
1440 produces no prefix and disables line-wrapping. Use rarely. */
1442 verbatim (const char *gmsgid
, ...)
1447 va_start (ap
, gmsgid
);
1448 text
.err_no
= errno
;
1449 text
.args_ptr
= &ap
;
1450 text
.format_spec
= _(gmsgid
);
1452 pp_format_verbatim (global_dc
->printer
, &text
);
1453 pp_newline_and_flush (global_dc
->printer
);
1457 /* Add a note with text GMSGID and with LOCATION to the diagnostic CONTEXT. */
1459 diagnostic_append_note (diagnostic_context
*context
,
1460 location_t location
,
1461 const char * gmsgid
, ...)
1463 diagnostic_info diagnostic
;
1465 rich_location
richloc (line_table
, location
);
1467 va_start (ap
, gmsgid
);
1468 diagnostic_set_info (&diagnostic
, gmsgid
, &ap
, &richloc
, DK_NOTE
);
1469 if (context
->inhibit_notes_p
)
1474 char *saved_prefix
= pp_take_prefix (context
->printer
);
1475 pp_set_prefix (context
->printer
,
1476 diagnostic_build_prefix (context
, &diagnostic
));
1477 pp_format (context
->printer
, &diagnostic
.message
);
1478 pp_output_formatted_text (context
->printer
);
1479 pp_destroy_prefix (context
->printer
);
1480 pp_set_prefix (context
->printer
, saved_prefix
);
1481 pp_newline (context
->printer
);
1482 diagnostic_show_locus (context
, &richloc
, DK_NOTE
);
1486 /* Implement emit_diagnostic, inform, warning, warning_at, pedwarn,
1487 permerror, error, error_at, error_at, sorry, fatal_error, internal_error,
1488 and internal_error_no_backtrace, as documented and defined below. */
1490 diagnostic_impl (rich_location
*richloc
, const diagnostic_metadata
*metadata
,
1491 int opt
, const char *gmsgid
,
1492 va_list *ap
, diagnostic_t kind
)
1494 diagnostic_info diagnostic
;
1495 if (kind
== DK_PERMERROR
)
1497 diagnostic_set_info (&diagnostic
, gmsgid
, ap
, richloc
,
1498 permissive_error_kind (global_dc
));
1499 diagnostic
.option_index
= permissive_error_option (global_dc
);
1503 diagnostic_set_info (&diagnostic
, gmsgid
, ap
, richloc
, kind
);
1504 if (kind
== DK_WARNING
|| kind
== DK_PEDWARN
)
1505 diagnostic
.option_index
= opt
;
1507 diagnostic
.metadata
= metadata
;
1508 return diagnostic_report_diagnostic (global_dc
, &diagnostic
);
1511 /* Implement inform_n, warning_n, and error_n, as documented and
1514 diagnostic_n_impl (rich_location
*richloc
, const diagnostic_metadata
*metadata
,
1515 int opt
, unsigned HOST_WIDE_INT n
,
1516 const char *singular_gmsgid
,
1517 const char *plural_gmsgid
,
1518 va_list *ap
, diagnostic_t kind
)
1520 diagnostic_info diagnostic
;
1523 if (sizeof n
<= sizeof gtn
)
1526 /* Use the largest number ngettext can handle, otherwise
1527 preserve the six least significant decimal digits for
1528 languages where the plural form depends on them. */
1529 gtn
= n
<= ULONG_MAX
? n
: n
% 1000000LU + 1000000LU;
1531 const char *text
= ngettext (singular_gmsgid
, plural_gmsgid
, gtn
);
1532 diagnostic_set_info_translated (&diagnostic
, text
, ap
, richloc
, kind
);
1533 if (kind
== DK_WARNING
)
1534 diagnostic
.option_index
= opt
;
1535 diagnostic
.metadata
= metadata
;
1536 return diagnostic_report_diagnostic (global_dc
, &diagnostic
);
1539 /* Wrapper around diagnostic_impl taking a variable argument list. */
1542 emit_diagnostic (diagnostic_t kind
, location_t location
, int opt
,
1543 const char *gmsgid
, ...)
1545 auto_diagnostic_group d
;
1547 va_start (ap
, gmsgid
);
1548 rich_location
richloc (line_table
, location
);
1549 bool ret
= diagnostic_impl (&richloc
, NULL
, opt
, gmsgid
, &ap
, kind
);
1554 /* As above, but for rich_location *. */
1557 emit_diagnostic (diagnostic_t kind
, rich_location
*richloc
, int opt
,
1558 const char *gmsgid
, ...)
1560 auto_diagnostic_group d
;
1562 va_start (ap
, gmsgid
);
1563 bool ret
= diagnostic_impl (richloc
, NULL
, opt
, gmsgid
, &ap
, kind
);
1568 /* Wrapper around diagnostic_impl taking a va_list parameter. */
1571 emit_diagnostic_valist (diagnostic_t kind
, location_t location
, int opt
,
1572 const char *gmsgid
, va_list *ap
)
1574 rich_location
richloc (line_table
, location
);
1575 return diagnostic_impl (&richloc
, NULL
, opt
, gmsgid
, ap
, kind
);
1578 /* An informative note at LOCATION. Use this for additional details on an error
1581 inform (location_t location
, const char *gmsgid
, ...)
1583 auto_diagnostic_group d
;
1585 va_start (ap
, gmsgid
);
1586 rich_location
richloc (line_table
, location
);
1587 diagnostic_impl (&richloc
, NULL
, -1, gmsgid
, &ap
, DK_NOTE
);
1591 /* Same as "inform" above, but at RICHLOC. */
1593 inform (rich_location
*richloc
, const char *gmsgid
, ...)
1595 gcc_assert (richloc
);
1597 auto_diagnostic_group d
;
1599 va_start (ap
, gmsgid
);
1600 diagnostic_impl (richloc
, NULL
, -1, gmsgid
, &ap
, DK_NOTE
);
1604 /* An informative note at LOCATION. Use this for additional details on an
1607 inform_n (location_t location
, unsigned HOST_WIDE_INT n
,
1608 const char *singular_gmsgid
, const char *plural_gmsgid
, ...)
1611 va_start (ap
, plural_gmsgid
);
1612 auto_diagnostic_group d
;
1613 rich_location
richloc (line_table
, location
);
1614 diagnostic_n_impl (&richloc
, NULL
, -1, n
, singular_gmsgid
, plural_gmsgid
,
1619 /* A warning at INPUT_LOCATION. Use this for code which is correct according
1620 to the relevant language specification but is likely to be buggy anyway.
1621 Returns true if the warning was printed, false if it was inhibited. */
1623 warning (int opt
, const char *gmsgid
, ...)
1625 auto_diagnostic_group d
;
1627 va_start (ap
, gmsgid
);
1628 rich_location
richloc (line_table
, input_location
);
1629 bool ret
= diagnostic_impl (&richloc
, NULL
, opt
, gmsgid
, &ap
, DK_WARNING
);
1634 /* A warning at LOCATION. Use this for code which is correct according to the
1635 relevant language specification but is likely to be buggy anyway.
1636 Returns true if the warning was printed, false if it was inhibited. */
1639 warning_at (location_t location
, int opt
, const char *gmsgid
, ...)
1641 auto_diagnostic_group d
;
1643 va_start (ap
, gmsgid
);
1644 rich_location
richloc (line_table
, location
);
1645 bool ret
= diagnostic_impl (&richloc
, NULL
, opt
, gmsgid
, &ap
, DK_WARNING
);
1650 /* Same as "warning at" above, but using RICHLOC. */
1653 warning_at (rich_location
*richloc
, int opt
, const char *gmsgid
, ...)
1655 gcc_assert (richloc
);
1657 auto_diagnostic_group d
;
1659 va_start (ap
, gmsgid
);
1660 bool ret
= diagnostic_impl (richloc
, NULL
, opt
, gmsgid
, &ap
, DK_WARNING
);
1665 /* Same as "warning at" above, but using METADATA. */
1668 warning_meta (rich_location
*richloc
,
1669 const diagnostic_metadata
&metadata
,
1670 int opt
, const char *gmsgid
, ...)
1672 gcc_assert (richloc
);
1674 auto_diagnostic_group d
;
1676 va_start (ap
, gmsgid
);
1678 = diagnostic_impl (richloc
, &metadata
, opt
, gmsgid
, &ap
,
1684 /* Same as warning_n plural variant below, but using RICHLOC. */
1687 warning_n (rich_location
*richloc
, int opt
, unsigned HOST_WIDE_INT n
,
1688 const char *singular_gmsgid
, const char *plural_gmsgid
, ...)
1690 gcc_assert (richloc
);
1692 auto_diagnostic_group d
;
1694 va_start (ap
, plural_gmsgid
);
1695 bool ret
= diagnostic_n_impl (richloc
, NULL
, opt
, n
,
1696 singular_gmsgid
, plural_gmsgid
,
1702 /* A warning at LOCATION. Use this for code which is correct according to the
1703 relevant language specification but is likely to be buggy anyway.
1704 Returns true if the warning was printed, false if it was inhibited. */
1707 warning_n (location_t location
, int opt
, unsigned HOST_WIDE_INT n
,
1708 const char *singular_gmsgid
, const char *plural_gmsgid
, ...)
1710 auto_diagnostic_group d
;
1712 va_start (ap
, plural_gmsgid
);
1713 rich_location
richloc (line_table
, location
);
1714 bool ret
= diagnostic_n_impl (&richloc
, NULL
, opt
, n
,
1715 singular_gmsgid
, plural_gmsgid
,
1721 /* A "pedantic" warning at LOCATION: issues a warning unless
1722 -pedantic-errors was given on the command line, in which case it
1723 issues an error. Use this for diagnostics required by the relevant
1724 language standard, if you have chosen not to make them errors.
1726 Note that these diagnostics are issued independent of the setting
1727 of the -Wpedantic command-line switch. To get a warning enabled
1728 only with that switch, use either "if (pedantic) pedwarn
1729 (OPT_Wpedantic,...)" or just "pedwarn (OPT_Wpedantic,..)". To get a
1730 pedwarn independently of the -Wpedantic switch use "pedwarn (0,...)".
1732 Returns true if the warning was printed, false if it was inhibited. */
1735 pedwarn (location_t location
, int opt
, const char *gmsgid
, ...)
1737 auto_diagnostic_group d
;
1739 va_start (ap
, gmsgid
);
1740 rich_location
richloc (line_table
, location
);
1741 bool ret
= diagnostic_impl (&richloc
, NULL
, opt
, gmsgid
, &ap
, DK_PEDWARN
);
1746 /* Same as pedwarn above, but using RICHLOC. */
1749 pedwarn (rich_location
*richloc
, int opt
, const char *gmsgid
, ...)
1751 gcc_assert (richloc
);
1753 auto_diagnostic_group d
;
1755 va_start (ap
, gmsgid
);
1756 bool ret
= diagnostic_impl (richloc
, NULL
, opt
, gmsgid
, &ap
, DK_PEDWARN
);
1761 /* A "permissive" error at LOCATION: issues an error unless
1762 -fpermissive was given on the command line, in which case it issues
1763 a warning. Use this for things that really should be errors but we
1764 want to support legacy code.
1766 Returns true if the warning was printed, false if it was inhibited. */
1769 permerror (location_t location
, const char *gmsgid
, ...)
1771 auto_diagnostic_group d
;
1773 va_start (ap
, gmsgid
);
1774 rich_location
richloc (line_table
, location
);
1775 bool ret
= diagnostic_impl (&richloc
, NULL
, -1, gmsgid
, &ap
, DK_PERMERROR
);
1780 /* Same as "permerror" above, but at RICHLOC. */
1783 permerror (rich_location
*richloc
, const char *gmsgid
, ...)
1785 gcc_assert (richloc
);
1787 auto_diagnostic_group d
;
1789 va_start (ap
, gmsgid
);
1790 bool ret
= diagnostic_impl (richloc
, NULL
, -1, gmsgid
, &ap
, DK_PERMERROR
);
1795 /* A hard error: the code is definitely ill-formed, and an object file
1796 will not be produced. */
1798 error (const char *gmsgid
, ...)
1800 auto_diagnostic_group d
;
1802 va_start (ap
, gmsgid
);
1803 rich_location
richloc (line_table
, input_location
);
1804 diagnostic_impl (&richloc
, NULL
, -1, gmsgid
, &ap
, DK_ERROR
);
1808 /* A hard error: the code is definitely ill-formed, and an object file
1809 will not be produced. */
1811 error_n (location_t location
, unsigned HOST_WIDE_INT n
,
1812 const char *singular_gmsgid
, const char *plural_gmsgid
, ...)
1814 auto_diagnostic_group d
;
1816 va_start (ap
, plural_gmsgid
);
1817 rich_location
richloc (line_table
, location
);
1818 diagnostic_n_impl (&richloc
, NULL
, -1, n
, singular_gmsgid
, plural_gmsgid
,
1823 /* Same as above, but use location LOC instead of input_location. */
1825 error_at (location_t loc
, const char *gmsgid
, ...)
1827 auto_diagnostic_group d
;
1829 va_start (ap
, gmsgid
);
1830 rich_location
richloc (line_table
, loc
);
1831 diagnostic_impl (&richloc
, NULL
, -1, gmsgid
, &ap
, DK_ERROR
);
1835 /* Same as above, but use RICH_LOC. */
1838 error_at (rich_location
*richloc
, const char *gmsgid
, ...)
1840 gcc_assert (richloc
);
1842 auto_diagnostic_group d
;
1844 va_start (ap
, gmsgid
);
1845 diagnostic_impl (richloc
, NULL
, -1, gmsgid
, &ap
, DK_ERROR
);
1849 /* "Sorry, not implemented." Use for a language feature which is
1850 required by the relevant specification but not implemented by GCC.
1851 An object file will not be produced. */
1853 sorry (const char *gmsgid
, ...)
1855 auto_diagnostic_group d
;
1857 va_start (ap
, gmsgid
);
1858 rich_location
richloc (line_table
, input_location
);
1859 diagnostic_impl (&richloc
, NULL
, -1, gmsgid
, &ap
, DK_SORRY
);
1863 /* Same as above, but use location LOC instead of input_location. */
1865 sorry_at (location_t loc
, const char *gmsgid
, ...)
1867 auto_diagnostic_group d
;
1869 va_start (ap
, gmsgid
);
1870 rich_location
richloc (line_table
, loc
);
1871 diagnostic_impl (&richloc
, NULL
, -1, gmsgid
, &ap
, DK_SORRY
);
1875 /* Return true if an error or a "sorry" has been seen. Various
1876 processing is disabled after errors. */
1880 return errorcount
|| sorrycount
;
1883 /* An error which is severe enough that we make no attempt to
1884 continue. Do not use this for internal consistency checks; that's
1885 internal_error. Use of this function should be rare. */
1887 fatal_error (location_t loc
, const char *gmsgid
, ...)
1889 auto_diagnostic_group d
;
1891 va_start (ap
, gmsgid
);
1892 rich_location
richloc (line_table
, loc
);
1893 diagnostic_impl (&richloc
, NULL
, -1, gmsgid
, &ap
, DK_FATAL
);
1899 /* An internal consistency check has failed. We make no attempt to
1900 continue. Note that unless there is debugging value to be had from
1901 a more specific message, or some other good reason, you should use
1902 abort () instead of calling this function directly. */
1904 internal_error (const char *gmsgid
, ...)
1906 auto_diagnostic_group d
;
1908 va_start (ap
, gmsgid
);
1909 rich_location
richloc (line_table
, input_location
);
1910 diagnostic_impl (&richloc
, NULL
, -1, gmsgid
, &ap
, DK_ICE
);
1916 /* Like internal_error, but no backtrace will be printed. Used when
1917 the internal error does not happen at the current location, but happened
1920 internal_error_no_backtrace (const char *gmsgid
, ...)
1922 auto_diagnostic_group d
;
1924 va_start (ap
, gmsgid
);
1925 rich_location
richloc (line_table
, input_location
);
1926 diagnostic_impl (&richloc
, NULL
, -1, gmsgid
, &ap
, DK_ICE_NOBT
);
1932 /* Special case error functions. Most are implemented in terms of the
1933 above, or should be. */
1935 /* Print a diagnostic MSGID on FILE. This is just fprintf, except it
1936 runs its second argument through gettext. */
1938 fnotice (FILE *file
, const char *cmsgid
, ...)
1942 va_start (ap
, cmsgid
);
1943 vfprintf (file
, _(cmsgid
), ap
);
1947 /* Inform the user that an error occurred while trying to report some
1948 other error. This indicates catastrophic internal inconsistencies,
1949 so give up now. But do try to flush out the previous error.
1950 This mustn't use internal_error, that will cause infinite recursion. */
1953 error_recursion (diagnostic_context
*context
)
1955 if (context
->lock
< 3)
1956 pp_newline_and_flush (context
->printer
);
1959 "Internal compiler error: Error reporting routines re-entered.\n");
1961 /* Call diagnostic_action_after_output to get the "please submit a bug
1963 diagnostic_action_after_output (context
, DK_ICE
);
1965 /* Do not use gcc_unreachable here; that goes through internal_error
1966 and therefore would cause infinite recursion. */
1970 /* Report an internal compiler error in a friendly manner. This is
1971 the function that gets called upon use of abort() in the source
1972 code generally, thanks to a special macro. */
1975 fancy_abort (const char *file
, int line
, const char *function
)
1977 /* If fancy_abort is called before the diagnostic subsystem is initialized,
1978 internal_error will crash internally in a way that prevents a
1979 useful message reaching the user.
1980 This can happen with libgccjit in the case of gcc_assert failures
1981 that occur outside of the libgccjit mutex that guards the rest of
1982 gcc's state, including global_dc (when global_dc may not be
1983 initialized yet, or might be in use by another thread).
1984 Handle such cases as gracefully as possible by falling back to a
1985 minimal abort handler that only relies on i18n. */
1986 if (global_dc
->printer
== NULL
)
1988 /* Print the error message. */
1989 fnotice (stderr
, diagnostic_kind_text
[DK_ICE
]);
1990 fnotice (stderr
, "in %s, at %s:%d", function
, trim_filename (file
), line
);
1991 fputc ('\n', stderr
);
1993 /* Attempt to print a backtrace. */
1994 struct backtrace_state
*state
1995 = backtrace_create_state (NULL
, 0, bt_err_callback
, NULL
);
1998 backtrace_full (state
, 2, bt_callback
, bt_err_callback
,
2001 /* We can't call warn_if_plugins or emergency_dump_function as these
2002 rely on GCC state that might not be initialized, or might be in
2003 use by another thread. */
2005 /* Abort the process. */
2009 internal_error ("in %s, at %s:%d", function
, trim_filename (file
), line
);
2012 /* class auto_diagnostic_group. */
2014 /* Constructor: "push" this group into global_dc. */
2016 auto_diagnostic_group::auto_diagnostic_group ()
2018 global_dc
->diagnostic_group_nesting_depth
++;
2021 /* Destructor: "pop" this group from global_dc. */
2023 auto_diagnostic_group::~auto_diagnostic_group ()
2025 if (--global_dc
->diagnostic_group_nesting_depth
== 0)
2027 /* Handle the case where we've popped the final diagnostic group.
2028 If any diagnostics were emitted, give the context a chance
2030 if (global_dc
->diagnostic_group_emission_count
> 0)
2032 if (global_dc
->end_group_cb
)
2033 global_dc
->end_group_cb (global_dc
);
2035 global_dc
->diagnostic_group_emission_count
= 0;
2039 /* Implementation of diagnostic_path::num_events vfunc for
2040 simple_diagnostic_path: simply get the number of events in the vec. */
2043 simple_diagnostic_path::num_events () const
2045 return m_events
.length ();
2048 /* Implementation of diagnostic_path::get_event vfunc for
2049 simple_diagnostic_path: simply return the event in the vec. */
2051 const diagnostic_event
&
2052 simple_diagnostic_path::get_event (int idx
) const
2054 return *m_events
[idx
];
2057 /* Add an event to this path at LOC within function FNDECL at
2060 Use m_context's printer to format FMT, as the text of the new
2063 Return the id of the new event. */
2065 diagnostic_event_id_t
2066 simple_diagnostic_path::add_event (location_t loc
, tree fndecl
, int depth
,
2067 const char *fmt
, ...)
2069 pretty_printer
*pp
= m_event_pp
;
2070 pp_clear_output_area (pp
);
2073 rich_location
rich_loc (line_table
, UNKNOWN_LOCATION
);
2079 ti
.format_spec
= _(fmt
);
2083 ti
.m_richloc
= &rich_loc
;
2085 pp_format (pp
, &ti
);
2086 pp_output_formatted_text (pp
);
2090 simple_diagnostic_event
*new_event
2091 = new simple_diagnostic_event (loc
, fndecl
, depth
, pp_formatted_text (pp
));
2092 m_events
.safe_push (new_event
);
2094 pp_clear_output_area (pp
);
2096 return diagnostic_event_id_t (m_events
.length () - 1);
2099 /* struct simple_diagnostic_event. */
2101 /* simple_diagnostic_event's ctor. */
2103 simple_diagnostic_event::simple_diagnostic_event (location_t loc
,
2107 : m_loc (loc
), m_fndecl (fndecl
), m_depth (depth
), m_desc (xstrdup (desc
))
2111 /* simple_diagnostic_event's dtor. */
2113 simple_diagnostic_event::~simple_diagnostic_event ()
2118 /* Print PATH by emitting a dummy "note" associated with it. */
2121 void debug (diagnostic_path
*path
)
2123 rich_location
richloc (line_table
, UNKNOWN_LOCATION
);
2124 richloc
.set_path (path
);
2125 inform (&richloc
, "debug path");
2128 /* Really call the system 'abort'. This has to go right at the end of
2129 this file, so that there are no functions after it that call abort
2130 and get the system abort instead of our macro. */
2140 namespace selftest
{
2142 /* Helper function for test_print_escaped_string. */
2145 assert_print_escaped_string (const location
&loc
, const char *expected_output
,
2149 print_escaped_string (&pp
, input
);
2150 ASSERT_STREQ_AT (loc
, expected_output
, pp_formatted_text (&pp
));
2153 #define ASSERT_PRINT_ESCAPED_STRING_STREQ(EXPECTED_OUTPUT, INPUT) \
2154 assert_print_escaped_string (SELFTEST_LOCATION, EXPECTED_OUTPUT, INPUT)
2156 /* Tests of print_escaped_string. */
2159 test_print_escaped_string ()
2162 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"\"", "");
2164 /* Non-empty string. */
2165 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"hello world\"", "hello world");
2167 /* Various things that need to be escaped: */
2169 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\\\after\"",
2172 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\tafter\"",
2175 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\nafter\"",
2178 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\\"after\"",
2181 /* Non-printable characters: BEL: '\a': 0x07 */
2182 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\007after\"",
2184 /* Non-printable characters: vertical tab: '\v': 0x0b */
2185 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\013after\"",
2189 /* Tests of print_parseable_fixits. */
2191 /* Verify that print_parseable_fixits emits the empty string if there
2195 test_print_parseable_fixits_none ()
2198 rich_location
richloc (line_table
, UNKNOWN_LOCATION
);
2200 print_parseable_fixits (&pp
, &richloc
, DIAGNOSTICS_COLUMN_UNIT_BYTE
, 8);
2201 ASSERT_STREQ ("", pp_formatted_text (&pp
));
2204 /* Verify that print_parseable_fixits does the right thing if there
2205 is an insertion fixit hint. */
2208 test_print_parseable_fixits_insert ()
2211 rich_location
richloc (line_table
, UNKNOWN_LOCATION
);
2213 linemap_add (line_table
, LC_ENTER
, false, "test.c", 0);
2214 linemap_line_start (line_table
, 5, 100);
2215 linemap_add (line_table
, LC_LEAVE
, false, NULL
, 0);
2216 location_t where
= linemap_position_for_column (line_table
, 10);
2217 richloc
.add_fixit_insert_before (where
, "added content");
2219 print_parseable_fixits (&pp
, &richloc
, DIAGNOSTICS_COLUMN_UNIT_BYTE
, 8);
2220 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:10}:\"added content\"\n",
2221 pp_formatted_text (&pp
));
2224 /* Verify that print_parseable_fixits does the right thing if there
2225 is an removal fixit hint. */
2228 test_print_parseable_fixits_remove ()
2231 rich_location
richloc (line_table
, UNKNOWN_LOCATION
);
2233 linemap_add (line_table
, LC_ENTER
, false, "test.c", 0);
2234 linemap_line_start (line_table
, 5, 100);
2235 linemap_add (line_table
, LC_LEAVE
, false, NULL
, 0);
2237 where
.m_start
= linemap_position_for_column (line_table
, 10);
2238 where
.m_finish
= linemap_position_for_column (line_table
, 20);
2239 richloc
.add_fixit_remove (where
);
2241 print_parseable_fixits (&pp
, &richloc
, DIAGNOSTICS_COLUMN_UNIT_BYTE
, 8);
2242 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:21}:\"\"\n",
2243 pp_formatted_text (&pp
));
2246 /* Verify that print_parseable_fixits does the right thing if there
2247 is an replacement fixit hint. */
2250 test_print_parseable_fixits_replace ()
2253 rich_location
richloc (line_table
, UNKNOWN_LOCATION
);
2255 linemap_add (line_table
, LC_ENTER
, false, "test.c", 0);
2256 linemap_line_start (line_table
, 5, 100);
2257 linemap_add (line_table
, LC_LEAVE
, false, NULL
, 0);
2259 where
.m_start
= linemap_position_for_column (line_table
, 10);
2260 where
.m_finish
= linemap_position_for_column (line_table
, 20);
2261 richloc
.add_fixit_replace (where
, "replacement");
2263 print_parseable_fixits (&pp
, &richloc
, DIAGNOSTICS_COLUMN_UNIT_BYTE
, 8);
2264 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:21}:\"replacement\"\n",
2265 pp_formatted_text (&pp
));
2268 /* Verify that print_parseable_fixits correctly handles
2269 DIAGNOSTICS_COLUMN_UNIT_BYTE vs DIAGNOSTICS_COLUMN_UNIT_COLUMN. */
2272 test_print_parseable_fixits_bytes_vs_display_columns ()
2274 line_table_test ltt
;
2275 rich_location
richloc (line_table
, UNKNOWN_LOCATION
);
2277 /* 1-based byte offsets: 12345677778888999900001234567. */
2278 const char *const content
= "smile \xf0\x9f\x98\x82 colour\n";
2279 /* 1-based display cols: 123456[......7-8.....]9012345. */
2280 const int tabstop
= 8;
2282 temp_source_file
tmp (SELFTEST_LOCATION
, ".c", content
);
2283 const char *const fname
= tmp
.get_filename ();
2285 linemap_add (line_table
, LC_ENTER
, false, fname
, 0);
2286 linemap_line_start (line_table
, 1, 100);
2287 linemap_add (line_table
, LC_LEAVE
, false, NULL
, 0);
2289 where
.m_start
= linemap_position_for_column (line_table
, 12);
2290 where
.m_finish
= linemap_position_for_column (line_table
, 17);
2291 richloc
.add_fixit_replace (where
, "color");
2294 pretty_printer tmp_pp
;
2295 print_escaped_string (&tmp_pp
, fname
);
2296 char *escaped_fname
= xstrdup (pp_formatted_text (&tmp_pp
));
2298 const int buf_len
= strlen (escaped_fname
) + 100;
2299 char *const expected
= XNEWVEC (char, buf_len
);
2303 print_parseable_fixits (&pp
, &richloc
, DIAGNOSTICS_COLUMN_UNIT_BYTE
,
2305 snprintf (expected
, buf_len
,
2306 "fix-it:%s:{1:12-1:18}:\"color\"\n", escaped_fname
);
2307 ASSERT_STREQ (expected
, pp_formatted_text (&pp
));
2311 print_parseable_fixits (&pp
, &richloc
, DIAGNOSTICS_COLUMN_UNIT_DISPLAY
,
2313 snprintf (expected
, buf_len
,
2314 "fix-it:%s:{1:10-1:16}:\"color\"\n", escaped_fname
);
2315 ASSERT_STREQ (expected
, pp_formatted_text (&pp
));
2318 XDELETEVEC (expected
);
2319 free (escaped_fname
);
2323 diagnostic_get_location_text (..., SHOW_COLUMN)
2324 generates EXPECTED_LOC_TEXT, given FILENAME, LINE, COLUMN, with
2325 colorization disabled. */
2328 assert_location_text (const char *expected_loc_text
,
2329 const char *filename
, int line
, int column
,
2332 enum diagnostics_column_unit column_unit
2333 = DIAGNOSTICS_COLUMN_UNIT_BYTE
)
2335 test_diagnostic_context dc
;
2336 dc
.show_column
= show_column
;
2337 dc
.column_unit
= column_unit
;
2338 dc
.column_origin
= origin
;
2340 expanded_location xloc
;
2341 xloc
.file
= filename
;
2343 xloc
.column
= column
;
2347 char *actual_loc_text
= diagnostic_get_location_text (&dc
, xloc
);
2348 ASSERT_STREQ (expected_loc_text
, actual_loc_text
);
2349 free (actual_loc_text
);
2352 /* Verify that diagnostic_get_location_text works as expected. */
2355 test_diagnostic_get_location_text ()
2357 const char *old_progname
= progname
;
2358 progname
= "PROGNAME";
2359 assert_location_text ("PROGNAME:", NULL
, 0, 0, true);
2360 assert_location_text ("<built-in>:", "<built-in>", 42, 10, true);
2361 assert_location_text ("foo.c:42:10:", "foo.c", 42, 10, true);
2362 assert_location_text ("foo.c:42:9:", "foo.c", 42, 10, true, 0);
2363 assert_location_text ("foo.c:42:1010:", "foo.c", 42, 10, true, 1001);
2364 for (int origin
= 0; origin
!= 2; ++origin
)
2365 assert_location_text ("foo.c:42:", "foo.c", 42, 0, true, origin
);
2366 assert_location_text ("foo.c:", "foo.c", 0, 10, true);
2367 assert_location_text ("foo.c:42:", "foo.c", 42, 10, false);
2368 assert_location_text ("foo.c:", "foo.c", 0, 10, false);
2370 maybe_line_and_column (INT_MAX
, INT_MAX
);
2371 maybe_line_and_column (INT_MIN
, INT_MIN
);
2374 /* In order to test display columns vs byte columns, we need to create a
2375 file for location_get_source_line() to read. */
2377 const char *const content
= "smile \xf0\x9f\x98\x82\n";
2378 const int line_bytes
= strlen (content
) - 1;
2379 const int def_tabstop
= 8;
2380 const cpp_char_column_policy
policy (def_tabstop
, cpp_wcwidth
);
2381 const int display_width
= cpp_display_width (content
, line_bytes
, policy
);
2382 ASSERT_EQ (line_bytes
- 2, display_width
);
2383 temp_source_file
tmp (SELFTEST_LOCATION
, ".c", content
);
2384 const char *const fname
= tmp
.get_filename ();
2385 const int buf_len
= strlen (fname
) + 16;
2386 char *const expected
= XNEWVEC (char, buf_len
);
2388 snprintf (expected
, buf_len
, "%s:1:%d:", fname
, line_bytes
);
2389 assert_location_text (expected
, fname
, 1, line_bytes
, true,
2390 1, DIAGNOSTICS_COLUMN_UNIT_BYTE
);
2392 snprintf (expected
, buf_len
, "%s:1:%d:", fname
, line_bytes
- 1);
2393 assert_location_text (expected
, fname
, 1, line_bytes
, true,
2394 0, DIAGNOSTICS_COLUMN_UNIT_BYTE
);
2396 snprintf (expected
, buf_len
, "%s:1:%d:", fname
, display_width
);
2397 assert_location_text (expected
, fname
, 1, line_bytes
, true,
2398 1, DIAGNOSTICS_COLUMN_UNIT_DISPLAY
);
2400 snprintf (expected
, buf_len
, "%s:1:%d:", fname
, display_width
- 1);
2401 assert_location_text (expected
, fname
, 1, line_bytes
, true,
2402 0, DIAGNOSTICS_COLUMN_UNIT_DISPLAY
);
2404 XDELETEVEC (expected
);
2408 progname
= old_progname
;
2411 /* Selftest for num_digits. */
2416 ASSERT_EQ (1, num_digits (0));
2417 ASSERT_EQ (1, num_digits (9));
2418 ASSERT_EQ (2, num_digits (10));
2419 ASSERT_EQ (2, num_digits (99));
2420 ASSERT_EQ (3, num_digits (100));
2421 ASSERT_EQ (3, num_digits (999));
2422 ASSERT_EQ (4, num_digits (1000));
2423 ASSERT_EQ (4, num_digits (9999));
2424 ASSERT_EQ (5, num_digits (10000));
2425 ASSERT_EQ (5, num_digits (99999));
2426 ASSERT_EQ (6, num_digits (100000));
2427 ASSERT_EQ (6, num_digits (999999));
2428 ASSERT_EQ (7, num_digits (1000000));
2429 ASSERT_EQ (7, num_digits (9999999));
2430 ASSERT_EQ (8, num_digits (10000000));
2431 ASSERT_EQ (8, num_digits (99999999));
2434 /* Run all of the selftests within this file. */
2437 diagnostic_c_tests ()
2439 test_print_escaped_string ();
2440 test_print_parseable_fixits_none ();
2441 test_print_parseable_fixits_insert ();
2442 test_print_parseable_fixits_remove ();
2443 test_print_parseable_fixits_replace ();
2444 test_print_parseable_fixits_bytes_vs_display_columns ();
2445 test_diagnostic_get_location_text ();
2450 } // namespace selftest
2452 #endif /* #if CHECKING_P */
2455 # pragma GCC diagnostic pop