1 /* Language-independent diagnostic subroutines for the GNU Compiler Collection 2 Copyright (C) 1999-2022 Free Software Foundation, Inc. 3 Contributed by Gabriel Dos Reis <gdr (at) codesourcery.com> 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 22 /* This file implements the language independent aspect of diagnostic 23 message module. */ 24 25 #include "config.h" 26 #include "system.h" 27 #include "coretypes.h" 28 #include "version.h" 29 #include "demangle.h" 30 #include "intl.h" 31 #include "backtrace.h" 32 #include "diagnostic.h" 33 #include "diagnostic-color.h" 34 #include "diagnostic-url.h" 35 #include "diagnostic-metadata.h" 36 #include "diagnostic-path.h" 37 #include "edit-context.h" 38 #include "selftest.h" 39 #include "selftest-diagnostic.h" 40 #include "opts.h" 41 #include "cpplib.h" 42 43 #ifdef HAVE_TERMIOS_H 44 # include <termios.h> 45 #endif 46 47 #ifdef GWINSZ_IN_SYS_IOCTL 48 # include <sys/ioctl.h> 49 #endif 50 51 /* Disable warnings about quoting issues in the pp_xxx calls below 52 that (intentionally) don't follow GCC diagnostic conventions. */ 53 #if __GNUC__ >= 10 54 # pragma GCC diagnostic push 55 # pragma GCC diagnostic ignored "-Wformat-diag" 56 #endif 57 58 #define pedantic_warning_kind(DC) \ 59 ((DC)->pedantic_errors ? DK_ERROR : DK_WARNING) 60 #define permissive_error_kind(DC) ((DC)->permissive ? DK_WARNING : DK_ERROR) 61 #define permissive_error_option(DC) ((DC)->opt_permissive) 62 63 /* Prototypes. */ 64 static bool diagnostic_impl (rich_location *, const diagnostic_metadata *, 65 int, const char *, 66 va_list *, diagnostic_t) ATTRIBUTE_GCC_DIAG(4,0); 67 static bool diagnostic_n_impl (rich_location *, const diagnostic_metadata *, 68 int, unsigned HOST_WIDE_INT, 69 const char *, const char *, va_list *, 70 diagnostic_t) ATTRIBUTE_GCC_DIAG(6,0); 71 72 static void error_recursion (diagnostic_context *) ATTRIBUTE_NORETURN; 73 static void real_abort (void) ATTRIBUTE_NORETURN; 74 75 /* Name of program invoked, sans directories. */ 76 77 const char *progname; 78 79 /* A diagnostic_context surrogate for stderr. */ 80 static diagnostic_context global_diagnostic_context; 81 diagnostic_context *global_dc = &global_diagnostic_context; 82 83 /* Return a malloc'd string containing MSG formatted a la printf. The 85 caller is responsible for freeing the memory. */ 86 char * 87 build_message_string (const char *msg, ...) 88 { 89 char *str; 90 va_list ap; 91 92 va_start (ap, msg); 93 str = xvasprintf (msg, ap); 94 va_end (ap); 95 96 return str; 97 } 98 99 /* Same as diagnostic_build_prefix, but only the source FILE is given. */ 100 char * 101 file_name_as_prefix (diagnostic_context *context, const char *f) 102 { 103 const char *locus_cs 104 = colorize_start (pp_show_color (context->printer), "locus"); 105 const char *locus_ce = colorize_stop (pp_show_color (context->printer)); 106 return build_message_string ("%s%s:%s ", locus_cs, f, locus_ce); 107 } 108 109 110 111 /* Return the value of the getenv("COLUMNS") as an integer. If the 113 value is not set to a positive integer, use ioctl to get the 114 terminal width. If it fails, return INT_MAX. */ 115 int 116 get_terminal_width (void) 117 { 118 const char * s = getenv ("COLUMNS"); 119 if (s != NULL) { 120 int n = atoi (s); 121 if (n > 0) 122 return n; 123 } 124 125 #ifdef TIOCGWINSZ 126 struct winsize w; 127 w.ws_col = 0; 128 if (ioctl (0, TIOCGWINSZ, &w) == 0 && w.ws_col > 0) 129 return w.ws_col; 130 #endif 131 132 return INT_MAX; 133 } 134 135 /* Set caret_max_width to value. */ 136 void 137 diagnostic_set_caret_max_width (diagnostic_context *context, int value) 138 { 139 /* One minus to account for the leading empty space. */ 140 value = value ? value - 1 141 : (isatty (fileno (pp_buffer (context->printer)->stream)) 142 ? get_terminal_width () - 1: INT_MAX); 143 144 if (value <= 0) 145 value = INT_MAX; 146 147 context->caret_max_width = value; 148 } 149 150 /* Default implementation of final_cb. */ 151 152 static void 153 default_diagnostic_final_cb (diagnostic_context *context) 154 { 155 /* Some of the errors may actually have been warnings. */ 156 if (diagnostic_kind_count (context, DK_WERROR)) 157 { 158 /* -Werror was given. */ 159 if (context->warning_as_error_requested) 160 pp_verbatim (context->printer, 161 _("%s: all warnings being treated as errors"), 162 progname); 163 /* At least one -Werror= was given. */ 164 else 165 pp_verbatim (context->printer, 166 _("%s: some warnings being treated as errors"), 167 progname); 168 pp_newline_and_flush (context->printer); 169 } 170 } 171 172 /* Initialize the diagnostic message outputting machinery. */ 173 void 174 diagnostic_initialize (diagnostic_context *context, int n_opts) 175 { 176 int i; 177 178 /* Allocate a basic pretty-printer. Clients will replace this a 179 much more elaborated pretty-printer if they wish. */ 180 context->printer = XNEW (pretty_printer); 181 new (context->printer) pretty_printer (); 182 183 memset (context->diagnostic_count, 0, sizeof context->diagnostic_count); 184 context->warning_as_error_requested = false; 185 context->n_opts = n_opts; 186 context->classify_diagnostic = XNEWVEC (diagnostic_t, n_opts); 187 for (i = 0; i < n_opts; i++) 188 context->classify_diagnostic[i] = DK_UNSPECIFIED; 189 context->show_caret = false; 190 diagnostic_set_caret_max_width (context, pp_line_cutoff (context->printer)); 191 for (i = 0; i < rich_location::STATICALLY_ALLOCATED_RANGES; i++) 192 context->caret_chars[i] = '^'; 193 context->show_cwe = false; 194 context->path_format = DPF_NONE; 195 context->show_path_depths = false; 196 context->show_option_requested = false; 197 context->abort_on_error = false; 198 context->show_column = false; 199 context->pedantic_errors = false; 200 context->permissive = false; 201 context->opt_permissive = 0; 202 context->fatal_errors = false; 203 context->dc_inhibit_warnings = false; 204 context->dc_warn_system_headers = false; 205 context->max_errors = 0; 206 context->internal_error = NULL; 207 diagnostic_starter (context) = default_diagnostic_starter; 208 context->start_span = default_diagnostic_start_span_fn; 209 diagnostic_finalizer (context) = default_diagnostic_finalizer; 210 context->option_enabled = NULL; 211 context->option_state = NULL; 212 context->option_name = NULL; 213 context->get_option_url = NULL; 214 context->last_location = UNKNOWN_LOCATION; 215 context->last_module = 0; 216 context->x_data = NULL; 217 context->lock = 0; 218 context->inhibit_notes_p = false; 219 context->colorize_source_p = false; 220 context->show_labels_p = false; 221 context->show_line_numbers_p = false; 222 context->min_margin_width = 0; 223 context->show_ruler_p = false; 224 context->report_bug = false; 225 226 if (const char *var = getenv ("GCC_EXTRA_DIAGNOSTIC_OUTPUT")) 227 { 228 if (!strcmp (var, "fixits-v1")) 229 context->extra_output_kind = EXTRA_DIAGNOSTIC_OUTPUT_fixits_v1; 230 else if (!strcmp (var, "fixits-v2")) 231 context->extra_output_kind = EXTRA_DIAGNOSTIC_OUTPUT_fixits_v2; 232 /* Silently ignore unrecognized values. */ 233 } 234 context->column_unit = DIAGNOSTICS_COLUMN_UNIT_DISPLAY; 235 context->column_origin = 1; 236 context->tabstop = 8; 237 context->escape_format = DIAGNOSTICS_ESCAPE_FORMAT_UNICODE; 238 context->edit_context_ptr = NULL; 239 context->diagnostic_group_nesting_depth = 0; 240 context->diagnostic_group_emission_count = 0; 241 context->begin_group_cb = NULL; 242 context->end_group_cb = NULL; 243 context->final_cb = default_diagnostic_final_cb; 244 context->includes_seen = NULL; 245 } 246 247 /* Maybe initialize the color support. We require clients to do this 248 explicitly, since most clients don't want color. When called 249 without a VALUE, it initializes with DIAGNOSTICS_COLOR_DEFAULT. */ 250 251 void 252 diagnostic_color_init (diagnostic_context *context, int value /*= -1 */) 253 { 254 /* value == -1 is the default value. */ 255 if (value < 0) 256 { 257 /* If DIAGNOSTICS_COLOR_DEFAULT is -1, default to 258 -fdiagnostics-color=auto if GCC_COLORS is in the environment, 259 otherwise default to -fdiagnostics-color=never, for other 260 values default to that 261 -fdiagnostics-color={never,auto,always}. */ 262 if (DIAGNOSTICS_COLOR_DEFAULT == -1) 263 { 264 if (!getenv ("GCC_COLORS")) 265 return; 266 value = DIAGNOSTICS_COLOR_AUTO; 267 } 268 else 269 value = DIAGNOSTICS_COLOR_DEFAULT; 270 } 271 pp_show_color (context->printer) 272 = colorize_init ((diagnostic_color_rule_t) value); 273 } 274 275 /* Initialize URL support within CONTEXT based on VALUE, handling "auto". */ 276 277 void 278 diagnostic_urls_init (diagnostic_context *context, int value /*= -1 */) 279 { 280 /* value == -1 is the default value. */ 281 if (value < 0) 282 { 283 /* If DIAGNOSTICS_URLS_DEFAULT is -1, default to 284 -fdiagnostics-urls=auto if GCC_URLS or TERM_URLS is in the 285 environment, otherwise default to -fdiagnostics-urls=never, 286 for other values default to that 287 -fdiagnostics-urls={never,auto,always}. */ 288 if (DIAGNOSTICS_URLS_DEFAULT == -1) 289 { 290 if (!getenv ("GCC_URLS") && !getenv ("TERM_URLS")) 291 return; 292 value = DIAGNOSTICS_URL_AUTO; 293 } 294 else 295 value = DIAGNOSTICS_URLS_DEFAULT; 296 } 297 298 context->printer->url_format 299 = determine_url_format ((diagnostic_url_rule_t) value); 300 } 301 302 /* Create the file_cache, if not already created, and tell it how to 303 translate files on input. */ 304 void diagnostic_initialize_input_context (diagnostic_context *context, 305 diagnostic_input_charset_callback ccb, 306 bool should_skip_bom) 307 { 308 if (!context->m_file_cache) 309 context->m_file_cache = new file_cache; 310 context->m_file_cache->initialize_input_context (ccb, should_skip_bom); 311 } 312 313 /* Do any cleaning up required after the last diagnostic is emitted. */ 314 315 void 316 diagnostic_finish (diagnostic_context *context) 317 { 318 if (context->final_cb) 319 context->final_cb (context); 320 321 diagnostic_file_cache_fini (); 322 323 XDELETEVEC (context->classify_diagnostic); 324 context->classify_diagnostic = NULL; 325 326 /* diagnostic_initialize allocates context->printer using XNEW 327 and placement-new. */ 328 context->printer->~pretty_printer (); 329 XDELETE (context->printer); 330 context->printer = NULL; 331 332 if (context->edit_context_ptr) 333 { 334 delete context->edit_context_ptr; 335 context->edit_context_ptr = NULL; 336 } 337 338 if (context->includes_seen) 339 { 340 delete context->includes_seen; 341 context->includes_seen = nullptr; 342 } 343 } 344 345 /* Initialize DIAGNOSTIC, where the message MSG has already been 346 translated. */ 347 void 348 diagnostic_set_info_translated (diagnostic_info *diagnostic, const char *msg, 349 va_list *args, rich_location *richloc, 350 diagnostic_t kind) 351 { 352 gcc_assert (richloc); 353 diagnostic->message.err_no = errno; 354 diagnostic->message.args_ptr = args; 355 diagnostic->message.format_spec = msg; 356 diagnostic->message.m_richloc = richloc; 357 diagnostic->richloc = richloc; 358 diagnostic->metadata = NULL; 359 diagnostic->kind = kind; 360 diagnostic->option_index = 0; 361 } 362 363 /* Initialize DIAGNOSTIC, where the message GMSGID has not yet been 364 translated. */ 365 void 366 diagnostic_set_info (diagnostic_info *diagnostic, const char *gmsgid, 367 va_list *args, rich_location *richloc, 368 diagnostic_t kind) 369 { 370 gcc_assert (richloc); 371 diagnostic_set_info_translated (diagnostic, _(gmsgid), args, richloc, kind); 372 } 373 374 static const char *const diagnostic_kind_color[] = { 375 #define DEFINE_DIAGNOSTIC_KIND(K, T, C) (C), 376 #include "diagnostic.def" 377 #undef DEFINE_DIAGNOSTIC_KIND 378 NULL 379 }; 380 381 /* Get a color name for diagnostics of type KIND 382 Result could be NULL. */ 383 384 const char * 385 diagnostic_get_color_for_kind (diagnostic_t kind) 386 { 387 return diagnostic_kind_color[kind]; 388 } 389 390 /* Given an expanded_location, convert the column (which is in 1-based bytes) 391 to the requested units, without converting the origin. 392 Return -1 if the column is invalid (<= 0). */ 393 394 static int 395 convert_column_unit (enum diagnostics_column_unit column_unit, 396 int tabstop, 397 expanded_location s) 398 { 399 if (s.column <= 0) 400 return -1; 401 402 switch (column_unit) 403 { 404 default: 405 gcc_unreachable (); 406 407 case DIAGNOSTICS_COLUMN_UNIT_DISPLAY: 408 { 409 cpp_char_column_policy policy (tabstop, cpp_wcwidth); 410 return location_compute_display_column (s, policy); 411 } 412 413 case DIAGNOSTICS_COLUMN_UNIT_BYTE: 414 return s.column; 415 } 416 } 417 418 /* Given an expanded_location, convert the column (which is in 1-based bytes) 419 to the requested units and origin. Return -1 if the column is 420 invalid (<= 0). */ 421 int 422 diagnostic_converted_column (diagnostic_context *context, expanded_location s) 423 { 424 int one_based_col 425 = convert_column_unit (context->column_unit, context->tabstop, s); 426 if (one_based_col <= 0) 427 return -1; 428 return one_based_col + (context->column_origin - 1); 429 } 430 431 /* Return a formatted line and column ':%line:%column'. Elided if 432 line == 0 or col < 0. (A column of 0 may be valid due to the 433 -fdiagnostics-column-origin option.) 434 The result is a statically allocated buffer. */ 435 436 static const char * 437 maybe_line_and_column (int line, int col) 438 { 439 static char result[32]; 440 441 if (line) 442 { 443 size_t l 444 = snprintf (result, sizeof (result), 445 col >= 0 ? ":%d:%d" : ":%d", line, col); 446 gcc_checking_assert (l < sizeof (result)); 447 } 448 else 449 result[0] = 0; 450 return result; 451 } 452 453 /* Return a malloc'd string describing a location e.g. "foo.c:42:10". 454 The caller is responsible for freeing the memory. */ 455 456 static char * 457 diagnostic_get_location_text (diagnostic_context *context, 458 expanded_location s) 459 { 460 pretty_printer *pp = context->printer; 461 const char *locus_cs = colorize_start (pp_show_color (pp), "locus"); 462 const char *locus_ce = colorize_stop (pp_show_color (pp)); 463 const char *file = s.file ? s.file : progname; 464 int line = 0; 465 int col = -1; 466 if (strcmp (file, N_("<built-in>"))) 467 { 468 line = s.line; 469 if (context->show_column) 470 col = diagnostic_converted_column (context, s); 471 } 472 473 const char *line_col = maybe_line_and_column (line, col); 474 return build_message_string ("%s%s%s:%s", locus_cs, file, 475 line_col, locus_ce); 476 } 477 478 static const char *const diagnostic_kind_text[] = { 479 #define DEFINE_DIAGNOSTIC_KIND(K, T, C) (T), 480 #include "diagnostic.def" 481 #undef DEFINE_DIAGNOSTIC_KIND 482 "must-not-happen" 483 }; 484 485 /* Return a malloc'd string describing a location and the severity of the 486 diagnostic, e.g. "foo.c:42:10: error: ". The caller is responsible for 487 freeing the memory. */ 488 char * 489 diagnostic_build_prefix (diagnostic_context *context, 490 const diagnostic_info *diagnostic) 491 { 492 gcc_assert (diagnostic->kind < DK_LAST_DIAGNOSTIC_KIND); 493 494 const char *text = _(diagnostic_kind_text[diagnostic->kind]); 495 const char *text_cs = "", *text_ce = ""; 496 pretty_printer *pp = context->printer; 497 498 if (diagnostic_kind_color[diagnostic->kind]) 499 { 500 text_cs = colorize_start (pp_show_color (pp), 501 diagnostic_kind_color[diagnostic->kind]); 502 text_ce = colorize_stop (pp_show_color (pp)); 503 } 504 505 expanded_location s = diagnostic_expand_location (diagnostic); 506 char *location_text = diagnostic_get_location_text (context, s); 507 508 char *result = build_message_string ("%s %s%s%s", location_text, 509 text_cs, text, text_ce); 510 free (location_text); 511 return result; 512 } 513 514 /* Functions at which to stop the backtrace print. It's not 515 particularly helpful to print the callers of these functions. */ 516 517 static const char * const bt_stop[] = 518 { 519 "main", 520 "toplev::main", 521 "execute_one_pass", 522 "compile_file", 523 }; 524 525 /* A callback function passed to the backtrace_full function. */ 526 527 static int 528 bt_callback (void *data, uintptr_t pc, const char *filename, int lineno, 529 const char *function) 530 { 531 int *pcount = (int *) data; 532 533 /* If we don't have any useful information, don't print 534 anything. */ 535 if (filename == NULL && function == NULL) 536 return 0; 537 538 /* Skip functions in diagnostic.cc. */ 539 if (*pcount == 0 540 && filename != NULL 541 && strcmp (lbasename (filename), "diagnostic.cc") == 0) 542 return 0; 543 544 /* Print up to 20 functions. We could make this a --param, but 545 since this is only for debugging just use a constant for now. */ 546 if (*pcount >= 20) 547 { 548 /* Returning a non-zero value stops the backtrace. */ 549 return 1; 550 } 551 ++*pcount; 552 553 char *alc = NULL; 554 if (function != NULL) 555 { 556 char *str = cplus_demangle_v3 (function, 557 (DMGL_VERBOSE | DMGL_ANSI 558 | DMGL_GNU_V3 | DMGL_PARAMS)); 559 if (str != NULL) 560 { 561 alc = str; 562 function = str; 563 } 564 565 for (size_t i = 0; i < ARRAY_SIZE (bt_stop); ++i) 566 { 567 size_t len = strlen (bt_stop[i]); 568 if (strncmp (function, bt_stop[i], len) == 0 569 && (function[len] == '\0' || function[len] == '(')) 570 { 571 if (alc != NULL) 572 free (alc); 573 /* Returning a non-zero value stops the backtrace. */ 574 return 1; 575 } 576 } 577 } 578 579 fprintf (stderr, "0x%lx %s\n\t%s:%d\n", 580 (unsigned long) pc, 581 function == NULL ? "???" : function, 582 filename == NULL ? "???" : filename, 583 lineno); 584 585 if (alc != NULL) 586 free (alc); 587 588 return 0; 589 } 590 591 /* A callback function passed to the backtrace_full function. This is 592 called if backtrace_full has an error. */ 593 594 static void 595 bt_err_callback (void *data ATTRIBUTE_UNUSED, const char *msg, int errnum) 596 { 597 if (errnum < 0) 598 { 599 /* This means that no debug info was available. Just quietly 600 skip printing backtrace info. */ 601 return; 602 } 603 fprintf (stderr, "%s%s%s\n", msg, errnum == 0 ? "" : ": ", 604 errnum == 0 ? "" : xstrerror (errnum)); 605 } 606 607 /* Check if we've met the maximum error limit, and if so fatally exit 608 with a message. CONTEXT is the context to check, and FLUSH 609 indicates whether a diagnostic_finish call is needed. */ 610 611 void 612 diagnostic_check_max_errors (diagnostic_context *context, bool flush) 613 { 614 if (!context->max_errors) 615 return; 616 617 int count = (diagnostic_kind_count (context, DK_ERROR) 618 + diagnostic_kind_count (context, DK_SORRY) 619 + diagnostic_kind_count (context, DK_WERROR)); 620 621 if (count >= context->max_errors) 622 { 623 fnotice (stderr, 624 "compilation terminated due to -fmax-errors=%u.\n", 625 context->max_errors); 626 if (flush) 627 diagnostic_finish (context); 628 exit (FATAL_EXIT_CODE); 629 } 630 } 631 632 /* Take any action which is expected to happen after the diagnostic 633 is written out. This function does not always return. */ 634 void 635 diagnostic_action_after_output (diagnostic_context *context, 636 diagnostic_t diag_kind) 637 { 638 switch (diag_kind) 639 { 640 case DK_DEBUG: 641 case DK_NOTE: 642 case DK_ANACHRONISM: 643 case DK_WARNING: 644 break; 645 646 case DK_ERROR: 647 case DK_SORRY: 648 if (context->abort_on_error) 649 real_abort (); 650 if (context->fatal_errors) 651 { 652 fnotice (stderr, "compilation terminated due to -Wfatal-errors.\n"); 653 diagnostic_finish (context); 654 exit (FATAL_EXIT_CODE); 655 } 656 break; 657 658 case DK_ICE: 659 case DK_ICE_NOBT: 660 { 661 struct backtrace_state *state = NULL; 662 if (diag_kind == DK_ICE) 663 state = backtrace_create_state (NULL, 0, bt_err_callback, NULL); 664 int count = 0; 665 if (state != NULL) 666 backtrace_full (state, 2, bt_callback, bt_err_callback, 667 (void *) &count); 668 669 if (context->abort_on_error) 670 real_abort (); 671 672 if (context->report_bug) 673 fnotice (stderr, "Please submit a full bug report, " 674 "with preprocessed source.\n"); 675 else 676 fnotice (stderr, "Please submit a full bug report, " 677 "with preprocessed source (by using -freport-bug).\n"); 678 679 if (count > 0) 680 fnotice (stderr, "Please include the complete backtrace " 681 "with any bug report.\n"); 682 fnotice (stderr, "See %s for instructions.\n", bug_report_url); 683 684 exit (ICE_EXIT_CODE); 685 } 686 687 case DK_FATAL: 688 if (context->abort_on_error) 689 real_abort (); 690 diagnostic_finish (context); 691 fnotice (stderr, "compilation terminated.\n"); 692 exit (FATAL_EXIT_CODE); 693 694 default: 695 gcc_unreachable (); 696 } 697 } 698 699 /* True if the last module or file in which a diagnostic was reported is 700 different from the current one. */ 701 702 static bool 703 last_module_changed_p (diagnostic_context *context, 704 const line_map_ordinary *map) 705 { 706 return context->last_module != map; 707 } 708 709 /* Remember the current module or file as being the last one in which we 710 report a diagnostic. */ 711 712 static void 713 set_last_module (diagnostic_context *context, const line_map_ordinary *map) 714 { 715 context->last_module = map; 716 } 717 718 /* Only dump the "In file included from..." stack once for each file. */ 719 720 static bool 721 includes_seen (diagnostic_context *context, const line_map_ordinary *map) 722 { 723 /* No include path for main. */ 724 if (MAIN_FILE_P (map)) 725 return true; 726 727 /* Always identify C++ modules, at least for now. */ 728 auto probe = map; 729 if (linemap_check_ordinary (map)->reason == LC_RENAME) 730 /* The module source file shows up as LC_RENAME inside LC_MODULE. */ 731 probe = linemap_included_from_linemap (line_table, map); 732 if (MAP_MODULE_P (probe)) 733 return false; 734 735 if (!context->includes_seen) 736 context->includes_seen = new hash_set<location_t, false, location_hash>; 737 738 /* Hash the location of the #include directive to better handle files 739 that are included multiple times with different macros defined. */ 740 return context->includes_seen->add (linemap_included_from (map)); 741 } 742 743 void 744 diagnostic_report_current_module (diagnostic_context *context, location_t where) 745 { 746 const line_map_ordinary *map = NULL; 747 748 if (pp_needs_newline (context->printer)) 749 { 750 pp_newline (context->printer); 751 pp_needs_newline (context->printer) = false; 752 } 753 754 if (where <= BUILTINS_LOCATION) 755 return; 756 757 linemap_resolve_location (line_table, where, 758 LRK_MACRO_DEFINITION_LOCATION, 759 &map); 760 761 if (map && last_module_changed_p (context, map)) 762 { 763 set_last_module (context, map); 764 if (!includes_seen (context, map)) 765 { 766 bool first = true, need_inc = true, was_module = MAP_MODULE_P (map); 767 expanded_location s = {}; 768 do 769 { 770 where = linemap_included_from (map); 771 map = linemap_included_from_linemap (line_table, map); 772 bool is_module = MAP_MODULE_P (map); 773 s.file = LINEMAP_FILE (map); 774 s.line = SOURCE_LINE (map, where); 775 int col = -1; 776 if (first && context->show_column) 777 { 778 s.column = SOURCE_COLUMN (map, where); 779 col = diagnostic_converted_column (context, s); 780 } 781 const char *line_col = maybe_line_and_column (s.line, col); 782 static const char *const msgs[] = 783 { 784 NULL, 785 N_(" from"), 786 N_("In file included from"), /* 2 */ 787 N_(" included from"), 788 N_("In module"), /* 4 */ 789 N_("of module"), 790 N_("In module imported at"), /* 6 */ 791 N_("imported at"), 792 }; 793 794 unsigned index = (was_module ? 6 : is_module ? 4 795 : need_inc ? 2 : 0) + !first; 796 797 pp_verbatim (context->printer, "%s%s %r%s%s%R", 798 first ? "" : was_module ? ", " : ",\n", 799 _(msgs[index]), 800 "locus", s.file, line_col); 801 first = false, need_inc = was_module, was_module = is_module; 802 } 803 while (!includes_seen (context, map)); 804 pp_verbatim (context->printer, ":"); 805 pp_newline (context->printer); 806 } 807 } 808 } 809 810 /* If DIAGNOSTIC has a diagnostic_path and CONTEXT supports printing paths, 811 print the path. */ 812 813 void 814 diagnostic_show_any_path (diagnostic_context *context, 815 diagnostic_info *diagnostic) 816 { 817 const diagnostic_path *path = diagnostic->richloc->get_path (); 818 if (!path) 819 return; 820 821 if (context->print_path) 822 context->print_path (context, path); 823 } 824 825 /* Return true if the events in this path involve more than one 826 function, or false if it is purely intraprocedural. */ 827 828 bool 829 diagnostic_path::interprocedural_p () const 830 { 831 const unsigned num = num_events (); 832 for (unsigned i = 0; i < num; i++) 833 { 834 if (get_event (i).get_fndecl () != get_event (0).get_fndecl ()) 835 return true; 836 if (get_event (i).get_stack_depth () != get_event (0).get_stack_depth ()) 837 return true; 838 } 839 return false; 840 } 841 842 void 843 default_diagnostic_starter (diagnostic_context *context, 844 diagnostic_info *diagnostic) 845 { 846 diagnostic_report_current_module (context, diagnostic_location (diagnostic)); 847 pp_set_prefix (context->printer, diagnostic_build_prefix (context, 848 diagnostic)); 849 } 850 851 void 852 default_diagnostic_start_span_fn (diagnostic_context *context, 853 expanded_location exploc) 854 { 855 char *text = diagnostic_get_location_text (context, exploc); 856 pp_string (context->printer, text); 857 free (text); 858 pp_newline (context->printer); 859 } 860 861 void 862 default_diagnostic_finalizer (diagnostic_context *context, 863 diagnostic_info *diagnostic, 864 diagnostic_t) 865 { 866 char *saved_prefix = pp_take_prefix (context->printer); 867 pp_set_prefix (context->printer, NULL); 868 pp_newline (context->printer); 869 diagnostic_show_locus (context, diagnostic->richloc, diagnostic->kind); 870 pp_set_prefix (context->printer, saved_prefix); 871 pp_flush (context->printer); 872 } 873 874 /* Interface to specify diagnostic kind overrides. Returns the 875 previous setting, or DK_UNSPECIFIED if the parameters are out of 876 range. If OPTION_INDEX is zero, the new setting is for all the 877 diagnostics. */ 878 diagnostic_t 879 diagnostic_classify_diagnostic (diagnostic_context *context, 880 int option_index, 881 diagnostic_t new_kind, 882 location_t where) 883 { 884 diagnostic_t old_kind; 885 886 if (option_index < 0 887 || option_index >= context->n_opts 888 || new_kind >= DK_LAST_DIAGNOSTIC_KIND) 889 return DK_UNSPECIFIED; 890 891 old_kind = context->classify_diagnostic[option_index]; 892 893 /* Handle pragmas separately, since we need to keep track of *where* 894 the pragmas were. */ 895 if (where != UNKNOWN_LOCATION) 896 { 897 int i; 898 899 /* Record the command-line status, so we can reset it back on DK_POP. */ 900 if (old_kind == DK_UNSPECIFIED) 901 { 902 old_kind = !context->option_enabled (option_index, 903 context->lang_mask, 904 context->option_state) 905 ? DK_IGNORED : (context->warning_as_error_requested 906 ? DK_ERROR : DK_WARNING); 907 context->classify_diagnostic[option_index] = old_kind; 908 } 909 910 for (i = context->n_classification_history - 1; i >= 0; i --) 911 if (context->classification_history[i].option == option_index) 912 { 913 old_kind = context->classification_history[i].kind; 914 break; 915 } 916 917 i = context->n_classification_history; 918 context->classification_history = 919 (diagnostic_classification_change_t *) xrealloc (context->classification_history, (i + 1) 920 * sizeof (diagnostic_classification_change_t)); 921 context->classification_history[i].location = where; 922 context->classification_history[i].option = option_index; 923 context->classification_history[i].kind = new_kind; 924 context->n_classification_history ++; 925 } 926 else 927 context->classify_diagnostic[option_index] = new_kind; 928 929 return old_kind; 930 } 931 932 /* Save all diagnostic classifications in a stack. */ 933 void 934 diagnostic_push_diagnostics (diagnostic_context *context, location_t where ATTRIBUTE_UNUSED) 935 { 936 context->push_list = (int *) xrealloc (context->push_list, (context->n_push + 1) * sizeof (int)); 937 context->push_list[context->n_push ++] = context->n_classification_history; 938 } 939 940 /* Restore the topmost classification set off the stack. If the stack 941 is empty, revert to the state based on command line parameters. */ 942 void 943 diagnostic_pop_diagnostics (diagnostic_context *context, location_t where) 944 { 945 int jump_to; 946 int i; 947 948 if (context->n_push) 949 jump_to = context->push_list [-- context->n_push]; 950 else 951 jump_to = 0; 952 953 i = context->n_classification_history; 954 context->classification_history = 955 (diagnostic_classification_change_t *) xrealloc (context->classification_history, (i + 1) 956 * sizeof (diagnostic_classification_change_t)); 957 context->classification_history[i].location = where; 958 context->classification_history[i].option = jump_to; 959 context->classification_history[i].kind = DK_POP; 960 context->n_classification_history ++; 961 } 962 963 /* Helper function for print_parseable_fixits. Print TEXT to PP, obeying the 964 escaping rules for -fdiagnostics-parseable-fixits. */ 965 966 static void 967 print_escaped_string (pretty_printer *pp, const char *text) 968 { 969 gcc_assert (pp); 970 gcc_assert (text); 971 972 pp_character (pp, '"'); 973 for (const char *ch = text; *ch; ch++) 974 { 975 switch (*ch) 976 { 977 case '\\': 978 /* Escape backslash as two backslashes. */ 979 pp_string (pp, "\\\\"); 980 break; 981 case '\t': 982 /* Escape tab as "\t". */ 983 pp_string (pp, "\\t"); 984 break; 985 case '\n': 986 /* Escape newline as "\n". */ 987 pp_string (pp, "\\n"); 988 break; 989 case '"': 990 /* Escape doublequotes as \". */ 991 pp_string (pp, "\\\""); 992 break; 993 default: 994 if (ISPRINT (*ch)) 995 pp_character (pp, *ch); 996 else 997 /* Use octal for non-printable chars. */ 998 { 999 unsigned char c = (*ch & 0xff); 1000 pp_printf (pp, "\\%o%o%o", (c / 64), (c / 8) & 007, c & 007); 1001 } 1002 break; 1003 } 1004 } 1005 pp_character (pp, '"'); 1006 } 1007 1008 /* Implementation of -fdiagnostics-parseable-fixits and 1009 GCC_EXTRA_DIAGNOSTIC_OUTPUT. 1010 Print a machine-parseable version of all fixits in RICHLOC to PP, 1011 using COLUMN_UNIT to express columns. 1012 Use TABSTOP when handling DIAGNOSTICS_COLUMN_UNIT_DISPLAY. */ 1013 1014 static void 1015 print_parseable_fixits (pretty_printer *pp, rich_location *richloc, 1016 enum diagnostics_column_unit column_unit, 1017 int tabstop) 1018 { 1019 gcc_assert (pp); 1020 gcc_assert (richloc); 1021 1022 char *saved_prefix = pp_take_prefix (pp); 1023 pp_set_prefix (pp, NULL); 1024 1025 for (unsigned i = 0; i < richloc->get_num_fixit_hints (); i++) 1026 { 1027 const fixit_hint *hint = richloc->get_fixit_hint (i); 1028 location_t start_loc = hint->get_start_loc (); 1029 expanded_location start_exploc = expand_location (start_loc); 1030 pp_string (pp, "fix-it:"); 1031 print_escaped_string (pp, start_exploc.file); 1032 /* For compatibility with clang, print as a half-open range. */ 1033 location_t next_loc = hint->get_next_loc (); 1034 expanded_location next_exploc = expand_location (next_loc); 1035 int start_col 1036 = convert_column_unit (column_unit, tabstop, start_exploc); 1037 int next_col 1038 = convert_column_unit (column_unit, tabstop, next_exploc); 1039 pp_printf (pp, ":{%i:%i-%i:%i}:", 1040 start_exploc.line, start_col, 1041 next_exploc.line, next_col); 1042 print_escaped_string (pp, hint->get_string ()); 1043 pp_newline (pp); 1044 } 1045 1046 pp_set_prefix (pp, saved_prefix); 1047 } 1048 1049 /* Update the inlining info in CONTEXT for a DIAGNOSTIC. */ 1050 1051 static void 1052 get_any_inlining_info (diagnostic_context *context, 1053 diagnostic_info *diagnostic) 1054 { 1055 auto &ilocs = diagnostic->m_iinfo.m_ilocs; 1056 1057 if (context->set_locations_cb) 1058 /* Retrieve the locations into which the expression about to be 1059 diagnosed has been inlined, including those of all the callers 1060 all the way down the inlining stack. */ 1061 context->set_locations_cb (context, diagnostic); 1062 else 1063 { 1064 /* When there's no callback use just the one location provided 1065 by the caller of the diagnostic function. */ 1066 location_t loc = diagnostic_location (diagnostic); 1067 ilocs.safe_push (loc); 1068 diagnostic->m_iinfo.m_allsyslocs = in_system_header_at (loc); 1069 } 1070 } 1071 1072 /* Update the kind of DIAGNOSTIC based on its location(s), including 1073 any of those in its inlining stack, relative to any 1074 #pragma GCC diagnostic 1075 directives recorded within CONTEXT. 1076 1077 Return the new kind of DIAGNOSTIC if it was updated, or DK_UNSPECIFIED 1078 otherwise. */ 1079 1080 static diagnostic_t 1081 update_effective_level_from_pragmas (diagnostic_context *context, 1082 diagnostic_info *diagnostic) 1083 { 1084 if (diagnostic->m_iinfo.m_allsyslocs && !context->dc_warn_system_headers) 1085 { 1086 /* Ignore the diagnostic if all the inlined locations are 1087 in system headers and -Wno-system-headers is in effect. */ 1088 diagnostic->kind = DK_IGNORED; 1089 return DK_IGNORED; 1090 } 1091 1092 if (context->n_classification_history <= 0) 1093 return DK_UNSPECIFIED; 1094 1095 /* Iterate over the locations, checking the diagnostic disposition 1096 for the diagnostic at each. If it's explicitly set as opposed 1097 to unspecified, update the disposition for this instance of 1098 the diagnostic and return it. */ 1099 for (location_t loc: diagnostic->m_iinfo.m_ilocs) 1100 { 1101 /* FIXME: Stupid search. Optimize later. */ 1102 for (int i = context->n_classification_history - 1; i >= 0; i --) 1103 { 1104 const diagnostic_classification_change_t &hist 1105 = context->classification_history[i]; 1106 1107 location_t pragloc = hist.location; 1108 if (!linemap_location_before_p (line_table, pragloc, loc)) 1109 continue; 1110 1111 if (hist.kind == (int) DK_POP) 1112 { 1113 /* Move on to the next region. */ 1114 i = hist.option; 1115 continue; 1116 } 1117 1118 int option = hist.option; 1119 /* The option 0 is for all the diagnostics. */ 1120 if (option == 0 || option == diagnostic->option_index) 1121 { 1122 diagnostic_t kind = hist.kind; 1123 if (kind != DK_UNSPECIFIED) 1124 diagnostic->kind = kind; 1125 return kind; 1126 } 1127 } 1128 } 1129 1130 return DK_UNSPECIFIED; 1131 } 1132 1133 /* Generate a URL string describing CWE. The caller is responsible for 1134 freeing the string. */ 1135 1136 static char * 1137 get_cwe_url (int cwe) 1138 { 1139 return xasprintf ("https://cwe.mitre.org/data/definitions/%i.html", cwe); 1140 } 1141 1142 /* If DIAGNOSTIC has a CWE identifier, print it. 1143 1144 For example, if the diagnostic metadata associates it with CWE-119, 1145 " [CWE-119]" will be printed, suitably colorized, and with a URL of a 1146 description of the security issue. */ 1147 1148 static void 1149 print_any_cwe (diagnostic_context *context, 1150 const diagnostic_info *diagnostic) 1151 { 1152 if (diagnostic->metadata == NULL) 1153 return; 1154 1155 int cwe = diagnostic->metadata->get_cwe (); 1156 if (cwe) 1157 { 1158 pretty_printer *pp = context->printer; 1159 char *saved_prefix = pp_take_prefix (context->printer); 1160 pp_string (pp, " ["); 1161 pp_string (pp, colorize_start (pp_show_color (pp), 1162 diagnostic_kind_color[diagnostic->kind])); 1163 if (pp->url_format != URL_FORMAT_NONE) 1164 { 1165 char *cwe_url = get_cwe_url (cwe); 1166 pp_begin_url (pp, cwe_url); 1167 free (cwe_url); 1168 } 1169 pp_printf (pp, "CWE-%i", cwe); 1170 pp_set_prefix (context->printer, saved_prefix); 1171 if (pp->url_format != URL_FORMAT_NONE) 1172 pp_end_url (pp); 1173 pp_string (pp, colorize_stop (pp_show_color (pp))); 1174 pp_character (pp, ']'); 1175 } 1176 } 1177 1178 /* Print any metadata about the option used to control DIAGNOSTIC to CONTEXT's 1179 printer, e.g. " [-Werror=uninitialized]". 1180 Subroutine of diagnostic_report_diagnostic. */ 1181 1182 static void 1183 print_option_information (diagnostic_context *context, 1184 const diagnostic_info *diagnostic, 1185 diagnostic_t orig_diag_kind) 1186 { 1187 char *option_text; 1188 1189 option_text = context->option_name (context, diagnostic->option_index, 1190 orig_diag_kind, diagnostic->kind); 1191 1192 if (option_text) 1193 { 1194 char *option_url = NULL; 1195 if (context->get_option_url 1196 && context->printer->url_format != URL_FORMAT_NONE) 1197 option_url = context->get_option_url (context, 1198 diagnostic->option_index); 1199 pretty_printer *pp = context->printer; 1200 pp_string (pp, " ["); 1201 pp_string (pp, colorize_start (pp_show_color (pp), 1202 diagnostic_kind_color[diagnostic->kind])); 1203 if (option_url) 1204 pp_begin_url (pp, option_url); 1205 pp_string (pp, option_text); 1206 if (option_url) 1207 { 1208 pp_end_url (pp); 1209 free (option_url); 1210 } 1211 pp_string (pp, colorize_stop (pp_show_color (pp))); 1212 pp_character (pp, ']'); 1213 free (option_text); 1214 } 1215 } 1216 1217 /* Returns whether a DIAGNOSTIC should be printed, and adjusts diagnostic->kind 1218 as appropriate for #pragma GCC diagnostic and -Werror=foo. */ 1219 1220 static bool 1221 diagnostic_enabled (diagnostic_context *context, 1222 diagnostic_info *diagnostic) 1223 { 1224 /* Update the inlining stack for this diagnostic. */ 1225 get_any_inlining_info (context, diagnostic); 1226 1227 /* Diagnostics with no option or -fpermissive are always enabled. */ 1228 if (!diagnostic->option_index 1229 || diagnostic->option_index == permissive_error_option (context)) 1230 return true; 1231 1232 /* This tests if the user provided the appropriate -Wfoo or 1233 -Wno-foo option. */ 1234 if (! context->option_enabled (diagnostic->option_index, 1235 context->lang_mask, 1236 context->option_state)) 1237 return false; 1238 1239 /* This tests for #pragma diagnostic changes. */ 1240 diagnostic_t diag_class 1241 = update_effective_level_from_pragmas (context, diagnostic); 1242 1243 /* This tests if the user provided the appropriate -Werror=foo 1244 option. */ 1245 if (diag_class == DK_UNSPECIFIED 1246 && (context->classify_diagnostic[diagnostic->option_index] 1247 != DK_UNSPECIFIED)) 1248 diagnostic->kind 1249 = context->classify_diagnostic[diagnostic->option_index]; 1250 1251 /* This allows for future extensions, like temporarily disabling 1252 warnings for ranges of source code. */ 1253 if (diagnostic->kind == DK_IGNORED) 1254 return false; 1255 1256 return true; 1257 } 1258 1259 /* Returns whether warning OPT is enabled at LOC. */ 1260 1261 bool 1262 warning_enabled_at (location_t loc, int opt) 1263 { 1264 if (!diagnostic_report_warnings_p (global_dc, loc)) 1265 return false; 1266 1267 rich_location richloc (line_table, loc); 1268 diagnostic_info diagnostic = {}; 1269 diagnostic.option_index = opt; 1270 diagnostic.richloc = &richloc; 1271 diagnostic.message.m_richloc = &richloc; 1272 diagnostic.kind = DK_WARNING; 1273 return diagnostic_enabled (global_dc, &diagnostic); 1274 } 1275 1276 /* Report a diagnostic message (an error or a warning) as specified by 1277 DC. This function is *the* subroutine in terms of which front-ends 1278 should implement their specific diagnostic handling modules. The 1279 front-end independent format specifiers are exactly those described 1280 in the documentation of output_format. 1281 Return true if a diagnostic was printed, false otherwise. */ 1282 1283 bool 1284 diagnostic_report_diagnostic (diagnostic_context *context, 1285 diagnostic_info *diagnostic) 1286 { 1287 location_t location = diagnostic_location (diagnostic); 1288 diagnostic_t orig_diag_kind = diagnostic->kind; 1289 1290 /* Give preference to being able to inhibit warnings, before they 1291 get reclassified to something else. */ 1292 bool report_warning_p = true; 1293 if (diagnostic->kind == DK_WARNING || diagnostic->kind == DK_PEDWARN) 1294 { 1295 if (context->dc_inhibit_warnings) 1296 return false; 1297 /* Remember the result of the overall system header warning setting 1298 but proceed to also check the inlining context. */ 1299 report_warning_p = diagnostic_report_warnings_p (context, location); 1300 if (!report_warning_p && diagnostic->kind == DK_PEDWARN) 1301 return false; 1302 } 1303 1304 if (diagnostic->kind == DK_PEDWARN) 1305 { 1306 diagnostic->kind = pedantic_warning_kind (context); 1307 /* We do this to avoid giving the message for -pedantic-errors. */ 1308 orig_diag_kind = diagnostic->kind; 1309 } 1310 1311 if (diagnostic->kind == DK_NOTE && context->inhibit_notes_p) 1312 return false; 1313 1314 if (context->lock > 0) 1315 { 1316 /* If we're reporting an ICE in the middle of some other error, 1317 try to flush out the previous error, then let this one 1318 through. Don't do this more than once. */ 1319 if ((diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT) 1320 && context->lock == 1) 1321 pp_newline_and_flush (context->printer); 1322 else 1323 error_recursion (context); 1324 } 1325 1326 /* If the user requested that warnings be treated as errors, so be 1327 it. Note that we do this before the next block so that 1328 individual warnings can be overridden back to warnings with 1329 -Wno-error=*. */ 1330 if (context->warning_as_error_requested 1331 && diagnostic->kind == DK_WARNING) 1332 diagnostic->kind = DK_ERROR; 1333 1334 diagnostic->message.x_data = &diagnostic->x_data; 1335 1336 /* Check to see if the diagnostic is enabled at the location and 1337 not disabled by #pragma GCC diagnostic anywhere along the inlining 1338 stack. . */ 1339 if (!diagnostic_enabled (context, diagnostic)) 1340 return false; 1341 1342 if (!report_warning_p && diagnostic->m_iinfo.m_allsyslocs) 1343 /* Bail if the warning is not to be reported because all locations 1344 in the inlining stack (if there is one) are in system headers. */ 1345 return false; 1346 1347 if (diagnostic->kind != DK_NOTE && diagnostic->kind != DK_ICE) 1348 diagnostic_check_max_errors (context); 1349 1350 context->lock++; 1351 1352 if (diagnostic->kind == DK_ICE || diagnostic->kind == DK_ICE_NOBT) 1353 { 1354 /* When not checking, ICEs are converted to fatal errors when an 1355 error has already occurred. This is counteracted by 1356 abort_on_error. */ 1357 if (!CHECKING_P 1358 && (diagnostic_kind_count (context, DK_ERROR) > 0 1359 || diagnostic_kind_count (context, DK_SORRY) > 0) 1360 && !context->abort_on_error) 1361 { 1362 expanded_location s 1363 = expand_location (diagnostic_location (diagnostic)); 1364 fnotice (stderr, "%s:%d: confused by earlier errors, bailing out\n", 1365 s.file, s.line); 1366 exit (ICE_EXIT_CODE); 1367 } 1368 if (context->internal_error) 1369 (*context->internal_error) (context, 1370 diagnostic->message.format_spec, 1371 diagnostic->message.args_ptr); 1372 } 1373 if (diagnostic->kind == DK_ERROR && orig_diag_kind == DK_WARNING) 1374 ++diagnostic_kind_count (context, DK_WERROR); 1375 else 1376 ++diagnostic_kind_count (context, diagnostic->kind); 1377 1378 /* Is this the initial diagnostic within the stack of groups? */ 1379 if (context->diagnostic_group_emission_count == 0) 1380 { 1381 if (context->begin_group_cb) 1382 context->begin_group_cb (context); 1383 } 1384 context->diagnostic_group_emission_count++; 1385 1386 pp_format (context->printer, &diagnostic->message); 1387 (*diagnostic_starter (context)) (context, diagnostic); 1388 pp_output_formatted_text (context->printer); 1389 if (context->show_cwe) 1390 print_any_cwe (context, diagnostic); 1391 if (context->show_option_requested) 1392 print_option_information (context, diagnostic, orig_diag_kind); 1393 (*diagnostic_finalizer (context)) (context, diagnostic, orig_diag_kind); 1394 switch (context->extra_output_kind) 1395 { 1396 default: 1397 break; 1398 case EXTRA_DIAGNOSTIC_OUTPUT_fixits_v1: 1399 print_parseable_fixits (context->printer, diagnostic->richloc, 1400 DIAGNOSTICS_COLUMN_UNIT_BYTE, 1401 context->tabstop); 1402 pp_flush (context->printer); 1403 break; 1404 case EXTRA_DIAGNOSTIC_OUTPUT_fixits_v2: 1405 print_parseable_fixits (context->printer, diagnostic->richloc, 1406 DIAGNOSTICS_COLUMN_UNIT_DISPLAY, 1407 context->tabstop); 1408 pp_flush (context->printer); 1409 break; 1410 } 1411 diagnostic_action_after_output (context, diagnostic->kind); 1412 diagnostic->x_data = NULL; 1413 1414 if (context->edit_context_ptr) 1415 if (diagnostic->richloc->fixits_can_be_auto_applied_p ()) 1416 context->edit_context_ptr->add_fixits (diagnostic->richloc); 1417 1418 context->lock--; 1419 1420 diagnostic_show_any_path (context, diagnostic); 1421 1422 return true; 1423 } 1424 1425 /* Get the number of digits in the decimal representation of VALUE. */ 1426 1427 int 1428 num_digits (int value) 1429 { 1430 /* Perhaps simpler to use log10 for this, but doing it this way avoids 1431 using floating point. */ 1432 gcc_assert (value >= 0); 1433 1434 if (value == 0) 1435 return 1; 1436 1437 int digits = 0; 1438 while (value > 0) 1439 { 1440 digits++; 1441 value /= 10; 1442 } 1443 return digits; 1444 } 1445 1446 /* Given a partial pathname as input, return another pathname that 1447 shares no directory elements with the pathname of __FILE__. This 1448 is used by fancy_abort() to print `internal compiler error in expr.cc' 1449 instead of `internal compiler error in ../../GCC/gcc/expr.cc'. */ 1450 1451 const char * 1452 trim_filename (const char *name) 1453 { 1454 static const char this_file[] = __FILE__; 1455 const char *p = name, *q = this_file; 1456 1457 /* First skip any "../" in each filename. This allows us to give a proper 1458 reference to a file in a subdirectory. */ 1459 while (p[0] == '.' && p[1] == '.' && IS_DIR_SEPARATOR (p[2])) 1460 p += 3; 1461 1462 while (q[0] == '.' && q[1] == '.' && IS_DIR_SEPARATOR (q[2])) 1463 q += 3; 1464 1465 /* Now skip any parts the two filenames have in common. */ 1466 while (*p == *q && *p != 0 && *q != 0) 1467 p++, q++; 1468 1469 /* Now go backwards until the previous directory separator. */ 1470 while (p > name && !IS_DIR_SEPARATOR (p[-1])) 1471 p--; 1472 1473 return p; 1474 } 1475 1476 /* Standard error reporting routines in increasing order of severity. 1478 All of these take arguments like printf. */ 1479 1480 /* Text to be emitted verbatim to the error message stream; this 1481 produces no prefix and disables line-wrapping. Use rarely. */ 1482 void 1483 verbatim (const char *gmsgid, ...) 1484 { 1485 text_info text; 1486 va_list ap; 1487 1488 va_start (ap, gmsgid); 1489 text.err_no = errno; 1490 text.args_ptr = ≈ 1491 text.format_spec = _(gmsgid); 1492 text.x_data = NULL; 1493 pp_format_verbatim (global_dc->printer, &text); 1494 pp_newline_and_flush (global_dc->printer); 1495 va_end (ap); 1496 } 1497 1498 /* Add a note with text GMSGID and with LOCATION to the diagnostic CONTEXT. */ 1499 void 1500 diagnostic_append_note (diagnostic_context *context, 1501 location_t location, 1502 const char * gmsgid, ...) 1503 { 1504 diagnostic_info diagnostic; 1505 va_list ap; 1506 rich_location richloc (line_table, location); 1507 1508 va_start (ap, gmsgid); 1509 diagnostic_set_info (&diagnostic, gmsgid, &ap, &richloc, DK_NOTE); 1510 if (context->inhibit_notes_p) 1511 { 1512 va_end (ap); 1513 return; 1514 } 1515 char *saved_prefix = pp_take_prefix (context->printer); 1516 pp_set_prefix (context->printer, 1517 diagnostic_build_prefix (context, &diagnostic)); 1518 pp_format (context->printer, &diagnostic.message); 1519 pp_output_formatted_text (context->printer); 1520 pp_destroy_prefix (context->printer); 1521 pp_set_prefix (context->printer, saved_prefix); 1522 pp_newline (context->printer); 1523 diagnostic_show_locus (context, &richloc, DK_NOTE); 1524 va_end (ap); 1525 } 1526 1527 /* Implement emit_diagnostic, inform, warning, warning_at, pedwarn, 1528 permerror, error, error_at, error_at, sorry, fatal_error, internal_error, 1529 and internal_error_no_backtrace, as documented and defined below. */ 1530 static bool 1531 diagnostic_impl (rich_location *richloc, const diagnostic_metadata *metadata, 1532 int opt, const char *gmsgid, 1533 va_list *ap, diagnostic_t kind) 1534 { 1535 diagnostic_info diagnostic; 1536 if (kind == DK_PERMERROR) 1537 { 1538 diagnostic_set_info (&diagnostic, gmsgid, ap, richloc, 1539 permissive_error_kind (global_dc)); 1540 diagnostic.option_index = permissive_error_option (global_dc); 1541 } 1542 else 1543 { 1544 diagnostic_set_info (&diagnostic, gmsgid, ap, richloc, kind); 1545 if (kind == DK_WARNING || kind == DK_PEDWARN) 1546 diagnostic.option_index = opt; 1547 } 1548 diagnostic.metadata = metadata; 1549 return diagnostic_report_diagnostic (global_dc, &diagnostic); 1550 } 1551 1552 /* Implement inform_n, warning_n, and error_n, as documented and 1553 defined below. */ 1554 static bool 1555 diagnostic_n_impl (rich_location *richloc, const diagnostic_metadata *metadata, 1556 int opt, unsigned HOST_WIDE_INT n, 1557 const char *singular_gmsgid, 1558 const char *plural_gmsgid, 1559 va_list *ap, diagnostic_t kind) 1560 { 1561 diagnostic_info diagnostic; 1562 unsigned long gtn; 1563 1564 if (sizeof n <= sizeof gtn) 1565 gtn = n; 1566 else 1567 /* Use the largest number ngettext can handle, otherwise 1568 preserve the six least significant decimal digits for 1569 languages where the plural form depends on them. */ 1570 gtn = n <= ULONG_MAX ? n : n % 1000000LU + 1000000LU; 1571 1572 const char *text = ngettext (singular_gmsgid, plural_gmsgid, gtn); 1573 diagnostic_set_info_translated (&diagnostic, text, ap, richloc, kind); 1574 if (kind == DK_WARNING) 1575 diagnostic.option_index = opt; 1576 diagnostic.metadata = metadata; 1577 return diagnostic_report_diagnostic (global_dc, &diagnostic); 1578 } 1579 1580 /* Wrapper around diagnostic_impl taking a variable argument list. */ 1581 1582 bool 1583 emit_diagnostic (diagnostic_t kind, location_t location, int opt, 1584 const char *gmsgid, ...) 1585 { 1586 auto_diagnostic_group d; 1587 va_list ap; 1588 va_start (ap, gmsgid); 1589 rich_location richloc (line_table, location); 1590 bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, kind); 1591 va_end (ap); 1592 return ret; 1593 } 1594 1595 /* As above, but for rich_location *. */ 1596 1597 bool 1598 emit_diagnostic (diagnostic_t kind, rich_location *richloc, int opt, 1599 const char *gmsgid, ...) 1600 { 1601 auto_diagnostic_group d; 1602 va_list ap; 1603 va_start (ap, gmsgid); 1604 bool ret = diagnostic_impl (richloc, NULL, opt, gmsgid, &ap, kind); 1605 va_end (ap); 1606 return ret; 1607 } 1608 1609 /* Wrapper around diagnostic_impl taking a va_list parameter. */ 1610 1611 bool 1612 emit_diagnostic_valist (diagnostic_t kind, location_t location, int opt, 1613 const char *gmsgid, va_list *ap) 1614 { 1615 rich_location richloc (line_table, location); 1616 return diagnostic_impl (&richloc, NULL, opt, gmsgid, ap, kind); 1617 } 1618 1619 /* An informative note at LOCATION. Use this for additional details on an error 1620 message. */ 1621 void 1622 inform (location_t location, const char *gmsgid, ...) 1623 { 1624 auto_diagnostic_group d; 1625 va_list ap; 1626 va_start (ap, gmsgid); 1627 rich_location richloc (line_table, location); 1628 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_NOTE); 1629 va_end (ap); 1630 } 1631 1632 /* Same as "inform" above, but at RICHLOC. */ 1633 void 1634 inform (rich_location *richloc, const char *gmsgid, ...) 1635 { 1636 gcc_assert (richloc); 1637 1638 auto_diagnostic_group d; 1639 va_list ap; 1640 va_start (ap, gmsgid); 1641 diagnostic_impl (richloc, NULL, -1, gmsgid, &ap, DK_NOTE); 1642 va_end (ap); 1643 } 1644 1645 /* An informative note at LOCATION. Use this for additional details on an 1646 error message. */ 1647 void 1648 inform_n (location_t location, unsigned HOST_WIDE_INT n, 1649 const char *singular_gmsgid, const char *plural_gmsgid, ...) 1650 { 1651 va_list ap; 1652 va_start (ap, plural_gmsgid); 1653 auto_diagnostic_group d; 1654 rich_location richloc (line_table, location); 1655 diagnostic_n_impl (&richloc, NULL, -1, n, singular_gmsgid, plural_gmsgid, 1656 &ap, DK_NOTE); 1657 va_end (ap); 1658 } 1659 1660 /* A warning at INPUT_LOCATION. Use this for code which is correct according 1661 to the relevant language specification but is likely to be buggy anyway. 1662 Returns true if the warning was printed, false if it was inhibited. */ 1663 bool 1664 warning (int opt, const char *gmsgid, ...) 1665 { 1666 auto_diagnostic_group d; 1667 va_list ap; 1668 va_start (ap, gmsgid); 1669 rich_location richloc (line_table, input_location); 1670 bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, DK_WARNING); 1671 va_end (ap); 1672 return ret; 1673 } 1674 1675 /* A warning at LOCATION. Use this for code which is correct according to the 1676 relevant language specification but is likely to be buggy anyway. 1677 Returns true if the warning was printed, false if it was inhibited. */ 1678 1679 bool 1680 warning_at (location_t location, int opt, const char *gmsgid, ...) 1681 { 1682 auto_diagnostic_group d; 1683 va_list ap; 1684 va_start (ap, gmsgid); 1685 rich_location richloc (line_table, location); 1686 bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, DK_WARNING); 1687 va_end (ap); 1688 return ret; 1689 } 1690 1691 /* Same as "warning at" above, but using RICHLOC. */ 1692 1693 bool 1694 warning_at (rich_location *richloc, int opt, const char *gmsgid, ...) 1695 { 1696 gcc_assert (richloc); 1697 1698 auto_diagnostic_group d; 1699 va_list ap; 1700 va_start (ap, gmsgid); 1701 bool ret = diagnostic_impl (richloc, NULL, opt, gmsgid, &ap, DK_WARNING); 1702 va_end (ap); 1703 return ret; 1704 } 1705 1706 /* Same as "warning at" above, but using METADATA. */ 1707 1708 bool 1709 warning_meta (rich_location *richloc, 1710 const diagnostic_metadata &metadata, 1711 int opt, const char *gmsgid, ...) 1712 { 1713 gcc_assert (richloc); 1714 1715 auto_diagnostic_group d; 1716 va_list ap; 1717 va_start (ap, gmsgid); 1718 bool ret 1719 = diagnostic_impl (richloc, &metadata, opt, gmsgid, &ap, 1720 DK_WARNING); 1721 va_end (ap); 1722 return ret; 1723 } 1724 1725 /* Same as warning_n plural variant below, but using RICHLOC. */ 1726 1727 bool 1728 warning_n (rich_location *richloc, int opt, unsigned HOST_WIDE_INT n, 1729 const char *singular_gmsgid, const char *plural_gmsgid, ...) 1730 { 1731 gcc_assert (richloc); 1732 1733 auto_diagnostic_group d; 1734 va_list ap; 1735 va_start (ap, plural_gmsgid); 1736 bool ret = diagnostic_n_impl (richloc, NULL, opt, n, 1737 singular_gmsgid, plural_gmsgid, 1738 &ap, DK_WARNING); 1739 va_end (ap); 1740 return ret; 1741 } 1742 1743 /* A warning at LOCATION. Use this for code which is correct according to the 1744 relevant language specification but is likely to be buggy anyway. 1745 Returns true if the warning was printed, false if it was inhibited. */ 1746 1747 bool 1748 warning_n (location_t location, int opt, unsigned HOST_WIDE_INT n, 1749 const char *singular_gmsgid, const char *plural_gmsgid, ...) 1750 { 1751 auto_diagnostic_group d; 1752 va_list ap; 1753 va_start (ap, plural_gmsgid); 1754 rich_location richloc (line_table, location); 1755 bool ret = diagnostic_n_impl (&richloc, NULL, opt, n, 1756 singular_gmsgid, plural_gmsgid, 1757 &ap, DK_WARNING); 1758 va_end (ap); 1759 return ret; 1760 } 1761 1762 /* A "pedantic" warning at LOCATION: issues a warning unless 1763 -pedantic-errors was given on the command line, in which case it 1764 issues an error. Use this for diagnostics required by the relevant 1765 language standard, if you have chosen not to make them errors. 1766 1767 Note that these diagnostics are issued independent of the setting 1768 of the -Wpedantic command-line switch. To get a warning enabled 1769 only with that switch, use either "if (pedantic) pedwarn 1770 (OPT_Wpedantic,...)" or just "pedwarn (OPT_Wpedantic,..)". To get a 1771 pedwarn independently of the -Wpedantic switch use "pedwarn (0,...)". 1772 1773 Returns true if the warning was printed, false if it was inhibited. */ 1774 1775 bool 1776 pedwarn (location_t location, int opt, const char *gmsgid, ...) 1777 { 1778 auto_diagnostic_group d; 1779 va_list ap; 1780 va_start (ap, gmsgid); 1781 rich_location richloc (line_table, location); 1782 bool ret = diagnostic_impl (&richloc, NULL, opt, gmsgid, &ap, DK_PEDWARN); 1783 va_end (ap); 1784 return ret; 1785 } 1786 1787 /* Same as pedwarn above, but using RICHLOC. */ 1788 1789 bool 1790 pedwarn (rich_location *richloc, int opt, const char *gmsgid, ...) 1791 { 1792 gcc_assert (richloc); 1793 1794 auto_diagnostic_group d; 1795 va_list ap; 1796 va_start (ap, gmsgid); 1797 bool ret = diagnostic_impl (richloc, NULL, opt, gmsgid, &ap, DK_PEDWARN); 1798 va_end (ap); 1799 return ret; 1800 } 1801 1802 /* A "permissive" error at LOCATION: issues an error unless 1803 -fpermissive was given on the command line, in which case it issues 1804 a warning. Use this for things that really should be errors but we 1805 want to support legacy code. 1806 1807 Returns true if the warning was printed, false if it was inhibited. */ 1808 1809 bool 1810 permerror (location_t location, const char *gmsgid, ...) 1811 { 1812 auto_diagnostic_group d; 1813 va_list ap; 1814 va_start (ap, gmsgid); 1815 rich_location richloc (line_table, location); 1816 bool ret = diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_PERMERROR); 1817 va_end (ap); 1818 return ret; 1819 } 1820 1821 /* Same as "permerror" above, but at RICHLOC. */ 1822 1823 bool 1824 permerror (rich_location *richloc, const char *gmsgid, ...) 1825 { 1826 gcc_assert (richloc); 1827 1828 auto_diagnostic_group d; 1829 va_list ap; 1830 va_start (ap, gmsgid); 1831 bool ret = diagnostic_impl (richloc, NULL, -1, gmsgid, &ap, DK_PERMERROR); 1832 va_end (ap); 1833 return ret; 1834 } 1835 1836 /* A hard error: the code is definitely ill-formed, and an object file 1837 will not be produced. */ 1838 void 1839 error (const char *gmsgid, ...) 1840 { 1841 auto_diagnostic_group d; 1842 va_list ap; 1843 va_start (ap, gmsgid); 1844 rich_location richloc (line_table, input_location); 1845 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ERROR); 1846 va_end (ap); 1847 } 1848 1849 /* A hard error: the code is definitely ill-formed, and an object file 1850 will not be produced. */ 1851 void 1852 error_n (location_t location, unsigned HOST_WIDE_INT n, 1853 const char *singular_gmsgid, const char *plural_gmsgid, ...) 1854 { 1855 auto_diagnostic_group d; 1856 va_list ap; 1857 va_start (ap, plural_gmsgid); 1858 rich_location richloc (line_table, location); 1859 diagnostic_n_impl (&richloc, NULL, -1, n, singular_gmsgid, plural_gmsgid, 1860 &ap, DK_ERROR); 1861 va_end (ap); 1862 } 1863 1864 /* Same as above, but use location LOC instead of input_location. */ 1865 void 1866 error_at (location_t loc, const char *gmsgid, ...) 1867 { 1868 auto_diagnostic_group d; 1869 va_list ap; 1870 va_start (ap, gmsgid); 1871 rich_location richloc (line_table, loc); 1872 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ERROR); 1873 va_end (ap); 1874 } 1875 1876 /* Same as above, but use RICH_LOC. */ 1877 1878 void 1879 error_at (rich_location *richloc, const char *gmsgid, ...) 1880 { 1881 gcc_assert (richloc); 1882 1883 auto_diagnostic_group d; 1884 va_list ap; 1885 va_start (ap, gmsgid); 1886 diagnostic_impl (richloc, NULL, -1, gmsgid, &ap, DK_ERROR); 1887 va_end (ap); 1888 } 1889 1890 /* "Sorry, not implemented." Use for a language feature which is 1891 required by the relevant specification but not implemented by GCC. 1892 An object file will not be produced. */ 1893 void 1894 sorry (const char *gmsgid, ...) 1895 { 1896 auto_diagnostic_group d; 1897 va_list ap; 1898 va_start (ap, gmsgid); 1899 rich_location richloc (line_table, input_location); 1900 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_SORRY); 1901 va_end (ap); 1902 } 1903 1904 /* Same as above, but use location LOC instead of input_location. */ 1905 void 1906 sorry_at (location_t loc, const char *gmsgid, ...) 1907 { 1908 auto_diagnostic_group d; 1909 va_list ap; 1910 va_start (ap, gmsgid); 1911 rich_location richloc (line_table, loc); 1912 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_SORRY); 1913 va_end (ap); 1914 } 1915 1916 /* Return true if an error or a "sorry" has been seen. Various 1917 processing is disabled after errors. */ 1918 bool 1919 seen_error (void) 1920 { 1921 return errorcount || sorrycount; 1922 } 1923 1924 /* An error which is severe enough that we make no attempt to 1925 continue. Do not use this for internal consistency checks; that's 1926 internal_error. Use of this function should be rare. */ 1927 void 1928 fatal_error (location_t loc, const char *gmsgid, ...) 1929 { 1930 auto_diagnostic_group d; 1931 va_list ap; 1932 va_start (ap, gmsgid); 1933 rich_location richloc (line_table, loc); 1934 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_FATAL); 1935 va_end (ap); 1936 1937 gcc_unreachable (); 1938 } 1939 1940 /* An internal consistency check has failed. We make no attempt to 1941 continue. Note that unless there is debugging value to be had from 1942 a more specific message, or some other good reason, you should use 1943 abort () instead of calling this function directly. */ 1944 void 1945 internal_error (const char *gmsgid, ...) 1946 { 1947 auto_diagnostic_group d; 1948 va_list ap; 1949 va_start (ap, gmsgid); 1950 rich_location richloc (line_table, input_location); 1951 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ICE); 1952 va_end (ap); 1953 1954 gcc_unreachable (); 1955 } 1956 1957 /* Like internal_error, but no backtrace will be printed. Used when 1958 the internal error does not happen at the current location, but happened 1959 somewhere else. */ 1960 void 1961 internal_error_no_backtrace (const char *gmsgid, ...) 1962 { 1963 auto_diagnostic_group d; 1964 va_list ap; 1965 va_start (ap, gmsgid); 1966 rich_location richloc (line_table, input_location); 1967 diagnostic_impl (&richloc, NULL, -1, gmsgid, &ap, DK_ICE_NOBT); 1968 va_end (ap); 1969 1970 gcc_unreachable (); 1971 } 1972 1973 /* Special case error functions. Most are implemented in terms of the 1975 above, or should be. */ 1976 1977 /* Print a diagnostic MSGID on FILE. This is just fprintf, except it 1978 runs its second argument through gettext. */ 1979 void 1980 fnotice (FILE *file, const char *cmsgid, ...) 1981 { 1982 va_list ap; 1983 1984 va_start (ap, cmsgid); 1985 vfprintf (file, _(cmsgid), ap); 1986 va_end (ap); 1987 } 1988 1989 /* Inform the user that an error occurred while trying to report some 1990 other error. This indicates catastrophic internal inconsistencies, 1991 so give up now. But do try to flush out the previous error. 1992 This mustn't use internal_error, that will cause infinite recursion. */ 1993 1994 static void 1995 error_recursion (diagnostic_context *context) 1996 { 1997 if (context->lock < 3) 1998 pp_newline_and_flush (context->printer); 1999 2000 fnotice (stderr, 2001 "internal compiler error: error reporting routines re-entered.\n"); 2002 2003 /* Call diagnostic_action_after_output to get the "please submit a bug 2004 report" message. */ 2005 diagnostic_action_after_output (context, DK_ICE); 2006 2007 /* Do not use gcc_unreachable here; that goes through internal_error 2008 and therefore would cause infinite recursion. */ 2009 real_abort (); 2010 } 2011 2012 /* Report an internal compiler error in a friendly manner. This is 2013 the function that gets called upon use of abort() in the source 2014 code generally, thanks to a special macro. */ 2015 2016 void 2017 fancy_abort (const char *file, int line, const char *function) 2018 { 2019 /* If fancy_abort is called before the diagnostic subsystem is initialized, 2020 internal_error will crash internally in a way that prevents a 2021 useful message reaching the user. 2022 This can happen with libgccjit in the case of gcc_assert failures 2023 that occur outside of the libgccjit mutex that guards the rest of 2024 gcc's state, including global_dc (when global_dc may not be 2025 initialized yet, or might be in use by another thread). 2026 Handle such cases as gracefully as possible by falling back to a 2027 minimal abort handler that only relies on i18n. */ 2028 if (global_dc->printer == NULL) 2029 { 2030 /* Print the error message. */ 2031 fnotice (stderr, diagnostic_kind_text[DK_ICE]); 2032 fnotice (stderr, "in %s, at %s:%d", function, trim_filename (file), line); 2033 fputc ('\n', stderr); 2034 2035 /* Attempt to print a backtrace. */ 2036 struct backtrace_state *state 2037 = backtrace_create_state (NULL, 0, bt_err_callback, NULL); 2038 int count = 0; 2039 if (state != NULL) 2040 backtrace_full (state, 2, bt_callback, bt_err_callback, 2041 (void *) &count); 2042 2043 /* We can't call warn_if_plugins or emergency_dump_function as these 2044 rely on GCC state that might not be initialized, or might be in 2045 use by another thread. */ 2046 2047 /* Abort the process. */ 2048 real_abort (); 2049 } 2050 2051 internal_error ("in %s, at %s:%d", function, trim_filename (file), line); 2052 } 2053 2054 /* class auto_diagnostic_group. */ 2055 2056 /* Constructor: "push" this group into global_dc. */ 2057 2058 auto_diagnostic_group::auto_diagnostic_group () 2059 { 2060 global_dc->diagnostic_group_nesting_depth++; 2061 } 2062 2063 /* Destructor: "pop" this group from global_dc. */ 2064 2065 auto_diagnostic_group::~auto_diagnostic_group () 2066 { 2067 if (--global_dc->diagnostic_group_nesting_depth == 0) 2068 { 2069 /* Handle the case where we've popped the final diagnostic group. 2070 If any diagnostics were emitted, give the context a chance 2071 to do something. */ 2072 if (global_dc->diagnostic_group_emission_count > 0) 2073 { 2074 if (global_dc->end_group_cb) 2075 global_dc->end_group_cb (global_dc); 2076 } 2077 global_dc->diagnostic_group_emission_count = 0; 2078 } 2079 } 2080 2081 /* Implementation of diagnostic_path::num_events vfunc for 2082 simple_diagnostic_path: simply get the number of events in the vec. */ 2083 2084 unsigned 2085 simple_diagnostic_path::num_events () const 2086 { 2087 return m_events.length (); 2088 } 2089 2090 /* Implementation of diagnostic_path::get_event vfunc for 2091 simple_diagnostic_path: simply return the event in the vec. */ 2092 2093 const diagnostic_event & 2094 simple_diagnostic_path::get_event (int idx) const 2095 { 2096 return *m_events[idx]; 2097 } 2098 2099 /* Add an event to this path at LOC within function FNDECL at 2100 stack depth DEPTH. 2101 2102 Use m_context's printer to format FMT, as the text of the new 2103 event. 2104 2105 Return the id of the new event. */ 2106 2107 diagnostic_event_id_t 2108 simple_diagnostic_path::add_event (location_t loc, tree fndecl, int depth, 2109 const char *fmt, ...) 2110 { 2111 pretty_printer *pp = m_event_pp; 2112 pp_clear_output_area (pp); 2113 2114 text_info ti; 2115 rich_location rich_loc (line_table, UNKNOWN_LOCATION); 2116 2117 va_list ap; 2118 2119 va_start (ap, fmt); 2120 2121 ti.format_spec = _(fmt); 2122 ti.args_ptr = ≈ 2123 ti.err_no = 0; 2124 ti.x_data = NULL; 2125 ti.m_richloc = &rich_loc; 2126 2127 pp_format (pp, &ti); 2128 pp_output_formatted_text (pp); 2129 2130 va_end (ap); 2131 2132 simple_diagnostic_event *new_event 2133 = new simple_diagnostic_event (loc, fndecl, depth, pp_formatted_text (pp)); 2134 m_events.safe_push (new_event); 2135 2136 pp_clear_output_area (pp); 2137 2138 return diagnostic_event_id_t (m_events.length () - 1); 2139 } 2140 2141 /* struct simple_diagnostic_event. */ 2142 2143 /* simple_diagnostic_event's ctor. */ 2144 2145 simple_diagnostic_event::simple_diagnostic_event (location_t loc, 2146 tree fndecl, 2147 int depth, 2148 const char *desc) 2149 : m_loc (loc), m_fndecl (fndecl), m_depth (depth), m_desc (xstrdup (desc)) 2150 { 2151 } 2152 2153 /* simple_diagnostic_event's dtor. */ 2154 2155 simple_diagnostic_event::~simple_diagnostic_event () 2156 { 2157 free (m_desc); 2158 } 2159 2160 /* Print PATH by emitting a dummy "note" associated with it. */ 2161 2162 DEBUG_FUNCTION 2163 void debug (diagnostic_path *path) 2164 { 2165 rich_location richloc (line_table, UNKNOWN_LOCATION); 2166 richloc.set_path (path); 2167 inform (&richloc, "debug path"); 2168 } 2169 2170 /* Really call the system 'abort'. This has to go right at the end of 2171 this file, so that there are no functions after it that call abort 2172 and get the system abort instead of our macro. */ 2173 #undef abort 2174 static void 2175 real_abort (void) 2176 { 2177 abort (); 2178 } 2179 2180 #if CHECKING_P 2181 2182 namespace selftest { 2183 2184 /* Helper function for test_print_escaped_string. */ 2185 2186 static void 2187 assert_print_escaped_string (const location &loc, const char *expected_output, 2188 const char *input) 2189 { 2190 pretty_printer pp; 2191 print_escaped_string (&pp, input); 2192 ASSERT_STREQ_AT (loc, expected_output, pp_formatted_text (&pp)); 2193 } 2194 2195 #define ASSERT_PRINT_ESCAPED_STRING_STREQ(EXPECTED_OUTPUT, INPUT) \ 2196 assert_print_escaped_string (SELFTEST_LOCATION, EXPECTED_OUTPUT, INPUT) 2197 2198 /* Tests of print_escaped_string. */ 2199 2200 static void 2201 test_print_escaped_string () 2202 { 2203 /* Empty string. */ 2204 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"\"", ""); 2205 2206 /* Non-empty string. */ 2207 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"hello world\"", "hello world"); 2208 2209 /* Various things that need to be escaped: */ 2210 /* Backslash. */ 2211 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\\\after\"", 2212 "before\\after"); 2213 /* Tab. */ 2214 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\tafter\"", 2215 "before\tafter"); 2216 /* Newline. */ 2217 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\nafter\"", 2218 "before\nafter"); 2219 /* Double quote. */ 2220 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\\"after\"", 2221 "before\"after"); 2222 2223 /* Non-printable characters: BEL: '\a': 0x07 */ 2224 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\007after\"", 2225 "before\aafter"); 2226 /* Non-printable characters: vertical tab: '\v': 0x0b */ 2227 ASSERT_PRINT_ESCAPED_STRING_STREQ ("\"before\\013after\"", 2228 "before\vafter"); 2229 } 2230 2231 /* Tests of print_parseable_fixits. */ 2232 2233 /* Verify that print_parseable_fixits emits the empty string if there 2234 are no fixits. */ 2235 2236 static void 2237 test_print_parseable_fixits_none () 2238 { 2239 pretty_printer pp; 2240 rich_location richloc (line_table, UNKNOWN_LOCATION); 2241 2242 print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_BYTE, 8); 2243 ASSERT_STREQ ("", pp_formatted_text (&pp)); 2244 } 2245 2246 /* Verify that print_parseable_fixits does the right thing if there 2247 is an insertion fixit hint. */ 2248 2249 static void 2250 test_print_parseable_fixits_insert () 2251 { 2252 pretty_printer pp; 2253 rich_location richloc (line_table, UNKNOWN_LOCATION); 2254 2255 linemap_add (line_table, LC_ENTER, false, "test.c", 0); 2256 linemap_line_start (line_table, 5, 100); 2257 linemap_add (line_table, LC_LEAVE, false, NULL, 0); 2258 location_t where = linemap_position_for_column (line_table, 10); 2259 richloc.add_fixit_insert_before (where, "added content"); 2260 2261 print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_BYTE, 8); 2262 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:10}:\"added content\"\n", 2263 pp_formatted_text (&pp)); 2264 } 2265 2266 /* Verify that print_parseable_fixits does the right thing if there 2267 is an removal fixit hint. */ 2268 2269 static void 2270 test_print_parseable_fixits_remove () 2271 { 2272 pretty_printer pp; 2273 rich_location richloc (line_table, UNKNOWN_LOCATION); 2274 2275 linemap_add (line_table, LC_ENTER, false, "test.c", 0); 2276 linemap_line_start (line_table, 5, 100); 2277 linemap_add (line_table, LC_LEAVE, false, NULL, 0); 2278 source_range where; 2279 where.m_start = linemap_position_for_column (line_table, 10); 2280 where.m_finish = linemap_position_for_column (line_table, 20); 2281 richloc.add_fixit_remove (where); 2282 2283 print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_BYTE, 8); 2284 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:21}:\"\"\n", 2285 pp_formatted_text (&pp)); 2286 } 2287 2288 /* Verify that print_parseable_fixits does the right thing if there 2289 is an replacement fixit hint. */ 2290 2291 static void 2292 test_print_parseable_fixits_replace () 2293 { 2294 pretty_printer pp; 2295 rich_location richloc (line_table, UNKNOWN_LOCATION); 2296 2297 linemap_add (line_table, LC_ENTER, false, "test.c", 0); 2298 linemap_line_start (line_table, 5, 100); 2299 linemap_add (line_table, LC_LEAVE, false, NULL, 0); 2300 source_range where; 2301 where.m_start = linemap_position_for_column (line_table, 10); 2302 where.m_finish = linemap_position_for_column (line_table, 20); 2303 richloc.add_fixit_replace (where, "replacement"); 2304 2305 print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_BYTE, 8); 2306 ASSERT_STREQ ("fix-it:\"test.c\":{5:10-5:21}:\"replacement\"\n", 2307 pp_formatted_text (&pp)); 2308 } 2309 2310 /* Verify that print_parseable_fixits correctly handles 2311 DIAGNOSTICS_COLUMN_UNIT_BYTE vs DIAGNOSTICS_COLUMN_UNIT_COLUMN. */ 2312 2313 static void 2314 test_print_parseable_fixits_bytes_vs_display_columns () 2315 { 2316 line_table_test ltt; 2317 rich_location richloc (line_table, UNKNOWN_LOCATION); 2318 2319 /* 1-based byte offsets: 12345677778888999900001234567. */ 2320 const char *const content = "smile \xf0\x9f\x98\x82 colour\n"; 2321 /* 1-based display cols: 123456[......7-8.....]9012345. */ 2322 const int tabstop = 8; 2323 2324 temp_source_file tmp (SELFTEST_LOCATION, ".c", content); 2325 const char *const fname = tmp.get_filename (); 2326 2327 linemap_add (line_table, LC_ENTER, false, fname, 0); 2328 linemap_line_start (line_table, 1, 100); 2329 linemap_add (line_table, LC_LEAVE, false, NULL, 0); 2330 source_range where; 2331 where.m_start = linemap_position_for_column (line_table, 12); 2332 where.m_finish = linemap_position_for_column (line_table, 17); 2333 richloc.add_fixit_replace (where, "color"); 2334 2335 /* Escape fname. */ 2336 pretty_printer tmp_pp; 2337 print_escaped_string (&tmp_pp, fname); 2338 char *escaped_fname = xstrdup (pp_formatted_text (&tmp_pp)); 2339 2340 const int buf_len = strlen (escaped_fname) + 100; 2341 char *const expected = XNEWVEC (char, buf_len); 2342 2343 { 2344 pretty_printer pp; 2345 print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_BYTE, 2346 tabstop); 2347 snprintf (expected, buf_len, 2348 "fix-it:%s:{1:12-1:18}:\"color\"\n", escaped_fname); 2349 ASSERT_STREQ (expected, pp_formatted_text (&pp)); 2350 } 2351 { 2352 pretty_printer pp; 2353 print_parseable_fixits (&pp, &richloc, DIAGNOSTICS_COLUMN_UNIT_DISPLAY, 2354 tabstop); 2355 snprintf (expected, buf_len, 2356 "fix-it:%s:{1:10-1:16}:\"color\"\n", escaped_fname); 2357 ASSERT_STREQ (expected, pp_formatted_text (&pp)); 2358 } 2359 2360 XDELETEVEC (expected); 2361 free (escaped_fname); 2362 } 2363 2364 /* Verify that 2365 diagnostic_get_location_text (..., SHOW_COLUMN) 2366 generates EXPECTED_LOC_TEXT, given FILENAME, LINE, COLUMN, with 2367 colorization disabled. */ 2368 2369 static void 2370 assert_location_text (const char *expected_loc_text, 2371 const char *filename, int line, int column, 2372 bool show_column, 2373 int origin = 1, 2374 enum diagnostics_column_unit column_unit 2375 = DIAGNOSTICS_COLUMN_UNIT_BYTE) 2376 { 2377 test_diagnostic_context dc; 2378 dc.show_column = show_column; 2379 dc.column_unit = column_unit; 2380 dc.column_origin = origin; 2381 2382 expanded_location xloc; 2383 xloc.file = filename; 2384 xloc.line = line; 2385 xloc.column = column; 2386 xloc.data = NULL; 2387 xloc.sysp = false; 2388 2389 char *actual_loc_text = diagnostic_get_location_text (&dc, xloc); 2390 ASSERT_STREQ (expected_loc_text, actual_loc_text); 2391 free (actual_loc_text); 2392 } 2393 2394 /* Verify that diagnostic_get_location_text works as expected. */ 2395 2396 static void 2397 test_diagnostic_get_location_text () 2398 { 2399 const char *old_progname = progname; 2400 progname = "PROGNAME"; 2401 assert_location_text ("PROGNAME:", NULL, 0, 0, true); 2402 assert_location_text ("<built-in>:", "<built-in>", 42, 10, true); 2403 assert_location_text ("foo.c:42:10:", "foo.c", 42, 10, true); 2404 assert_location_text ("foo.c:42:9:", "foo.c", 42, 10, true, 0); 2405 assert_location_text ("foo.c:42:1010:", "foo.c", 42, 10, true, 1001); 2406 for (int origin = 0; origin != 2; ++origin) 2407 assert_location_text ("foo.c:42:", "foo.c", 42, 0, true, origin); 2408 assert_location_text ("foo.c:", "foo.c", 0, 10, true); 2409 assert_location_text ("foo.c:42:", "foo.c", 42, 10, false); 2410 assert_location_text ("foo.c:", "foo.c", 0, 10, false); 2411 2412 maybe_line_and_column (INT_MAX, INT_MAX); 2413 maybe_line_and_column (INT_MIN, INT_MIN); 2414 2415 { 2416 /* In order to test display columns vs byte columns, we need to create a 2417 file for location_get_source_line() to read. */ 2418 2419 const char *const content = "smile \xf0\x9f\x98\x82\n"; 2420 const int line_bytes = strlen (content) - 1; 2421 const int def_tabstop = 8; 2422 const cpp_char_column_policy policy (def_tabstop, cpp_wcwidth); 2423 const int display_width = cpp_display_width (content, line_bytes, policy); 2424 ASSERT_EQ (line_bytes - 2, display_width); 2425 temp_source_file tmp (SELFTEST_LOCATION, ".c", content); 2426 const char *const fname = tmp.get_filename (); 2427 const int buf_len = strlen (fname) + 16; 2428 char *const expected = XNEWVEC (char, buf_len); 2429 2430 snprintf (expected, buf_len, "%s:1:%d:", fname, line_bytes); 2431 assert_location_text (expected, fname, 1, line_bytes, true, 2432 1, DIAGNOSTICS_COLUMN_UNIT_BYTE); 2433 2434 snprintf (expected, buf_len, "%s:1:%d:", fname, line_bytes - 1); 2435 assert_location_text (expected, fname, 1, line_bytes, true, 2436 0, DIAGNOSTICS_COLUMN_UNIT_BYTE); 2437 2438 snprintf (expected, buf_len, "%s:1:%d:", fname, display_width); 2439 assert_location_text (expected, fname, 1, line_bytes, true, 2440 1, DIAGNOSTICS_COLUMN_UNIT_DISPLAY); 2441 2442 snprintf (expected, buf_len, "%s:1:%d:", fname, display_width - 1); 2443 assert_location_text (expected, fname, 1, line_bytes, true, 2444 0, DIAGNOSTICS_COLUMN_UNIT_DISPLAY); 2445 2446 XDELETEVEC (expected); 2447 } 2448 2449 2450 progname = old_progname; 2451 } 2452 2453 /* Selftest for num_digits. */ 2454 2455 static void 2456 test_num_digits () 2457 { 2458 ASSERT_EQ (1, num_digits (0)); 2459 ASSERT_EQ (1, num_digits (9)); 2460 ASSERT_EQ (2, num_digits (10)); 2461 ASSERT_EQ (2, num_digits (99)); 2462 ASSERT_EQ (3, num_digits (100)); 2463 ASSERT_EQ (3, num_digits (999)); 2464 ASSERT_EQ (4, num_digits (1000)); 2465 ASSERT_EQ (4, num_digits (9999)); 2466 ASSERT_EQ (5, num_digits (10000)); 2467 ASSERT_EQ (5, num_digits (99999)); 2468 ASSERT_EQ (6, num_digits (100000)); 2469 ASSERT_EQ (6, num_digits (999999)); 2470 ASSERT_EQ (7, num_digits (1000000)); 2471 ASSERT_EQ (7, num_digits (9999999)); 2472 ASSERT_EQ (8, num_digits (10000000)); 2473 ASSERT_EQ (8, num_digits (99999999)); 2474 } 2475 2476 /* Run all of the selftests within this file. */ 2477 2478 void 2479 c_diagnostic_cc_tests () 2480 { 2481 test_print_escaped_string (); 2482 test_print_parseable_fixits_none (); 2483 test_print_parseable_fixits_insert (); 2484 test_print_parseable_fixits_remove (); 2485 test_print_parseable_fixits_replace (); 2486 test_print_parseable_fixits_bytes_vs_display_columns (); 2487 test_diagnostic_get_location_text (); 2488 test_num_digits (); 2489 2490 } 2491 2492 } // namespace selftest 2493 2494 #endif /* #if CHECKING_P */ 2495 2496 #if __GNUC__ >= 10 2497 # pragma GCC diagnostic pop 2498 #endif 2499