Branch data Line data Source code
1 : : /* Handle errors.
2 : : Copyright (C) 2000-2024 Free Software Foundation, Inc.
3 : : Contributed by Andy Vaught & Niels Kristian Bech Jensen
4 : :
5 : : This file is part of GCC.
6 : :
7 : : GCC is free software; you can redistribute it and/or modify it under
8 : : the terms of the GNU General Public License as published by the Free
9 : : Software Foundation; either version 3, or (at your option) any later
10 : : version.
11 : :
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.
16 : :
17 : : You should have received a copy of the GNU General Public License
18 : : along with GCC; see the file COPYING3. If not see
19 : : <http://www.gnu.org/licenses/>. */
20 : :
21 : : /* Handle the inevitable errors. A major catch here is that things
22 : : flagged as errors in one match subroutine can conceivably be legal
23 : : elsewhere. This means that error messages are recorded and saved
24 : : for possible use later. If a line does not match a legal
25 : : construction, then the saved error message is reported. */
26 : :
27 : : #include "config.h"
28 : : #include "system.h"
29 : : #include "coretypes.h"
30 : : #include "options.h"
31 : : #include "gfortran.h"
32 : :
33 : : #include "diagnostic.h"
34 : : #include "diagnostic-color.h"
35 : : #include "tree-diagnostic.h" /* tree_diagnostics_defaults */
36 : : #include "diagnostic-format-text.h"
37 : :
38 : : static int suppress_errors = 0;
39 : :
40 : : static bool warnings_not_errors = false;
41 : :
42 : : /* True if the error/warnings should be buffered. */
43 : : static bool buffered_p;
44 : :
45 : : static gfc_error_buffer *error_buffer;
46 : : static diagnostic_buffer *pp_error_buffer, *pp_warning_buffer;
47 : :
48 : 7552488 : gfc_error_buffer::gfc_error_buffer ()
49 : 7552488 : : flag (false), buffer (*global_dc)
50 : : {
51 : 7552488 : }
52 : :
53 : : /* Return a location_t suitable for 'tree' for a gfortran locus. During
54 : : parsing in gfortran, loc->u.lb->location contains only the line number
55 : : and LOCATION_COLUMN is 0; hence, the column has to be added when generating
56 : : locations for 'tree'. If available, return location_t directly, which
57 : : might be a range. */
58 : :
59 : : location_t
60 : 18423762 : gfc_get_location_with_offset (locus *loc, unsigned offset)
61 : : {
62 : 18423762 : if (loc->nextc == (gfc_char_t *) -1)
63 : : {
64 : 365933 : gcc_checking_assert (offset == 0);
65 : 365933 : return loc->u.location;
66 : : }
67 : 18057829 : gcc_checking_assert (loc->nextc >= loc->u.lb->line);
68 : 18057829 : return linemap_position_for_loc_and_offset (line_table, loc->u.lb->location,
69 : 18057829 : loc->nextc - loc->u.lb->line
70 : 18057829 : + offset);
71 : : }
72 : :
73 : : /* Convert a locus to a range. */
74 : :
75 : : locus
76 : 6988009 : gfc_get_location_range (locus *caret_loc, unsigned caret_offset,
77 : : locus *start_loc, unsigned start_offset,
78 : : locus *end_loc)
79 : : {
80 : 6988009 : location_t caret;
81 : 6988009 : location_t start = gfc_get_location_with_offset (start_loc, start_offset);
82 : 6988009 : location_t end = gfc_get_location_with_offset (end_loc, 0);
83 : :
84 : 6988009 : if (caret_loc)
85 : 0 : caret = gfc_get_location_with_offset (caret_loc, caret_offset);
86 : :
87 : 0 : locus range;
88 : 0 : range.nextc = (gfc_char_t *) -1;
89 : 6988009 : range.u.location = make_location (caret_loc ? caret : start, start, end);
90 : 6988009 : return range;
91 : : }
92 : :
93 : : /* Return buffered_p. */
94 : : bool
95 : 73 : gfc_buffered_p (void)
96 : : {
97 : 73 : return buffered_p;
98 : : }
99 : :
100 : : /* Go one level deeper suppressing errors. */
101 : :
102 : : void
103 : 441654 : gfc_push_suppress_errors (void)
104 : : {
105 : 441654 : gcc_assert (suppress_errors >= 0);
106 : 441654 : ++suppress_errors;
107 : 441654 : }
108 : :
109 : : static void
110 : : gfc_error_opt (int opt, const char *gmsgid, va_list ap) ATTRIBUTE_GCC_GFC(2,0);
111 : :
112 : : static bool
113 : : gfc_warning (int opt, const char *gmsgid, va_list ap) ATTRIBUTE_GCC_GFC(2,0);
114 : :
115 : :
116 : : /* Leave one level of error suppressing. */
117 : :
118 : : void
119 : 441654 : gfc_pop_suppress_errors (void)
120 : : {
121 : 441654 : gcc_assert (suppress_errors > 0);
122 : 441654 : --suppress_errors;
123 : 441654 : }
124 : :
125 : :
126 : : /* Query whether errors are suppressed. */
127 : :
128 : : bool
129 : 139 : gfc_query_suppress_errors (void)
130 : : {
131 : 139 : return suppress_errors > 0;
132 : : }
133 : :
134 : :
135 : : /* Per-file error initialization. */
136 : :
137 : : void
138 : 30461 : gfc_error_init_1 (void)
139 : : {
140 : 30461 : gfc_buffer_error (false);
141 : 30461 : }
142 : :
143 : :
144 : : /* Set the flag for buffering errors or not. */
145 : :
146 : : void
147 : 5905057 : gfc_buffer_error (bool flag)
148 : : {
149 : 5905057 : buffered_p = flag;
150 : 5905057 : }
151 : :
152 : :
153 : : static int
154 : 25 : print_wide_char_into_buffer (gfc_char_t c, char *buf)
155 : : {
156 : 25 : static const char xdigit[16] = { '0', '1', '2', '3', '4', '5', '6',
157 : : '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
158 : :
159 : 25 : if (gfc_wide_is_printable (c) || c == '\t')
160 : : {
161 : 2 : buf[1] = '\0';
162 : : /* Tabulation is output as a space. */
163 : 2 : buf[0] = (unsigned char) (c == '\t' ? ' ' : c);
164 : 2 : return 1;
165 : : }
166 : 23 : else if (c < ((gfc_char_t) 1 << 8))
167 : : {
168 : 14 : buf[4] = '\0';
169 : 14 : buf[3] = xdigit[c & 0x0F];
170 : 14 : c = c >> 4;
171 : 14 : buf[2] = xdigit[c & 0x0F];
172 : :
173 : 14 : buf[1] = 'x';
174 : 14 : buf[0] = '\\';
175 : 14 : return 4;
176 : : }
177 : 9 : else if (c < ((gfc_char_t) 1 << 16))
178 : : {
179 : 8 : buf[6] = '\0';
180 : 8 : buf[5] = xdigit[c & 0x0F];
181 : 8 : c = c >> 4;
182 : 8 : buf[4] = xdigit[c & 0x0F];
183 : 8 : c = c >> 4;
184 : 8 : buf[3] = xdigit[c & 0x0F];
185 : 8 : c = c >> 4;
186 : 8 : buf[2] = xdigit[c & 0x0F];
187 : :
188 : 8 : buf[1] = 'u';
189 : 8 : buf[0] = '\\';
190 : 8 : return 6;
191 : : }
192 : : else
193 : : {
194 : 1 : buf[10] = '\0';
195 : 1 : buf[9] = xdigit[c & 0x0F];
196 : 1 : c = c >> 4;
197 : 1 : buf[8] = xdigit[c & 0x0F];
198 : 1 : c = c >> 4;
199 : 1 : buf[7] = xdigit[c & 0x0F];
200 : 1 : c = c >> 4;
201 : 1 : buf[6] = xdigit[c & 0x0F];
202 : 1 : c = c >> 4;
203 : 1 : buf[5] = xdigit[c & 0x0F];
204 : 1 : c = c >> 4;
205 : 1 : buf[4] = xdigit[c & 0x0F];
206 : 1 : c = c >> 4;
207 : 1 : buf[3] = xdigit[c & 0x0F];
208 : 1 : c = c >> 4;
209 : 1 : buf[2] = xdigit[c & 0x0F];
210 : :
211 : 1 : buf[1] = 'U';
212 : 1 : buf[0] = '\\';
213 : 1 : return 10;
214 : : }
215 : : }
216 : :
217 : : static char wide_char_print_buffer[11];
218 : :
219 : : const char *
220 : 25 : gfc_print_wide_char (gfc_char_t c)
221 : : {
222 : 25 : print_wide_char_into_buffer (c, wide_char_print_buffer);
223 : 25 : return wide_char_print_buffer;
224 : : }
225 : :
226 : :
227 : : /* Clear any output buffered in THIS_BUFFER without issuing
228 : : it to global_dc. */
229 : :
230 : : static void
231 : 21508079 : gfc_clear_diagnostic_buffer (diagnostic_buffer *this_buffer)
232 : : {
233 : 21508079 : gcc_assert (this_buffer);
234 : 21508079 : global_dc->clear_diagnostic_buffer (*this_buffer);
235 : 21508079 : }
236 : :
237 : : /* The currently-printing diagnostic, for use by gfc_format_decoder,
238 : : for colorizing %C and %L. */
239 : :
240 : : static diagnostic_info *curr_diagnostic;
241 : :
242 : : /* A helper function to call diagnostic_report_diagnostic, while setting
243 : : curr_diagnostic for the duration of the call. */
244 : :
245 : : static bool
246 : 1187087 : gfc_report_diagnostic (diagnostic_info *diagnostic)
247 : : {
248 : 1187087 : gcc_assert (diagnostic != NULL);
249 : 1187087 : curr_diagnostic = diagnostic;
250 : 1187087 : bool ret = diagnostic_report_diagnostic (global_dc, diagnostic);
251 : 1187079 : curr_diagnostic = NULL;
252 : 1187079 : return ret;
253 : : }
254 : :
255 : : /* This is just a helper function to avoid duplicating the logic of
256 : : gfc_warning. */
257 : :
258 : : static bool
259 : 19393 : gfc_warning (int opt, const char *gmsgid, va_list ap)
260 : : {
261 : 19393 : va_list argp;
262 : 19393 : va_copy (argp, ap);
263 : :
264 : 19393 : diagnostic_info diagnostic;
265 : 19393 : rich_location rich_loc (line_table, UNKNOWN_LOCATION);
266 : 19393 : diagnostic_buffer *old_buffer = global_dc->get_diagnostic_buffer ();
267 : 19393 : gcc_assert (!old_buffer);
268 : :
269 : 19393 : gfc_clear_diagnostic_buffer (pp_warning_buffer);
270 : :
271 : 19393 : if (buffered_p)
272 : 15620 : global_dc->set_diagnostic_buffer (pp_warning_buffer);
273 : :
274 : 19393 : diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc,
275 : : DK_WARNING);
276 : 19393 : diagnostic.option_id = opt;
277 : 19393 : bool ret = gfc_report_diagnostic (&diagnostic);
278 : :
279 : 19393 : if (buffered_p)
280 : 15620 : global_dc->set_diagnostic_buffer (old_buffer);
281 : :
282 : 19393 : va_end (argp);
283 : 38786 : return ret;
284 : 19393 : }
285 : :
286 : : /* Issue a warning. */
287 : :
288 : : bool
289 : 3653 : gfc_warning (int opt, const char *gmsgid, ...)
290 : : {
291 : 3653 : va_list argp;
292 : :
293 : 3653 : va_start (argp, gmsgid);
294 : 3653 : bool ret = gfc_warning (opt, gmsgid, argp);
295 : 3653 : va_end (argp);
296 : 3653 : return ret;
297 : : }
298 : :
299 : :
300 : : /* Whether, for a feature included in a given standard set (GFC_STD_*),
301 : : we should issue an error or a warning, or be quiet. */
302 : :
303 : : notification
304 : 247155 : gfc_notification_std (int std)
305 : : {
306 : 247155 : bool warning;
307 : :
308 : 247155 : warning = ((gfc_option.warn_std & std) != 0) && !inhibit_warnings;
309 : 247155 : if ((gfc_option.allow_std & std) != 0 && !warning)
310 : : return SILENT;
311 : :
312 : 384 : return warning ? WARNING : ERROR;
313 : : }
314 : :
315 : :
316 : : /* Return a string describing the nature of a standard violation
317 : : * and/or the relevant version of the standard. */
318 : :
319 : : char const*
320 : 16445 : notify_std_msg(int std)
321 : : {
322 : :
323 : 16445 : if (std & GFC_STD_F2023_DEL)
324 : 10 : return _("Prohibited in Fortran 2023:");
325 : 16435 : else if (std & GFC_STD_F2023)
326 : 5 : return _("Fortran 2023:");
327 : 16430 : else if (std & GFC_STD_F2018_DEL)
328 : 1 : return _("Fortran 2018 deleted feature:");
329 : 16429 : else if (std & GFC_STD_F2018_OBS)
330 : 8 : return _("Fortran 2018 obsolescent feature:");
331 : 16421 : else if (std & GFC_STD_F2018)
332 : 118 : return _("Fortran 2018:");
333 : 16303 : else if (std & GFC_STD_F2008_OBS)
334 : 2 : return _("Fortran 2008 obsolescent feature:");
335 : 16301 : else if (std & GFC_STD_F2008)
336 : : return "Fortran 2008:";
337 : 15907 : else if (std & GFC_STD_F2003)
338 : : return "Fortran 2003:";
339 : 15781 : else if (std & GFC_STD_GNU)
340 : 384 : return _("GNU Extension:");
341 : 15397 : else if (std & GFC_STD_LEGACY)
342 : 11558 : return _("Legacy Extension:");
343 : 3839 : else if (std & GFC_STD_F95_OBS)
344 : 3708 : return _("Obsolescent feature:");
345 : 131 : else if (std & GFC_STD_F95_DEL)
346 : 130 : return _("Deleted feature:");
347 : 1 : else if (std & GFC_STD_UNSIGNED)
348 : 1 : return _("Unsigned:");
349 : : else
350 : 0 : gcc_unreachable ();
351 : : }
352 : :
353 : :
354 : : /* Possibly issue a warning/error about use of a nonstandard (or deleted)
355 : : feature. An error/warning will be issued if the currently selected
356 : : standard does not contain the requested bits. Return false if
357 : : an error is generated. */
358 : :
359 : : bool
360 : 313226 : gfc_notify_std (int std, const char *gmsgid, ...)
361 : : {
362 : 313226 : va_list argp;
363 : 313226 : const char *msg, *msg2;
364 : 313226 : char *buffer;
365 : :
366 : : /* Determine whether an error or a warning is needed. */
367 : 313226 : const int wstd = std & gfc_option.warn_std; /* Standard to warn about. */
368 : 313226 : const int estd = std & ~gfc_option.allow_std; /* Standard to error about. */
369 : 313226 : const bool warning = (wstd != 0) && !inhibit_warnings;
370 : 313226 : const bool error = (estd != 0);
371 : :
372 : 313226 : if (!error && !warning)
373 : : return true;
374 : 16446 : if (suppress_errors)
375 : : return !error;
376 : :
377 : 16445 : if (error)
378 : 749 : msg = notify_std_msg (estd);
379 : : else
380 : 15696 : msg = notify_std_msg (wstd);
381 : :
382 : 16445 : msg2 = _(gmsgid);
383 : 16445 : buffer = (char *) alloca (strlen (msg) + strlen (msg2) + 2);
384 : 16445 : strcpy (buffer, msg);
385 : 16445 : strcat (buffer, " ");
386 : 16445 : strcat (buffer, msg2);
387 : :
388 : 16445 : va_start (argp, gmsgid);
389 : 16445 : if (error)
390 : 749 : gfc_error_opt (0, buffer, argp);
391 : : else
392 : 15696 : gfc_warning (0, buffer, argp);
393 : 16445 : va_end (argp);
394 : :
395 : 16445 : if (error)
396 : : return false;
397 : : else
398 : 15699 : return (warning && !warnings_are_errors);
399 : : }
400 : :
401 : :
402 : : /* Called from output_format -- during diagnostic message processing
403 : : to handle Fortran specific format specifiers with the following meanings:
404 : :
405 : : %C Current locus (no argument)
406 : : %L Takes locus argument
407 : : */
408 : : static bool
409 : 1160635 : gfc_format_decoder (pretty_printer *pp, text_info *text, const char *spec,
410 : : int precision, bool wide, bool set_locus, bool hash,
411 : : bool *quoted, pp_token_list &formatted_token_list)
412 : : {
413 : 1160635 : unsigned offset = 0;
414 : 1160635 : switch (*spec)
415 : : {
416 : 1160612 : case 'C':
417 : 1160612 : case 'L':
418 : 1160612 : {
419 : 1160612 : static const char *result[2] = { "(1)", "(2)" };
420 : 1160612 : locus *loc;
421 : 1160612 : if (*spec == 'C')
422 : : {
423 : 1144915 : loc = &gfc_current_locus;
424 : : /* Point %C first offending character not the last good one. */
425 : 1144915 : if (*loc->nextc != '\0')
426 : 1085324 : offset++;
427 : : }
428 : : else
429 : 15697 : loc = va_arg (*text->m_args_ptr, locus *);
430 : :
431 : : /* If location[0] != UNKNOWN_LOCATION means that we already
432 : : processed one of %C/%L. */
433 : 1160612 : int loc_num = text->get_location (0) == UNKNOWN_LOCATION ? 0 : 1;
434 : 1160612 : location_t src_loc = gfc_get_location_with_offset (loc, offset);
435 : 1160612 : text->set_location (loc_num, src_loc, SHOW_RANGE_WITH_CARET);
436 : : /* Colorize the markers to match the color choices of
437 : : diagnostic_show_locus (the initial location has a color given
438 : : by the "kind" of the diagnostic, the secondary location has
439 : : color "range1"). */
440 : 1160612 : gcc_assert (curr_diagnostic != NULL);
441 : 1160612 : const char *color
442 : : = (loc_num
443 : 1160612 : ? "range1"
444 : 1160163 : : diagnostic_get_color_for_kind (curr_diagnostic->kind));
445 : 1160612 : pp_string (pp, colorize_start (pp_show_color (pp), color));
446 : 1160612 : pp_string (pp, result[loc_num]);
447 : 1160612 : pp_string (pp, colorize_stop (pp_show_color (pp)));
448 : 1160612 : return true;
449 : : }
450 : 23 : default:
451 : : /* Fall through info the middle-end decoder, as e.g. stor-layout.cc
452 : : etc. diagnostics can use the FE printer while the FE is still
453 : : active. */
454 : 23 : return default_tree_printer (pp, text, spec, precision, wide,
455 : : set_locus, hash, quoted,
456 : 23 : formatted_token_list);
457 : : }
458 : : }
459 : :
460 : : /* Return a malloc'd string describing the kind of diagnostic. The
461 : : caller is responsible for freeing the memory. */
462 : : static char *
463 : 1162786 : gfc_diagnostic_build_kind_prefix (diagnostic_context *context,
464 : : const diagnostic_info *diagnostic)
465 : : {
466 : 1162786 : static const char *const diagnostic_kind_text[] = {
467 : : #define DEFINE_DIAGNOSTIC_KIND(K, T, C) (T),
468 : : #include "gfc-diagnostic.def"
469 : : #undef DEFINE_DIAGNOSTIC_KIND
470 : : "must-not-happen"
471 : : };
472 : 1162786 : static const char *const diagnostic_kind_color[] = {
473 : : #define DEFINE_DIAGNOSTIC_KIND(K, T, C) (C),
474 : : #include "gfc-diagnostic.def"
475 : : #undef DEFINE_DIAGNOSTIC_KIND
476 : : NULL
477 : : };
478 : 1162786 : gcc_assert (diagnostic->kind < DK_LAST_DIAGNOSTIC_KIND);
479 : 1162786 : const char *text = _(diagnostic_kind_text[diagnostic->kind]);
480 : 1162786 : const char *text_cs = "", *text_ce = "";
481 : 1162786 : pretty_printer *const pp = context->get_reference_printer ();
482 : :
483 : 1162786 : if (diagnostic_kind_color[diagnostic->kind])
484 : : {
485 : 2325572 : text_cs = colorize_start (pp_show_color (pp),
486 : 1162786 : diagnostic_kind_color[diagnostic->kind]);
487 : 1162786 : text_ce = colorize_stop (pp_show_color (pp));
488 : : }
489 : 1162786 : return build_message_string ("%s%s:%s ", text_cs, text, text_ce);
490 : : }
491 : :
492 : : /* Return a malloc'd string describing a location. The caller is
493 : : responsible for freeing the memory. */
494 : : static char *
495 : 1162924 : gfc_diagnostic_build_locus_prefix (const diagnostic_location_print_policy &loc_policy,
496 : : expanded_location s,
497 : : bool colorize)
498 : : {
499 : 1162924 : const char *locus_cs = colorize_start (colorize, "locus");
500 : 1162924 : const char *locus_ce = colorize_stop (colorize);
501 : 1162924 : return (s.file == NULL
502 : 1162924 : ? build_message_string ("%s%s:%s", locus_cs, progname, locus_ce )
503 : 1162860 : : !strcmp (s.file, special_fname_builtin ())
504 : 1162860 : ? build_message_string ("%s%s:%s", locus_cs, s.file, locus_ce)
505 : 1162850 : : loc_policy.show_column_p ()
506 : 1162850 : ? build_message_string ("%s%s:%d:%d:%s", locus_cs, s.file, s.line,
507 : : s.column, locus_ce)
508 : 0 : : build_message_string ("%s%s:%d:%s", locus_cs, s.file, s.line, locus_ce));
509 : : }
510 : :
511 : : /* Return a malloc'd string describing two locations. The caller is
512 : : responsible for freeing the memory. */
513 : : static char *
514 : 155 : gfc_diagnostic_build_locus_prefix (const diagnostic_location_print_policy &loc_policy,
515 : : expanded_location s, expanded_location s2,
516 : : bool colorize)
517 : : {
518 : 155 : const char *locus_cs = colorize_start (colorize, "locus");
519 : 155 : const char *locus_ce = colorize_stop (colorize);
520 : :
521 : 155 : return (s.file == NULL
522 : 155 : ? build_message_string ("%s%s:%s", locus_cs, progname, locus_ce )
523 : 155 : : !strcmp (s.file, special_fname_builtin ())
524 : 155 : ? build_message_string ("%s%s:%s", locus_cs, s.file, locus_ce)
525 : 155 : : loc_policy.show_column_p ()
526 : 155 : ? build_message_string ("%s%s:%d:%d-%d:%s", locus_cs, s.file, s.line,
527 : : MIN (s.column, s2.column),
528 : : MAX (s.column, s2.column), locus_ce)
529 : 0 : : build_message_string ("%s%s:%d:%s", locus_cs, s.file, s.line,
530 : 155 : locus_ce));
531 : : }
532 : :
533 : : /* This function prints the locus (file:line:column), the diagnostic kind
534 : : (Error, Warning) and (optionally) the relevant lines of code with
535 : : annotation lines with '1' and/or '2' below them.
536 : :
537 : : With -fdiagnostic-show-caret (the default) it prints:
538 : :
539 : : [locus of primary range]:
540 : :
541 : : some code
542 : : 1
543 : : Error: Some error at (1)
544 : :
545 : : With -fno-diagnostic-show-caret or if the primary range is not
546 : : valid, it prints:
547 : :
548 : : [locus of primary range]: Error: Some error at (1) and (2)
549 : : */
550 : : static void
551 : 1162786 : gfc_diagnostic_text_starter (diagnostic_text_output_format &text_output,
552 : : const diagnostic_info *diagnostic)
553 : : {
554 : 1162786 : diagnostic_context *const context = &text_output.get_context ();
555 : 1162786 : pretty_printer *const pp = text_output.get_printer ();
556 : 1162786 : char * kind_prefix = gfc_diagnostic_build_kind_prefix (context, diagnostic);
557 : :
558 : 1162786 : expanded_location s1 = diagnostic_expand_location (diagnostic);
559 : 1162786 : expanded_location s2;
560 : 1162786 : bool one_locus = diagnostic->richloc->get_num_locations () < 2;
561 : 1162786 : bool same_locus = false;
562 : :
563 : 1162786 : if (!one_locus)
564 : : {
565 : 449 : s2 = diagnostic_expand_location (diagnostic, 1);
566 : 898 : same_locus = diagnostic_same_line (context, s1, s2);
567 : : }
568 : :
569 : 1162786 : diagnostic_location_print_policy loc_policy (text_output);
570 : 1162786 : const bool colorize = pp_show_color (pp);
571 : 1162786 : char * locus_prefix = (one_locus || !same_locus)
572 : 1162786 : ? gfc_diagnostic_build_locus_prefix (loc_policy, s1, colorize)
573 : 155 : : gfc_diagnostic_build_locus_prefix (loc_policy, s1, s2, colorize);
574 : :
575 : 1162786 : if (!context->m_source_printing.enabled
576 : 16194 : || diagnostic_location (diagnostic, 0) <= BUILTINS_LOCATION
577 : 1178980 : || diagnostic_location (diagnostic, 0) == context->m_last_location)
578 : : {
579 : 1146592 : pp_set_prefix (pp,
580 : : concat (locus_prefix, " ", kind_prefix, NULL));
581 : 1146592 : free (locus_prefix);
582 : :
583 : 1146592 : if (one_locus || same_locus)
584 : : {
585 : 1146300 : free (kind_prefix);
586 : 1146300 : return;
587 : : }
588 : : /* In this case, we print the previous locus and prefix as:
589 : :
590 : : [locus]:[prefix]: (1)
591 : :
592 : : and we flush with a new line before setting the new prefix. */
593 : 292 : pp_string (pp, "(1)");
594 : 292 : pp_newline (pp);
595 : 292 : locus_prefix = gfc_diagnostic_build_locus_prefix (loc_policy, s2, colorize);
596 : 292 : pp_set_prefix (pp,
597 : : concat (locus_prefix, " ", kind_prefix, NULL));
598 : 292 : free (kind_prefix);
599 : 292 : free (locus_prefix);
600 : : }
601 : : else
602 : : {
603 : 16194 : pp_verbatim (pp, "%s", locus_prefix);
604 : 16194 : free (locus_prefix);
605 : : /* Fortran uses an empty line between locus and caret line. */
606 : 16194 : pp_newline (pp);
607 : 16194 : pp_set_prefix (pp, NULL);
608 : 16194 : pp_newline (pp);
609 : 16194 : diagnostic_show_locus (context,
610 : 16194 : text_output.get_source_printing_options (),
611 : 16194 : diagnostic->richloc, diagnostic->kind,
612 : : pp);
613 : : /* If the caret line was shown, the prefix does not contain the
614 : : locus. */
615 : 16194 : pp_set_prefix (pp, kind_prefix);
616 : : }
617 : : }
618 : :
619 : : static void
620 : 1 : gfc_diagnostic_start_span (const diagnostic_location_print_policy &loc_policy,
621 : : pretty_printer *pp,
622 : : expanded_location exploc)
623 : : {
624 : 1 : const bool colorize = pp_show_color (pp);
625 : 1 : char *locus_prefix
626 : 1 : = gfc_diagnostic_build_locus_prefix (loc_policy, exploc, colorize);
627 : 1 : pp_verbatim (pp, "%s", locus_prefix);
628 : 1 : free (locus_prefix);
629 : 1 : pp_newline (pp);
630 : : /* Fortran uses an empty line between locus and caret line. */
631 : 1 : pp_newline (pp);
632 : 1 : }
633 : :
634 : :
635 : : static void
636 : 1162786 : gfc_diagnostic_text_finalizer (diagnostic_text_output_format &text_output,
637 : : const diagnostic_info *diagnostic ATTRIBUTE_UNUSED,
638 : : diagnostic_t orig_diag_kind ATTRIBUTE_UNUSED)
639 : : {
640 : 1162786 : pretty_printer *const pp = text_output.get_printer ();
641 : 1162786 : pp_destroy_prefix (pp);
642 : 1162786 : pp_newline_and_flush (pp);
643 : 1162786 : }
644 : :
645 : : /* Immediate warning (i.e. do not buffer the warning) with an explicit
646 : : location. */
647 : :
648 : : bool
649 : 3 : gfc_warning_now_at (location_t loc, int opt, const char *gmsgid, ...)
650 : : {
651 : 3 : va_list argp;
652 : 3 : diagnostic_info diagnostic;
653 : 3 : rich_location rich_loc (line_table, loc);
654 : 3 : bool ret;
655 : :
656 : 3 : va_start (argp, gmsgid);
657 : 3 : diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc, DK_WARNING);
658 : 3 : diagnostic.option_id = opt;
659 : 3 : ret = gfc_report_diagnostic (&diagnostic);
660 : 3 : va_end (argp);
661 : 6 : return ret;
662 : 3 : }
663 : :
664 : : /* Immediate warning (i.e. do not buffer the warning). */
665 : :
666 : : bool
667 : 26044 : gfc_warning_now (int opt, const char *gmsgid, ...)
668 : : {
669 : 26044 : va_list argp;
670 : 26044 : diagnostic_info diagnostic;
671 : 26044 : rich_location rich_loc (line_table, UNKNOWN_LOCATION);
672 : 26044 : bool ret;
673 : :
674 : 26044 : va_start (argp, gmsgid);
675 : 26044 : diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc,
676 : : DK_WARNING);
677 : 26044 : diagnostic.option_id = opt;
678 : 26044 : ret = gfc_report_diagnostic (&diagnostic);
679 : 26044 : va_end (argp);
680 : 52088 : return ret;
681 : 26044 : }
682 : :
683 : : /* Internal warning, do not buffer. */
684 : :
685 : : bool
686 : 0 : gfc_warning_internal (int opt, const char *gmsgid, ...)
687 : : {
688 : 0 : va_list argp;
689 : 0 : diagnostic_info diagnostic;
690 : 0 : rich_location rich_loc (line_table, UNKNOWN_LOCATION);
691 : 0 : bool ret;
692 : :
693 : 0 : va_start (argp, gmsgid);
694 : 0 : diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc,
695 : : DK_WARNING);
696 : 0 : diagnostic.option_id = opt;
697 : 0 : ret = gfc_report_diagnostic (&diagnostic);
698 : 0 : va_end (argp);
699 : 0 : return ret;
700 : 0 : }
701 : :
702 : : /* Immediate error (i.e. do not buffer). */
703 : :
704 : : void
705 : 403 : gfc_error_now (const char *gmsgid, ...)
706 : : {
707 : 403 : va_list argp;
708 : 403 : diagnostic_info diagnostic;
709 : 403 : rich_location rich_loc (line_table, UNKNOWN_LOCATION);
710 : :
711 : 403 : error_buffer->flag = true;
712 : :
713 : 403 : va_start (argp, gmsgid);
714 : 403 : diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc, DK_ERROR);
715 : 403 : gfc_report_diagnostic (&diagnostic);
716 : 403 : va_end (argp);
717 : 403 : }
718 : :
719 : :
720 : : /* Fatal error, never returns. */
721 : :
722 : : void
723 : 8 : gfc_fatal_error (const char *gmsgid, ...)
724 : : {
725 : 8 : va_list argp;
726 : 8 : diagnostic_info diagnostic;
727 : 8 : rich_location rich_loc (line_table, UNKNOWN_LOCATION);
728 : :
729 : 8 : va_start (argp, gmsgid);
730 : 8 : diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc, DK_FATAL);
731 : 8 : gfc_report_diagnostic (&diagnostic);
732 : 0 : va_end (argp);
733 : :
734 : 0 : gcc_unreachable ();
735 : : }
736 : :
737 : : /* Clear the warning flag. */
738 : :
739 : : void
740 : 12526024 : gfc_clear_warning (void)
741 : : {
742 : 12526024 : gfc_clear_diagnostic_buffer (pp_warning_buffer);
743 : 12526024 : }
744 : :
745 : :
746 : : /* Check to see if any warnings have been saved.
747 : : If so, print the warning. */
748 : :
749 : : void
750 : 1233976 : gfc_warning_check (void)
751 : : {
752 : 1233976 : if (! pp_warning_buffer->empty_p ())
753 : 3959 : global_dc->flush_diagnostic_buffer (*pp_warning_buffer);
754 : 1233976 : }
755 : :
756 : :
757 : : /* Issue an error. */
758 : :
759 : : static void
760 : 1158463 : gfc_error_opt (int opt, const char *gmsgid, va_list ap)
761 : : {
762 : 1158463 : va_list argp;
763 : 1158463 : va_copy (argp, ap);
764 : :
765 : 1158463 : if (warnings_not_errors)
766 : : {
767 : 44 : gfc_warning (opt, gmsgid, argp);
768 : 44 : va_end (argp);
769 : 17227 : return;
770 : : }
771 : :
772 : 1158419 : if (suppress_errors)
773 : : {
774 : 17183 : va_end (argp);
775 : 17183 : return;
776 : : }
777 : :
778 : 1141236 : diagnostic_info diagnostic;
779 : 1141236 : rich_location richloc (line_table, UNKNOWN_LOCATION);
780 : 1141236 : diagnostic_buffer *old_buffer = global_dc->get_diagnostic_buffer ();
781 : 1141236 : gcc_assert (!old_buffer);
782 : :
783 : 1141236 : gfc_clear_diagnostic_buffer (pp_error_buffer);
784 : :
785 : 1141236 : if (buffered_p)
786 : 1134627 : global_dc->set_diagnostic_buffer (pp_error_buffer);
787 : :
788 : 1141236 : diagnostic_set_info (&diagnostic, gmsgid, &argp, &richloc, DK_ERROR);
789 : 1141236 : gfc_report_diagnostic (&diagnostic);
790 : :
791 : 1141236 : if (buffered_p)
792 : 1134627 : global_dc->set_diagnostic_buffer (old_buffer);
793 : :
794 : 1141236 : va_end (argp);
795 : 1141236 : }
796 : :
797 : :
798 : : void
799 : 250 : gfc_error_opt (int opt, const char *gmsgid, ...)
800 : : {
801 : 250 : va_list argp;
802 : 250 : va_start (argp, gmsgid);
803 : 250 : gfc_error_opt (opt, gmsgid, argp);
804 : 250 : va_end (argp);
805 : 250 : }
806 : :
807 : :
808 : : void
809 : 1157464 : gfc_error (const char *gmsgid, ...)
810 : : {
811 : 1157464 : va_list argp;
812 : 1157464 : va_start (argp, gmsgid);
813 : 1157464 : gfc_error_opt (0, gmsgid, argp);
814 : 1157464 : va_end (argp);
815 : 1157464 : }
816 : :
817 : :
818 : : /* This shouldn't happen... but sometimes does. */
819 : :
820 : : void
821 : 0 : gfc_internal_error (const char *gmsgid, ...)
822 : : {
823 : 0 : int e, w;
824 : 0 : va_list argp;
825 : 0 : diagnostic_info diagnostic;
826 : 0 : rich_location rich_loc (line_table, UNKNOWN_LOCATION);
827 : :
828 : 0 : gfc_get_errors (&w, &e);
829 : 0 : if (e > 0)
830 : 0 : exit(EXIT_FAILURE);
831 : :
832 : 0 : va_start (argp, gmsgid);
833 : 0 : diagnostic_set_info (&diagnostic, gmsgid, &argp, &rich_loc, DK_ICE);
834 : 0 : gfc_report_diagnostic (&diagnostic);
835 : 0 : va_end (argp);
836 : :
837 : 0 : gcc_unreachable ();
838 : : }
839 : :
840 : :
841 : : /* Clear the error flag when we start to compile a source line. */
842 : :
843 : : void
844 : 4773614 : gfc_clear_error (void)
845 : : {
846 : 4773614 : error_buffer->flag = false;
847 : 4773614 : warnings_not_errors = false;
848 : 4773614 : gfc_clear_diagnostic_buffer (pp_error_buffer);
849 : 4773614 : }
850 : :
851 : :
852 : : /* Tests the state of error_flag. */
853 : :
854 : : bool
855 : 1562507 : gfc_error_flag_test (void)
856 : : {
857 : 1562507 : return (error_buffer->flag
858 : 1562507 : || !pp_error_buffer->empty_p ());
859 : : }
860 : :
861 : :
862 : : /* Check to see if any errors have been saved.
863 : : If so, print the error. Returns the state of error_flag. */
864 : :
865 : : bool
866 : 5235 : gfc_error_check (void)
867 : : {
868 : 5235 : if (error_buffer->flag
869 : 5235 : || ! pp_error_buffer->empty_p ())
870 : : {
871 : 2985 : error_buffer->flag = false;
872 : 2985 : global_dc->flush_diagnostic_buffer (*pp_error_buffer);
873 : 2985 : return true;
874 : : }
875 : :
876 : : return false;
877 : : }
878 : :
879 : : /* Move the text buffered from FROM to TO, then clear
880 : : FROM. Independently if there was text in FROM, TO is also
881 : : cleared. */
882 : :
883 : : static void
884 : 2871246 : gfc_move_error_buffer_from_to (gfc_error_buffer * buffer_from,
885 : : gfc_error_buffer * buffer_to)
886 : : {
887 : 2871246 : diagnostic_buffer * from = &(buffer_from->buffer);
888 : 2871246 : diagnostic_buffer * to = &(buffer_to->buffer);
889 : :
890 : 2871246 : buffer_to->flag = buffer_from->flag;
891 : 2871246 : buffer_from->flag = false;
892 : :
893 : 2871246 : gfc_clear_diagnostic_buffer (to);
894 : :
895 : 2871246 : if (! from->empty_p ())
896 : : {
897 : 101950 : from->move_to (*to);
898 : 101950 : gfc_clear_diagnostic_buffer (from);
899 : : }
900 : 2871246 : }
901 : :
902 : : /* Save the existing error state. */
903 : :
904 : : void
905 : 1473017 : gfc_push_error (gfc_error_buffer *err)
906 : : {
907 : 1473017 : gfc_move_error_buffer_from_to (error_buffer, err);
908 : 1473017 : }
909 : :
910 : :
911 : : /* Restore a previous pushed error state. */
912 : :
913 : : void
914 : 1398229 : gfc_pop_error (gfc_error_buffer *err)
915 : : {
916 : 1398229 : gfc_move_error_buffer_from_to (err, error_buffer);
917 : 1398229 : }
918 : :
919 : :
920 : : /* Free a pushed error state, but keep the current error state. */
921 : :
922 : : void
923 : 74616 : gfc_free_error (gfc_error_buffer *err)
924 : : {
925 : 74616 : gfc_clear_diagnostic_buffer (&(err->buffer));
926 : 74616 : }
927 : :
928 : :
929 : : /* Report the number of warnings and errors that occurred to the caller. */
930 : :
931 : : void
932 : 337776 : gfc_get_errors (int *w, int *e)
933 : : {
934 : 337776 : if (w != NULL)
935 : 288397 : *w = warningcount + werrorcount;
936 : 337776 : if (e != NULL)
937 : 337776 : *e = errorcount + sorrycount + werrorcount;
938 : 337776 : }
939 : :
940 : :
941 : : /* Switch errors into warnings. */
942 : :
943 : : void
944 : 48217 : gfc_errors_to_warnings (bool f)
945 : : {
946 : 48217 : warnings_not_errors = f;
947 : 48217 : }
948 : :
949 : : void
950 : 30462 : gfc_diagnostics_init (void)
951 : : {
952 : 30462 : diagnostic_text_starter (global_dc) = gfc_diagnostic_text_starter;
953 : 30462 : diagnostic_start_span (global_dc) = gfc_diagnostic_start_span;
954 : 30462 : diagnostic_text_finalizer (global_dc) = gfc_diagnostic_text_finalizer;
955 : 30462 : global_dc->set_format_decoder (gfc_format_decoder);
956 : 30462 : global_dc->m_source_printing.caret_chars[0] = '1';
957 : 30462 : global_dc->m_source_printing.caret_chars[1] = '2';
958 : 30462 : pp_warning_buffer = new diagnostic_buffer (*global_dc);
959 : 30462 : error_buffer = new gfc_error_buffer ();
960 : 30462 : pp_error_buffer = &(error_buffer->buffer);
961 : 30462 : }
962 : :
963 : : void
964 : 30436 : gfc_diagnostics_finish (void)
965 : : {
966 : 30436 : tree_diagnostics_defaults (global_dc);
967 : : /* We still want to use the gfc starter and finalizer, not the tree
968 : : defaults. */
969 : 30436 : diagnostic_text_starter (global_dc) = gfc_diagnostic_text_starter;
970 : 30436 : diagnostic_text_finalizer (global_dc) = gfc_diagnostic_text_finalizer;
971 : 30436 : global_dc->m_source_printing.caret_chars[0] = '^';
972 : 30436 : global_dc->m_source_printing.caret_chars[1] = '^';
973 : 60872 : delete error_buffer;
974 : 30436 : error_buffer = nullptr;
975 : 30436 : pp_error_buffer = nullptr;
976 : 30436 : }
|