LCOV - code coverage report
Current view: top level - gcc - diagnostic.c (source / functions) Hit Total Coverage
Test: gcc.info Lines: 823 948 86.8 %
Date: 2020-04-04 11:58:09 Functions: 79 92 85.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 0 -

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

Generated by: LCOV version 1.0

LCOV profile is generated on x86_64 machine using following configure options: configure --disable-bootstrap --enable-coverage=opt --enable-languages=c,c++,fortran,go,jit,lto --enable-host-shared. GCC test suite is run with the built compiler.