]>
Commit | Line | Data |
---|---|---|
25e2ffe1 | 1 | /* Language-independent diagnostic subroutines for the GNU Compiler Collection |
f1717362 | 2 | Copyright (C) 1999-2016 Free Software Foundation, Inc. |
dfac2e0f | 3 | Contributed by Gabriel Dos Reis <gdr@codesourcery.com> |
076f8fe1 | 4 | |
f12b58b3 | 5 | This file is part of GCC. |
076f8fe1 | 6 | |
f12b58b3 | 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 | |
8c4c00c1 | 9 | Software Foundation; either version 3, or (at your option) any later |
f12b58b3 | 10 | version. |
076f8fe1 | 11 | |
f12b58b3 | 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 | |
15 | for more details. | |
076f8fe1 | 16 | |
17 | You should have received a copy of the GNU General Public License | |
8c4c00c1 | 18 | along with GCC; see the file COPYING3. If not see |
19 | <http://www.gnu.org/licenses/>. */ | |
076f8fe1 | 20 | |
21 | ||
9588521d | 22 | /* This file implements the language independent aspect of diagnostic |
076f8fe1 | 23 | message module. */ |
24 | ||
25 | #include "config.h" | |
076f8fe1 | 26 | #include "system.h" |
805e22b2 | 27 | #include "coretypes.h" |
af225e7d | 28 | #include "version.h" |
3f425711 | 29 | #include "demangle.h" |
076f8fe1 | 30 | #include "intl.h" |
3f425711 | 31 | #include "backtrace.h" |
993ca5a5 | 32 | #include "diagnostic.h" |
41609f8b | 33 | #include "diagnostic-color.h" |
076f8fe1 | 34 | |
de96a063 | 35 | #ifdef HAVE_TERMIOS_H |
36 | # include <termios.h> | |
37 | #endif | |
38 | ||
39 | #ifdef GWINSZ_IN_SYS_IOCTL | |
40 | # include <sys/ioctl.h> | |
41 | #endif | |
42 | ||
2c2efebb | 43 | #define pedantic_warning_kind(DC) \ |
44 | ((DC)->pedantic_errors ? DK_ERROR : DK_WARNING) | |
45 | #define permissive_error_kind(DC) ((DC)->permissive ? DK_WARNING : DK_ERROR) | |
3c6a9715 | 46 | #define permissive_error_option(DC) ((DC)->opt_permissive) |
d252af3e | 47 | |
6312a35e | 48 | /* Prototypes. */ |
d598ad0d | 49 | static void error_recursion (diagnostic_context *) ATTRIBUTE_NORETURN; |
43404f28 | 50 | |
d598ad0d | 51 | static void real_abort (void) ATTRIBUTE_NORETURN; |
19fafbd3 | 52 | |
852f689e | 53 | /* Name of program invoked, sans directories. */ |
54 | ||
55 | const char *progname; | |
56 | ||
ce601f29 | 57 | /* A diagnostic_context surrogate for stderr. */ |
58 | static diagnostic_context global_diagnostic_context; | |
59 | diagnostic_context *global_dc = &global_diagnostic_context; | |
076f8fe1 | 60 | \f |
2faf8f38 | 61 | /* Return a malloc'd string containing MSG formatted a la printf. The |
62 | caller is responsible for freeing the memory. */ | |
dc8078a3 | 63 | char * |
ee582a61 | 64 | build_message_string (const char *msg, ...) |
104d5c0c | 65 | { |
2f5d30d9 | 66 | char *str; |
ee582a61 | 67 | va_list ap; |
104d5c0c | 68 | |
ee582a61 | 69 | va_start (ap, msg); |
5e9ac72e | 70 | str = xvasprintf (msg, ap); |
ee582a61 | 71 | va_end (ap); |
104d5c0c | 72 | |
73 | return str; | |
74 | } | |
75 | ||
d716ce75 | 76 | /* Same as diagnostic_build_prefix, but only the source FILE is given. */ |
b9995fca | 77 | char * |
2cafe211 | 78 | file_name_as_prefix (diagnostic_context *context, const char *f) |
b9995fca | 79 | { |
2cafe211 | 80 | const char *locus_cs |
81 | = colorize_start (pp_show_color (context->printer), "locus"); | |
82 | const char *locus_ce = colorize_stop (pp_show_color (context->printer)); | |
83 | return build_message_string ("%s%s:%s ", locus_cs, f, locus_ce); | |
b9995fca | 84 | } |
85 | ||
25e2ffe1 | 86 | |
076f8fe1 | 87 | \f |
5a983084 | 88 | /* Return the value of the getenv("COLUMNS") as an integer. If the |
de96a063 | 89 | value is not set to a positive integer, use ioctl to get the |
90 | terminal width. If it fails, return INT_MAX. */ | |
91 | int | |
92 | get_terminal_width (void) | |
5a983084 | 93 | { |
94 | const char * s = getenv ("COLUMNS"); | |
95 | if (s != NULL) { | |
96 | int n = atoi (s); | |
97 | if (n > 0) | |
98 | return n; | |
99 | } | |
de96a063 | 100 | |
101 | #ifdef TIOCGWINSZ | |
102 | struct winsize w; | |
103 | w.ws_col = 0; | |
104 | if (ioctl (0, TIOCGWINSZ, &w) == 0 && w.ws_col > 0) | |
105 | return w.ws_col; | |
106 | #endif | |
107 | ||
5a983084 | 108 | return INT_MAX; |
109 | } | |
110 | ||
111 | /* Set caret_max_width to value. */ | |
112 | void | |
113 | diagnostic_set_caret_max_width (diagnostic_context *context, int value) | |
114 | { | |
115 | /* One minus to account for the leading empty space. */ | |
116 | value = value ? value - 1 | |
6f07f480 | 117 | : (isatty (fileno (pp_buffer (context->printer)->stream)) |
de96a063 | 118 | ? get_terminal_width () - 1: INT_MAX); |
5a983084 | 119 | |
120 | if (value <= 0) | |
121 | value = INT_MAX; | |
122 | ||
123 | context->caret_max_width = value; | |
124 | } | |
125 | ||
25e2ffe1 | 126 | /* Initialize the diagnostic message outputting machinery. */ |
127 | void | |
3c6a9715 | 128 | diagnostic_initialize (diagnostic_context *context, int n_opts) |
25e2ffe1 | 129 | { |
3c6a9715 | 130 | int i; |
131 | ||
aa6db498 | 132 | /* Allocate a basic pretty-printer. Clients will replace this a |
133 | much more elaborated pretty-printer if they wish. */ | |
4c36ffe6 | 134 | context->printer = XNEW (pretty_printer); |
eed6bc21 | 135 | new (context->printer) pretty_printer (); |
25e2ffe1 | 136 | |
aa6db498 | 137 | memset (context->diagnostic_count, 0, sizeof context->diagnostic_count); |
096f40ca | 138 | context->warning_as_error_requested = false; |
3c6a9715 | 139 | context->n_opts = n_opts; |
140 | context->classify_diagnostic = XNEWVEC (diagnostic_t, n_opts); | |
141 | for (i = 0; i < n_opts; i++) | |
142 | context->classify_diagnostic[i] = DK_UNSPECIFIED; | |
5a983084 | 143 | context->show_caret = false; |
144 | diagnostic_set_caret_max_width (context, pp_line_cutoff (context->printer)); | |
f0479000 | 145 | for (i = 0; i < rich_location::MAX_RANGES; i++) |
389a9009 | 146 | context->caret_chars[i] = '^'; |
b0932b2f | 147 | context->show_option_requested = false; |
aa6db498 | 148 | context->abort_on_error = false; |
3c6a9715 | 149 | context->show_column = false; |
150 | context->pedantic_errors = false; | |
151 | context->permissive = false; | |
152 | context->opt_permissive = 0; | |
153 | context->fatal_errors = false; | |
5ae82d58 | 154 | context->dc_inhibit_warnings = false; |
155 | context->dc_warn_system_headers = false; | |
566d7c74 | 156 | context->max_errors = 0; |
aa6db498 | 157 | context->internal_error = NULL; |
25e2ffe1 | 158 | diagnostic_starter (context) = default_diagnostic_starter; |
aec1f4bd | 159 | context->start_span = default_diagnostic_start_span_fn; |
25e2ffe1 | 160 | diagnostic_finalizer (context) = default_diagnostic_finalizer; |
3c6a9715 | 161 | context->option_enabled = NULL; |
2c5d2e39 | 162 | context->option_state = NULL; |
3c6a9715 | 163 | context->option_name = NULL; |
d834564a | 164 | context->last_location = UNKNOWN_LOCATION; |
aa6db498 | 165 | context->last_module = 0; |
ce084dfc | 166 | context->x_data = NULL; |
aa6db498 | 167 | context->lock = 0; |
16b4d5bb | 168 | context->inhibit_notes_p = false; |
25e2ffe1 | 169 | } |
170 | ||
9b11544d | 171 | /* Maybe initialize the color support. We require clients to do this |
172 | explicitly, since most clients don't want color. When called | |
173 | without a VALUE, it initializes with DIAGNOSTICS_COLOR_DEFAULT. */ | |
174 | ||
175 | void | |
176 | diagnostic_color_init (diagnostic_context *context, int value /*= -1 */) | |
177 | { | |
178 | /* value == -1 is the default value. */ | |
179 | if (value < 0) | |
180 | { | |
181 | /* If DIAGNOSTICS_COLOR_DEFAULT is -1, default to | |
182 | -fdiagnostics-color=auto if GCC_COLORS is in the environment, | |
183 | otherwise default to -fdiagnostics-color=never, for other | |
184 | values default to that | |
185 | -fdiagnostics-color={never,auto,always}. */ | |
186 | if (DIAGNOSTICS_COLOR_DEFAULT == -1) | |
187 | { | |
188 | if (!getenv ("GCC_COLORS")) | |
189 | return; | |
190 | value = DIAGNOSTICS_COLOR_AUTO; | |
191 | } | |
192 | else | |
193 | value = DIAGNOSTICS_COLOR_DEFAULT; | |
194 | } | |
195 | pp_show_color (context->printer) | |
196 | = colorize_init ((diagnostic_color_rule_t) value); | |
197 | } | |
198 | ||
543725f3 | 199 | /* Do any cleaning up required after the last diagnostic is emitted. */ |
200 | ||
201 | void | |
202 | diagnostic_finish (diagnostic_context *context) | |
203 | { | |
204 | /* Some of the errors may actually have been warnings. */ | |
5e6392e8 | 205 | if (diagnostic_kind_count (context, DK_WERROR)) |
543725f3 | 206 | { |
207 | /* -Werror was given. */ | |
208 | if (context->warning_as_error_requested) | |
209 | pp_verbatim (context->printer, | |
00c00a40 | 210 | _("%s: all warnings being treated as errors"), |
543725f3 | 211 | progname); |
212 | /* At least one -Werror= was given. */ | |
213 | else | |
214 | pp_verbatim (context->printer, | |
00c00a40 | 215 | _("%s: some warnings being treated as errors"), |
543725f3 | 216 | progname); |
5f7f600e | 217 | pp_newline_and_flush (context->printer); |
543725f3 | 218 | } |
ffc2c526 | 219 | |
220 | diagnostic_file_cache_fini (); | |
415309e2 | 221 | |
222 | XDELETEVEC (context->classify_diagnostic); | |
223 | context->classify_diagnostic = NULL; | |
224 | ||
225 | /* diagnostic_initialize allocates context->printer using XNEW | |
226 | and placement-new. */ | |
227 | context->printer->~pretty_printer (); | |
228 | XDELETE (context->printer); | |
229 | context->printer = NULL; | |
543725f3 | 230 | } |
231 | ||
eb0d20b7 | 232 | /* Initialize DIAGNOSTIC, where the message MSG has already been |
233 | translated. */ | |
25e2ffe1 | 234 | void |
eb0d20b7 | 235 | diagnostic_set_info_translated (diagnostic_info *diagnostic, const char *msg, |
f0479000 | 236 | va_list *args, rich_location *richloc, |
eb0d20b7 | 237 | diagnostic_t kind) |
25e2ffe1 | 238 | { |
f0479000 | 239 | gcc_assert (richloc); |
d07c9932 | 240 | diagnostic->message.err_no = errno; |
25e2ffe1 | 241 | diagnostic->message.args_ptr = args; |
eb0d20b7 | 242 | diagnostic->message.format_spec = msg; |
f0479000 | 243 | diagnostic->message.m_richloc = richloc; |
244 | diagnostic->richloc = richloc; | |
25e2ffe1 | 245 | diagnostic->kind = kind; |
efb9d9ee | 246 | diagnostic->option_index = 0; |
25e2ffe1 | 247 | } |
248 | ||
eb0d20b7 | 249 | /* Initialize DIAGNOSTIC, where the message GMSGID has not yet been |
250 | translated. */ | |
251 | void | |
252 | diagnostic_set_info (diagnostic_info *diagnostic, const char *gmsgid, | |
f0479000 | 253 | va_list *args, rich_location *richloc, |
eb0d20b7 | 254 | diagnostic_t kind) |
255 | { | |
f0479000 | 256 | gcc_assert (richloc); |
257 | diagnostic_set_info_translated (diagnostic, _(gmsgid), args, richloc, kind); | |
258 | } | |
259 | ||
260 | static const char *const diagnostic_kind_color[] = { | |
261 | #define DEFINE_DIAGNOSTIC_KIND(K, T, C) (C), | |
262 | #include "diagnostic.def" | |
263 | #undef DEFINE_DIAGNOSTIC_KIND | |
264 | NULL | |
265 | }; | |
266 | ||
267 | /* Get a color name for diagnostics of type KIND | |
268 | Result could be NULL. */ | |
269 | ||
270 | const char * | |
271 | diagnostic_get_color_for_kind (diagnostic_t kind) | |
272 | { | |
273 | return diagnostic_kind_color[kind]; | |
eb0d20b7 | 274 | } |
275 | ||
aec1f4bd | 276 | /* Return a malloc'd string describing a location e.g. "foo.c:42:10". |
277 | The caller is responsible for freeing the memory. */ | |
278 | ||
279 | static char * | |
280 | diagnostic_get_location_text (diagnostic_context *context, | |
281 | expanded_location s) | |
282 | { | |
283 | pretty_printer *pp = context->printer; | |
284 | const char *locus_cs = colorize_start (pp_show_color (pp), "locus"); | |
285 | const char *locus_ce = colorize_stop (pp_show_color (pp)); | |
286 | ||
287 | if (s.file == NULL) | |
288 | return build_message_string ("%s%s:%s", locus_cs, progname, locus_ce); | |
289 | ||
290 | if (!strcmp (s.file, N_("<built-in>"))) | |
291 | return build_message_string ("%s%s:%s", locus_cs, s.file, locus_ce); | |
292 | ||
293 | if (context->show_column) | |
294 | return build_message_string ("%s%s:%d:%d:%s", locus_cs, s.file, s.line, | |
295 | s.column, locus_ce); | |
296 | else | |
297 | return build_message_string ("%s%s:%d:%s", locus_cs, s.file, s.line, | |
298 | locus_ce); | |
299 | } | |
300 | ||
301 | /* Return a malloc'd string describing a location and the severity of the | |
302 | diagnostic, e.g. "foo.c:42:10: error: ". The caller is responsible for | |
303 | freeing the memory. */ | |
25e2ffe1 | 304 | char * |
2c2efebb | 305 | diagnostic_build_prefix (diagnostic_context *context, |
ff213692 | 306 | const diagnostic_info *diagnostic) |
25e2ffe1 | 307 | { |
11a6a4d0 | 308 | static const char *const diagnostic_kind_text[] = { |
41609f8b | 309 | #define DEFINE_DIAGNOSTIC_KIND(K, T, C) (T), |
479f88cd | 310 | #include "diagnostic.def" |
311 | #undef DEFINE_DIAGNOSTIC_KIND | |
312 | "must-not-happen" | |
313 | }; | |
aa47f95a | 314 | gcc_assert (diagnostic->kind < DK_LAST_DIAGNOSTIC_KIND); |
315 | ||
5cf56417 | 316 | const char *text = _(diagnostic_kind_text[diagnostic->kind]); |
41609f8b | 317 | const char *text_cs = "", *text_ce = ""; |
41609f8b | 318 | pretty_printer *pp = context->printer; |
319 | ||
320 | if (diagnostic_kind_color[diagnostic->kind]) | |
321 | { | |
322 | text_cs = colorize_start (pp_show_color (pp), | |
323 | diagnostic_kind_color[diagnostic->kind]); | |
324 | text_ce = colorize_stop (pp_show_color (pp)); | |
325 | } | |
41609f8b | 326 | |
aa47f95a | 327 | expanded_location s = diagnostic_expand_location (diagnostic); |
aec1f4bd | 328 | char *location_text = diagnostic_get_location_text (context, s); |
329 | ||
330 | char *result = build_message_string ("%s %s%s%s", location_text, | |
331 | text_cs, text, text_ce); | |
332 | free (location_text); | |
333 | return result; | |
25e2ffe1 | 334 | } |
335 | ||
3f425711 | 336 | /* Functions at which to stop the backtrace print. It's not |
337 | particularly helpful to print the callers of these functions. */ | |
338 | ||
339 | static const char * const bt_stop[] = | |
340 | { | |
341 | "main", | |
415309e2 | 342 | "toplev::main", |
3f425711 | 343 | "execute_one_pass", |
344 | "compile_file", | |
345 | }; | |
346 | ||
347 | /* A callback function passed to the backtrace_full function. */ | |
348 | ||
349 | static int | |
350 | bt_callback (void *data, uintptr_t pc, const char *filename, int lineno, | |
351 | const char *function) | |
352 | { | |
353 | int *pcount = (int *) data; | |
354 | ||
355 | /* If we don't have any useful information, don't print | |
356 | anything. */ | |
357 | if (filename == NULL && function == NULL) | |
358 | return 0; | |
359 | ||
360 | /* Skip functions in diagnostic.c. */ | |
361 | if (*pcount == 0 | |
362 | && filename != NULL | |
9af5ce0c | 363 | && strcmp (lbasename (filename), "diagnostic.c") == 0) |
3f425711 | 364 | return 0; |
365 | ||
366 | /* Print up to 20 functions. We could make this a --param, but | |
367 | since this is only for debugging just use a constant for now. */ | |
368 | if (*pcount >= 20) | |
369 | { | |
370 | /* Returning a non-zero value stops the backtrace. */ | |
371 | return 1; | |
372 | } | |
373 | ++*pcount; | |
374 | ||
375 | char *alc = NULL; | |
376 | if (function != NULL) | |
377 | { | |
378 | char *str = cplus_demangle_v3 (function, | |
379 | (DMGL_VERBOSE | DMGL_ANSI | |
380 | | DMGL_GNU_V3 | DMGL_PARAMS)); | |
381 | if (str != NULL) | |
382 | { | |
383 | alc = str; | |
384 | function = str; | |
385 | } | |
386 | ||
387 | for (size_t i = 0; i < ARRAY_SIZE (bt_stop); ++i) | |
388 | { | |
389 | size_t len = strlen (bt_stop[i]); | |
390 | if (strncmp (function, bt_stop[i], len) == 0 | |
391 | && (function[len] == '\0' || function[len] == '(')) | |
392 | { | |
393 | if (alc != NULL) | |
394 | free (alc); | |
395 | /* Returning a non-zero value stops the backtrace. */ | |
396 | return 1; | |
397 | } | |
398 | } | |
399 | } | |
400 | ||
401 | fprintf (stderr, "0x%lx %s\n\t%s:%d\n", | |
7de0a5e4 | 402 | (unsigned long) pc, |
3f425711 | 403 | function == NULL ? "???" : function, |
404 | filename == NULL ? "???" : filename, | |
405 | lineno); | |
406 | ||
407 | if (alc != NULL) | |
408 | free (alc); | |
409 | ||
410 | return 0; | |
411 | } | |
412 | ||
413 | /* A callback function passed to the backtrace_full function. This is | |
414 | called if backtrace_full has an error. */ | |
415 | ||
416 | static void | |
417 | bt_err_callback (void *data ATTRIBUTE_UNUSED, const char *msg, int errnum) | |
418 | { | |
419 | if (errnum < 0) | |
420 | { | |
421 | /* This means that no debug info was available. Just quietly | |
422 | skip printing backtrace info. */ | |
423 | return; | |
424 | } | |
425 | fprintf (stderr, "%s%s%s\n", msg, errnum == 0 ? "" : ": ", | |
426 | errnum == 0 ? "" : xstrerror (errnum)); | |
427 | } | |
428 | ||
78323b05 | 429 | /* Take any action which is expected to happen after the diagnostic |
430 | is written out. This function does not always return. */ | |
716da296 | 431 | void |
d598ad0d | 432 | diagnostic_action_after_output (diagnostic_context *context, |
716da296 | 433 | diagnostic_t diag_kind) |
78323b05 | 434 | { |
716da296 | 435 | switch (diag_kind) |
78323b05 | 436 | { |
437 | case DK_DEBUG: | |
438 | case DK_NOTE: | |
439 | case DK_ANACHRONISM: | |
440 | case DK_WARNING: | |
441 | break; | |
442 | ||
443 | case DK_ERROR: | |
444 | case DK_SORRY: | |
445 | if (context->abort_on_error) | |
446 | real_abort (); | |
2c2efebb | 447 | if (context->fatal_errors) |
295acf4f | 448 | { |
449 | fnotice (stderr, "compilation terminated due to -Wfatal-errors.\n"); | |
543725f3 | 450 | diagnostic_finish (context); |
295acf4f | 451 | exit (FATAL_EXIT_CODE); |
452 | } | |
566d7c74 | 453 | if (context->max_errors != 0 |
454 | && ((unsigned) (diagnostic_kind_count (context, DK_ERROR) | |
716da296 | 455 | + diagnostic_kind_count (context, DK_SORRY) |
456 | + diagnostic_kind_count (context, DK_WERROR)) | |
566d7c74 | 457 | >= context->max_errors)) |
458 | { | |
459 | fnotice (stderr, | |
460 | "compilation terminated due to -fmax-errors=%u.\n", | |
461 | context->max_errors); | |
462 | diagnostic_finish (context); | |
463 | exit (FATAL_EXIT_CODE); | |
464 | } | |
78323b05 | 465 | break; |
466 | ||
467 | case DK_ICE: | |
9d7131bf | 468 | case DK_ICE_NOBT: |
3f425711 | 469 | { |
9d7131bf | 470 | struct backtrace_state *state = NULL; |
471 | if (diag_kind == DK_ICE) | |
472 | state = backtrace_create_state (NULL, 0, bt_err_callback, NULL); | |
3f425711 | 473 | int count = 0; |
474 | if (state != NULL) | |
475 | backtrace_full (state, 2, bt_callback, bt_err_callback, | |
476 | (void *) &count); | |
477 | ||
478 | if (context->abort_on_error) | |
479 | real_abort (); | |
480 | ||
481 | fnotice (stderr, "Please submit a full bug report,\n" | |
482 | "with preprocessed source if appropriate.\n"); | |
483 | if (count > 0) | |
484 | fnotice (stderr, | |
485 | ("Please include the complete backtrace " | |
486 | "with any bug report.\n")); | |
487 | fnotice (stderr, "See %s for instructions.\n", bug_report_url); | |
78323b05 | 488 | |
3f425711 | 489 | exit (ICE_EXIT_CODE); |
490 | } | |
78323b05 | 491 | |
492 | case DK_FATAL: | |
493 | if (context->abort_on_error) | |
494 | real_abort (); | |
543725f3 | 495 | diagnostic_finish (context); |
78323b05 | 496 | fnotice (stderr, "compilation terminated.\n"); |
497 | exit (FATAL_EXIT_CODE); | |
498 | ||
499 | default: | |
583fa9e0 | 500 | gcc_unreachable (); |
78323b05 | 501 | } |
502 | } | |
503 | ||
076f8fe1 | 504 | void |
3de02a0f | 505 | diagnostic_report_current_module (diagnostic_context *context, location_t where) |
076f8fe1 | 506 | { |
551e34da | 507 | const line_map_ordinary *map = NULL; |
076f8fe1 | 508 | |
aa6db498 | 509 | if (pp_needs_newline (context->printer)) |
2faf8f38 | 510 | { |
aa6db498 | 511 | pp_newline (context->printer); |
512 | pp_needs_newline (context->printer) = false; | |
2faf8f38 | 513 | } |
076f8fe1 | 514 | |
3de02a0f | 515 | if (where <= BUILTINS_LOCATION) |
26cb3d1c | 516 | return; |
517 | ||
3de02a0f | 518 | linemap_resolve_location (line_table, where, |
519 | LRK_MACRO_DEFINITION_LOCATION, | |
520 | &map); | |
521 | ||
26cb3d1c | 522 | if (map && diagnostic_last_module_changed (context, map)) |
2faf8f38 | 523 | { |
26cb3d1c | 524 | diagnostic_set_last_module (context, map); |
525 | if (! MAIN_FILE_P (map)) | |
7bd3dcc4 | 526 | { |
26cb3d1c | 527 | map = INCLUDED_FROM (line_table, map); |
2c2efebb | 528 | if (context->show_column) |
b559b9e2 | 529 | pp_verbatim (context->printer, |
721cebe6 | 530 | "In file included from %r%s:%d:%d%R", "locus", |
97bfb9ef | 531 | LINEMAP_FILE (map), |
b559b9e2 | 532 | LAST_SOURCE_LINE (map), LAST_SOURCE_COLUMN (map)); |
533 | else | |
534 | pp_verbatim (context->printer, | |
721cebe6 | 535 | "In file included from %r%s:%d%R", "locus", |
97bfb9ef | 536 | LINEMAP_FILE (map), LAST_SOURCE_LINE (map)); |
26cb3d1c | 537 | while (! MAIN_FILE_P (map)) |
538 | { | |
539 | map = INCLUDED_FROM (line_table, map); | |
540 | pp_verbatim (context->printer, | |
721cebe6 | 541 | ",\n from %r%s:%d%R", "locus", |
97bfb9ef | 542 | LINEMAP_FILE (map), LAST_SOURCE_LINE (map)); |
26cb3d1c | 543 | } |
544 | pp_verbatim (context->printer, ":"); | |
545 | pp_newline (context->printer); | |
7bd3dcc4 | 546 | } |
2faf8f38 | 547 | } |
548 | } | |
f060a027 | 549 | |
34e5cced | 550 | void |
d598ad0d | 551 | default_diagnostic_starter (diagnostic_context *context, |
552 | diagnostic_info *diagnostic) | |
076f8fe1 | 553 | { |
389a9009 | 554 | diagnostic_report_current_module (context, diagnostic_location (diagnostic)); |
2c2efebb | 555 | pp_set_prefix (context->printer, diagnostic_build_prefix (context, |
556 | diagnostic)); | |
2faf8f38 | 557 | } |
076f8fe1 | 558 | |
aec1f4bd | 559 | void |
560 | default_diagnostic_start_span_fn (diagnostic_context *context, | |
561 | expanded_location exploc) | |
562 | { | |
563 | pp_set_prefix (context->printer, | |
564 | diagnostic_get_location_text (context, exploc)); | |
565 | pp_string (context->printer, ""); | |
566 | pp_newline (context->printer); | |
567 | } | |
568 | ||
34e5cced | 569 | void |
399d4f80 | 570 | default_diagnostic_finalizer (diagnostic_context *context, |
571 | diagnostic_info *diagnostic) | |
2faf8f38 | 572 | { |
399d4f80 | 573 | diagnostic_show_locus (context, diagnostic); |
574 | pp_destroy_prefix (context->printer); | |
3752e5b1 | 575 | pp_flush (context->printer); |
076f8fe1 | 576 | } |
577 | ||
76f02516 | 578 | /* Interface to specify diagnostic kind overrides. Returns the |
579 | previous setting, or DK_UNSPECIFIED if the parameters are out of | |
af776050 | 580 | range. If OPTION_INDEX is zero, the new setting is for all the |
581 | diagnostics. */ | |
76f02516 | 582 | diagnostic_t |
583 | diagnostic_classify_diagnostic (diagnostic_context *context, | |
584 | int option_index, | |
0955be65 | 585 | diagnostic_t new_kind, |
586 | location_t where) | |
76f02516 | 587 | { |
588 | diagnostic_t old_kind; | |
589 | ||
af776050 | 590 | if (option_index < 0 |
3c6a9715 | 591 | || option_index >= context->n_opts |
76f02516 | 592 | || new_kind >= DK_LAST_DIAGNOSTIC_KIND) |
593 | return DK_UNSPECIFIED; | |
594 | ||
595 | old_kind = context->classify_diagnostic[option_index]; | |
0955be65 | 596 | |
597 | /* Handle pragmas separately, since we need to keep track of *where* | |
598 | the pragmas were. */ | |
599 | if (where != UNKNOWN_LOCATION) | |
600 | { | |
601 | int i; | |
602 | ||
e472ce46 | 603 | /* Record the command-line status, so we can reset it back on DK_POP. */ |
604 | if (old_kind == DK_UNSPECIFIED) | |
605 | { | |
0a489f51 | 606 | old_kind = !context->option_enabled (option_index, |
607 | context->option_state) | |
608 | ? DK_IGNORED : (context->warning_as_error_requested | |
609 | ? DK_ERROR : DK_WARNING); | |
e472ce46 | 610 | context->classify_diagnostic[option_index] = old_kind; |
611 | } | |
612 | ||
0955be65 | 613 | for (i = context->n_classification_history - 1; i >= 0; i --) |
614 | if (context->classification_history[i].option == option_index) | |
615 | { | |
616 | old_kind = context->classification_history[i].kind; | |
617 | break; | |
618 | } | |
619 | ||
620 | i = context->n_classification_history; | |
621 | context->classification_history = | |
622 | (diagnostic_classification_change_t *) xrealloc (context->classification_history, (i + 1) | |
623 | * sizeof (diagnostic_classification_change_t)); | |
624 | context->classification_history[i].location = where; | |
625 | context->classification_history[i].option = option_index; | |
626 | context->classification_history[i].kind = new_kind; | |
627 | context->n_classification_history ++; | |
628 | } | |
629 | else | |
630 | context->classify_diagnostic[option_index] = new_kind; | |
631 | ||
76f02516 | 632 | return old_kind; |
633 | } | |
634 | ||
0955be65 | 635 | /* Save all diagnostic classifications in a stack. */ |
636 | void | |
637 | diagnostic_push_diagnostics (diagnostic_context *context, location_t where ATTRIBUTE_UNUSED) | |
638 | { | |
639 | context->push_list = (int *) xrealloc (context->push_list, (context->n_push + 1) * sizeof (int)); | |
640 | context->push_list[context->n_push ++] = context->n_classification_history; | |
641 | } | |
642 | ||
643 | /* Restore the topmost classification set off the stack. If the stack | |
644 | is empty, revert to the state based on command line parameters. */ | |
645 | void | |
646 | diagnostic_pop_diagnostics (diagnostic_context *context, location_t where) | |
647 | { | |
648 | int jump_to; | |
649 | int i; | |
650 | ||
651 | if (context->n_push) | |
652 | jump_to = context->push_list [-- context->n_push]; | |
653 | else | |
654 | jump_to = 0; | |
655 | ||
656 | i = context->n_classification_history; | |
657 | context->classification_history = | |
658 | (diagnostic_classification_change_t *) xrealloc (context->classification_history, (i + 1) | |
659 | * sizeof (diagnostic_classification_change_t)); | |
660 | context->classification_history[i].location = where; | |
661 | context->classification_history[i].option = jump_to; | |
662 | context->classification_history[i].kind = DK_POP; | |
663 | context->n_classification_history ++; | |
664 | } | |
665 | ||
2faf8f38 | 666 | /* Report a diagnostic message (an error or a warning) as specified by |
667 | DC. This function is *the* subroutine in terms of which front-ends | |
668 | should implement their specific diagnostic handling modules. The | |
669 | front-end independent format specifiers are exactly those described | |
48e1416a | 670 | in the documentation of output_format. |
a52d5726 | 671 | Return true if a diagnostic was printed, false otherwise. */ |
f060a027 | 672 | |
a52d5726 | 673 | bool |
d598ad0d | 674 | diagnostic_report_diagnostic (diagnostic_context *context, |
675 | diagnostic_info *diagnostic) | |
f060a027 | 676 | { |
389a9009 | 677 | location_t location = diagnostic_location (diagnostic); |
543725f3 | 678 | diagnostic_t orig_diag_kind = diagnostic->kind; |
43404f28 | 679 | const char *saved_format_spec; |
f9a354ab | 680 | |
681 | /* Give preference to being able to inhibit warnings, before they | |
682 | get reclassified to something else. */ | |
a52d5726 | 683 | if ((diagnostic->kind == DK_WARNING || diagnostic->kind == DK_PEDWARN) |
3c6a9715 | 684 | && !diagnostic_report_warnings_p (context, location)) |
a52d5726 | 685 | return false; |
686 | ||
48e1416a | 687 | if (diagnostic->kind == DK_PEDWARN) |
543725f3 | 688 | { |
2c2efebb | 689 | diagnostic->kind = pedantic_warning_kind (context); |
543725f3 | 690 | /* We do this to avoid giving the message for -pedantic-errors. */ |
691 | orig_diag_kind = diagnostic->kind; | |
692 | } | |
16b4d5bb | 693 | |
694 | if (diagnostic->kind == DK_NOTE && context->inhibit_notes_p) | |
695 | return false; | |
48e1416a | 696 | |
583fa9e0 | 697 | if (context->lock > 0) |
698 | { | |
699 | /* If we're reporting an ICE in the middle of some other error, | |
700 | try to flush out the previous error, then let this one | |
701 | through. Don't do this more than once. */ | |
9d7131bf | 702 | if ((diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT) |
703 | && context->lock == 1) | |
5f7f600e | 704 | pp_newline_and_flush (context->printer); |
583fa9e0 | 705 | else |
706 | error_recursion (context); | |
707 | } | |
708 | ||
f9a354ab | 709 | /* If the user requested that warnings be treated as errors, so be |
710 | it. Note that we do this before the next block so that | |
711 | individual warnings can be overridden back to warnings with | |
712 | -Wno-error=*. */ | |
713 | if (context->warning_as_error_requested | |
714 | && diagnostic->kind == DK_WARNING) | |
715 | { | |
716 | diagnostic->kind = DK_ERROR; | |
f9a354ab | 717 | } |
48e1416a | 718 | |
bba5a206 | 719 | if (diagnostic->option_index |
720 | && diagnostic->option_index != permissive_error_option (context)) | |
76f02516 | 721 | { |
0955be65 | 722 | diagnostic_t diag_class = DK_UNSPECIFIED; |
723 | ||
76f02516 | 724 | /* This tests if the user provided the appropriate -Wfoo or |
725 | -Wno-foo option. */ | |
2c5d2e39 | 726 | if (! context->option_enabled (diagnostic->option_index, |
727 | context->option_state)) | |
a52d5726 | 728 | return false; |
0955be65 | 729 | |
730 | /* This tests for #pragma diagnostic changes. */ | |
731 | if (context->n_classification_history > 0) | |
732 | { | |
0955be65 | 733 | /* FIXME: Stupid search. Optimize later. */ |
af776050 | 734 | for (int i = context->n_classification_history - 1; i >= 0; i --) |
0955be65 | 735 | { |
97bfb9ef | 736 | if (linemap_location_before_p |
737 | (line_table, | |
738 | context->classification_history[i].location, | |
739 | location)) | |
0955be65 | 740 | { |
741 | if (context->classification_history[i].kind == (int) DK_POP) | |
742 | { | |
743 | i = context->classification_history[i].option; | |
744 | continue; | |
745 | } | |
af776050 | 746 | int option = context->classification_history[i].option; |
747 | /* The option 0 is for all the diagnostics. */ | |
748 | if (option == 0 || option == diagnostic->option_index) | |
0955be65 | 749 | { |
750 | diag_class = context->classification_history[i].kind; | |
751 | if (diag_class != DK_UNSPECIFIED) | |
752 | diagnostic->kind = diag_class; | |
753 | break; | |
754 | } | |
755 | } | |
756 | } | |
757 | } | |
76f02516 | 758 | /* This tests if the user provided the appropriate -Werror=foo |
759 | option. */ | |
0955be65 | 760 | if (diag_class == DK_UNSPECIFIED |
761 | && context->classify_diagnostic[diagnostic->option_index] != DK_UNSPECIFIED) | |
f9a354ab | 762 | { |
763 | diagnostic->kind = context->classify_diagnostic[diagnostic->option_index]; | |
f9a354ab | 764 | } |
334ec2d8 | 765 | /* This allows for future extensions, like temporarily disabling |
76f02516 | 766 | warnings for ranges of source code. */ |
767 | if (diagnostic->kind == DK_IGNORED) | |
a52d5726 | 768 | return false; |
76f02516 | 769 | } |
b0932b2f | 770 | |
583fa9e0 | 771 | context->lock++; |
f060a027 | 772 | |
9d7131bf | 773 | if (diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT) |
2faf8f38 | 774 | { |
43404f28 | 775 | /* When not checking, ICEs are converted to fatal errors when an |
776 | error has already occurred. This is counteracted by | |
777 | abort_on_error. */ | |
382ecba7 | 778 | if (!CHECKING_P |
779 | && (diagnostic_kind_count (context, DK_ERROR) > 0 | |
780 | || diagnostic_kind_count (context, DK_SORRY) > 0) | |
43404f28 | 781 | && !context->abort_on_error) |
782 | { | |
389a9009 | 783 | expanded_location s |
784 | = expand_location (diagnostic_location (diagnostic)); | |
43404f28 | 785 | fnotice (stderr, "%s:%d: confused by earlier errors, bailing out\n", |
786 | s.file, s.line); | |
787 | exit (ICE_EXIT_CODE); | |
788 | } | |
43404f28 | 789 | if (context->internal_error) |
1f63d337 | 790 | (*context->internal_error) (context, |
791 | diagnostic->message.format_spec, | |
43404f28 | 792 | diagnostic->message.args_ptr); |
b63957b3 | 793 | } |
d9d1b0a4 | 794 | if (diagnostic->kind == DK_ERROR && orig_diag_kind == DK_WARNING) |
795 | ++diagnostic_kind_count (context, DK_WERROR); | |
796 | else | |
797 | ++diagnostic_kind_count (context, diagnostic->kind); | |
48e1416a | 798 | |
43404f28 | 799 | saved_format_spec = diagnostic->message.format_spec; |
61c21070 | 800 | if (context->show_option_requested) |
801 | { | |
3c6a9715 | 802 | char *option_text; |
48e1416a | 803 | |
3c6a9715 | 804 | option_text = context->option_name (context, diagnostic->option_index, |
805 | orig_diag_kind, diagnostic->kind); | |
61c21070 | 806 | |
807 | if (option_text) | |
3c6a9715 | 808 | { |
f0479000 | 809 | const char *cs |
810 | = colorize_start (pp_show_color (context->printer), | |
811 | diagnostic_kind_color[diagnostic->kind]); | |
812 | const char *ce = colorize_stop (pp_show_color (context->printer)); | |
3c6a9715 | 813 | diagnostic->message.format_spec |
814 | = ACONCAT ((diagnostic->message.format_spec, | |
815 | " ", | |
f0479000 | 816 | "[", cs, option_text, ce, "]", |
3c6a9715 | 817 | NULL)); |
818 | free (option_text); | |
819 | } | |
61c21070 | 820 | } |
ce084dfc | 821 | diagnostic->message.x_data = &diagnostic->x_data; |
822 | diagnostic->x_data = NULL; | |
43404f28 | 823 | pp_format (context->printer, &diagnostic->message); |
824 | (*diagnostic_starter (context)) (context, diagnostic); | |
825 | pp_output_formatted_text (context->printer); | |
826 | (*diagnostic_finalizer (context)) (context, diagnostic); | |
716da296 | 827 | diagnostic_action_after_output (context, diagnostic->kind); |
43404f28 | 828 | diagnostic->message.format_spec = saved_format_spec; |
ce084dfc | 829 | diagnostic->x_data = NULL; |
78323b05 | 830 | |
831 | context->lock--; | |
a52d5726 | 832 | |
833 | return true; | |
2faf8f38 | 834 | } |
b63957b3 | 835 | |
2faf8f38 | 836 | /* Given a partial pathname as input, return another pathname that |
837 | shares no directory elements with the pathname of __FILE__. This | |
838 | is used by fancy_abort() to print `Internal compiler error in expr.c' | |
839 | instead of `Internal compiler error in ../../GCC/gcc/expr.c'. */ | |
1eefe280 | 840 | |
2faf8f38 | 841 | const char * |
d598ad0d | 842 | trim_filename (const char *name) |
2faf8f38 | 843 | { |
844 | static const char this_file[] = __FILE__; | |
845 | const char *p = name, *q = this_file; | |
b63957b3 | 846 | |
2faf8f38 | 847 | /* First skip any "../" in each filename. This allows us to give a proper |
848 | reference to a file in a subdirectory. */ | |
583fa9e0 | 849 | while (p[0] == '.' && p[1] == '.' && IS_DIR_SEPARATOR (p[2])) |
2faf8f38 | 850 | p += 3; |
851 | ||
583fa9e0 | 852 | while (q[0] == '.' && q[1] == '.' && IS_DIR_SEPARATOR (q[2])) |
2faf8f38 | 853 | q += 3; |
854 | ||
855 | /* Now skip any parts the two filenames have in common. */ | |
856 | while (*p == *q && *p != 0 && *q != 0) | |
857 | p++, q++; | |
858 | ||
859 | /* Now go backwards until the previous directory separator. */ | |
7ebd7605 | 860 | while (p > name && !IS_DIR_SEPARATOR (p[-1])) |
2faf8f38 | 861 | p--; |
862 | ||
863 | return p; | |
076f8fe1 | 864 | } |
2faf8f38 | 865 | \f |
866 | /* Standard error reporting routines in increasing order of severity. | |
867 | All of these take arguments like printf. */ | |
076f8fe1 | 868 | |
2faf8f38 | 869 | /* Text to be emitted verbatim to the error message stream; this |
870 | produces no prefix and disables line-wrapping. Use rarely. */ | |
076f8fe1 | 871 | void |
380c6697 | 872 | verbatim (const char *gmsgid, ...) |
2faf8f38 | 873 | { |
874 | text_info text; | |
ee582a61 | 875 | va_list ap; |
2faf8f38 | 876 | |
380c6697 | 877 | va_start (ap, gmsgid); |
d07c9932 | 878 | text.err_no = errno; |
2faf8f38 | 879 | text.args_ptr = ≈ |
380c6697 | 880 | text.format_spec = _(gmsgid); |
ce084dfc | 881 | text.x_data = NULL; |
aa6db498 | 882 | pp_format_verbatim (global_dc->printer, &text); |
5f7f600e | 883 | pp_newline_and_flush (global_dc->printer); |
ee582a61 | 884 | va_end (ap); |
2faf8f38 | 885 | } |
886 | ||
ff213692 | 887 | /* Add a note with text GMSGID and with LOCATION to the diagnostic CONTEXT. */ |
888 | void | |
889 | diagnostic_append_note (diagnostic_context *context, | |
890 | location_t location, | |
891 | const char * gmsgid, ...) | |
892 | { | |
893 | diagnostic_info diagnostic; | |
894 | va_list ap; | |
29d52322 | 895 | const char *saved_prefix; |
a96cefb2 | 896 | rich_location richloc (line_table, location); |
ff213692 | 897 | |
898 | va_start (ap, gmsgid); | |
f0479000 | 899 | diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_NOTE); |
900 | if (context->inhibit_notes_p) | |
901 | { | |
902 | va_end (ap); | |
903 | return; | |
904 | } | |
905 | saved_prefix = pp_get_prefix (context->printer); | |
906 | pp_set_prefix (context->printer, | |
907 | diagnostic_build_prefix (context, &diagnostic)); | |
ff213692 | 908 | pp_format (context->printer, &diagnostic.message); |
909 | pp_output_formatted_text (context->printer); | |
910 | pp_destroy_prefix (context->printer); | |
29d52322 | 911 | pp_set_prefix (context->printer, saved_prefix); |
ff213692 | 912 | diagnostic_show_locus (context, &diagnostic); |
9af5ce0c | 913 | va_end (ap); |
ff213692 | 914 | } |
915 | ||
a52d5726 | 916 | bool |
48e1416a | 917 | emit_diagnostic (diagnostic_t kind, location_t location, int opt, |
a52d5726 | 918 | const char *gmsgid, ...) |
076f8fe1 | 919 | { |
25e2ffe1 | 920 | diagnostic_info diagnostic; |
ee582a61 | 921 | va_list ap; |
e3d533cf | 922 | bool ret; |
a96cefb2 | 923 | rich_location richloc (line_table, location); |
2faf8f38 | 924 | |
380c6697 | 925 | va_start (ap, gmsgid); |
a52d5726 | 926 | if (kind == DK_PERMERROR) |
927 | { | |
f0479000 | 928 | diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, |
2c2efebb | 929 | permissive_error_kind (global_dc)); |
3c6a9715 | 930 | diagnostic.option_index = permissive_error_option (global_dc); |
a52d5726 | 931 | } |
932 | else { | |
f0479000 | 933 | diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, kind); |
a52d5726 | 934 | if (kind == DK_WARNING || kind == DK_PEDWARN) |
935 | diagnostic.option_index = opt; | |
936 | } | |
a52d5726 | 937 | |
e3d533cf | 938 | ret = report_diagnostic (&diagnostic); |
939 | va_end (ap); | |
940 | return ret; | |
076f8fe1 | 941 | } |
942 | ||
5bcc316e | 943 | /* An informative note at LOCATION. Use this for additional details on an error |
a52d5726 | 944 | message. */ |
076f8fe1 | 945 | void |
5bcc316e | 946 | inform (location_t location, const char *gmsgid, ...) |
f0479000 | 947 | { |
948 | diagnostic_info diagnostic; | |
949 | va_list ap; | |
a96cefb2 | 950 | rich_location richloc (line_table, location); |
f0479000 | 951 | |
952 | va_start (ap, gmsgid); | |
953 | diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_NOTE); | |
954 | report_diagnostic (&diagnostic); | |
955 | va_end (ap); | |
956 | } | |
957 | ||
958 | /* Same as "inform", but at RICHLOC. */ | |
959 | void | |
960 | inform_at_rich_loc (rich_location *richloc, const char *gmsgid, ...) | |
c3ceba8e | 961 | { |
962 | diagnostic_info diagnostic; | |
963 | va_list ap; | |
964 | ||
380c6697 | 965 | va_start (ap, gmsgid); |
f0479000 | 966 | diagnostic_set_info (&diagnostic, gmsgid, &ap, richloc, DK_NOTE); |
c3ceba8e | 967 | report_diagnostic (&diagnostic); |
968 | va_end (ap); | |
969 | } | |
970 | ||
c0ddc4f8 | 971 | /* An informative note at LOCATION. Use this for additional details on an |
972 | error message. */ | |
973 | void | |
974 | inform_n (location_t location, int n, const char *singular_gmsgid, | |
975 | const char *plural_gmsgid, ...) | |
976 | { | |
977 | diagnostic_info diagnostic; | |
978 | va_list ap; | |
a96cefb2 | 979 | rich_location richloc (line_table, location); |
c0ddc4f8 | 980 | |
981 | va_start (ap, plural_gmsgid); | |
982 | diagnostic_set_info_translated (&diagnostic, | |
983 | ngettext (singular_gmsgid, plural_gmsgid, n), | |
f0479000 | 984 | &ap, &richloc, DK_NOTE); |
c0ddc4f8 | 985 | report_diagnostic (&diagnostic); |
986 | va_end (ap); | |
987 | } | |
988 | ||
a52d5726 | 989 | /* A warning at INPUT_LOCATION. Use this for code which is correct according |
48e1416a | 990 | to the relevant language specification but is likely to be buggy anyway. |
a52d5726 | 991 | Returns true if the warning was printed, false if it was inhibited. */ |
992 | bool | |
993 | warning (int opt, const char *gmsgid, ...) | |
076f8fe1 | 994 | { |
25e2ffe1 | 995 | diagnostic_info diagnostic; |
ee582a61 | 996 | va_list ap; |
e3d533cf | 997 | bool ret; |
a96cefb2 | 998 | rich_location richloc (line_table, input_location); |
076f8fe1 | 999 | |
380c6697 | 1000 | va_start (ap, gmsgid); |
f0479000 | 1001 | diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_WARNING); |
a52d5726 | 1002 | diagnostic.option_index = opt; |
1003 | ||
e3d533cf | 1004 | ret = report_diagnostic (&diagnostic); |
ee582a61 | 1005 | va_end (ap); |
e3d533cf | 1006 | return ret; |
076f8fe1 | 1007 | } |
1008 | ||
bdbc474b | 1009 | /* A warning at LOCATION. Use this for code which is correct according to the |
a52d5726 | 1010 | relevant language specification but is likely to be buggy anyway. |
1011 | Returns true if the warning was printed, false if it was inhibited. */ | |
1012 | ||
1013 | bool | |
bdbc474b | 1014 | warning_at (location_t location, int opt, const char *gmsgid, ...) |
f0479000 | 1015 | { |
1016 | diagnostic_info diagnostic; | |
1017 | va_list ap; | |
1018 | bool ret; | |
a96cefb2 | 1019 | rich_location richloc (line_table, location); |
f0479000 | 1020 | |
1021 | va_start (ap, gmsgid); | |
1022 | diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_WARNING); | |
1023 | diagnostic.option_index = opt; | |
1024 | ret = report_diagnostic (&diagnostic); | |
1025 | va_end (ap); | |
1026 | return ret; | |
1027 | } | |
1028 | ||
1029 | /* Same as warning at, but using RICHLOC. */ | |
1030 | ||
1031 | bool | |
1032 | warning_at_rich_loc (rich_location *richloc, int opt, const char *gmsgid, ...) | |
bdbc474b | 1033 | { |
1034 | diagnostic_info diagnostic; | |
1035 | va_list ap; | |
e3d533cf | 1036 | bool ret; |
bdbc474b | 1037 | |
1038 | va_start (ap, gmsgid); | |
f0479000 | 1039 | diagnostic_set_info (&diagnostic, gmsgid, &ap, richloc, DK_WARNING); |
bdbc474b | 1040 | diagnostic.option_index = opt; |
e3d533cf | 1041 | ret = report_diagnostic (&diagnostic); |
bdbc474b | 1042 | va_end (ap); |
e3d533cf | 1043 | return ret; |
bdbc474b | 1044 | } |
1045 | ||
1b355793 | 1046 | /* A warning at LOCATION. Use this for code which is correct according to the |
1047 | relevant language specification but is likely to be buggy anyway. | |
1048 | Returns true if the warning was printed, false if it was inhibited. */ | |
1049 | ||
1050 | bool | |
1051 | warning_n (location_t location, int opt, int n, const char *singular_gmsgid, | |
1052 | const char *plural_gmsgid, ...) | |
1053 | { | |
1054 | diagnostic_info diagnostic; | |
1055 | va_list ap; | |
1056 | bool ret; | |
a96cefb2 | 1057 | rich_location richloc (line_table, location); |
1b355793 | 1058 | |
1059 | va_start (ap, plural_gmsgid); | |
1060 | diagnostic_set_info_translated (&diagnostic, | |
1061 | ngettext (singular_gmsgid, plural_gmsgid, n), | |
f0479000 | 1062 | &ap, &richloc, DK_WARNING |
1063 | ); | |
1b355793 | 1064 | diagnostic.option_index = opt; |
1065 | ret = report_diagnostic (&diagnostic); | |
1066 | va_end (ap); | |
1067 | return ret; | |
1068 | } | |
1069 | ||
e8fc0d34 | 1070 | /* A "pedantic" warning at LOCATION: issues a warning unless |
1071 | -pedantic-errors was given on the command line, in which case it | |
1072 | issues an error. Use this for diagnostics required by the relevant | |
1073 | language standard, if you have chosen not to make them errors. | |
78323b05 | 1074 | |
1075 | Note that these diagnostics are issued independent of the setting | |
29438999 | 1076 | of the -Wpedantic command-line switch. To get a warning enabled |
8864917d | 1077 | only with that switch, use either "if (pedantic) pedwarn |
29438999 | 1078 | (OPT_Wpedantic,...)" or just "pedwarn (OPT_Wpedantic,..)". To get a |
1079 | pedwarn independently of the -Wpedantic switch use "pedwarn (0,...)". | |
8864917d | 1080 | |
a52d5726 | 1081 | Returns true if the warning was printed, false if it was inhibited. */ |
1082 | ||
e8fc0d34 | 1083 | bool |
21ca8540 | 1084 | pedwarn (location_t location, int opt, const char *gmsgid, ...) |
e8fc0d34 | 1085 | { |
1086 | diagnostic_info diagnostic; | |
1087 | va_list ap; | |
e3d533cf | 1088 | bool ret; |
a96cefb2 | 1089 | rich_location richloc (line_table, location); |
e8fc0d34 | 1090 | |
1091 | va_start (ap, gmsgid); | |
f0479000 | 1092 | diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_PEDWARN); |
e8fc0d34 | 1093 | diagnostic.option_index = opt; |
e3d533cf | 1094 | ret = report_diagnostic (&diagnostic); |
e8fc0d34 | 1095 | va_end (ap); |
e3d533cf | 1096 | return ret; |
e8fc0d34 | 1097 | } |
1098 | ||
2ba27e7e | 1099 | /* A "permissive" error at LOCATION: issues an error unless |
1100 | -fpermissive was given on the command line, in which case it issues | |
1101 | a warning. Use this for things that really should be errors but we | |
a52d5726 | 1102 | want to support legacy code. |
2ba27e7e | 1103 | |
a52d5726 | 1104 | Returns true if the warning was printed, false if it was inhibited. */ |
1105 | ||
1106 | bool | |
2b9e3597 | 1107 | permerror (location_t location, const char *gmsgid, ...) |
2ba27e7e | 1108 | { |
1109 | diagnostic_info diagnostic; | |
1110 | va_list ap; | |
e3d533cf | 1111 | bool ret; |
a96cefb2 | 1112 | rich_location richloc (line_table, location); |
2ba27e7e | 1113 | |
1114 | va_start (ap, gmsgid); | |
f0479000 | 1115 | diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, |
1116 | permissive_error_kind (global_dc)); | |
1117 | diagnostic.option_index = permissive_error_option (global_dc); | |
1118 | ret = report_diagnostic (&diagnostic); | |
1119 | va_end (ap); | |
1120 | return ret; | |
1121 | } | |
1122 | ||
1123 | /* Same as "permerror", but at RICHLOC. */ | |
1124 | ||
1125 | bool | |
1126 | permerror_at_rich_loc (rich_location *richloc, const char *gmsgid, ...) | |
1127 | { | |
1128 | diagnostic_info diagnostic; | |
1129 | va_list ap; | |
1130 | bool ret; | |
1131 | ||
1132 | va_start (ap, gmsgid); | |
1133 | diagnostic_set_info (&diagnostic, gmsgid, &ap, richloc, | |
2c2efebb | 1134 | permissive_error_kind (global_dc)); |
3c6a9715 | 1135 | diagnostic.option_index = permissive_error_option (global_dc); |
e3d533cf | 1136 | ret = report_diagnostic (&diagnostic); |
2ba27e7e | 1137 | va_end (ap); |
e3d533cf | 1138 | return ret; |
2ba27e7e | 1139 | } |
1140 | ||
2faf8f38 | 1141 | /* A hard error: the code is definitely ill-formed, and an object file |
1142 | will not be produced. */ | |
2d6f73d2 | 1143 | void |
380c6697 | 1144 | error (const char *gmsgid, ...) |
2d6f73d2 | 1145 | { |
2faf8f38 | 1146 | diagnostic_info diagnostic; |
ee582a61 | 1147 | va_list ap; |
a96cefb2 | 1148 | rich_location richloc (line_table, input_location); |
2faf8f38 | 1149 | |
380c6697 | 1150 | va_start (ap, gmsgid); |
f0479000 | 1151 | diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_ERROR); |
2faf8f38 | 1152 | report_diagnostic (&diagnostic); |
ee582a61 | 1153 | va_end (ap); |
b7c4d3f3 | 1154 | } |
1155 | ||
c0ddc4f8 | 1156 | /* A hard error: the code is definitely ill-formed, and an object file |
1157 | will not be produced. */ | |
1158 | void | |
1159 | error_n (location_t location, int n, const char *singular_gmsgid, | |
1160 | const char *plural_gmsgid, ...) | |
1161 | { | |
1162 | diagnostic_info diagnostic; | |
1163 | va_list ap; | |
a96cefb2 | 1164 | rich_location richloc (line_table, location); |
c0ddc4f8 | 1165 | |
1166 | va_start (ap, plural_gmsgid); | |
1167 | diagnostic_set_info_translated (&diagnostic, | |
1168 | ngettext (singular_gmsgid, plural_gmsgid, n), | |
f0479000 | 1169 | &ap, &richloc, DK_ERROR); |
c0ddc4f8 | 1170 | report_diagnostic (&diagnostic); |
1171 | va_end (ap); | |
1172 | } | |
1173 | ||
3bc1df45 | 1174 | /* Same as ebove, but use location LOC instead of input_location. */ |
1175 | void | |
1176 | error_at (location_t loc, const char *gmsgid, ...) | |
1177 | { | |
1178 | diagnostic_info diagnostic; | |
1179 | va_list ap; | |
a96cefb2 | 1180 | rich_location richloc (line_table, loc); |
3bc1df45 | 1181 | |
1182 | va_start (ap, gmsgid); | |
f0479000 | 1183 | diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_ERROR); |
1184 | report_diagnostic (&diagnostic); | |
1185 | va_end (ap); | |
1186 | } | |
1187 | ||
1188 | /* Same as above, but use RICH_LOC. */ | |
1189 | ||
1190 | void | |
1191 | error_at_rich_loc (rich_location *rich_loc, const char *gmsgid, ...) | |
1192 | { | |
1193 | diagnostic_info diagnostic; | |
1194 | va_list ap; | |
1195 | ||
1196 | va_start (ap, gmsgid); | |
1197 | diagnostic_set_info (&diagnostic, gmsgid, &ap, rich_loc, | |
1198 | DK_ERROR); | |
3bc1df45 | 1199 | report_diagnostic (&diagnostic); |
1200 | va_end (ap); | |
1201 | } | |
1202 | ||
2faf8f38 | 1203 | /* "Sorry, not implemented." Use for a language feature which is |
1204 | required by the relevant specification but not implemented by GCC. | |
1205 | An object file will not be produced. */ | |
b7c4d3f3 | 1206 | void |
380c6697 | 1207 | sorry (const char *gmsgid, ...) |
b7c4d3f3 | 1208 | { |
2faf8f38 | 1209 | diagnostic_info diagnostic; |
ee582a61 | 1210 | va_list ap; |
a96cefb2 | 1211 | rich_location richloc (line_table, input_location); |
19fafbd3 | 1212 | |
380c6697 | 1213 | va_start (ap, gmsgid); |
f0479000 | 1214 | diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_SORRY); |
78323b05 | 1215 | report_diagnostic (&diagnostic); |
ee582a61 | 1216 | va_end (ap); |
2faf8f38 | 1217 | } |
b63957b3 | 1218 | |
852f689e | 1219 | /* Return true if an error or a "sorry" has been seen. Various |
1220 | processing is disabled after errors. */ | |
1221 | bool | |
1222 | seen_error (void) | |
1223 | { | |
1224 | return errorcount || sorrycount; | |
1225 | } | |
1226 | ||
4d0069ee | 1227 | /* An error which is severe enough that we make no attempt to |
1228 | continue. Do not use this for internal consistency checks; that's | |
1229 | internal_error. Use of this function should be rare. */ | |
1230 | void | |
1231 | fatal_error (location_t loc, const char *gmsgid, ...) | |
1232 | { | |
1233 | diagnostic_info diagnostic; | |
1234 | va_list ap; | |
a96cefb2 | 1235 | rich_location richloc (line_table, loc); |
4d0069ee | 1236 | |
1237 | va_start (ap, gmsgid); | |
f0479000 | 1238 | diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_FATAL); |
4d0069ee | 1239 | report_diagnostic (&diagnostic); |
1240 | va_end (ap); | |
1241 | ||
1242 | gcc_unreachable (); | |
1243 | } | |
1244 | ||
2faf8f38 | 1245 | /* An internal consistency check has failed. We make no attempt to |
1246 | continue. Note that unless there is debugging value to be had from | |
1247 | a more specific message, or some other good reason, you should use | |
1248 | abort () instead of calling this function directly. */ | |
1249 | void | |
380c6697 | 1250 | internal_error (const char *gmsgid, ...) |
19fafbd3 | 1251 | { |
2faf8f38 | 1252 | diagnostic_info diagnostic; |
ee582a61 | 1253 | va_list ap; |
a96cefb2 | 1254 | rich_location richloc (line_table, input_location); |
19fafbd3 | 1255 | |
380c6697 | 1256 | va_start (ap, gmsgid); |
f0479000 | 1257 | diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_ICE); |
2faf8f38 | 1258 | report_diagnostic (&diagnostic); |
ee582a61 | 1259 | va_end (ap); |
19fafbd3 | 1260 | |
583fa9e0 | 1261 | gcc_unreachable (); |
19fafbd3 | 1262 | } |
9d7131bf | 1263 | |
1264 | /* Like internal_error, but no backtrace will be printed. Used when | |
1265 | the internal error does not happen at the current location, but happened | |
1266 | somewhere else. */ | |
1267 | void | |
1268 | internal_error_no_backtrace (const char *gmsgid, ...) | |
1269 | { | |
1270 | diagnostic_info diagnostic; | |
1271 | va_list ap; | |
a96cefb2 | 1272 | rich_location richloc (line_table, input_location); |
9d7131bf | 1273 | |
1274 | va_start (ap, gmsgid); | |
f0479000 | 1275 | diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_ICE_NOBT); |
9d7131bf | 1276 | report_diagnostic (&diagnostic); |
1277 | va_end (ap); | |
1278 | ||
1279 | gcc_unreachable (); | |
1280 | } | |
2faf8f38 | 1281 | \f |
2faf8f38 | 1282 | /* Special case error functions. Most are implemented in terms of the |
1283 | above, or should be. */ | |
88da234d | 1284 | |
2faf8f38 | 1285 | /* Print a diagnostic MSGID on FILE. This is just fprintf, except it |
1286 | runs its second argument through gettext. */ | |
9cab5830 | 1287 | void |
380c6697 | 1288 | fnotice (FILE *file, const char *cmsgid, ...) |
9cab5830 | 1289 | { |
ee582a61 | 1290 | va_list ap; |
9cab5830 | 1291 | |
380c6697 | 1292 | va_start (ap, cmsgid); |
1293 | vfprintf (file, _(cmsgid), ap); | |
ee582a61 | 1294 | va_end (ap); |
9cab5830 | 1295 | } |
1296 | ||
2faf8f38 | 1297 | /* Inform the user that an error occurred while trying to report some |
1298 | other error. This indicates catastrophic internal inconsistencies, | |
1299 | so give up now. But do try to flush out the previous error. | |
1300 | This mustn't use internal_error, that will cause infinite recursion. */ | |
1301 | ||
1302 | static void | |
d598ad0d | 1303 | error_recursion (diagnostic_context *context) |
2faf8f38 | 1304 | { |
1305 | if (context->lock < 3) | |
5f7f600e | 1306 | pp_newline_and_flush (context->printer); |
2faf8f38 | 1307 | |
1308 | fnotice (stderr, | |
1309 | "Internal compiler error: Error reporting routines re-entered.\n"); | |
583fa9e0 | 1310 | |
1311 | /* Call diagnostic_action_after_output to get the "please submit a bug | |
716da296 | 1312 | report" message. */ |
1313 | diagnostic_action_after_output (context, DK_ICE); | |
583fa9e0 | 1314 | |
1315 | /* Do not use gcc_unreachable here; that goes through internal_error | |
1316 | and therefore would cause infinite recursion. */ | |
1317 | real_abort (); | |
2faf8f38 | 1318 | } |
1319 | ||
1320 | /* Report an internal compiler error in a friendly manner. This is | |
1321 | the function that gets called upon use of abort() in the source | |
1322 | code generally, thanks to a special macro. */ | |
1323 | ||
1324 | void | |
d598ad0d | 1325 | fancy_abort (const char *file, int line, const char *function) |
2faf8f38 | 1326 | { |
1327 | internal_error ("in %s, at %s:%d", function, trim_filename (file), line); | |
1328 | } | |
1329 | ||
5f07bab0 | 1330 | /* Really call the system 'abort'. This has to go right at the end of |
1331 | this file, so that there are no functions after it that call abort | |
1332 | and get the system abort instead of our macro. */ | |
1333 | #undef abort | |
d598ad0d | 1334 | static void |
1335 | real_abort (void) | |
5f07bab0 | 1336 | { |
1337 | abort (); | |
1338 | } |