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