LCOV - code coverage report
Current view: top level - gcc - opts.cc (source / functions) Coverage Total Hit
Test: gcc.info Lines: 88.1 % 1821 1604
Test Date: 2026-07-11 15:47:05 Functions: 98.3 % 58 57
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /* Command line option handling.
       2              :    Copyright (C) 2002-2026 Free Software Foundation, Inc.
       3              :    Contributed by Neil Booth.
       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              : #define INCLUDE_LIST
      22              : #define INCLUDE_VECTOR
      23              : #include "config.h"
      24              : #include "system.h"
      25              : #include "intl.h"
      26              : #include "coretypes.h"
      27              : #include "opts.h"
      28              : #include "tm.h"
      29              : #include "flags.h"
      30              : #include "diagnostic.h"
      31              : #include "opts-diagnostic.h"
      32              : #include "insn-attr-common.h"
      33              : #include "common/common-target.h"
      34              : #include "spellcheck.h"
      35              : #include "opt-suggestions.h"
      36              : #include "diagnostics/color.h"
      37              : #include "diagnostics/sink.h"
      38              : #include "version.h"
      39              : #include "selftest.h"
      40              : #include "file-prefix-map.h"
      41              : 
      42              : /* In this file all option sets are explicit.  */
      43              : #undef OPTION_SET_P
      44              : 
      45              : /* Set by -fcanon-prefix-map.  */
      46              : bool flag_canon_prefix_map;
      47              : 
      48              : /* Set by finish_options when flag_stack_protector was set only because of
      49              :    -fhardened.  Yuck.  */
      50              : bool flag_stack_protector_set_by_fhardened_p;
      51              : 
      52              : static void set_Wstrict_aliasing (struct gcc_options *opts, int onoff);
      53              : 
      54              : /* Names of fundamental debug info formats indexed by enum
      55              :    debug_info_type.  */
      56              : 
      57              : const char *const debug_type_names[] =
      58              : {
      59              :   "none", "dwarf-2", "vms", "ctf", "btf", "codeview"
      60              : };
      61              : 
      62              : /* Bitmasks of fundamental debug info formats indexed by enum
      63              :    debug_info_type.  */
      64              : 
      65              : static uint32_t debug_type_masks[] =
      66              : {
      67              :   NO_DEBUG, DWARF2_DEBUG, VMS_DEBUG,
      68              :   CTF_DEBUG, BTF_DEBUG, CODEVIEW_DEBUG
      69              : };
      70              : 
      71              : /* Names of the set of debug formats requested by user.  Updated and accessed
      72              :    via debug_set_names.  */
      73              : 
      74              : static char df_set_names[sizeof "none dwarf-2 vms ctf btf codeview"];
      75              : 
      76              : /* Get enum debug_info_type of the specified debug format, for error messages.
      77              :    Can be used only for individual debug format types.  */
      78              : 
      79              : enum debug_info_type
      80            0 : debug_set_to_format (uint32_t debug_info_set)
      81              : {
      82            0 :   int idx = 0;
      83            0 :   enum debug_info_type dinfo_type = DINFO_TYPE_NONE;
      84              :   /* Find first set bit.  */
      85            0 :   if (debug_info_set)
      86            0 :     idx = exact_log2 (debug_info_set & - debug_info_set);
      87              :   /* Check that only one bit is set, if at all.  This function is meant to be
      88              :      used only for vanilla debug_info_set bitmask values, i.e. for individual
      89              :      debug format types upto DINFO_TYPE_MAX.  */
      90            0 :   gcc_assert ((debug_info_set & (debug_info_set - 1)) == 0);
      91            0 :   dinfo_type = (enum debug_info_type)idx;
      92            0 :   gcc_assert (dinfo_type <= DINFO_TYPE_MAX);
      93            0 :   return dinfo_type;
      94              : }
      95              : 
      96              : /* Get the number of debug formats enabled for output.  */
      97              : 
      98              : unsigned int
      99           12 : debug_set_count (uint32_t w_symbols)
     100              : {
     101           12 :   unsigned int count = 0;
     102           18 :   while (w_symbols)
     103              :     {
     104            6 :       ++ count;
     105            6 :       w_symbols &= ~ (w_symbols & - w_symbols);
     106              :     }
     107           12 :   return count;
     108              : }
     109              : 
     110              : /* Get the names of the debug formats enabled for output.  */
     111              : 
     112              : const char *
     113           12 : debug_set_names (uint32_t w_symbols)
     114              : {
     115           12 :   uint32_t df_mask = 0;
     116              :   /* Reset the string to be returned.  */
     117           12 :   memset (df_set_names, 0, sizeof (df_set_names));
     118              :   /* Get the popcount.  */
     119           12 :   int num_set_df = debug_set_count (w_symbols);
     120              :   /* Iterate over the debug formats.  Add name string for those enabled.  */
     121           18 :   for (int i = DINFO_TYPE_NONE; i <= DINFO_TYPE_MAX; i++)
     122              :     {
     123           18 :       df_mask = debug_type_masks[i];
     124           18 :       if (w_symbols & df_mask)
     125              :         {
     126            6 :           strcat (df_set_names, debug_type_names[i]);
     127            6 :           num_set_df--;
     128            6 :           if (num_set_df)
     129            0 :             strcat (df_set_names, " ");
     130              :           else
     131              :             break;
     132              :         }
     133           12 :       else if (!w_symbols)
     134              :         {
     135              :           /* No debug formats enabled.  */
     136            6 :           gcc_assert (i == DINFO_TYPE_NONE);
     137            6 :           strcat (df_set_names, debug_type_names[i]);
     138            6 :           break;
     139              :         }
     140              :     }
     141           12 :   return df_set_names;
     142              : }
     143              : 
     144              : /* Return TRUE iff BTF debug info is enabled.  */
     145              : 
     146              : bool
     147       108023 : btf_debuginfo_p ()
     148              : {
     149       108023 :   return (write_symbols & BTF_DEBUG);
     150              : }
     151              : 
     152              : /* Return TRUE iff BTF with CO-RE debug info is enabled.  */
     153              : 
     154              : bool
     155          181 : btf_with_core_debuginfo_p ()
     156              : {
     157          181 :   return (write_symbols & BTF_WITH_CORE_DEBUG);
     158              : }
     159              : 
     160              : /* Return TRUE iff CTF debug info is enabled.  */
     161              : 
     162              : bool
     163          311 : ctf_debuginfo_p ()
     164              : {
     165          311 :   return (write_symbols & CTF_DEBUG);
     166              : }
     167              : 
     168              : /* Return TRUE iff CodeView debug info is enabled.  */
     169              : 
     170              : bool
     171          317 : codeview_debuginfo_p ()
     172              : {
     173          317 :   return (write_symbols & CODEVIEW_DEBUG);
     174              : }
     175              : 
     176              : /* Return TRUE iff dwarf2 debug info is enabled.  */
     177              : 
     178              : bool
     179     46111460 : dwarf_debuginfo_p (struct gcc_options *opts)
     180              : {
     181     46111460 :   return (opts->x_write_symbols & DWARF2_DEBUG);
     182              : }
     183              : 
     184              : /* Return true iff the debug info format is to be generated based on DWARF
     185              :    DIEs (like CTF and BTF debug info formats).  */
     186              : 
     187      4976633 : bool dwarf_based_debuginfo_p ()
     188              : {
     189      4976633 :   return ((write_symbols & CTF_DEBUG)
     190      4975473 :           || (write_symbols & BTF_DEBUG)
     191      9951843 :           || (write_symbols & CODEVIEW_DEBUG));
     192              : }
     193              : 
     194              : /* All flag uses below need to explicitly reference the option sets
     195              :    to operate on.  */
     196              : #define global_options DO_NOT_USE
     197              : #define global_options_set DO_NOT_USE
     198              : 
     199              : /* Parse the -femit-struct-debug-detailed option value
     200              :    and set the flag variables. */
     201              : 
     202              : #define MATCH( prefix, string ) \
     203              :   ((strncmp (prefix, string, sizeof prefix - 1) == 0) \
     204              :    ? ((string += sizeof prefix - 1), 1) : 0)
     205              : 
     206              : void
     207           42 : set_struct_debug_option (struct gcc_options *opts, location_t loc,
     208              :                          const char *spec)
     209              : {
     210              :   /* various labels for comparison */
     211           58 :   static const char dfn_lbl[] = "dfn:", dir_lbl[] = "dir:", ind_lbl[] = "ind:";
     212           58 :   static const char ord_lbl[] = "ord:", gen_lbl[] = "gen:";
     213           58 :   static const char none_lbl[] = "none", any_lbl[] = "any";
     214           58 :   static const char base_lbl[] = "base", sys_lbl[] = "sys";
     215              : 
     216           58 :   enum debug_struct_file files = DINFO_STRUCT_FILE_ANY;
     217              :   /* Default is to apply to as much as possible. */
     218           58 :   enum debug_info_usage usage = DINFO_USAGE_NUM_ENUMS;
     219           58 :   int ord = 1, gen = 1;
     220              : 
     221              :   /* What usage? */
     222           58 :   if (MATCH (dfn_lbl, spec))
     223              :     usage = DINFO_USAGE_DFN;
     224           58 :   else if (MATCH (dir_lbl, spec))
     225              :     usage = DINFO_USAGE_DIR_USE;
     226           42 :   else if (MATCH (ind_lbl, spec))
     227            8 :     usage = DINFO_USAGE_IND_USE;
     228              : 
     229              :   /* Generics or not? */
     230           58 :   if (MATCH (ord_lbl, spec))
     231              :     gen = 0;
     232           50 :   else if (MATCH (gen_lbl, spec))
     233            8 :     ord = 0;
     234              : 
     235              :   /* What allowable environment? */
     236           58 :   if (MATCH (none_lbl, spec))
     237              :     files = DINFO_STRUCT_FILE_NONE;
     238           54 :   else if (MATCH (any_lbl, spec))
     239              :     files = DINFO_STRUCT_FILE_ANY;
     240           42 :   else if (MATCH (sys_lbl, spec))
     241              :     files = DINFO_STRUCT_FILE_SYS;
     242           30 :   else if (MATCH (base_lbl, spec))
     243              :     files = DINFO_STRUCT_FILE_BASE;
     244              :   else
     245            0 :     error_at (loc,
     246              :               "argument %qs to %<-femit-struct-debug-detailed%> "
     247              :               "not recognized",
     248              :               spec);
     249              : 
     250              :   /* Effect the specification. */
     251           58 :   if (usage == DINFO_USAGE_NUM_ENUMS)
     252              :     {
     253           34 :       if (ord)
     254              :         {
     255           34 :           opts->x_debug_struct_ordinary[DINFO_USAGE_DFN] = files;
     256           34 :           opts->x_debug_struct_ordinary[DINFO_USAGE_DIR_USE] = files;
     257           34 :           opts->x_debug_struct_ordinary[DINFO_USAGE_IND_USE] = files;
     258              :         }
     259           34 :       if (gen)
     260              :         {
     261           34 :           opts->x_debug_struct_generic[DINFO_USAGE_DFN] = files;
     262           34 :           opts->x_debug_struct_generic[DINFO_USAGE_DIR_USE] = files;
     263           34 :           opts->x_debug_struct_generic[DINFO_USAGE_IND_USE] = files;
     264              :         }
     265              :     }
     266              :   else
     267              :     {
     268           24 :       if (ord)
     269           16 :         opts->x_debug_struct_ordinary[usage] = files;
     270           24 :       if (gen)
     271           16 :         opts->x_debug_struct_generic[usage] = files;
     272              :     }
     273              : 
     274           58 :   if (*spec == ',')
     275           16 :     set_struct_debug_option (opts, loc, spec+1);
     276              :   else
     277              :     {
     278              :       /* No more -femit-struct-debug-detailed specifications.
     279              :          Do final checks. */
     280           42 :       if (*spec != '\0')
     281            0 :         error_at (loc,
     282              :                   "argument %qs to %<-femit-struct-debug-detailed%> unknown",
     283              :                   spec);
     284           42 :       if (opts->x_debug_struct_ordinary[DINFO_USAGE_DIR_USE]
     285           42 :                 < opts->x_debug_struct_ordinary[DINFO_USAGE_IND_USE]
     286           42 :           || opts->x_debug_struct_generic[DINFO_USAGE_DIR_USE]
     287           42 :                 < opts->x_debug_struct_generic[DINFO_USAGE_IND_USE])
     288            0 :         error_at (loc,
     289              :                   "%<-femit-struct-debug-detailed=dir:...%> must allow "
     290              :                   "at least as much as "
     291              :                   "%<-femit-struct-debug-detailed=ind:...%>");
     292              :     }
     293           42 : }
     294              : 
     295              : /* Strip off a legitimate source ending from the input string NAME of
     296              :    length LEN.  Rather than having to know the names used by all of
     297              :    our front ends, we strip off an ending of a period followed by
     298              :    up to fource characters.  (C++ uses ".cpp".)  */
     299              : 
     300              : void
     301         1526 : strip_off_ending (char *name, int len)
     302              : {
     303         1526 :   int i;
     304         1686 :   for (i = 2; i < 5 && len > i; i++)
     305              :     {
     306         1686 :       if (name[len - i] == '.')
     307              :         {
     308         1526 :           name[len - i] = '\0';
     309         1526 :           break;
     310              :         }
     311              :     }
     312         1526 : }
     313              : 
     314              : /* Find the base name of a path, stripping off both directories and
     315              :    a single final extension. */
     316              : int
     317       292484 : base_of_path (const char *path, const char **base_out)
     318              : {
     319       292484 :   const char *base = path;
     320       292484 :   const char *dot = 0;
     321       292484 :   const char *p = path;
     322       292484 :   char c = *p;
     323     22743848 :   while (c)
     324              :     {
     325     22451364 :       if (IS_DIR_SEPARATOR (c))
     326              :         {
     327      2560107 :           base = p + 1;
     328      2560107 :           dot = 0;
     329              :         }
     330     19891257 :       else if (c == '.')
     331       511848 :         dot = p;
     332     22451364 :       c = *++p;
     333              :     }
     334       292484 :   if (!dot)
     335          421 :     dot = p;
     336       292484 :   *base_out = base;
     337       292484 :   return dot - base;
     338              : }
     339              : 
     340              : /* What to print when a switch has no documentation.  */
     341              : static const char undocumented_msg[] = N_("This option lacks documentation.");
     342              : static const char use_diagnosed_msg[] = N_("Uses of this option are diagnosed.");
     343              : 
     344              : typedef char *char_p; /* For DEF_VEC_P.  */
     345              : 
     346              : static void set_debug_level (uint32_t dinfo, int extended,
     347              :                              const char *arg, struct gcc_options *opts,
     348              :                              struct gcc_options *opts_set,
     349              :                              location_t loc);
     350              : static void set_fast_math_flags (struct gcc_options *opts, int set);
     351              : static void decode_d_option (const char *arg, struct gcc_options *opts,
     352              :                              location_t loc, diagnostics::context *dc);
     353              : static void set_unsafe_math_optimizations_flags (struct gcc_options *opts,
     354              :                                                  int set);
     355              : static void enable_warning_as_error (const char *arg, int value,
     356              :                                      unsigned int lang_mask,
     357              :                                      const struct cl_option_handlers *handlers,
     358              :                                      struct gcc_options *opts,
     359              :                                      struct gcc_options *opts_set,
     360              :                                      location_t loc,
     361              :                                      diagnostics::context *dc);
     362              : 
     363              : /* Handle a back-end option; arguments and return value as for
     364              :    handle_option.  */
     365              : 
     366              : bool
     367      1287785 : target_handle_option (struct gcc_options *opts,
     368              :                       struct gcc_options *opts_set,
     369              :                       const struct cl_decoded_option *decoded,
     370              :                       unsigned int lang_mask ATTRIBUTE_UNUSED, int kind,
     371              :                       location_t loc,
     372              :                       const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED,
     373              :                       diagnostics::context *dc, void (*) (void))
     374              : {
     375      1287785 :   gcc_assert (dc == global_dc);
     376      1287785 :   gcc_assert (static_cast<diagnostics::kind> (kind)
     377              :               == diagnostics::kind::unspecified);
     378      1287785 :   return targetm_common.handle_option (opts, opts_set, decoded, loc);
     379              : }
     380              : 
     381              : /* Add comma-separated strings to a char_p vector.  */
     382              : 
     383              : static void
     384          102 : add_comma_separated_to_vector (void **pvec, const char *arg)
     385              : {
     386          102 :   char *tmp;
     387          102 :   char *r;
     388          102 :   char *w;
     389          102 :   char *token_start;
     390          102 :   vec<char_p> *v = (vec<char_p> *) *pvec;
     391              : 
     392          102 :   vec_check_alloc (v, 1);
     393              : 
     394              :   /* We never free this string.  */
     395          102 :   tmp = xstrdup (arg);
     396              : 
     397          102 :   r = tmp;
     398          102 :   w = tmp;
     399          102 :   token_start = tmp;
     400              : 
     401         1227 :   while (*r != '\0')
     402              :     {
     403         1125 :       if (*r == ',')
     404              :         {
     405           20 :           *w++ = '\0';
     406           20 :           ++r;
     407           20 :           v->safe_push (token_start);
     408           20 :           token_start = w;
     409              :         }
     410         1125 :       if (*r == '\\' && r[1] == ',')
     411              :         {
     412            0 :           *w++ = ',';
     413            0 :           r += 2;
     414              :         }
     415              :       else
     416         1125 :         *w++ = *r++;
     417              :     }
     418              : 
     419          102 :   *w = '\0';
     420          102 :   if (*token_start != '\0')
     421          102 :     v->safe_push (token_start);
     422              : 
     423          102 :   *pvec = v;
     424          102 : }
     425              : 
     426              : /* Initialize opts_obstack.  */
     427              : 
     428              : void
     429       608835 : init_opts_obstack (void)
     430              : {
     431       608835 :   gcc_obstack_init (&opts_obstack);
     432       608835 : }
     433              : 
     434              : /* Initialize OPTS and OPTS_SET before using them in parsing options.  */
     435              : 
     436              : void
     437     48374170 : init_options_struct (struct gcc_options *opts, struct gcc_options *opts_set)
     438              : {
     439              :   /* Ensure that opts_obstack has already been initialized by the time
     440              :      that we initialize any gcc_options instances (PR jit/68446).  */
     441     48374170 :   gcc_assert (opts_obstack.chunk_size > 0);
     442              : 
     443     48374170 :   *opts = global_options_init;
     444              : 
     445     48374170 :   if (opts_set)
     446       596494 :     memset (opts_set, 0, sizeof (*opts_set));
     447              : 
     448              :   /* Initialize whether `char' is signed.  */
     449     48374170 :   opts->x_flag_signed_char = DEFAULT_SIGNED_CHAR;
     450              : 
     451              :   /* Initialize target_flags before default_options_optimization
     452              :      so the latter can modify it.  */
     453     48374170 :   opts->x_target_flags = targetm_common.default_target_flags;
     454              : 
     455              :   /* Some targets have ABI-specified unwind tables.  */
     456     48374170 :   opts->x_flag_unwind_tables = targetm_common.unwind_tables_default;
     457              : 
     458              :   /* Languages not explicitly specifying a default get fortran rules.  */
     459     48374170 :   opts->x_flag_complex_method = 1;
     460              : 
     461              :   /* Some targets have other target-specific initialization.  */
     462     48374170 :   targetm_common.option_init_struct (opts);
     463     48374170 : }
     464              : 
     465              : /* If indicated by the optimization level LEVEL (-Os if SIZE is set,
     466              :    -Ofast if FAST is set, -Og if DEBUG is set), apply the option DEFAULT_OPT
     467              :    to OPTS and OPTS_SET, diagnostic context DC, location LOC, with language
     468              :    mask LANG_MASK and option handlers HANDLERS.  */
     469              : 
     470              : static void
     471     76562640 : maybe_default_option (struct gcc_options *opts,
     472              :                       struct gcc_options *opts_set,
     473              :                       const struct default_options *default_opt,
     474              :                       int level, bool size, bool fast, bool debug,
     475              :                       unsigned int lang_mask,
     476              :                       const struct cl_option_handlers *handlers,
     477              :                       location_t loc,
     478              :                       diagnostics::context *dc)
     479              : {
     480     76562640 :   const struct cl_option *option = &cl_options[default_opt->opt_index];
     481     76562640 :   bool enabled;
     482              : 
     483     76562640 :   if (size)
     484      1876320 :     gcc_assert (level == 2);
     485     76562640 :   if (fast)
     486        76200 :     gcc_assert (level == 3);
     487     76562640 :   if (debug)
     488        83280 :     gcc_assert (level == 1);
     489              : 
     490     76562640 :   switch (default_opt->levels)
     491              :     {
     492              :     case OPT_LEVELS_ALL:
     493              :       enabled = true;
     494              :       break;
     495              : 
     496            0 :     case OPT_LEVELS_0_ONLY:
     497            0 :       enabled = (level == 0);
     498            0 :       break;
     499              : 
     500     19140660 :     case OPT_LEVELS_1_PLUS:
     501     19140660 :       enabled = (level >= 1);
     502     19140660 :       break;
     503              : 
     504            0 :     case OPT_LEVELS_1_PLUS_SPEED_ONLY:
     505            0 :       enabled = (level >= 1 && !size && !debug);
     506              :       break;
     507              : 
     508      8294286 :     case OPT_LEVELS_1_PLUS_NOT_DEBUG:
     509      8294286 :       enabled = (level >= 1 && !debug);
     510      8294286 :       break;
     511              : 
     512     26796924 :     case OPT_LEVELS_2_PLUS:
     513     26796924 :       enabled = (level >= 2);
     514     26796924 :       break;
     515              : 
     516      7656264 :     case OPT_LEVELS_2_PLUS_SPEED_ONLY:
     517      7656264 :       enabled = (level >= 2 && !size && !debug);
     518              :       break;
     519              : 
     520     10846374 :     case OPT_LEVELS_3_PLUS:
     521     10846374 :       enabled = (level >= 3);
     522     10846374 :       break;
     523              : 
     524            0 :     case OPT_LEVELS_3_PLUS_AND_SIZE:
     525            0 :       enabled = (level >= 3 || size);
     526            0 :       break;
     527              : 
     528              :     case OPT_LEVELS_SIZE:
     529              :       enabled = size;
     530              :       break;
     531              : 
     532      1914066 :     case OPT_LEVELS_FAST:
     533      1914066 :       enabled = fast;
     534      1914066 :       break;
     535              : 
     536            0 :     case OPT_LEVELS_NONE:
     537            0 :     default:
     538            0 :       gcc_unreachable ();
     539              :     }
     540              : 
     541     66992310 :   if (enabled)
     542     51419483 :     handle_generated_option (opts, opts_set, default_opt->opt_index,
     543     51419483 :                              default_opt->arg, default_opt->value,
     544              :                              lang_mask,
     545              :                              static_cast<int> (diagnostics::kind::unspecified),
     546              :                              loc,
     547              :                              handlers, true, dc);
     548     25143157 :   else if (default_opt->arg == NULL
     549     25143157 :            && !option->cl_reject_negative
     550     23928536 :            && !(option->flags & CL_PARAMS))
     551     20886051 :     handle_generated_option (opts, opts_set, default_opt->opt_index,
     552     20886051 :                              default_opt->arg, !default_opt->value,
     553              :                              lang_mask,
     554              :                              static_cast<int> (diagnostics::kind::unspecified),
     555              :                              loc,
     556              :                              handlers, true, dc);
     557     76562640 : }
     558              : 
     559              : /* As indicated by the optimization level LEVEL (-Os if SIZE is set,
     560              :    -Ofast if FAST is set), apply the options in array DEFAULT_OPTS to
     561              :    OPTS and OPTS_SET, diagnostic context DC, location LOC, with
     562              :    language mask LANG_MASK and option handlers HANDLERS.  */
     563              : 
     564              : static void
     565      1276044 : maybe_default_options (struct gcc_options *opts,
     566              :                        struct gcc_options *opts_set,
     567              :                        const struct default_options *default_opts,
     568              :                        int level, bool size, bool fast, bool debug,
     569              :                        unsigned int lang_mask,
     570              :                        const struct cl_option_handlers *handlers,
     571              :                        location_t loc,
     572              :                        diagnostics::context *dc)
     573              : {
     574      1276044 :   size_t i;
     575              : 
     576     77838684 :   for (i = 0; default_opts[i].levels != OPT_LEVELS_NONE; i++)
     577     76562640 :     maybe_default_option (opts, opts_set, &default_opts[i],
     578              :                           level, size, fast, debug,
     579              :                           lang_mask, handlers, loc, dc);
     580      1276044 : }
     581              : 
     582              : /* Table of options enabled by default at different levels.
     583              :    Please keep this list sorted by level and alphabetized within
     584              :    each level; this makes it easier to keep the documentation
     585              :    in sync.  */
     586              : 
     587              : static const struct default_options default_options_table[] =
     588              :   {
     589              :     /* -O1 and -Og optimizations.  */
     590              :     { OPT_LEVELS_1_PLUS, OPT_fbit_tests, NULL, 1 },
     591              :     { OPT_LEVELS_1_PLUS, OPT_fcombine_stack_adjustments, NULL, 1 },
     592              :     { OPT_LEVELS_1_PLUS, OPT_fcompare_elim, NULL, 1 },
     593              :     { OPT_LEVELS_1_PLUS, OPT_fcprop_registers, NULL, 1 },
     594              :     { OPT_LEVELS_1_PLUS, OPT_fdefer_pop, NULL, 1 },
     595              :     { OPT_LEVELS_1_PLUS, OPT_fforward_propagate, NULL, 1 },
     596              :     { OPT_LEVELS_1_PLUS, OPT_fguess_branch_probability, NULL, 1 },
     597              :     { OPT_LEVELS_1_PLUS, OPT_fipa_profile, NULL, 1 },
     598              :     { OPT_LEVELS_1_PLUS, OPT_fipa_pure_const, NULL, 1 },
     599              :     { OPT_LEVELS_1_PLUS, OPT_fipa_reference, NULL, 1 },
     600              :     { OPT_LEVELS_1_PLUS, OPT_fipa_reference_addressable, NULL, 1 },
     601              :     { OPT_LEVELS_1_PLUS, OPT_fjump_tables, NULL, 1 },
     602              :     { OPT_LEVELS_1_PLUS, OPT_fmerge_constants, NULL, 1 },
     603              :     { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
     604              :     { OPT_LEVELS_1_PLUS, OPT_freorder_blocks, NULL, 1 },
     605              :     { OPT_LEVELS_1_PLUS, OPT_fshrink_wrap, NULL, 1 },
     606              :     { OPT_LEVELS_1_PLUS, OPT_fsplit_wide_types, NULL, 1 },
     607              :     { OPT_LEVELS_1_PLUS, OPT_fthread_jumps, NULL, 1 },
     608              :     { OPT_LEVELS_1_PLUS, OPT_ftree_builtin_call_dce, NULL, 1 },
     609              :     { OPT_LEVELS_1_PLUS, OPT_ftree_ccp, NULL, 1 },
     610              :     { OPT_LEVELS_1_PLUS, OPT_ftree_ch, NULL, 1 },
     611              :     { OPT_LEVELS_1_PLUS, OPT_ftree_coalesce_vars, NULL, 1 },
     612              :     { OPT_LEVELS_1_PLUS, OPT_ftree_copy_prop, NULL, 1 },
     613              :     { OPT_LEVELS_1_PLUS, OPT_ftree_dce, NULL, 1 },
     614              :     { OPT_LEVELS_1_PLUS, OPT_ftree_dominator_opts, NULL, 1 },
     615              :     { OPT_LEVELS_1_PLUS, OPT_ftree_fre, NULL, 1 },
     616              :     { OPT_LEVELS_1_PLUS, OPT_ftree_sink, NULL, 1 },
     617              :     { OPT_LEVELS_1_PLUS, OPT_ftree_slsr, NULL, 1 },
     618              :     { OPT_LEVELS_1_PLUS, OPT_ftree_ter, NULL, 1 },
     619              :     { OPT_LEVELS_1_PLUS, OPT_fvar_tracking, NULL, 1 },
     620              : 
     621              :     /* -O1 (and not -Og) optimizations.  */
     622              :     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fbranch_count_reg, NULL, 1 },
     623              : #if DELAY_SLOTS
     624              :     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fdelayed_branch, NULL, 1 },
     625              : #endif
     626              :     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fdse, NULL, 1 },
     627              :     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fif_conversion, NULL, 1 },
     628              :     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fif_conversion2, NULL, 1 },
     629              :     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_finline_functions_called_once, NULL, 1 },
     630              :     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fmove_loop_invariants, NULL, 1 },
     631              :     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fmove_loop_stores, NULL, 1 },
     632              :     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fssa_phiopt, NULL, 1 },
     633              :     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fipa_modref, NULL, 1 },
     634              :     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_bit_ccp, NULL, 1 },
     635              :     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_dse, NULL, 1 },
     636              :     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_pta, NULL, 1 },
     637              :     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_sra, NULL, 1 },
     638              : 
     639              :     /* -O2 and -Os optimizations.  */
     640              :     { OPT_LEVELS_2_PLUS, OPT_fcaller_saves, NULL, 1 },
     641              :     { OPT_LEVELS_2_PLUS, OPT_fcode_hoisting, NULL, 1 },
     642              :     { OPT_LEVELS_2_PLUS, OPT_fcrossjumping, NULL, 1 },
     643              :     { OPT_LEVELS_2_PLUS, OPT_fcse_follow_jumps, NULL, 1 },
     644              :     { OPT_LEVELS_2_PLUS, OPT_fdep_fusion, NULL, 1 },
     645              :     { OPT_LEVELS_2_PLUS, OPT_fdevirtualize, NULL, 1 },
     646              :     { OPT_LEVELS_2_PLUS, OPT_fdevirtualize_speculatively, NULL, 1 },
     647              :     { OPT_LEVELS_2_PLUS, OPT_fexpensive_optimizations, NULL, 1 },
     648              :     { OPT_LEVELS_2_PLUS, OPT_fext_dce, NULL, 1 },
     649              :     { OPT_LEVELS_2_PLUS, OPT_fgcse, NULL, 1 },
     650              :     { OPT_LEVELS_2_PLUS, OPT_fhoist_adjacent_loads, NULL, 1 },
     651              :     { OPT_LEVELS_2_PLUS, OPT_findirect_inlining, NULL, 1 },
     652              :     { OPT_LEVELS_2_PLUS, OPT_finline_small_functions, NULL, 1 },
     653              :     { OPT_LEVELS_2_PLUS, OPT_fipa_bit_cp, NULL, 1 },
     654              :     { OPT_LEVELS_2_PLUS, OPT_fipa_cp, NULL, 1 },
     655              :     { OPT_LEVELS_2_PLUS, OPT_fipa_icf, NULL, 1 },
     656              :     { OPT_LEVELS_2_PLUS, OPT_fipa_ra, NULL, 1 },
     657              :     { OPT_LEVELS_2_PLUS, OPT_fipa_sra, NULL, 1 },
     658              :     { OPT_LEVELS_2_PLUS, OPT_fipa_vrp, NULL, 1 },
     659              :     { OPT_LEVELS_2_PLUS, OPT_fisolate_erroneous_paths_dereference, NULL, 1 },
     660              :     { OPT_LEVELS_2_PLUS, OPT_flra_remat, NULL, 1 },
     661              :     { OPT_LEVELS_2_PLUS, OPT_foptimize_sibling_calls, NULL, 1 },
     662              :     { OPT_LEVELS_2_PLUS, OPT_fpartial_inlining, NULL, 1 },
     663              :     { OPT_LEVELS_2_PLUS, OPT_fpeephole2, NULL, 1 },
     664              :     { OPT_LEVELS_2_PLUS, OPT_freorder_functions, NULL, 1 },
     665              :     { OPT_LEVELS_2_PLUS, OPT_frerun_cse_after_loop, NULL, 1 },
     666              :     { OPT_LEVELS_2_PLUS, OPT_fspeculatively_call_stored_functions, NULL, 1 },
     667              : #ifdef INSN_SCHEDULING
     668              :     { OPT_LEVELS_2_PLUS, OPT_fschedule_insns2, NULL, 1 },
     669              : #endif
     670              :     { OPT_LEVELS_2_PLUS, OPT_fstrict_aliasing, NULL, 1 },
     671              :     { OPT_LEVELS_2_PLUS, OPT_fstore_merging, NULL, 1 },
     672              :     { OPT_LEVELS_2_PLUS, OPT_ftree_pre, NULL, 1 },
     673              :     { OPT_LEVELS_2_PLUS, OPT_ftree_switch_conversion, NULL, 1 },
     674              :     { OPT_LEVELS_2_PLUS, OPT_ftree_tail_merge, NULL, 1 },
     675              :     { OPT_LEVELS_2_PLUS, OPT_ftree_vrp, NULL, 1 },
     676              :     { OPT_LEVELS_2_PLUS, OPT_fvect_cost_model_, NULL,
     677              :       VECT_COST_MODEL_VERY_CHEAP },
     678              :     { OPT_LEVELS_2_PLUS, OPT_finline_functions, NULL, 1 },
     679              :     { OPT_LEVELS_2_PLUS, OPT_ftree_loop_distribute_patterns, NULL, 1 },
     680              :     { OPT_LEVELS_2_PLUS, OPT_foptimize_crc, NULL, 1 },
     681              :     { OPT_LEVELS_2_PLUS, OPT_flate_combine_instructions, NULL, 1 },
     682              : 
     683              :     /* -O2 and above optimizations, but not -Os or -Og.  */
     684              :     { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_falign_functions, NULL, 1 },
     685              :     { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_falign_jumps, NULL, 1 },
     686              :     { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_falign_labels, NULL, 1 },
     687              :     { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_falign_loops, NULL, 1 },
     688              :     { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_foptimize_strlen, NULL, 1 },
     689              :     { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_freorder_blocks_algorithm_, NULL,
     690              :       REORDER_BLOCKS_ALGORITHM_STC },
     691              :     { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_ftree_loop_vectorize, NULL, 1 },
     692              :     { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_ftree_slp_vectorize, NULL, 1 },
     693              :     { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_fopenmp_target_simd_clone_, NULL,
     694              :       OMP_TARGET_SIMD_CLONE_NOHOST },
     695              : #ifdef INSN_SCHEDULING
     696              :   /* Only run the pre-regalloc scheduling pass if optimizing for speed.  */
     697              :     { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_fschedule_insns, NULL, 1 },
     698              : #endif
     699              : 
     700              :     /* -O3 and -Os optimizations.  */
     701              : 
     702              :     /* -O3 optimizations.  */
     703              :     { OPT_LEVELS_3_PLUS, OPT_fgcse_after_reload, NULL, 1 },
     704              :     { OPT_LEVELS_3_PLUS, OPT_fipa_cp_clone, NULL, 1 },
     705              :     { OPT_LEVELS_3_PLUS, OPT_floop_interchange, NULL, 1 },
     706              :     { OPT_LEVELS_3_PLUS, OPT_floop_unroll_and_jam, NULL, 1 },
     707              :     { OPT_LEVELS_3_PLUS, OPT_fpeel_loops, NULL, 1 },
     708              :     { OPT_LEVELS_3_PLUS, OPT_fpredictive_commoning, NULL, 1 },
     709              :     { OPT_LEVELS_3_PLUS, OPT_fsplit_loops, NULL, 1 },
     710              :     { OPT_LEVELS_3_PLUS, OPT_ftree_loop_distribution, NULL, 1 },
     711              :     { OPT_LEVELS_3_PLUS, OPT_ftree_partial_pre, NULL, 1 },
     712              :     { OPT_LEVELS_3_PLUS, OPT_funswitch_loops, NULL, 1 },
     713              :     { OPT_LEVELS_3_PLUS, OPT_fvect_cost_model_, NULL, VECT_COST_MODEL_DYNAMIC },
     714              :     { OPT_LEVELS_3_PLUS, OPT_fversion_loops_for_strides, NULL, 1 },
     715              : 
     716              :     /* -O3 parameters.  */
     717              :     { OPT_LEVELS_3_PLUS, OPT__param_max_inline_insns_auto_, NULL, 30 },
     718              :     { OPT_LEVELS_3_PLUS, OPT__param_early_inlining_insns_, NULL, 14 },
     719              :     { OPT_LEVELS_3_PLUS, OPT__param_inline_heuristics_hint_percent_, NULL, 600 },
     720              :     { OPT_LEVELS_3_PLUS, OPT__param_inline_min_speedup_, NULL, 15 },
     721              :     { OPT_LEVELS_3_PLUS, OPT__param_max_inline_insns_single_, NULL, 200 },
     722              : 
     723              :     /* -Ofast adds optimizations to -O3.  */
     724              :     { OPT_LEVELS_FAST, OPT_ffast_math, NULL, 1 },
     725              :     { OPT_LEVELS_FAST, OPT_fallow_store_data_races, NULL, 1 },
     726              :     { OPT_LEVELS_FAST, OPT_fsemantic_interposition, NULL, 0 },
     727              : 
     728              :     { OPT_LEVELS_NONE, 0, NULL, 0 }
     729              :   };
     730              : 
     731              : /* Default the options in OPTS and OPTS_SET based on the optimization
     732              :    settings in DECODED_OPTIONS and DECODED_OPTIONS_COUNT.  */
     733              : void
     734       638022 : default_options_optimization (struct gcc_options *opts,
     735              :                               struct gcc_options *opts_set,
     736              :                               struct cl_decoded_option *decoded_options,
     737              :                               unsigned int decoded_options_count,
     738              :                               location_t loc,
     739              :                               unsigned int lang_mask,
     740              :                               const struct cl_option_handlers *handlers,
     741              :                               diagnostics::context *dc)
     742              : {
     743       638022 :   unsigned int i;
     744       638022 :   int opt2;
     745       638022 :   bool openacc_mode = false;
     746              : 
     747              :   /* Scan to see what optimization level has been specified.  That will
     748              :      determine the default value of many flags.  */
     749     10893395 :   for (i = 1; i < decoded_options_count; i++)
     750              :     {
     751     10255373 :       struct cl_decoded_option *opt = &decoded_options[i];
     752     10255373 :       switch (opt->opt_index)
     753              :         {
     754       571495 :         case OPT_O:
     755       571495 :           if (*opt->arg == '\0')
     756              :             {
     757        14540 :               opts->x_optimize = 1;
     758        14540 :               opts->x_optimize_size = 0;
     759        14540 :               opts->x_optimize_fast = 0;
     760        14540 :               opts->x_optimize_debug = 0;
     761              :             }
     762              :           else
     763              :             {
     764       556955 :               const int optimize_val = integral_argument (opt->arg);
     765       556955 :               if (optimize_val == -1)
     766            0 :                 error_at (loc, "argument to %<-O%> should be a non-negative "
     767              :                                "integer, %<g%>, %<s%>, %<z%> or %<fast%>");
     768              :               else
     769              :                 {
     770       556955 :                   opts->x_optimize = optimize_val;
     771       556955 :                   if ((unsigned int) opts->x_optimize > 255)
     772            3 :                     opts->x_optimize = 255;
     773       556955 :                   opts->x_optimize_size = 0;
     774       556955 :                   opts->x_optimize_fast = 0;
     775       556955 :                   opts->x_optimize_debug = 0;
     776              :                 }
     777              :             }
     778              :           break;
     779              : 
     780        15783 :         case OPT_Os:
     781        15783 :           opts->x_optimize_size = 1;
     782              : 
     783              :           /* Optimizing for size forces optimize to be 2.  */
     784        15783 :           opts->x_optimize = 2;
     785        15783 :           opts->x_optimize_fast = 0;
     786        15783 :           opts->x_optimize_debug = 0;
     787        15783 :           break;
     788              : 
     789           21 :         case OPT_Oz:
     790           21 :           opts->x_optimize_size = 2;
     791              : 
     792              :           /* Optimizing for size forces optimize to be 2.  */
     793           21 :           opts->x_optimize = 2;
     794           21 :           opts->x_optimize_fast = 0;
     795           21 :           opts->x_optimize_debug = 0;
     796           21 :           break;
     797              : 
     798          722 :         case OPT_Ofast:
     799              :           /* -Ofast only adds flags to -O3.  */
     800          722 :           opts->x_optimize_size = 0;
     801          722 :           opts->x_optimize = 3;
     802          722 :           opts->x_optimize_fast = 1;
     803          722 :           opts->x_optimize_debug = 0;
     804          722 :           break;
     805              : 
     806          718 :         case OPT_Og:
     807              :           /* -Og selects optimization level 1.  */
     808          718 :           opts->x_optimize_size = 0;
     809          718 :           opts->x_optimize = 1;
     810          718 :           opts->x_optimize_fast = 0;
     811          718 :           opts->x_optimize_debug = 1;
     812          718 :           break;
     813              : 
     814        23453 :         case OPT_fopenacc:
     815        23453 :           if (opt->value)
     816     10255373 :             openacc_mode = true;
     817              :           break;
     818              : 
     819              :         default:
     820              :           /* Ignore other options in this prescan.  */
     821              :           break;
     822              :         }
     823              :     }
     824              : 
     825       638022 :   maybe_default_options (opts, opts_set, default_options_table,
     826       638022 :                          opts->x_optimize, opts->x_optimize_size,
     827       638022 :                          opts->x_optimize_fast, opts->x_optimize_debug,
     828              :                          lang_mask, handlers, loc, dc);
     829              : 
     830              :   /* -O2 param settings.  */
     831       638022 :   opt2 = (opts->x_optimize >= 2);
     832              : 
     833       638022 :   if (openacc_mode)
     834         3281 :     SET_OPTION_IF_UNSET (opts, opts_set, flag_ipa_pta, true);
     835              : 
     836              :   /* Track fields in field-sensitive alias analysis.  */
     837       638022 :   if (opt2)
     838       494309 :     SET_OPTION_IF_UNSET (opts, opts_set, param_max_fields_for_field_sensitive,
     839              :                          100);
     840              : 
     841       638022 :   if (opts->x_optimize_size)
     842              :     /* We want to crossjump as much as possible.  */
     843        15636 :     SET_OPTION_IF_UNSET (opts, opts_set, param_min_crossjump_insns, 1);
     844              : 
     845              :   /* Restrict the amount of work combine does at -Og while retaining
     846              :      most of its useful transforms.  */
     847       638022 :   if (opts->x_optimize_debug)
     848          694 :     SET_OPTION_IF_UNSET (opts, opts_set, param_max_combine_insns, 2);
     849              : 
     850              :   /* Allow default optimizations to be specified on a per-machine basis.  */
     851       638022 :   maybe_default_options (opts, opts_set,
     852              :                          targetm_common.option_optimization_table,
     853              :                          opts->x_optimize, opts->x_optimize_size,
     854       638022 :                          opts->x_optimize_fast, opts->x_optimize_debug,
     855              :                          lang_mask, handlers, loc, dc);
     856       638022 : }
     857              : 
     858              : /* Control IPA optimizations based on different live patching LEVEL.  */
     859              : static void
     860           20 : control_options_for_live_patching (struct gcc_options *opts,
     861              :                                    struct gcc_options *opts_set,
     862              :                                    enum live_patching_level level,
     863              :                                    location_t loc)
     864              : {
     865           20 :   gcc_assert (level > LIVE_PATCHING_NONE);
     866              : 
     867           20 :   switch (level)
     868              :     {
     869            3 :     case LIVE_PATCHING_INLINE_ONLY_STATIC:
     870              : #define LIVE_PATCHING_OPTION "-flive-patching=inline-only-static"
     871            3 :       if (opts_set->x_flag_ipa_cp_clone && opts->x_flag_ipa_cp_clone)
     872            0 :         error_at (loc, "%qs is incompatible with %qs",
     873              :                   "-fipa-cp-clone", LIVE_PATCHING_OPTION);
     874              :       else
     875            3 :         opts->x_flag_ipa_cp_clone = 0;
     876              : 
     877            3 :       if (opts_set->x_flag_ipa_sra && opts->x_flag_ipa_sra)
     878            0 :         error_at (loc, "%qs is incompatible with %qs",
     879              :                   "-fipa-sra", LIVE_PATCHING_OPTION);
     880              :       else
     881            3 :         opts->x_flag_ipa_sra = 0;
     882              : 
     883            3 :       if (opts_set->x_flag_partial_inlining && opts->x_flag_partial_inlining)
     884            0 :         error_at (loc, "%qs is incompatible with %qs",
     885              :                   "-fpartial-inlining", LIVE_PATCHING_OPTION);
     886              :       else
     887            3 :         opts->x_flag_partial_inlining = 0;
     888              : 
     889            3 :       if (opts_set->x_flag_ipa_cp && opts->x_flag_ipa_cp)
     890            0 :         error_at (loc, "%qs is incompatible with %qs",
     891              :                   "-fipa-cp", LIVE_PATCHING_OPTION);
     892              :       else
     893            3 :         opts->x_flag_ipa_cp = 0;
     894              : 
     895              :       /* FALLTHROUGH.  */
     896           20 :     case LIVE_PATCHING_INLINE_CLONE:
     897              : #undef LIVE_PATCHING_OPTION
     898              : #define LIVE_PATCHING_OPTION "-flive-patching=inline-only-static|inline-clone"
     899              :       /* live patching should disable whole-program optimization.  */
     900           20 :       if (opts_set->x_flag_whole_program && opts->x_flag_whole_program)
     901            1 :         error_at (loc, "%qs is incompatible with %qs",
     902              :                   "-fwhole-program", LIVE_PATCHING_OPTION);
     903              :       else
     904           19 :         opts->x_flag_whole_program = 0;
     905              : 
     906              :       /* visibility change should be excluded by !flag_whole_program
     907              :          && !in_lto_p && !flag_ipa_cp_clone && !flag_ipa_sra
     908              :          && !flag_partial_inlining.  */
     909              : 
     910           20 :       if (opts_set->x_flag_ipa_pta && opts->x_flag_ipa_pta)
     911            0 :         error_at (loc, "%qs is incompatible with %qs",
     912              :                   "-fipa-pta", LIVE_PATCHING_OPTION);
     913              :       else
     914           20 :         opts->x_flag_ipa_pta = 0;
     915              : 
     916           20 :       if (opts_set->x_flag_ipa_reference && opts->x_flag_ipa_reference)
     917            0 :         error_at (loc, "%qs is incompatible with %qs",
     918              :                   "-fipa-reference", LIVE_PATCHING_OPTION);
     919              :       else
     920           20 :         opts->x_flag_ipa_reference = 0;
     921              : 
     922           20 :       if (opts_set->x_flag_ipa_ra && opts->x_flag_ipa_ra)
     923            0 :         error_at (loc, "%qs is incompatible with %qs",
     924              :                   "-fipa-ra", LIVE_PATCHING_OPTION);
     925              :       else
     926           20 :         opts->x_flag_ipa_ra = 0;
     927              : 
     928           20 :       if (opts_set->x_flag_ipa_icf && opts->x_flag_ipa_icf)
     929            0 :         error_at (loc, "%qs is incompatible with %qs",
     930              :                   "-fipa-icf", LIVE_PATCHING_OPTION);
     931              :       else
     932           20 :         opts->x_flag_ipa_icf = 0;
     933              : 
     934           20 :       if (opts_set->x_flag_ipa_icf_functions && opts->x_flag_ipa_icf_functions)
     935            0 :         error_at (loc, "%qs is incompatible with %qs",
     936              :                   "-fipa-icf-functions", LIVE_PATCHING_OPTION);
     937              :       else
     938           20 :         opts->x_flag_ipa_icf_functions = 0;
     939              : 
     940           20 :       if (opts_set->x_flag_ipa_icf_variables && opts->x_flag_ipa_icf_variables)
     941            0 :         error_at (loc, "%qs is incompatible with %qs",
     942              :                   "-fipa-icf-variables", LIVE_PATCHING_OPTION);
     943              :       else
     944           20 :         opts->x_flag_ipa_icf_variables = 0;
     945              : 
     946           20 :       if (opts_set->x_flag_ipa_bit_cp && opts->x_flag_ipa_bit_cp)
     947            0 :         error_at (loc, "%qs is incompatible with %qs",
     948              :                   "-fipa-bit-cp", LIVE_PATCHING_OPTION);
     949              :       else
     950           20 :         opts->x_flag_ipa_bit_cp = 0;
     951              : 
     952           20 :       if (opts_set->x_flag_ipa_vrp && opts->x_flag_ipa_vrp)
     953            0 :         error_at (loc, "%qs is incompatible with %qs",
     954              :                   "-fipa-vrp", LIVE_PATCHING_OPTION);
     955              :       else
     956           20 :         opts->x_flag_ipa_vrp = 0;
     957              : 
     958           20 :       if (opts_set->x_flag_ipa_pure_const && opts->x_flag_ipa_pure_const)
     959            0 :         error_at (loc, "%qs is incompatible with %qs",
     960              :                   "-fipa-pure-const", LIVE_PATCHING_OPTION);
     961              :       else
     962           20 :         opts->x_flag_ipa_pure_const = 0;
     963              : 
     964           20 :       if (opts_set->x_flag_ipa_modref && opts->x_flag_ipa_modref)
     965            0 :         error_at (loc,
     966              :                   "%<-fipa-modref%> is incompatible with %qs",
     967              :                   LIVE_PATCHING_OPTION);
     968              :       else
     969           20 :         opts->x_flag_ipa_modref = 0;
     970              : 
     971              :       /* FIXME: disable unreachable code removal.  */
     972              : 
     973              :       /* discovery of functions/variables with no address taken.  */
     974           20 :       if (opts_set->x_flag_ipa_reference_addressable
     975            0 :           && opts->x_flag_ipa_reference_addressable)
     976            0 :         error_at (loc, "%qs is incompatible with %qs",
     977              :                   "-fipa-reference-addressable", LIVE_PATCHING_OPTION);
     978              :       else
     979           20 :         opts->x_flag_ipa_reference_addressable = 0;
     980              : 
     981              :       /* ipa stack alignment propagation.  */
     982           20 :       if (opts_set->x_flag_ipa_stack_alignment
     983            0 :           && opts->x_flag_ipa_stack_alignment)
     984            0 :         error_at (loc, "%qs is incompatible with %qs",
     985              :                   "-fipa-stack-alignment", LIVE_PATCHING_OPTION);
     986              :       else
     987           20 :         opts->x_flag_ipa_stack_alignment = 0;
     988           20 :       break;
     989            0 :     default:
     990            0 :       gcc_unreachable ();
     991              :     }
     992              : 
     993              : #undef LIVE_PATCHING_OPTION
     994           20 : }
     995              : 
     996              : /* --help option argument if set.  */
     997              : vec<const char *> help_option_arguments;
     998              : 
     999              : /* Return the string name describing a sanitizer argument which has been
    1000              :    provided on the command line and has set this particular flag.  */
    1001              : const char *
    1002          208 : find_sanitizer_argument (struct gcc_options *opts,
    1003              :                          sanitize_code_type flags)
    1004              : {
    1005          706 :   for (int i = 0; sanitizer_opts[i].name != NULL; ++i)
    1006              :     {
    1007              :       /* Need to find the sanitizer_opts element which:
    1008              :          a) Could have set the flags requested.
    1009              :          b) Has been set on the command line.
    1010              : 
    1011              :          Can have (a) without (b) if the flag requested is e.g.
    1012              :          SANITIZE_ADDRESS, since both -fsanitize=address and
    1013              :          -fsanitize=kernel-address set this flag.
    1014              : 
    1015              :          Can have (b) without (a) by requesting more than one sanitizer on the
    1016              :          command line.  */
    1017          706 :       if ((sanitizer_opts[i].flag & opts->x_flag_sanitize)
    1018              :           != sanitizer_opts[i].flag)
    1019          352 :         continue;
    1020          354 :       if ((sanitizer_opts[i].flag & flags) != flags)
    1021          146 :         continue;
    1022              :       return sanitizer_opts[i].name;
    1023              :     }
    1024              :   return NULL;
    1025              : }
    1026              : 
    1027              : 
    1028              : /* Report an error to the user about sanitizer options they have requested
    1029              :    which have set conflicting flags.
    1030              : 
    1031              :    LEFT and RIGHT indicate sanitizer flags which conflict with each other, this
    1032              :    function reports an error if both have been set in OPTS->x_flag_sanitize and
    1033              :    ensures the error identifies the requested command line options that have
    1034              :    set these flags.  */
    1035              : static void
    1036      5104176 : report_conflicting_sanitizer_options (struct gcc_options *opts, location_t loc,
    1037              :                                       sanitize_code_type left,
    1038              :                                       sanitize_code_type right)
    1039              : {
    1040      5104176 :   sanitize_code_type left_seen = (opts->x_flag_sanitize & left);
    1041      5104176 :   sanitize_code_type right_seen = (opts->x_flag_sanitize & right);
    1042      5104176 :   if (left_seen && right_seen)
    1043              :     {
    1044          104 :       const char* left_arg = find_sanitizer_argument (opts, left_seen);
    1045          104 :       const char* right_arg = find_sanitizer_argument (opts, right_seen);
    1046          104 :       gcc_assert (left_arg && right_arg);
    1047          104 :       error_at (loc,
    1048              :                 "%<-fsanitize=%s%> is incompatible with %<-fsanitize=%s%>",
    1049              :                 left_arg, right_arg);
    1050              :     }
    1051      5104176 : }
    1052              : 
    1053              : /* Validate from OPTS and OPTS_SET that when -fipa-reorder-for-locality is
    1054              :    enabled no explicit -flto-partition is also passed as the locality cloning
    1055              :    pass uses its own partitioning scheme.  */
    1056              : 
    1057              : static void
    1058       638022 : validate_ipa_reorder_locality_lto_partition (struct gcc_options *opts,
    1059              :                                              struct gcc_options *opts_set)
    1060              : {
    1061       638022 :   static bool validated_p = false;
    1062              : 
    1063       638022 :   if (opts_set->x_flag_lto_partition)
    1064              :     {
    1065        15433 :       if (opts->x_flag_ipa_reorder_for_locality && !validated_p)
    1066            0 :         error ("%<-fipa-reorder-for-locality%> is incompatible with"
    1067              :                " an explicit %qs option", "-flto-partition");
    1068              :     }
    1069       638022 :   validated_p = true;
    1070       638022 : }
    1071              : 
    1072              : /* If OPTS.x_dump_base_name doesn't contain any directory separators
    1073              :    and has not had OPTS.x_dump_dir_name prepended to it, generate
    1074              :    a new string in opts_obstack that has the dump_dir_name prepended to
    1075              :    the dump_base_name.  */
    1076              : 
    1077              : const char *
    1078       289665 : maybe_prepend_dump_dir_name (const gcc_options &opts)
    1079              : {
    1080       289665 :   const char *sep = opts.x_dump_base_name;
    1081              : 
    1082      3922402 :   for (; *sep; sep++)
    1083      3652908 :     if (IS_DIR_SEPARATOR (*sep))
    1084              :       break;
    1085              : 
    1086       289665 :   if (*sep)
    1087              :     {
    1088              :       /* If dump_base_name contains subdirectories, don't prepend
    1089              :          anything.  */
    1090              :       return nullptr;
    1091              :     }
    1092              : 
    1093       269494 :   if (opts.x_dump_dir_name)
    1094              :     {
    1095              :       /* We have a DUMP_DIR_NAME, prepend that.  */
    1096       107530 :       return opts_concat (opts.x_dump_dir_name,
    1097       107530 :                           opts.x_dump_base_name, NULL);
    1098              :     }
    1099              : 
    1100              :   return nullptr;
    1101              : }
    1102              : 
    1103              : /* After all options at LOC have been read into OPTS and OPTS_SET,
    1104              :    finalize settings of those options and diagnose incompatible
    1105              :    combinations.  */
    1106              : void
    1107       638022 : finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
    1108              :                 location_t loc)
    1109              : {
    1110       638022 :   if (opts->x_dump_base_name
    1111       635198 :       && ! opts->x_dump_base_name_prefixed)
    1112              :     {
    1113       579094 :       if (const char *prepended_dump_base_name
    1114       289547 :           = maybe_prepend_dump_dir_name (*opts))
    1115       107530 :         opts->x_dump_base_name = prepended_dump_base_name;
    1116              : 
    1117              :       /* It is definitely prefixed now.  */
    1118       289547 :       opts->x_dump_base_name_prefixed = true;
    1119              :     }
    1120              : 
    1121              :   /* Handle related options for unit-at-a-time, toplevel-reorder, and
    1122              :      section-anchors.  */
    1123       638022 :   if (!opts->x_flag_unit_at_a_time)
    1124              :     {
    1125            5 :       if (opts->x_flag_section_anchors && opts_set->x_flag_section_anchors)
    1126            0 :         error_at (loc, "section anchors must be disabled when unit-at-a-time "
    1127              :                   "is disabled");
    1128            5 :       opts->x_flag_section_anchors = 0;
    1129            5 :       if (opts->x_flag_toplevel_reorder == 1)
    1130            0 :         error_at (loc, "toplevel reorder must be disabled when unit-at-a-time "
    1131              :                   "is disabled");
    1132            5 :       opts->x_flag_toplevel_reorder = 0;
    1133              :     }
    1134              : 
    1135              :   /* -fself-test depends on the state of the compiler prior to
    1136              :      compiling anything.  Ideally it should be run on an empty source
    1137              :      file.  However, in case we get run with actual source, assume
    1138              :      -fsyntax-only which will inhibit any compiler initialization
    1139              :      which may confuse the self tests.  */
    1140       638022 :   if (opts->x_flag_self_test)
    1141            5 :     opts->x_flag_syntax_only = 1;
    1142              : 
    1143       638022 :   if (opts->x_flag_tm && opts->x_flag_non_call_exceptions)
    1144            3 :     sorry ("transactional memory is not supported with non-call exceptions");
    1145              : 
    1146              :   /* Unless the user has asked for section anchors, we disable toplevel
    1147              :      reordering at -O0 to disable transformations that might be surprising
    1148              :      to end users and to get -fno-toplevel-reorder tested.  */
    1149       638022 :   if (!opts->x_optimize
    1150       114637 :       && opts->x_flag_toplevel_reorder == 2
    1151       114407 :       && !(opts->x_flag_section_anchors && opts_set->x_flag_section_anchors))
    1152              :     {
    1153       114407 :       opts->x_flag_toplevel_reorder = 0;
    1154       114407 :       opts->x_flag_section_anchors = 0;
    1155              :     }
    1156       638022 :   if (!opts->x_flag_toplevel_reorder)
    1157              :     {
    1158       134212 :       if (opts->x_flag_section_anchors && opts_set->x_flag_section_anchors)
    1159            0 :         error_at (loc, "section anchors must be disabled when toplevel reorder"
    1160              :                   " is disabled");
    1161       134212 :       opts->x_flag_section_anchors = 0;
    1162              :     }
    1163              : 
    1164       638022 :   if (opts->x_flag_hardened)
    1165              :     {
    1166           92 :       if (!opts_set->x_flag_auto_var_init)
    1167           88 :         opts->x_flag_auto_var_init = AUTO_INIT_ZERO;
    1168            4 :       else if (opts->x_flag_auto_var_init != AUTO_INIT_ZERO)
    1169            4 :         warning_at (loc, OPT_Whardened,
    1170              :                     "%<-ftrivial-auto-var-init=zero%> is not enabled by "
    1171              :                     "%<-fhardened%> because it was specified on the command "
    1172              :                     "line");
    1173              :     }
    1174              : 
    1175       638022 :   if (!opts->x_flag_opts_finished)
    1176              :     {
    1177              :       /* We initialize opts->x_flag_pie to -1 so that targets can set a
    1178              :          default value.  */
    1179       292371 :       if (opts->x_flag_pie == -1)
    1180              :         {
    1181              :           /* We initialize opts->x_flag_pic to -1 so that we can tell if
    1182              :              -fpic, -fPIC, -fno-pic or -fno-PIC is used.  */
    1183       272181 :           if (opts->x_flag_pic == -1)
    1184       262819 :             opts->x_flag_pie = (opts->x_flag_hardened
    1185       262819 :                                 ? /*-fPIE*/ 2 : DEFAULT_FLAG_PIE);
    1186              :           else
    1187         9362 :             opts->x_flag_pie = 0;
    1188              :         }
    1189              :       /* If -fPIE or -fpie is used, turn on PIC.  */
    1190       292371 :       if (opts->x_flag_pie)
    1191          268 :         opts->x_flag_pic = opts->x_flag_pie;
    1192       292103 :       else if (opts->x_flag_pic == -1)
    1193       282741 :         opts->x_flag_pic = 0;
    1194       292371 :       if (opts->x_flag_pic && !opts->x_flag_pie)
    1195         9189 :         opts->x_flag_shlib = 1;
    1196       292371 :       opts->x_flag_opts_finished = true;
    1197              :     }
    1198              : 
    1199              :   /* We initialize opts->x_flag_stack_protect to -1 so that targets
    1200              :      can set a default value.  With --enable-default-ssp or -fhardened
    1201              :      the default is -fstack-protector-strong.  */
    1202       638022 :   if (opts->x_flag_stack_protect == -1)
    1203              :     {
    1204              :       /* This should check FRAME_GROWS_DOWNWARD, but on some targets it's
    1205              :          defined in such a way that it uses flag_stack_protect which can't
    1206              :          be used here.  Moreover, some targets like BPF don't support
    1207              :          -fstack-protector at all but we don't know that here.  So remember
    1208              :          that flag_stack_protect was set at the behest of -fhardened.  */
    1209       291051 :       if (opts->x_flag_hardened)
    1210              :         {
    1211           88 :           opts->x_flag_stack_protect = SPCT_FLAG_STRONG;
    1212           88 :           flag_stack_protector_set_by_fhardened_p = true;
    1213              :         }
    1214              :       else
    1215       290963 :         opts->x_flag_stack_protect = DEFAULT_FLAG_SSP;
    1216              :     }
    1217       346971 :   else if (opts->x_flag_hardened
    1218            4 :            && opts->x_flag_stack_protect != SPCT_FLAG_STRONG)
    1219            4 :     warning_at (UNKNOWN_LOCATION, OPT_Whardened,
    1220              :                 "%<-fstack-protector-strong%> is not enabled by "
    1221              :                 "%<-fhardened%> because it was specified on the command "
    1222              :                 "line");
    1223              : 
    1224       638022 :   if (opts->x_optimize == 0)
    1225              :     {
    1226              :       /* Inlining does not work if not optimizing,
    1227              :          so force it not to be done.  */
    1228       114637 :       opts->x_warn_inline = 0;
    1229       114637 :       opts->x_flag_no_inline = 1;
    1230              :     }
    1231              : 
    1232              :   /* At -O0 or -Og, turn __builtin_unreachable into a trap.  */
    1233       638022 :   if (!opts->x_optimize || opts->x_optimize_debug)
    1234       115331 :     SET_OPTION_IF_UNSET (opts, opts_set, flag_unreachable_traps, true);
    1235              : 
    1236              :   /* Pipelining of outer loops is only possible when general pipelining
    1237              :      capabilities are requested.  */
    1238       638022 :   if (!opts->x_flag_sel_sched_pipelining)
    1239       637970 :     opts->x_flag_sel_sched_pipelining_outer_loops = 0;
    1240              : 
    1241       638022 :   if (opts->x_flag_conserve_stack)
    1242              :     {
    1243           30 :       SET_OPTION_IF_UNSET (opts, opts_set, param_large_stack_frame, 100);
    1244           30 :       SET_OPTION_IF_UNSET (opts, opts_set, param_stack_frame_growth, 40);
    1245              :     }
    1246              : 
    1247       638022 :   if (opts->x_flag_lto)
    1248              :     {
    1249              : #ifdef ENABLE_LTO
    1250       184004 :       opts->x_flag_generate_lto = 1;
    1251              : 
    1252              :       /* When generating IL, do not operate in whole-program mode.
    1253              :          Otherwise, symbols will be privatized too early, causing link
    1254              :          errors later.  */
    1255       184004 :       opts->x_flag_whole_program = 0;
    1256              : #else
    1257              :       error_at (loc, "LTO support has not been enabled in this configuration");
    1258              : #endif
    1259       184004 :       if (!opts->x_flag_fat_lto_objects
    1260        21005 :           && (!HAVE_LTO_PLUGIN
    1261        21005 :               || (opts_set->x_flag_use_linker_plugin
    1262        19475 :                   && !opts->x_flag_use_linker_plugin)))
    1263              :         {
    1264         8867 :           if (opts_set->x_flag_fat_lto_objects)
    1265            0 :             error_at (loc, "%<-fno-fat-lto-objects%> are supported only with "
    1266              :                       "linker plugin");
    1267         8867 :           opts->x_flag_fat_lto_objects = 1;
    1268              :         }
    1269              : 
    1270              :       /* -gsplit-dwarf isn't compatible with LTO, see PR88389.  */
    1271       184004 :       if (opts->x_dwarf_split_debug_info)
    1272              :         {
    1273            1 :           inform (loc, "%<-gsplit-dwarf%> is not supported with LTO,"
    1274              :                   " disabling");
    1275            1 :           opts->x_dwarf_split_debug_info = 0;
    1276              :         }
    1277              :     }
    1278              : 
    1279              :   /* We initialize opts->x_flag_split_stack to -1 so that targets can set a
    1280              :      default value if they choose based on other options.  */
    1281       638022 :   if (opts->x_flag_split_stack == -1)
    1282       290681 :     opts->x_flag_split_stack = 0;
    1283       347341 :   else if (opts->x_flag_split_stack)
    1284              :     {
    1285         1718 :       if (!targetm_common.supports_split_stack (true, opts))
    1286              :         {
    1287            0 :           error_at (loc, "%<-fsplit-stack%> is not supported by "
    1288              :                     "this compiler configuration");
    1289            0 :           opts->x_flag_split_stack = 0;
    1290              :         }
    1291              :     }
    1292              : 
    1293              :   /* If stack splitting is turned on, and the user did not explicitly
    1294              :      request function partitioning, turn off partitioning, as it
    1295              :      confuses the linker when trying to handle partitioned split-stack
    1296              :      code that calls a non-split-stack functions.  But if partitioning
    1297              :      was turned on explicitly just hope for the best.  */
    1298       638022 :   if (opts->x_flag_split_stack
    1299         1718 :       && opts->x_flag_reorder_blocks_and_partition)
    1300         1280 :     SET_OPTION_IF_UNSET (opts, opts_set, flag_reorder_blocks_and_partition, 0);
    1301              : 
    1302       638022 :   if (opts->x_flag_reorder_blocks_and_partition)
    1303       493070 :     SET_OPTION_IF_UNSET (opts, opts_set, flag_reorder_functions, 1);
    1304              : 
    1305       638022 :   validate_ipa_reorder_locality_lto_partition (opts, opts_set);
    1306              : 
    1307              :   /* The -gsplit-dwarf option requires -ggnu-pubnames.  */
    1308       638022 :   if (opts->x_dwarf_split_debug_info)
    1309          311 :     opts->x_debug_generate_pub_sections = 2;
    1310              : 
    1311       638022 :   if ((opts->x_flag_sanitize
    1312       638022 :        & (SANITIZE_USER_ADDRESS | SANITIZE_KERNEL_ADDRESS)) == 0)
    1313              :     {
    1314       634940 :       if (opts->x_flag_sanitize & SANITIZE_POINTER_COMPARE)
    1315            0 :         error_at (loc,
    1316              :                   "%<-fsanitize=pointer-compare%> must be combined with "
    1317              :                   "%<-fsanitize=address%> or %<-fsanitize=kernel-address%>");
    1318       634940 :       if (opts->x_flag_sanitize & SANITIZE_POINTER_SUBTRACT)
    1319            0 :         error_at (loc,
    1320              :                   "%<-fsanitize=pointer-subtract%> must be combined with "
    1321              :                   "%<-fsanitize=address%> or %<-fsanitize=kernel-address%>");
    1322              :     }
    1323              : 
    1324              :   /* Address sanitizers conflict with the thread sanitizer.  */
    1325       638022 :   report_conflicting_sanitizer_options (opts, loc, SANITIZE_THREAD,
    1326              :                                         SANITIZE_ADDRESS);
    1327       638022 :   report_conflicting_sanitizer_options (opts, loc, SANITIZE_THREAD,
    1328              :                                         SANITIZE_HWADDRESS);
    1329              :   /* The leak sanitizer conflicts with the thread sanitizer.  */
    1330       638022 :   report_conflicting_sanitizer_options (opts, loc, SANITIZE_LEAK,
    1331              :                                         SANITIZE_THREAD);
    1332              : 
    1333              :   /* No combination of HWASAN and ASAN work together.  */
    1334       638022 :   report_conflicting_sanitizer_options (opts, loc,
    1335              :                                         SANITIZE_HWADDRESS, SANITIZE_ADDRESS);
    1336              : 
    1337              :   /* The userspace and kernel address sanitizers conflict with each other.  */
    1338       638022 :   report_conflicting_sanitizer_options (opts, loc, SANITIZE_USER_HWADDRESS,
    1339              :                                         SANITIZE_KERNEL_HWADDRESS);
    1340       638022 :   report_conflicting_sanitizer_options (opts, loc, SANITIZE_USER_ADDRESS,
    1341              :                                         SANITIZE_KERNEL_ADDRESS);
    1342              : 
    1343              :   /* Sanitizers using Memory-Tagging Extension conflict with HWASAN and
    1344              :      ASAN.  */
    1345       638022 :   report_conflicting_sanitizer_options (opts, loc, SANITIZE_MEMTAG,
    1346              :                                         SANITIZE_HWADDRESS);
    1347       638022 :   report_conflicting_sanitizer_options (opts, loc, SANITIZE_MEMTAG,
    1348              :                                         SANITIZE_ADDRESS);
    1349              : 
    1350              :   /* Memtag sanitizer implies HWASAN but with tags always generated by
    1351              :      the hardware randomly.  */
    1352       638022 :   if ((opts->x_flag_sanitize & SANITIZE_MEMTAG_STACK)
    1353            0 :       && opts->x_param_hwasan_random_frame_tag == 0)
    1354              :     {
    1355            0 :        warning_at (loc, OPT_fsanitize_,
    1356              :                    "%<--param hwasan-random-frame-tag=0%> is ignored when "
    1357              :                    "%<-fsanitize=memtag-stack%> is present");
    1358            0 :        opts->x_param_hwasan_random_frame_tag = 1;
    1359              :     }
    1360              : 
    1361              :   /* Check error recovery for -fsanitize-recover option.  */
    1362     22330770 :   for (int i = 0; sanitizer_opts[i].name != NULL; ++i)
    1363     21692748 :     if ((opts->x_flag_sanitize_recover & sanitizer_opts[i].flag)
    1364     15308113 :         && !sanitizer_opts[i].can_recover)
    1365           40 :       error_at (loc, "%<-fsanitize-recover=%s%> is not supported",
    1366              :                 sanitizer_opts[i].name);
    1367              : 
    1368              :   /* Check -fsanitize-trap option.  */
    1369     22330770 :   for (int i = 0; sanitizer_opts[i].name != NULL; ++i)
    1370     21692748 :     if ((opts->x_flag_sanitize_trap & sanitizer_opts[i].flag)
    1371         4381 :         && !sanitizer_opts[i].can_trap
    1372              :         /* Allow -fsanitize-trap=all or -fsanitize-trap=undefined
    1373              :            to set flag_sanitize_trap & SANITIZE_VPTR bit which will
    1374              :            effectively disable -fsanitize=vptr, just disallow
    1375              :            explicit -fsanitize-trap=vptr.  */
    1376          184 :         && sanitizer_opts[i].flag != SANITIZE_VPTR)
    1377            0 :       error_at (loc, "%<-fsanitize-trap=%s%> is not supported",
    1378              :                 sanitizer_opts[i].name);
    1379              : 
    1380              :   /* When instrumenting the pointers, we don't want to remove
    1381              :      the null pointer checks.  */
    1382       638022 :   if (opts->x_flag_sanitize & (SANITIZE_NULL | SANITIZE_NONNULL_ATTRIBUTE
    1383              :                                 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE))
    1384         1686 :     opts->x_flag_delete_null_pointer_checks = 0;
    1385              : 
    1386              :   /* Aggressive compiler optimizations may cause false negatives.  */
    1387       638022 :   if (opts->x_flag_sanitize & ~(SANITIZE_LEAK | SANITIZE_UNREACHABLE))
    1388         7497 :     opts->x_flag_aggressive_loop_optimizations = 0;
    1389              : 
    1390              :   /* Enable -fsanitize-address-use-after-scope if either address sanitizer is
    1391              :      enabled.  */
    1392       638022 :   if (opts->x_flag_sanitize
    1393       638022 :       & (SANITIZE_USER_ADDRESS | SANITIZE_USER_HWADDRESS))
    1394         3291 :     SET_OPTION_IF_UNSET (opts, opts_set, flag_sanitize_address_use_after_scope,
    1395              :                          true);
    1396              : 
    1397              :   /* Force -fstack-reuse=none in case -fsanitize-address-use-after-scope
    1398              :      is enabled.  */
    1399       638022 :   if (opts->x_flag_sanitize_address_use_after_scope)
    1400              :     {
    1401         3257 :       if (opts->x_flag_stack_reuse != SR_NONE
    1402         3207 :           && opts_set->x_flag_stack_reuse != SR_NONE)
    1403            0 :         error_at (loc,
    1404              :                   "%<-fsanitize-address-use-after-scope%> requires "
    1405              :                   "%<-fstack-reuse=none%> option");
    1406              : 
    1407         3257 :       opts->x_flag_stack_reuse = SR_NONE;
    1408              :     }
    1409              : 
    1410       638022 :   if ((opts->x_flag_sanitize & SANITIZE_USER_ADDRESS) && opts->x_flag_tm)
    1411            0 :     sorry ("transactional memory is not supported with %<-fsanitize=address%>");
    1412              : 
    1413       638022 :   if ((opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS) && opts->x_flag_tm)
    1414            0 :     sorry ("transactional memory is not supported with "
    1415              :            "%<-fsanitize=kernel-address%>");
    1416              : 
    1417              :   /* Currently live patching is not support for LTO.  */
    1418       638022 :   if (opts->x_flag_live_patching == LIVE_PATCHING_INLINE_ONLY_STATIC && opts->x_flag_lto)
    1419            1 :     sorry ("live patching (with %qs) is not supported with LTO",
    1420              :            "inline-only-static");
    1421              : 
    1422              :   /* Currently vtable verification is not supported for LTO */
    1423       638022 :   if (opts->x_flag_vtable_verify && opts->x_flag_lto)
    1424            0 :     sorry ("vtable verification is not supported with LTO");
    1425              : 
    1426              :   /* Control IPA optimizations based on different -flive-patching level.  */
    1427       638022 :   if (opts->x_flag_live_patching)
    1428           20 :     control_options_for_live_patching (opts, opts_set,
    1429              :                                        opts->x_flag_live_patching,
    1430              :                                        loc);
    1431              : 
    1432              :   /* Allow cunroll to grow size accordingly.  */
    1433       638022 :   if (!opts_set->x_flag_cunroll_grow_size)
    1434       638022 :     opts->x_flag_cunroll_grow_size
    1435      1276044 :       = (opts->x_flag_unroll_loops
    1436       159218 :          || opts->x_flag_peel_loops
    1437      1276044 :          || opts->x_optimize >= 3);
    1438              : 
    1439              :   /* Use -fvect-cost-model=cheap instead of -fvect-cost-mode=very-cheap
    1440              :      by default with explicit -ftree-{loop,slp}-vectorize.  */
    1441       638022 :   if (opts->x_optimize == 2
    1442       464784 :       && (opts_set->x_flag_tree_loop_vectorize
    1443       464723 :           || opts_set->x_flag_tree_vectorize))
    1444       347549 :     SET_OPTION_IF_UNSET (opts, opts_set, flag_vect_cost_model,
    1445              :                          VECT_COST_MODEL_CHEAP);
    1446              : 
    1447       638022 :   if (opts->x_flag_gtoggle)
    1448              :     {
    1449              :       /* Make sure to process -gtoggle only once.  */
    1450          629 :       opts->x_flag_gtoggle = false;
    1451          629 :       if (opts->x_debug_info_level == DINFO_LEVEL_NONE)
    1452              :         {
    1453          380 :           opts->x_debug_info_level = DINFO_LEVEL_NORMAL;
    1454              : 
    1455          380 :           if (opts->x_write_symbols == NO_DEBUG)
    1456          380 :             opts->x_write_symbols = PREFERRED_DEBUGGING_TYPE;
    1457              :         }
    1458              :       else
    1459          249 :         opts->x_debug_info_level = DINFO_LEVEL_NONE;
    1460              :     }
    1461              : 
    1462              :   /* Also enable markers with -fauto-profile even when debug info is disabled,
    1463              :      so we assign same discriminators and can read back the profile info.  */
    1464       638022 :   if (!opts_set->x_debug_nonbind_markers_p)
    1465       637990 :     opts->x_debug_nonbind_markers_p
    1466       637990 :       = (opts->x_optimize
    1467       523353 :          && ((opts->x_debug_info_level >= DINFO_LEVEL_NORMAL
    1468        52379 :               && (dwarf_debuginfo_p (opts) || codeview_debuginfo_p ()))
    1469       470983 :              || opts->x_flag_auto_profile)
    1470      1328350 :          && !(opts->x_flag_selective_scheduling
    1471        52370 :               || opts->x_flag_selective_scheduling2));
    1472              : 
    1473              :   /* We know which debug output will be used so we can set flag_var_tracking
    1474              :      and flag_var_tracking_uninit if the user has not specified them.  */
    1475       638022 :   if (opts->x_debug_info_level < DINFO_LEVEL_NORMAL
    1476       638022 :       || (!dwarf_debuginfo_p (opts) && !codeview_debuginfo_p ())
    1477              :       /* We have not yet initialized debug hooks so match that to check
    1478              :          whether we're only doing DWARF2_LINENO_DEBUGGING_INFO.  */
    1479              : #ifndef DWARF2_DEBUGGING_INFO
    1480              :       || true
    1481              : #endif
    1482              :      )
    1483              :     {
    1484       579126 :       if ((opts_set->x_flag_var_tracking && opts->x_flag_var_tracking == 1)
    1485       579110 :           || (opts_set->x_flag_var_tracking_uninit
    1486            0 :               && opts->x_flag_var_tracking_uninit == 1))
    1487              :         {
    1488           16 :           if (opts->x_debug_info_level < DINFO_LEVEL_NORMAL)
    1489           15 :             warning_at (UNKNOWN_LOCATION, 0,
    1490              :                         "variable tracking requested, but useless unless "
    1491              :                         "producing debug info");
    1492              :           else
    1493            1 :             warning_at (UNKNOWN_LOCATION, 0,
    1494              :                         "variable tracking requested, but not supported "
    1495              :                         "by this debug format");
    1496              :         }
    1497       579126 :       opts->x_flag_var_tracking = 0;
    1498       579126 :       opts->x_flag_var_tracking_uninit = 0;
    1499       579126 :       opts->x_flag_var_tracking_assignments = 0;
    1500              :     }
    1501              : 
    1502              :   /* One could use EnabledBy, but it would lead to a circular dependency.  */
    1503       638022 :   if (!opts_set->x_flag_var_tracking_uninit)
    1504       638022 :     opts->x_flag_var_tracking_uninit = opts->x_flag_var_tracking;
    1505              : 
    1506       638022 :   if (!opts_set->x_flag_var_tracking_assignments)
    1507       637948 :     opts->x_flag_var_tracking_assignments
    1508      1275896 :       = (opts->x_flag_var_tracking
    1509      1275896 :          && !(opts->x_flag_selective_scheduling
    1510        52366 :               || opts->x_flag_selective_scheduling2));
    1511              : 
    1512       638022 :   if (opts->x_flag_var_tracking_assignments_toggle)
    1513            0 :     opts->x_flag_var_tracking_assignments
    1514            0 :       = !opts->x_flag_var_tracking_assignments;
    1515              : 
    1516       638022 :   if (opts->x_flag_var_tracking_assignments && !opts->x_flag_var_tracking)
    1517            2 :     opts->x_flag_var_tracking = opts->x_flag_var_tracking_assignments = -1;
    1518              : 
    1519       638022 :   if (opts->x_flag_var_tracking_assignments
    1520        52373 :       && (opts->x_flag_selective_scheduling
    1521        52373 :           || opts->x_flag_selective_scheduling2))
    1522            5 :     warning_at (loc, 0,
    1523              :                 "var-tracking-assignments changes selective scheduling");
    1524              : 
    1525       638022 :   if (opts->x_flag_syntax_only)
    1526              :     {
    1527          284 :       opts->x_write_symbols = NO_DEBUG;
    1528          284 :       opts->x_profile_flag = 0;
    1529              :     }
    1530              : 
    1531       638022 :   if (opts->x_warn_strict_flex_arrays)
    1532           13 :     if (opts->x_flag_strict_flex_arrays == 0)
    1533              :       {
    1534            4 :         opts->x_warn_strict_flex_arrays = 0;
    1535            4 :         warning_at (UNKNOWN_LOCATION, 0,
    1536              :                     "%<-Wstrict-flex-arrays%> is ignored when"
    1537              :                     " %<-fstrict-flex-arrays%> is not present");
    1538              :       }
    1539              : 
    1540       638022 :   if ((opts->x_flag_openmp_ompt || opts->x_flag_openmp_ompt_detailed)
    1541           24 :       && !opts->x_flag_openmp)
    1542            8 :     error_at (
    1543              :       loc,
    1544              :       "%<-fopenmp-ompt%> and %<-fopenmp-ompt-detailed%> require %<-fopenmp%>");
    1545              : 
    1546       638022 :   diagnose_options (opts, opts_set, loc);
    1547       638022 : }
    1548              : 
    1549              : /* The function diagnoses incompatible combinations for provided options
    1550              :    (OPTS and OPTS_SET) at a given LOCation.  The function is called both
    1551              :    when command line is parsed (after the target optimization hook) and
    1552              :    when an optimize/target attribute (or pragma) is used.  */
    1553              : 
    1554       930313 : void diagnose_options (gcc_options *opts, gcc_options *opts_set,
    1555              :                        location_t loc)
    1556              : {
    1557              :   /* The optimization to partition hot and cold basic blocks into separate
    1558              :      sections of the .o and executable files does not work (currently)
    1559              :      with exception handling.  This is because there is no support for
    1560              :      generating unwind info.  If opts->x_flag_exceptions is turned on
    1561              :      we need to turn off the partitioning optimization.  */
    1562              : 
    1563       930313 :   enum unwind_info_type ui_except
    1564       930313 :     = targetm_common.except_unwind_info (opts);
    1565              : 
    1566       930313 :   if (opts->x_flag_exceptions
    1567       266739 :       && opts->x_flag_reorder_blocks_and_partition
    1568        89126 :       && (ui_except == UI_SJLJ || ui_except >= UI_TARGET))
    1569              :     {
    1570            0 :       if (opts_set->x_flag_reorder_blocks_and_partition)
    1571            0 :         inform (loc,
    1572              :                 "%<-freorder-blocks-and-partition%> does not work "
    1573              :                 "with exceptions on this architecture");
    1574            0 :       opts->x_flag_reorder_blocks_and_partition = 0;
    1575            0 :       opts->x_flag_reorder_blocks = 1;
    1576              :     }
    1577              : 
    1578              :   /* If user requested unwind info, then turn off the partitioning
    1579              :      optimization.  */
    1580              : 
    1581       930313 :   if (opts->x_flag_unwind_tables
    1582       638899 :       && !targetm_common.unwind_tables_default
    1583       638899 :       && opts->x_flag_reorder_blocks_and_partition
    1584       491208 :       && (ui_except == UI_SJLJ || ui_except >= UI_TARGET))
    1585              :     {
    1586            0 :       if (opts_set->x_flag_reorder_blocks_and_partition)
    1587            0 :         inform (loc,
    1588              :                 "%<-freorder-blocks-and-partition%> does not support "
    1589              :                 "unwind info on this architecture");
    1590            0 :       opts->x_flag_reorder_blocks_and_partition = 0;
    1591            0 :       opts->x_flag_reorder_blocks = 1;
    1592              :     }
    1593              : 
    1594              :   /* If the target requested unwind info, then turn off the partitioning
    1595              :      optimization with a different message.  Likewise, if the target does not
    1596              :      support named sections.  */
    1597              : 
    1598       930313 :   if (opts->x_flag_reorder_blocks_and_partition
    1599       638578 :       && (!targetm_common.have_named_sections
    1600       638578 :           || (opts->x_flag_unwind_tables
    1601       491208 :               && targetm_common.unwind_tables_default
    1602            0 :               && (ui_except == UI_SJLJ || ui_except >= UI_TARGET))))
    1603              :     {
    1604            0 :       if (opts_set->x_flag_reorder_blocks_and_partition)
    1605            0 :         inform (loc,
    1606              :                 "%<-freorder-blocks-and-partition%> does not work "
    1607              :                 "on this architecture");
    1608            0 :       opts->x_flag_reorder_blocks_and_partition = 0;
    1609            0 :       opts->x_flag_reorder_blocks = 1;
    1610              :     }
    1611              : 
    1612              : 
    1613       930313 : }
    1614              : 
    1615              : #define LEFT_COLUMN     27
    1616              : 
    1617              : /* Output ITEM, of length ITEM_WIDTH, in the left column,
    1618              :    followed by word-wrapped HELP in a second column.  */
    1619              : static void
    1620        28828 : wrap_help (const char *help,
    1621              :            const char *item,
    1622              :            unsigned int item_width,
    1623              :            unsigned int columns)
    1624              : {
    1625        28828 :   unsigned int col_width = LEFT_COLUMN;
    1626        28828 :   unsigned int remaining, room, len;
    1627              : 
    1628        28828 :   remaining = strlen (help);
    1629              : 
    1630        41464 :   do
    1631              :     {
    1632        41464 :       room = columns - 3 - MAX (col_width, item_width);
    1633        41464 :       if (room > columns)
    1634            0 :         room = 0;
    1635        41464 :       len = remaining;
    1636              : 
    1637        41464 :       if (room < len)
    1638              :         {
    1639              :           unsigned int i;
    1640              : 
    1641       566981 :           for (i = 0; help[i]; i++)
    1642              :             {
    1643       566981 :               if (i >= room && len != remaining)
    1644              :                 break;
    1645       554345 :               if (help[i] == ' ')
    1646              :                 len = i;
    1647       471406 :               else if ((help[i] == '-' || help[i] == '/')
    1648         1969 :                        && help[i + 1] != ' '
    1649         1969 :                        && i > 0 && ISALPHA (help[i - 1]))
    1650       554345 :                 len = i + 1;
    1651              :             }
    1652              :         }
    1653              : 
    1654        41464 :       printf ("  %-*.*s %.*s\n", col_width, item_width, item, len, help);
    1655        41464 :       item_width = 0;
    1656        95341 :       while (help[len] == ' ')
    1657        12413 :         len++;
    1658        41464 :       help += len;
    1659        41464 :       remaining -= len;
    1660              :     }
    1661        41464 :   while (remaining);
    1662        28828 : }
    1663              : 
    1664              : /* Data structure used to print list of valid option values.  */
    1665              : 
    1666              : class option_help_tuple
    1667              : {
    1668              : public:
    1669           14 :   option_help_tuple (int code, vec<const char *> values):
    1670           14 :     m_code (code), m_values (values)
    1671              :   {}
    1672              : 
    1673              :   /* Code of an option.  */
    1674              :   int m_code;
    1675              : 
    1676              :   /* List of possible values.  */
    1677              :   vec<const char *> m_values;
    1678              : };
    1679              : 
    1680              : /* Print help for a specific front-end, etc.  */
    1681              : static void
    1682          136 : print_filtered_help (unsigned int include_flags,
    1683              :                      unsigned int exclude_flags,
    1684              :                      unsigned int any_flags,
    1685              :                      unsigned int columns,
    1686              :                      struct gcc_options *opts,
    1687              :                      unsigned int lang_mask)
    1688              : {
    1689          136 :   unsigned int i;
    1690          136 :   const char *help;
    1691          136 :   bool found = false;
    1692          136 :   bool displayed = false;
    1693          136 :   char new_help[256];
    1694              : 
    1695          136 :   if (!opts->x_help_printed)
    1696           71 :     opts->x_help_printed = XCNEWVAR (char, cl_options_count);
    1697              : 
    1698          136 :   if (!opts->x_help_enum_printed)
    1699           71 :     opts->x_help_enum_printed = XCNEWVAR (char, cl_enums_count);
    1700              : 
    1701          136 :   auto_vec<option_help_tuple> help_tuples;
    1702              : 
    1703       350336 :   for (i = 0; i < cl_options_count; i++)
    1704              :     {
    1705       350200 :       const struct cl_option *option = cl_options + i;
    1706       350200 :       unsigned int len;
    1707       350200 :       const char *opt;
    1708       350200 :       const char *tab;
    1709              : 
    1710       350200 :       if (include_flags == 0
    1711       342475 :           || ((option->flags & include_flags) != include_flags))
    1712              :         {
    1713       308962 :           if ((option->flags & any_flags) == 0)
    1714       305590 :             continue;
    1715              :         }
    1716              : 
    1717              :       /* Skip unwanted switches.  */
    1718        44610 :       if ((option->flags & exclude_flags) != 0)
    1719         9920 :         continue;
    1720              : 
    1721              :       /* The driver currently prints its own help text.  */
    1722        34690 :       if ((option->flags & CL_DRIVER) != 0
    1723          861 :           && (option->flags & (((1U << cl_lang_count) - 1)
    1724          767 :                                | CL_COMMON | CL_TARGET)) == 0)
    1725           94 :         continue;
    1726              : 
    1727              :       /* If an option contains a language specification,
    1728              :          exclude it from common unless all languages are present.  */
    1729        34596 :       if ((include_flags & CL_COMMON)
    1730         4857 :           && !(option->flags & CL_DRIVER)
    1731         4467 :           && (option->flags & CL_LANG_ALL)
    1732          140 :           && (option->flags & CL_LANG_ALL) != CL_LANG_ALL)
    1733          140 :         continue;
    1734              : 
    1735        34456 :       found = true;
    1736              :       /* Skip switches that have already been printed.  */
    1737        34456 :       if (opts->x_help_printed[i])
    1738         5618 :         continue;
    1739              : 
    1740        28838 :       opts->x_help_printed[i] = true;
    1741              : 
    1742        28838 :       help = option->help;
    1743        28838 :       if (help == NULL)
    1744              :         {
    1745         1557 :           if (exclude_flags & CL_UNDOCUMENTED)
    1746           10 :             continue;
    1747              : 
    1748              :           help = undocumented_msg;
    1749              :         }
    1750              : 
    1751              :       /* Get the translation.  */
    1752        28828 :       help = _(help);
    1753              : 
    1754        28828 :       if (option->alias_target < N_OPTS
    1755         1587 :           && cl_options [option->alias_target].help)
    1756              :         {
    1757         1554 :           const struct cl_option *target = cl_options + option->alias_target;
    1758         1554 :           if (option->help == NULL)
    1759              :             {
    1760              :               /* The option is undocumented but is an alias for an option that
    1761              :                  is documented.  If the option has alias arguments, then its
    1762              :                  purpose is to provide certain arguments to the other option, so
    1763              :                  inform the reader of this.  Otherwise, point the reader to the
    1764              :                  other option in preference to the former.  */
    1765              : 
    1766          912 :               if (option->alias_arg)
    1767              :                 {
    1768          138 :                   if (option->neg_alias_arg)
    1769          116 :                     snprintf (new_help, sizeof new_help,
    1770          116 :                               _("Same as %s%s (or, in negated form, %s%s)."),
    1771              :                               target->opt_text, option->alias_arg,
    1772          116 :                               target->opt_text, option->neg_alias_arg);
    1773              :                   else
    1774           22 :                     snprintf (new_help, sizeof new_help,
    1775           22 :                               _("Same as %s%s."),
    1776           22 :                               target->opt_text, option->alias_arg);
    1777              :                 }
    1778              :               else
    1779          774 :                 snprintf (new_help, sizeof new_help,
    1780          774 :                           _("Same as %s."),
    1781          774 :                           target->opt_text);
    1782              :             }
    1783              :           else
    1784              :             {
    1785              :               /* For documented options with aliases, mention the aliased
    1786              :                  option's name for reference.  */
    1787          642 :               snprintf (new_help, sizeof new_help,
    1788          642 :                         _("%s  Same as %s."),
    1789          642 :                         help, cl_options [option->alias_target].opt_text);
    1790              :             }
    1791              : 
    1792              :           help = new_help;
    1793              :         }
    1794              : 
    1795        28828 :       if (option->warn_message)
    1796              :         {
    1797              :           /* Mention that the use of the option will trigger a warning.  */
    1798           50 :           if (help == new_help)
    1799           43 :             snprintf (new_help + strlen (new_help),
    1800           43 :                       sizeof new_help - strlen (new_help),
    1801              :                       "  %s", _(use_diagnosed_msg));
    1802              :           else
    1803            7 :             snprintf (new_help, sizeof new_help,
    1804              :                       "%s  %s", help, _(use_diagnosed_msg));
    1805              : 
    1806              :           help = new_help;
    1807              :         }
    1808              : 
    1809              :       /* Find the gap between the name of the
    1810              :          option and its descriptive text.  */
    1811        28828 :       tab = strchr (help, '\t');
    1812        28828 :       if (tab)
    1813              :         {
    1814         1649 :           len = tab - help;
    1815         1649 :           opt = help;
    1816         1649 :           help = tab + 1;
    1817              :         }
    1818              :       else
    1819              :         {
    1820        27179 :           opt = option->opt_text;
    1821        27179 :           len = strlen (opt);
    1822              :         }
    1823              : 
    1824              :       /* With the -Q option enabled we change the descriptive text associated
    1825              :          with an option to be an indication of its current setting.  */
    1826        28828 :       if (!opts->x_quiet_flag)
    1827              :         {
    1828         2802 :           void *flag_var = option_flag_var (i, opts);
    1829              : 
    1830         2802 :           if (len < (LEFT_COLUMN + 2))
    1831         2498 :             strcpy (new_help, "\t\t");
    1832              :           else
    1833          304 :             strcpy (new_help, "\t");
    1834              : 
    1835              :           /* Set to print whether the option is enabled or disabled,
    1836              :              or, if it's an alias for another option, the name of
    1837              :              the aliased option.  */
    1838         2802 :           bool print_state = false;
    1839              : 
    1840         2802 :           if (flag_var != NULL
    1841         2552 :               && option->var_type != CLVC_DEFER)
    1842              :             {
    1843              :               /* If OPTION is only available for a specific subset
    1844              :                  of languages other than this one, mention them.  */
    1845         2552 :               bool avail_for_lang = true;
    1846         2552 :               if (unsigned langset = option->flags & CL_LANG_ALL)
    1847              :                 {
    1848         1548 :                   if (!(langset & lang_mask))
    1849              :                     {
    1850          715 :                       avail_for_lang = false;
    1851          715 :                       strcat (new_help, _("[available in "));
    1852        12155 :                       for (unsigned i = 0, n = 0; (1U << i) < CL_LANG_ALL; ++i)
    1853        11440 :                         if (langset & (1U << i))
    1854              :                           {
    1855         1068 :                             if (n++)
    1856          353 :                               strcat (new_help, ", ");
    1857         1068 :                             strcat (new_help, lang_names[i]);
    1858              :                           }
    1859          715 :                       strcat (new_help, "]");
    1860              :                     }
    1861              :                 }
    1862          715 :               if (!avail_for_lang)
    1863              :                 ; /* Print nothing else if the option is not available
    1864              :                      in the current language.  */
    1865         1837 :               else if (option->flags & CL_JOINED)
    1866              :                 {
    1867          159 :                   if (option->var_type == CLVC_STRING)
    1868              :                     {
    1869           10 :                       if (* (const char **) flag_var != NULL)
    1870            8 :                         snprintf (new_help + strlen (new_help),
    1871            8 :                                   sizeof (new_help) - strlen (new_help),
    1872              :                                   "%s", * (const char **) flag_var);
    1873              :                     }
    1874          149 :                   else if (option->var_type == CLVC_ENUM)
    1875              :                     {
    1876           53 :                       const struct cl_enum *e = &cl_enums[option->var_enum];
    1877           53 :                       int value;
    1878           53 :                       const char *arg = NULL;
    1879              : 
    1880           53 :                       value = e->get (flag_var);
    1881           53 :                       enum_value_to_arg (e->values, &arg, value, lang_mask);
    1882           53 :                       if (arg == NULL)
    1883           10 :                         arg = _("[default]");
    1884           53 :                       snprintf (new_help + strlen (new_help),
    1885           53 :                                 sizeof (new_help) - strlen (new_help),
    1886              :                                 "%s", arg);
    1887              :                     }
    1888              :                   else
    1889              :                     {
    1890           96 :                       if (option->cl_host_wide_int)
    1891           24 :                         sprintf (new_help + strlen (new_help),
    1892           24 :                                  _("%llu bytes"), (unsigned long long)
    1893              :                                  *(unsigned HOST_WIDE_INT *) flag_var);
    1894              :                       else
    1895           72 :                         sprintf (new_help + strlen (new_help),
    1896              :                                  "%i", * (int *) flag_var);
    1897              :                     }
    1898              :                 }
    1899              :               else
    1900              :                 print_state = true;
    1901              :             }
    1902              :           else
    1903              :             /* When there is no argument, print the option state only
    1904              :                if the option takes no argument.  */
    1905          250 :             print_state = !(option->flags & CL_JOINED);
    1906              : 
    1907         1122 :           if (print_state)
    1908              :             {
    1909         1902 :               if (option->alias_target < N_OPTS
    1910              :                   && option->alias_target != OPT_SPECIAL_warn_removed
    1911              :                   && option->alias_target != OPT_SPECIAL_ignore
    1912              :                   && option->alias_target != OPT_SPECIAL_input_file
    1913              :                   && option->alias_target != OPT_SPECIAL_program_name
    1914              :                   && option->alias_target != OPT_SPECIAL_unknown)
    1915              :                 {
    1916          162 :                   const struct cl_option *target
    1917          162 :                     = &cl_options[option->alias_target];
    1918          324 :                   sprintf (new_help + strlen (new_help), "%s%s",
    1919          162 :                            target->opt_text,
    1920          162 :                            option->alias_arg ? option->alias_arg : "");
    1921              :                 }
    1922         1740 :               else if (option->alias_target == OPT_SPECIAL_ignore)
    1923           20 :                 strcat (new_help, ("[ignored]"));
    1924              :               else
    1925              :                 {
    1926              :                   /* Print the state for an on/off option.  */
    1927         1720 :                   int ena = option_enabled (i, lang_mask, opts);
    1928         1720 :                   if (ena > 0)
    1929          791 :                     strcat (new_help, _("[enabled]"));
    1930          929 :                   else if (ena == 0)
    1931          828 :                     strcat (new_help, _("[disabled]"));
    1932              :                 }
    1933              :             }
    1934              : 
    1935              :           help = new_help;
    1936              :         }
    1937              : 
    1938        28828 :       if (option->range_max != -1 && tab == NULL)
    1939              :         {
    1940         4456 :           char b[128];
    1941         4456 :           snprintf (b, sizeof (b), "<%d,%d>", option->range_min,
    1942              :                     option->range_max);
    1943         4456 :           opt = concat (opt, b, NULL);
    1944         4456 :           len += strlen (b);
    1945              :         }
    1946              : 
    1947        28828 :       wrap_help (help, opt, len, columns);
    1948        28828 :       displayed = true;
    1949              : 
    1950        28828 :       if (option->var_type == CLVC_ENUM
    1951          911 :           && opts->x_help_enum_printed[option->var_enum] != 2)
    1952          911 :         opts->x_help_enum_printed[option->var_enum] = 1;
    1953              :       else
    1954              :         {
    1955        27917 :           vec<const char *> option_values
    1956        27917 :             = targetm_common.get_valid_option_values (i, NULL);
    1957        27931 :           if (!option_values.is_empty ())
    1958           14 :             help_tuples.safe_push (option_help_tuple (i, option_values));
    1959              :         }
    1960              :     }
    1961              : 
    1962          136 :   if (! found)
    1963              :     {
    1964            9 :       unsigned int langs = include_flags & CL_LANG_ALL;
    1965              : 
    1966            9 :       if (langs == 0)
    1967            0 :         printf (_(" No options with the desired characteristics were found\n"));
    1968              :       else
    1969              :         {
    1970              :           unsigned int i;
    1971              : 
    1972              :           /* PR 31349: Tell the user how to see all of the
    1973              :              options supported by a specific front end.  */
    1974          153 :           for (i = 0; (1U << i) < CL_LANG_ALL; i ++)
    1975          144 :             if ((1U << i) & langs)
    1976            9 :               printf (_(" None found.  Use --help=%s to show *all* the options supported by the %s front-end.\n"),
    1977            9 :                       lang_names[i], lang_names[i]);
    1978              :         }
    1979              : 
    1980              :     }
    1981          127 :   else if (! displayed)
    1982            0 :     printf (_(" All options with the desired characteristics have already been displayed\n"));
    1983              : 
    1984          136 :   putchar ('\n');
    1985              : 
    1986              :   /* Print details of enumerated option arguments, if those
    1987              :      enumerations have help text headings provided.  If no help text
    1988              :      is provided, presume that the possible values are listed in the
    1989              :      help text for the relevant options.  */
    1990        11832 :   for (i = 0; i < cl_enums_count; i++)
    1991              :     {
    1992        11696 :       unsigned int j, pos;
    1993              : 
    1994        11696 :       if (opts->x_help_enum_printed[i] != 1)
    1995         9931 :         continue;
    1996         1765 :       if (cl_enums[i].help == NULL)
    1997         1667 :         continue;
    1998           98 :       printf ("  %s\n    ", _(cl_enums[i].help));
    1999           98 :       pos = 4;
    2000          455 :       for (j = 0; cl_enums[i].values[j].arg != NULL; j++)
    2001              :         {
    2002          357 :           unsigned int len = strlen (cl_enums[i].values[j].arg);
    2003              : 
    2004          357 :           if (pos > 4 && pos + 1 + len <= columns)
    2005              :             {
    2006          258 :               printf (" %s", cl_enums[i].values[j].arg);
    2007          258 :               pos += 1 + len;
    2008              :             }
    2009              :           else
    2010              :             {
    2011            1 :               if (pos > 4)
    2012              :                 {
    2013            1 :                   printf ("\n    ");
    2014            1 :                   pos = 4;
    2015              :                 }
    2016           99 :               printf ("%s", cl_enums[i].values[j].arg);
    2017           99 :               pos += len;
    2018              :             }
    2019              :         }
    2020           98 :       printf ("\n\n");
    2021           98 :       opts->x_help_enum_printed[i] = 2;
    2022              :     }
    2023              : 
    2024          150 :   for (unsigned i = 0; i < help_tuples.length (); i++)
    2025              :     {
    2026           14 :       const struct cl_option *option = cl_options + help_tuples[i].m_code;
    2027           14 :       printf (_("  Known valid arguments for %s option:\n   "),
    2028           14 :               option->opt_text);
    2029         1302 :       for (unsigned j = 0; j < help_tuples[i].m_values.length (); j++)
    2030         1288 :         printf (" %s", help_tuples[i].m_values[j]);
    2031           14 :       printf ("\n\n");
    2032              :     }
    2033          136 : }
    2034              : 
    2035              : /* Display help for a specified type of option.
    2036              :    The options must have ALL of the INCLUDE_FLAGS set
    2037              :    ANY of the flags in the ANY_FLAGS set
    2038              :    and NONE of the EXCLUDE_FLAGS set.  The current option state is in
    2039              :    OPTS; LANG_MASK is used for interpreting enumerated option state.  */
    2040              : static void
    2041          136 : print_specific_help (unsigned int include_flags,
    2042              :                      unsigned int exclude_flags,
    2043              :                      unsigned int any_flags,
    2044              :                      struct gcc_options *opts,
    2045              :                      unsigned int lang_mask)
    2046              : {
    2047          136 :   unsigned int all_langs_mask = (1U << cl_lang_count) - 1;
    2048          136 :   const char * description = NULL;
    2049          136 :   const char * descrip_extra = "";
    2050          136 :   size_t i;
    2051          136 :   unsigned int flag;
    2052              : 
    2053              :   /* Sanity check: Make sure that we do not have more
    2054              :      languages than we have bits available to enumerate them.  */
    2055          136 :   gcc_assert ((1U << cl_lang_count) <= CL_MIN_OPTION_CLASS);
    2056              : 
    2057              :   /* If we have not done so already, obtain
    2058              :      the desired maximum width of the output.  */
    2059          136 :   if (opts->x_help_columns == 0)
    2060              :     {
    2061           71 :       opts->x_help_columns = get_terminal_width ();
    2062           71 :       if (opts->x_help_columns == INT_MAX)
    2063              :         /* Use a reasonable default.  */
    2064           27 :         opts->x_help_columns = 80;
    2065              :     }
    2066              : 
    2067              :   /* Decide upon the title for the options that we are going to display.  */
    2068         3128 :   for (i = 0, flag = 1; flag <= CL_MAX_OPTION_CLASS; flag <<= 1, i ++)
    2069              :     {
    2070         2992 :       switch (flag & include_flags)
    2071              :         {
    2072              :         case 0:
    2073              :         case CL_DRIVER:
    2074              :           break;
    2075              : 
    2076            7 :         case CL_TARGET:
    2077            7 :           description = _("The following options are target specific");
    2078            7 :           break;
    2079           11 :         case CL_WARNING:
    2080           11 :           description = _("The following options control compiler warning messages");
    2081           11 :           break;
    2082           10 :         case CL_OPTIMIZATION:
    2083           10 :           description = _("The following options control optimizations");
    2084           10 :           break;
    2085            5 :         case CL_COMMON:
    2086            5 :           description = _("The following options are language-independent");
    2087            5 :           break;
    2088           33 :         case CL_PARAMS:
    2089           33 :           description = _("The following options control parameters");
    2090           33 :           break;
    2091           62 :         default:
    2092           62 :           if (i >= cl_lang_count)
    2093              :             break;
    2094           62 :           if (exclude_flags & all_langs_mask)
    2095           48 :             description = _("The following options are specific to just the language ");
    2096              :           else
    2097           14 :             description = _("The following options are supported by the language ");
    2098           62 :           descrip_extra = lang_names [i];
    2099           62 :           break;
    2100              :         }
    2101              :     }
    2102              : 
    2103          136 :   if (description == NULL)
    2104              :     {
    2105            9 :       if (any_flags == 0)
    2106              :         {
    2107            6 :           if (include_flags & CL_UNDOCUMENTED)
    2108            2 :             description = _("The following options are not documented");
    2109            4 :           else if (include_flags & CL_SEPARATE)
    2110            2 :             description = _("The following options take separate arguments");
    2111            2 :           else if (include_flags & CL_JOINED)
    2112            2 :             description = _("The following options take joined arguments");
    2113              :           else
    2114              :             {
    2115            0 :               internal_error ("unrecognized %<include_flags 0x%x%> passed "
    2116              :                               "to %<print_specific_help%>",
    2117              :                               include_flags);
    2118              :               return;
    2119              :             }
    2120              :         }
    2121              :       else
    2122              :         {
    2123            3 :           if (any_flags & all_langs_mask)
    2124            3 :             description = _("The following options are language-related");
    2125              :           else
    2126            0 :             description = _("The following options are language-independent");
    2127              :         }
    2128              :     }
    2129              : 
    2130          136 :   printf ("%s%s:\n", description, descrip_extra);
    2131          136 :   print_filtered_help (include_flags, exclude_flags, any_flags,
    2132              :                        opts->x_help_columns, opts, lang_mask);
    2133              : }
    2134              : 
    2135              : /* Enable FDO-related flags.  */
    2136              : 
    2137              : static void
    2138          154 : enable_fdo_optimizations (struct gcc_options *opts,
    2139              :                           struct gcc_options *opts_set,
    2140              :                           int value, bool autofdo)
    2141              : {
    2142          154 :   if (!autofdo)
    2143              :     {
    2144          154 :       SET_OPTION_IF_UNSET (opts, opts_set, flag_branch_probabilities, value);
    2145          154 :       SET_OPTION_IF_UNSET (opts, opts_set, flag_profile_values, value);
    2146              :     }
    2147          154 :   SET_OPTION_IF_UNSET (opts, opts_set, flag_value_profile_transformations,
    2148              :                        value);
    2149              : 
    2150              :   /* Enable IPA optimizatins that makes effective use of profile data.  */
    2151          154 :   SET_OPTION_IF_UNSET (opts, opts_set, flag_inline_functions, value);
    2152          154 :   SET_OPTION_IF_UNSET (opts, opts_set, flag_ipa_cp, value);
    2153          154 :   if (value)
    2154              :     {
    2155          154 :       SET_OPTION_IF_UNSET (opts, opts_set, flag_ipa_cp_clone, 1);
    2156          154 :       SET_OPTION_IF_UNSET (opts, opts_set, flag_ipa_bit_cp, 1);
    2157              :     }
    2158              : 
    2159          154 :   SET_OPTION_IF_UNSET (opts, opts_set, flag_gcse_after_reload, value);
    2160          154 :   SET_OPTION_IF_UNSET (opts, opts_set, flag_tracer, value);
    2161              : 
    2162              :   /* Loop optimizations uses profile feedback to determine their profitability
    2163              :      and thus it makes sense to enable them by default even at -O2.
    2164              :      Auto-profile, in its current form, is not very good on determining
    2165              :      iteration counts and thus only real profile feedback is used.  */
    2166          154 :   if (!autofdo)
    2167              :     {
    2168          154 :       SET_OPTION_IF_UNSET (opts, opts_set, flag_unroll_loops, value);
    2169          154 :       SET_OPTION_IF_UNSET (opts, opts_set, flag_peel_loops, value);
    2170          154 :       SET_OPTION_IF_UNSET (opts, opts_set, flag_predictive_commoning, value);
    2171          154 :       SET_OPTION_IF_UNSET (opts, opts_set, flag_split_loops, value);
    2172          154 :       SET_OPTION_IF_UNSET (opts, opts_set, flag_unswitch_loops, value);
    2173          154 :       SET_OPTION_IF_UNSET (opts, opts_set, flag_tree_loop_vectorize, value);
    2174          154 :       SET_OPTION_IF_UNSET (opts, opts_set, flag_tree_slp_vectorize, value);
    2175          154 :       SET_OPTION_IF_UNSET (opts, opts_set, flag_version_loops_for_strides, value);
    2176          154 :       SET_OPTION_IF_UNSET (opts, opts_set, flag_vect_cost_model,
    2177              :                            VECT_COST_MODEL_DYNAMIC);
    2178          154 :       SET_OPTION_IF_UNSET (opts, opts_set, flag_tree_loop_distribute_patterns,
    2179              :                            value);
    2180          154 :       SET_OPTION_IF_UNSET (opts, opts_set, flag_loop_interchange, value);
    2181          154 :       SET_OPTION_IF_UNSET (opts, opts_set, flag_unroll_jam, value);
    2182          154 :       SET_OPTION_IF_UNSET (opts, opts_set, flag_tree_loop_distribution, value);
    2183          154 :       SET_OPTION_IF_UNSET (opts, opts_set, flag_optimize_crc, value);
    2184              :     }
    2185          154 : }
    2186              : 
    2187              : /* -f{,no-}sanitize{,-recover}= suboptions.  */
    2188              : const struct sanitizer_opts_s sanitizer_opts[] =
    2189              : {
    2190              : #define SANITIZER_OPT(name, flags, recover, trap) \
    2191              :     { #name, flags, sizeof #name - 1, recover, trap }
    2192              :   SANITIZER_OPT (address, (SANITIZE_ADDRESS | SANITIZE_USER_ADDRESS), true,
    2193              :                  false),
    2194              :   SANITIZER_OPT (hwaddress, (SANITIZE_HWADDRESS | SANITIZE_USER_HWADDRESS),
    2195              :                  true, false),
    2196              :   SANITIZER_OPT (kernel-address, (SANITIZE_ADDRESS | SANITIZE_KERNEL_ADDRESS),
    2197              :                  true, false),
    2198              :   SANITIZER_OPT (kernel-hwaddress,
    2199              :                  (SANITIZE_HWADDRESS | SANITIZE_KERNEL_HWADDRESS),
    2200              :                  true, false),
    2201              :   SANITIZER_OPT (pointer-compare, SANITIZE_POINTER_COMPARE, true, false),
    2202              :   SANITIZER_OPT (pointer-subtract, SANITIZE_POINTER_SUBTRACT, true, false),
    2203              :   SANITIZER_OPT (thread, SANITIZE_THREAD, false, false),
    2204              :   SANITIZER_OPT (leak, SANITIZE_LEAK, false, false),
    2205              :   SANITIZER_OPT (shift, SANITIZE_SHIFT, true, true),
    2206              :   SANITIZER_OPT (shift-base, SANITIZE_SHIFT_BASE, true, true),
    2207              :   SANITIZER_OPT (shift-exponent, SANITIZE_SHIFT_EXPONENT, true, true),
    2208              :   SANITIZER_OPT (integer-divide-by-zero, SANITIZE_DIVIDE, true, true),
    2209              :   SANITIZER_OPT (undefined, SANITIZE_UNDEFINED, true, true),
    2210              :   SANITIZER_OPT (unreachable, SANITIZE_UNREACHABLE, false, true),
    2211              :   SANITIZER_OPT (vla-bound, SANITIZE_VLA, true, true),
    2212              :   SANITIZER_OPT (return, SANITIZE_RETURN, false, true),
    2213              :   SANITIZER_OPT (null, SANITIZE_NULL, true, true),
    2214              :   SANITIZER_OPT (signed-integer-overflow, SANITIZE_SI_OVERFLOW, true, true),
    2215              :   SANITIZER_OPT (bool, SANITIZE_BOOL, true, true),
    2216              :   SANITIZER_OPT (enum, SANITIZE_ENUM, true, true),
    2217              :   SANITIZER_OPT (float-divide-by-zero, SANITIZE_FLOAT_DIVIDE, true, true),
    2218              :   SANITIZER_OPT (float-cast-overflow, SANITIZE_FLOAT_CAST, true, true),
    2219              :   SANITIZER_OPT (bounds, SANITIZE_BOUNDS, true, true),
    2220              :   SANITIZER_OPT (bounds-strict, SANITIZE_BOUNDS | SANITIZE_BOUNDS_STRICT, true,
    2221              :                  true),
    2222              :   SANITIZER_OPT (alignment, SANITIZE_ALIGNMENT, true, true),
    2223              :   SANITIZER_OPT (nonnull-attribute, SANITIZE_NONNULL_ATTRIBUTE, true, true),
    2224              :   SANITIZER_OPT (returns-nonnull-attribute, SANITIZE_RETURNS_NONNULL_ATTRIBUTE,
    2225              :                  true, true),
    2226              :   SANITIZER_OPT (object-size, SANITIZE_OBJECT_SIZE, true, true),
    2227              :   SANITIZER_OPT (vptr, SANITIZE_VPTR, true, false),
    2228              :   SANITIZER_OPT (pointer-overflow, SANITIZE_POINTER_OVERFLOW, true, true),
    2229              :   SANITIZER_OPT (builtin, SANITIZE_BUILTIN, true, true),
    2230              :   SANITIZER_OPT (shadow-call-stack, SANITIZE_SHADOW_CALL_STACK, false, false),
    2231              :   SANITIZER_OPT (memtag-stack, SANITIZE_MEMTAG_STACK, false, false),
    2232              :   SANITIZER_OPT (all, ~sanitize_code_type (0), true, true),
    2233              : #undef SANITIZER_OPT
    2234              :   { NULL, sanitize_code_type (0), 0UL, false, false }
    2235              : };
    2236              : 
    2237              : /* -fzero-call-used-regs= suboptions.  */
    2238              : const struct zero_call_used_regs_opts_s zero_call_used_regs_opts[] =
    2239              : {
    2240              : #define ZERO_CALL_USED_REGS_OPT(name, flags) \
    2241              :     { #name, flags }
    2242              :   ZERO_CALL_USED_REGS_OPT (skip, zero_regs_flags::SKIP),
    2243              :   ZERO_CALL_USED_REGS_OPT (used-gpr-arg, zero_regs_flags::USED_GPR_ARG),
    2244              :   ZERO_CALL_USED_REGS_OPT (used-gpr, zero_regs_flags::USED_GPR),
    2245              :   ZERO_CALL_USED_REGS_OPT (used-arg, zero_regs_flags::USED_ARG),
    2246              :   ZERO_CALL_USED_REGS_OPT (used, zero_regs_flags::USED),
    2247              :   ZERO_CALL_USED_REGS_OPT (all-gpr-arg, zero_regs_flags::ALL_GPR_ARG),
    2248              :   ZERO_CALL_USED_REGS_OPT (all-gpr, zero_regs_flags::ALL_GPR),
    2249              :   ZERO_CALL_USED_REGS_OPT (all-arg, zero_regs_flags::ALL_ARG),
    2250              :   ZERO_CALL_USED_REGS_OPT (all, zero_regs_flags::ALL),
    2251              :   ZERO_CALL_USED_REGS_OPT (leafy-gpr-arg, zero_regs_flags::LEAFY_GPR_ARG),
    2252              :   ZERO_CALL_USED_REGS_OPT (leafy-gpr, zero_regs_flags::LEAFY_GPR),
    2253              :   ZERO_CALL_USED_REGS_OPT (leafy-arg, zero_regs_flags::LEAFY_ARG),
    2254              :   ZERO_CALL_USED_REGS_OPT (leafy, zero_regs_flags::LEAFY),
    2255              : #undef ZERO_CALL_USED_REGS_OPT
    2256              :   {NULL, 0U}
    2257              : };
    2258              : 
    2259              : /* A struct for describing a run of chars within a string.  */
    2260              : 
    2261              : class string_fragment
    2262              : {
    2263              : public:
    2264            6 :   string_fragment (const char *start, size_t len)
    2265            6 :   : m_start (start), m_len (len) {}
    2266              : 
    2267              :   const char *m_start;
    2268              :   size_t m_len;
    2269              : };
    2270              : 
    2271              : /* Specialization of edit_distance_traits for string_fragment,
    2272              :    for use by get_closest_sanitizer_option.  */
    2273              : 
    2274              : template <>
    2275              : struct edit_distance_traits<const string_fragment &>
    2276              : {
    2277            6 :   static size_t get_length (const string_fragment &fragment)
    2278              :   {
    2279            6 :     return fragment.m_len;
    2280              :   }
    2281              : 
    2282            6 :   static const char *get_string (const string_fragment &fragment)
    2283              :   {
    2284            6 :     return fragment.m_start;
    2285              :   }
    2286              : };
    2287              : 
    2288              : /* Given ARG, an unrecognized sanitizer option, return the best
    2289              :    matching sanitizer option, or NULL if there isn't one.
    2290              :    OPTS is array of candidate sanitizer options.
    2291              :    CODE is OPT_fsanitize_, OPT_fsanitize_recover_ or OPT_fsanitize_trap_.
    2292              :    VALUE is non-zero for the regular form of the option, zero
    2293              :    for the "no-" form (e.g. "-fno-sanitize-recover=").  */
    2294              : 
    2295              : static const char *
    2296            6 : get_closest_sanitizer_option (const string_fragment &arg,
    2297              :                               const struct sanitizer_opts_s *opts,
    2298              :                               enum opt_code code, int value)
    2299              : {
    2300            6 :   best_match <const string_fragment &, const char*> bm (arg);
    2301          210 :   for (int i = 0; opts[i].name != NULL; ++i)
    2302              :     {
    2303              :       /* -fsanitize=all is not valid, so don't offer it.  */
    2304          204 :       if (code == OPT_fsanitize_
    2305          170 :           && opts[i].flag == ~sanitize_code_type (0)
    2306            5 :           && value)
    2307            4 :         continue;
    2308              : 
    2309              :       /* For -fsanitize-recover= (and not -fno-sanitize-recover=),
    2310              :          don't offer the non-recoverable options.  */
    2311          200 :       if (code == OPT_fsanitize_recover_
    2312           34 :           && !opts[i].can_recover
    2313            6 :           && value)
    2314            6 :         continue;
    2315              : 
    2316              :       /* For -fsanitize-trap= (and not -fno-sanitize-trap=),
    2317              :          don't offer the non-trapping options.  */
    2318          194 :       if (code == OPT_fsanitize_trap_
    2319            0 :           && !opts[i].can_trap
    2320            0 :           && value)
    2321            0 :         continue;
    2322              : 
    2323          194 :       bm.consider (opts[i].name);
    2324              :     }
    2325            6 :   return bm.get_best_meaningful_candidate ();
    2326              : }
    2327              : 
    2328              : /* Parse comma separated sanitizer suboptions from P for option SCODE,
    2329              :    adjust previous FLAGS and return new ones.  If COMPLAIN is false,
    2330              :    don't issue diagnostics.  */
    2331              : 
    2332              : sanitize_code_type
    2333        19122 : parse_sanitizer_options (const char *p, location_t loc, int scode,
    2334              :                          sanitize_code_type flags, int value, bool complain)
    2335              : {
    2336        19122 :   enum opt_code code = (enum opt_code) scode;
    2337              : 
    2338        20057 :   while (*p != 0)
    2339              :     {
    2340        20057 :       size_t len, i;
    2341        20057 :       bool found = false;
    2342        20057 :       const char *comma = strchr (p, ',');
    2343              : 
    2344        20057 :       if (comma == NULL)
    2345        19122 :         len = strlen (p);
    2346              :       else
    2347          935 :         len = comma - p;
    2348        20057 :       if (len == 0)
    2349              :         {
    2350            0 :           p = comma + 1;
    2351            0 :           continue;
    2352              :         }
    2353              : 
    2354              :       /* Check to see if the string matches an option class name.  */
    2355       187585 :       for (i = 0; sanitizer_opts[i].name != NULL; ++i)
    2356       187579 :         if (len == sanitizer_opts[i].len
    2357        29345 :             && memcmp (p, sanitizer_opts[i].name, len) == 0)
    2358              :           {
    2359              :             /* Handle both -fsanitize and -fno-sanitize cases.  */
    2360        20051 :             if (value && sanitizer_opts[i].flag == ~sanitize_code_type (0))
    2361              :               {
    2362           42 :                 if (code == OPT_fsanitize_)
    2363              :                   {
    2364            3 :                     if (complain)
    2365            3 :                       error_at (loc, "%<-fsanitize=all%> option is not valid");
    2366              :                   }
    2367           39 :                 else if (code == OPT_fsanitize_recover_)
    2368           13 :                   flags |= ~(SANITIZE_THREAD | SANITIZE_LEAK
    2369              :                              | SANITIZE_UNREACHABLE | SANITIZE_RETURN
    2370              :                              | SANITIZE_SHADOW_CALL_STACK
    2371              :                              | SANITIZE_MEMTAG_STACK);
    2372              :                 else /* if (code == OPT_fsanitize_trap_) */
    2373           26 :                   flags |= (SANITIZE_UNDEFINED
    2374              :                             | SANITIZE_UNDEFINED_NONDEFAULT);
    2375              :               }
    2376        18729 :             else if (value)
    2377              :               {
    2378              :                 /* Do not enable -fsanitize-recover=unreachable and
    2379              :                    -fsanitize-recover=return if -fsanitize-recover=undefined
    2380              :                    is selected.  */
    2381        18729 :                 if (code == OPT_fsanitize_recover_
    2382          404 :                     && sanitizer_opts[i].flag == SANITIZE_UNDEFINED)
    2383           40 :                   flags |= (SANITIZE_UNDEFINED
    2384              :                             & ~(SANITIZE_UNREACHABLE | SANITIZE_RETURN));
    2385        18689 :                 else if (code == OPT_fsanitize_trap_
    2386          176 :                          && sanitizer_opts[i].flag == SANITIZE_VPTR)
    2387            0 :                   error_at (loc, "%<-fsanitize-trap=%s%> is not supported",
    2388              :                             sanitizer_opts[i].name);
    2389              :                 else
    2390        18689 :                   flags |= sanitizer_opts[i].flag;
    2391              :               }
    2392              :             else
    2393              :               {
    2394         1280 :                 flags &= ~sanitizer_opts[i].flag;
    2395              :                 /* Don't always clear SANITIZE_ADDRESS if it was previously
    2396              :                    set: -fsanitize=address -fno-sanitize=kernel-address should
    2397              :                    leave SANITIZE_ADDRESS set.  */
    2398         1280 :                 if (flags & (SANITIZE_KERNEL_ADDRESS | SANITIZE_USER_ADDRESS))
    2399          754 :                   flags |= SANITIZE_ADDRESS;
    2400              :               }
    2401              :             found = true;
    2402              :             break;
    2403              :           }
    2404              : 
    2405        20057 :       if (! found && complain)
    2406              :         {
    2407            6 :           const char *hint
    2408            6 :             = get_closest_sanitizer_option (string_fragment (p, len),
    2409              :                                             sanitizer_opts, code, value);
    2410              : 
    2411            6 :           const char *suffix;
    2412            6 :           if (code == OPT_fsanitize_recover_)
    2413              :             suffix = "-recover";
    2414            5 :           else if (code == OPT_fsanitize_trap_)
    2415              :             suffix = "-trap";
    2416              :           else
    2417            5 :             suffix = "";
    2418              : 
    2419            6 :           if (hint)
    2420            4 :             error_at (loc,
    2421              :                       "unrecognized argument to %<-f%ssanitize%s=%> "
    2422              :                       "option: %q.*s; did you mean %qs?",
    2423              :                       value ? "" : "no-",
    2424              :                       suffix, (int) len, p, hint);
    2425              :           else
    2426            3 :             error_at (loc,
    2427              :                       "unrecognized argument to %<-f%ssanitize%s=%> option: "
    2428              :                       "%q.*s", value ? "" : "no-",
    2429              :                       suffix, (int) len, p);
    2430              :         }
    2431              : 
    2432        20057 :       if (comma == NULL)
    2433              :         break;
    2434          935 :       p = comma + 1;
    2435              :     }
    2436        19122 :   return flags;
    2437              : }
    2438              : 
    2439              : /* Parse string values of no_sanitize attribute passed in VALUE.
    2440              :    Values are separated with comma.  */
    2441              : 
    2442              : sanitize_code_type
    2443          280 : parse_no_sanitize_attribute (char *value)
    2444              : {
    2445          280 :   sanitize_code_type flags = 0;
    2446          280 :   unsigned int i;
    2447          280 :   char *q = strtok (value, ",");
    2448              : 
    2449         1070 :   while (q != NULL)
    2450              :     {
    2451         6155 :       for (i = 0; sanitizer_opts[i].name != NULL; ++i)
    2452         6135 :         if (strcmp (sanitizer_opts[i].name, q) == 0)
    2453              :           {
    2454          490 :             flags |= sanitizer_opts[i].flag;
    2455          490 :             if (sanitizer_opts[i].flag == SANITIZE_UNDEFINED)
    2456           57 :               flags |= SANITIZE_UNDEFINED_NONDEFAULT;
    2457              :             break;
    2458              :           }
    2459              : 
    2460          510 :       if (sanitizer_opts[i].name == NULL)
    2461           20 :         warning (OPT_Wattributes,
    2462              :                  "%qs attribute directive ignored", q);
    2463              : 
    2464          510 :       q = strtok (NULL, ",");
    2465              :     }
    2466              : 
    2467          280 :   return flags;
    2468              : }
    2469              : 
    2470              : /* Parse -fzero-call-used-regs suboptions from ARG, return the FLAGS.  */
    2471              : 
    2472              : unsigned int
    2473           78 : parse_zero_call_used_regs_options (const char *arg)
    2474              : {
    2475           78 :   unsigned int flags = 0;
    2476              : 
    2477              :   /* Check to see if the string matches a sub-option name.  */
    2478          468 :   for (unsigned int i = 0; zero_call_used_regs_opts[i].name != NULL; ++i)
    2479          468 :     if (strcmp (arg, zero_call_used_regs_opts[i].name) == 0)
    2480              :       {
    2481           78 :         flags = zero_call_used_regs_opts[i].flag;
    2482           78 :         break;
    2483              :       }
    2484              : 
    2485           78 :   if (!flags)
    2486            0 :     error ("unrecognized argument to %<-fzero-call-used-regs=%>: %qs", arg);
    2487              : 
    2488           78 :   return flags;
    2489              : }
    2490              : 
    2491              : /* Parse -falign-NAME format for a FLAG value.  Return individual
    2492              :    parsed integer values into RESULT_VALUES array.  If REPORT_ERROR is
    2493              :    set, print error message at LOC location.  */
    2494              : 
    2495              : bool
    2496       365315 : parse_and_check_align_values (const char *flag,
    2497              :                               const char *name,
    2498              :                               auto_vec<unsigned> &result_values,
    2499              :                               bool report_error,
    2500              :                               location_t loc)
    2501              : {
    2502       365315 :   char *str = xstrdup (flag);
    2503      1217688 :   for (char *p = strtok (str, ":"); p; p = strtok (NULL, ":"))
    2504              :     {
    2505       852373 :       char *end;
    2506       852373 :       int v = strtol (p, &end, 10);
    2507       852373 :       if (*end != '\0' || v < 0)
    2508              :         {
    2509            0 :           if (report_error)
    2510            0 :             error_at (loc, "invalid arguments for %<-falign-%s%> option: %qs",
    2511              :                       name, flag);
    2512              : 
    2513            0 :           return false;
    2514              :         }
    2515              : 
    2516       852373 :       result_values.safe_push ((unsigned)v);
    2517              :     }
    2518              : 
    2519       365315 :   free (str);
    2520              : 
    2521              :   /* Check that we have a correct number of values.  */
    2522       730630 :   if (result_values.is_empty () || result_values.length () > 4)
    2523              :     {
    2524            0 :       if (report_error)
    2525            0 :         error_at (loc, "invalid number of arguments for %<-falign-%s%> "
    2526              :                   "option: %qs", name, flag);
    2527            0 :       return false;
    2528              :     }
    2529              : 
    2530      1217687 :   for (unsigned i = 0; i < result_values.length (); i++)
    2531       852373 :     if (result_values[i] > MAX_CODE_ALIGN_VALUE)
    2532              :       {
    2533            1 :         if (report_error)
    2534            1 :           error_at (loc, "%<-falign-%s%> is not between 0 and %d",
    2535              :                     name, MAX_CODE_ALIGN_VALUE);
    2536            1 :         return false;
    2537              :       }
    2538              : 
    2539              :   return true;
    2540              : }
    2541              : 
    2542              : /* Check that alignment value FLAG for -falign-NAME is valid at a given
    2543              :    location LOC. OPT_STR points to the stored -falign-NAME=argument and
    2544              :    OPT_FLAG points to the associated -falign-NAME on/off flag.  */
    2545              : 
    2546              : static void
    2547           20 : check_alignment_argument (location_t loc, const char *flag, const char *name,
    2548              :                           int *opt_flag, const char **opt_str)
    2549              : {
    2550           20 :   auto_vec<unsigned> align_result;
    2551           20 :   parse_and_check_align_values (flag, name, align_result, true, loc);
    2552              : 
    2553           40 :   if (align_result.length() >= 1 && align_result[0] == 0)
    2554              :     {
    2555            0 :       *opt_flag = 1;
    2556            0 :       *opt_str = NULL;
    2557              :     }
    2558           20 : }
    2559              : 
    2560              : /* Parse argument of -fpatchable-function-entry option ARG and store
    2561              :    corresponding values to PATCH_AREA_SIZE and PATCH_AREA_START.
    2562              :    If REPORT_ERROR is set to true, generate error for a problematic
    2563              :    option arguments.  */
    2564              : 
    2565              : void
    2566      1798052 : parse_and_check_patch_area (const char *arg, bool report_error,
    2567              :                             HOST_WIDE_INT *patch_area_size,
    2568              :                             HOST_WIDE_INT *patch_area_start)
    2569              : {
    2570      1798052 :   *patch_area_size = 0;
    2571      1798052 :   *patch_area_start = 0;
    2572              : 
    2573      1798052 :   if (arg == NULL)
    2574              :     return;
    2575              : 
    2576          115 :   char *patch_area_arg = xstrdup (arg);
    2577          115 :   char *comma = strchr (patch_area_arg, ',');
    2578          115 :   if (comma)
    2579              :     {
    2580           52 :       *comma = '\0';
    2581           52 :       *patch_area_size = integral_argument (patch_area_arg);
    2582           52 :       *patch_area_start = integral_argument (comma + 1);
    2583              :     }
    2584              :   else
    2585           63 :     *patch_area_size = integral_argument (patch_area_arg);
    2586              : 
    2587          115 :   if (*patch_area_size < 0
    2588          115 :       || *patch_area_size > USHRT_MAX
    2589          107 :       || *patch_area_start < 0
    2590          107 :       || *patch_area_start > USHRT_MAX
    2591           99 :       || *patch_area_size < *patch_area_start)
    2592           16 :     if (report_error)
    2593            8 :       error ("invalid arguments for %<-fpatchable-function-entry%>");
    2594              : 
    2595          115 :   free (patch_area_arg);
    2596              : }
    2597              : 
    2598              : /* Print options enabled by -fhardened.  Keep this in sync with the manual!  */
    2599              : 
    2600              : static void
    2601            1 : print_help_hardened ()
    2602              : {
    2603            1 :   printf ("%s\n", "The following options are enabled by -fhardened:");
    2604              :   /* Unfortunately, I can't seem to use targetm.fortify_source_default_level
    2605              :      here.  */
    2606            1 :   printf ("  %s\n", "-D_FORTIFY_SOURCE=3 (or =2 for glibc < 2.35)");
    2607            1 :   printf ("  %s\n", "-D_GLIBCXX_ASSERTIONS");
    2608            1 :   printf ("  %s\n", "-ftrivial-auto-var-init=zero");
    2609              : #ifdef HAVE_LD_PIE
    2610            1 :   printf ("  %s  %s\n", "-fPIE", "-pie");
    2611              : #endif
    2612            1 :   if (HAVE_LD_NOW_SUPPORT)
    2613            1 :     printf ("  %s\n", "-Wl,-z,now");
    2614            1 :   if (HAVE_LD_RELRO_SUPPORT)
    2615            1 :     printf ("  %s\n", "-Wl,-z,relro");
    2616            1 :   printf ("  %s\n", "-fstack-protector-strong");
    2617            1 :   printf ("  %s\n", "-fstack-clash-protection");
    2618            1 :   printf ("  %s\n", "-fcf-protection=full");
    2619            1 :   putchar ('\n');
    2620            1 : }
    2621              : 
    2622              : /* Print help when OPT__help_ is set.  */
    2623              : 
    2624              : void
    2625           74 : print_help (struct gcc_options *opts, unsigned int lang_mask,
    2626              :             const char *help_option_argument)
    2627              : {
    2628           74 :   const char *a = help_option_argument;
    2629           74 :   unsigned int include_flags = 0;
    2630              :   /* Note - by default we include undocumented options when listing
    2631              :      specific classes.  If you only want to see documented options
    2632              :      then add ",^undocumented" to the --help= option.  E.g.:
    2633              : 
    2634              :      --help=target,^undocumented  */
    2635           74 :   unsigned int exclude_flags = 0;
    2636              : 
    2637           74 :   if (lang_mask == CL_DRIVER)
    2638            0 :     return;
    2639              : 
    2640              :   /* Walk along the argument string, parsing each word in turn.
    2641              :      The format is:
    2642              :      arg = [^]{word}[,{arg}]
    2643              :      word = {optimizers|target|warnings|undocumented|
    2644              :      params|common|<language>}  */
    2645           84 :   while (*a != 0)
    2646              :     {
    2647           84 :       static const struct
    2648              :         {
    2649              :           const char *string;
    2650              :           unsigned int flag;
    2651              :         }
    2652              :       specifics[] =
    2653              :         {
    2654              :             { "optimizers", CL_OPTIMIZATION },
    2655              :             { "target", CL_TARGET },
    2656              :             { "warnings", CL_WARNING },
    2657              :             { "undocumented", CL_UNDOCUMENTED },
    2658              :             { "params", CL_PARAMS },
    2659              :             { "joined", CL_JOINED },
    2660              :             { "separate", CL_SEPARATE },
    2661              :             { "common", CL_COMMON },
    2662              :             { NULL, 0 }
    2663              :         };
    2664           84 :       unsigned int *pflags;
    2665           84 :       const char *comma;
    2666           84 :       unsigned int lang_flag, specific_flag;
    2667           84 :       unsigned int len;
    2668           84 :       unsigned int i;
    2669              : 
    2670           84 :       if (*a == '^')
    2671              :         {
    2672            8 :           ++a;
    2673            8 :           if (*a == '\0')
    2674              :             {
    2675            1 :               error ("missing argument to %qs", "--help=^");
    2676            1 :               break;
    2677              :             }
    2678              :           pflags = &exclude_flags;
    2679              :         }
    2680              :       else
    2681              :         pflags = &include_flags;
    2682              : 
    2683           83 :       comma = strchr (a, ',');
    2684           83 :       if (comma == NULL)
    2685           73 :         len = strlen (a);
    2686              :       else
    2687           10 :         len = comma - a;
    2688           83 :       if (len == 0)
    2689              :         {
    2690            0 :           a = comma + 1;
    2691            0 :           continue;
    2692              :         }
    2693              : 
    2694              :       /* Check to see if the string matches an option class name.  */
    2695          434 :       for (i = 0, specific_flag = 0; specifics[i].string != NULL; i++)
    2696          421 :         if (strncasecmp (a, specifics[i].string, len) == 0)
    2697              :           {
    2698           70 :             specific_flag = specifics[i].flag;
    2699           70 :             break;
    2700              :           }
    2701              : 
    2702              :       /* Check to see if the string matches a language name.
    2703              :          Note - we rely upon the alpha-sorted nature of the entries in
    2704              :          the lang_names array, specifically that shorter names appear
    2705              :          before their longer variants.  (i.e. C before C++).  That way
    2706              :          when we are attempting to match --help=c for example we will
    2707              :          match with C first and not C++.  */
    2708         1292 :       for (i = 0, lang_flag = 0; i < cl_lang_count; i++)
    2709         1223 :         if (strncasecmp (a, lang_names[i], len) == 0)
    2710              :           {
    2711           14 :             lang_flag = 1U << i;
    2712           14 :             break;
    2713              :           }
    2714              : 
    2715           83 :       if (specific_flag != 0)
    2716              :         {
    2717           70 :           if (lang_flag == 0)
    2718           68 :             *pflags |= specific_flag;
    2719              :           else
    2720              :             {
    2721              :               /* The option's argument matches both the start of a
    2722              :                  language name and the start of an option class name.
    2723              :                  We have a special case for when the user has
    2724              :                  specified "--help=c", but otherwise we have to issue
    2725              :                  a warning.  */
    2726            2 :               if (strncasecmp (a, "c", len) == 0)
    2727            2 :                 *pflags |= lang_flag;
    2728              :               else
    2729            0 :                 warning (0,
    2730              :                          "%<--help%> argument %q.*s is ambiguous, "
    2731              :                          "please be more specific",
    2732              :                          len, a);
    2733              :             }
    2734              :         }
    2735           13 :       else if (lang_flag != 0)
    2736           12 :         *pflags |= lang_flag;
    2737            1 :       else if (strncasecmp (a, "hardened", len) == 0)
    2738            1 :         print_help_hardened ();
    2739              :       else
    2740            0 :         warning (0,
    2741              :                  "unrecognized argument to %<--help=%> option: %q.*s",
    2742              :                  len, a);
    2743              : 
    2744           83 :       if (comma == NULL)
    2745              :         break;
    2746           10 :       a = comma + 1;
    2747              :     }
    2748              : 
    2749              :   /* We started using PerFunction/Optimization for parameters and
    2750              :      a warning.  We should exclude these from optimization options.  */
    2751           74 :   if (include_flags & CL_OPTIMIZATION)
    2752            7 :     exclude_flags |= CL_WARNING;
    2753           74 :   if (!(include_flags & CL_PARAMS))
    2754           44 :     exclude_flags |= CL_PARAMS;
    2755              : 
    2756           74 :   if (include_flags)
    2757           70 :     print_specific_help (include_flags, exclude_flags, 0, opts,
    2758              :                          lang_mask);
    2759              : }
    2760              : 
    2761              : /* Handle target- and language-independent options.  Return zero to
    2762              :    generate an "unknown option" message.  Only options that need
    2763              :    extra handling need to be listed here; if you simply want
    2764              :    DECODED->value assigned to a variable, it happens automatically.  */
    2765              : 
    2766              : bool
    2767     82524072 : common_handle_option (struct gcc_options *opts,
    2768              :                       struct gcc_options *opts_set,
    2769              :                       const struct cl_decoded_option *decoded,
    2770              :                       unsigned int lang_mask, int kind ATTRIBUTE_UNUSED,
    2771              :                       location_t loc,
    2772              :                       const struct cl_option_handlers *handlers,
    2773              :                       diagnostics::context *dc,
    2774              :                       void (*target_option_override_hook) (void))
    2775              : {
    2776     82524072 :   size_t scode = decoded->opt_index;
    2777     82524072 :   const char *arg = decoded->arg;
    2778     82524072 :   HOST_WIDE_INT value = decoded->value;
    2779     82524072 :   enum opt_code code = (enum opt_code) scode;
    2780              : 
    2781     82524072 :   gcc_assert (decoded->canonical_option_num_elements <= 2);
    2782              : 
    2783     82524072 :   switch (code)
    2784              :     {
    2785            7 :     case OPT__help:
    2786            7 :       {
    2787            7 :         unsigned int all_langs_mask = (1U << cl_lang_count) - 1;
    2788            7 :         unsigned int undoc_mask;
    2789            7 :         unsigned int i;
    2790              : 
    2791            7 :         if (lang_mask == CL_DRIVER)
    2792              :           break;
    2793              : 
    2794            0 :         undoc_mask = ((opts->x_verbose_flag | opts->x_extra_warnings)
    2795            3 :                       ? 0
    2796              :                       : CL_UNDOCUMENTED);
    2797            3 :         target_option_override_hook ();
    2798              :         /* First display any single language specific options.  */
    2799           54 :         for (i = 0; i < cl_lang_count; i++)
    2800           48 :           print_specific_help
    2801           48 :             (1U << i, (all_langs_mask & (~ (1U << i))) | undoc_mask, 0, opts,
    2802              :              lang_mask);
    2803              :         /* Next display any multi language specific options.  */
    2804            3 :         print_specific_help (0, undoc_mask, all_langs_mask, opts, lang_mask);
    2805              :         /* Then display any remaining, non-language options.  */
    2806           24 :         for (i = CL_MIN_OPTION_CLASS; i <= CL_MAX_OPTION_CLASS; i <<= 1)
    2807           18 :           if (i != CL_DRIVER)
    2808           15 :             print_specific_help (i, undoc_mask, 0, opts, lang_mask);
    2809            3 :         opts->x_exit_after_options = true;
    2810            3 :         break;
    2811              :       }
    2812              : 
    2813            0 :     case OPT__target_help:
    2814            0 :       if (lang_mask == CL_DRIVER)
    2815              :         break;
    2816              : 
    2817            0 :       target_option_override_hook ();
    2818            0 :       print_specific_help (CL_TARGET, 0, 0, opts, lang_mask);
    2819            0 :       opts->x_exit_after_options = true;
    2820            0 :       break;
    2821              : 
    2822          148 :     case OPT__help_:
    2823          148 :       {
    2824          148 :         help_option_arguments.safe_push (arg);
    2825          148 :         opts->x_exit_after_options = true;
    2826          148 :         break;
    2827              :       }
    2828              : 
    2829           78 :     case OPT__version:
    2830           78 :       if (lang_mask == CL_DRIVER)
    2831              :         break;
    2832              : 
    2833            0 :       opts->x_exit_after_options = true;
    2834            0 :       break;
    2835              : 
    2836              :     case OPT__completion_:
    2837              :       break;
    2838              : 
    2839        17850 :     case OPT_fsanitize_:
    2840        17850 :       opts_set->x_flag_sanitize = true;
    2841        17850 :       opts->x_flag_sanitize
    2842        17850 :         = parse_sanitizer_options (arg, loc, code,
    2843              :                                    opts->x_flag_sanitize, value, true);
    2844              : 
    2845              :       /* Kernel ASan implies normal ASan but does not yet support
    2846              :          all features.  */
    2847        17850 :       if (opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS)
    2848              :         {
    2849          372 :           SET_OPTION_IF_UNSET (opts, opts_set,
    2850              :                                param_asan_instrumentation_with_call_threshold,
    2851              :                                0);
    2852          372 :           SET_OPTION_IF_UNSET (opts, opts_set, param_asan_globals, 0);
    2853          372 :           SET_OPTION_IF_UNSET (opts, opts_set, param_asan_stack, 0);
    2854          372 :           SET_OPTION_IF_UNSET (opts, opts_set, param_asan_protect_allocas, 0);
    2855          372 :           SET_OPTION_IF_UNSET (opts, opts_set, param_asan_use_after_return, 0);
    2856              :         }
    2857        17850 :       if (opts->x_flag_sanitize & SANITIZE_KERNEL_HWADDRESS)
    2858              :         {
    2859           56 :           SET_OPTION_IF_UNSET (opts, opts_set,
    2860              :                                param_hwasan_instrument_stack, 0);
    2861           56 :           SET_OPTION_IF_UNSET (opts, opts_set,
    2862              :                                param_hwasan_random_frame_tag, 0);
    2863           56 :           SET_OPTION_IF_UNSET (opts, opts_set,
    2864              :                                param_hwasan_instrument_allocas, 0);
    2865              :         }
    2866              :       break;
    2867              : 
    2868         1070 :     case OPT_fsanitize_recover_:
    2869         1070 :       opts->x_flag_sanitize_recover
    2870         1070 :         = parse_sanitizer_options (arg, loc, code,
    2871              :                                    opts->x_flag_sanitize_recover, value, true);
    2872         1070 :       break;
    2873              : 
    2874          202 :     case OPT_fsanitize_trap_:
    2875          202 :       opts->x_flag_sanitize_trap
    2876          202 :         = parse_sanitizer_options (arg, loc, code,
    2877              :                                    opts->x_flag_sanitize_trap, value, true);
    2878          202 :       break;
    2879              : 
    2880              :     case OPT_fasan_shadow_offset_:
    2881              :       /* Deferred.  */
    2882              :       break;
    2883              : 
    2884           68 :     case OPT_fsanitize_address_use_after_scope:
    2885           68 :       opts->x_flag_sanitize_address_use_after_scope = value;
    2886           68 :       break;
    2887              : 
    2888            6 :     case OPT_fsanitize_recover:
    2889            6 :       if (value)
    2890            0 :         opts->x_flag_sanitize_recover
    2891            0 :           |= (SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT)
    2892              :              & ~(SANITIZE_UNREACHABLE | SANITIZE_RETURN);
    2893              :       else
    2894            6 :         opts->x_flag_sanitize_recover
    2895            6 :           &= ~(SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT);
    2896              :       break;
    2897              : 
    2898          238 :     case OPT_fsanitize_trap:
    2899          238 :       if (value)
    2900          238 :         opts->x_flag_sanitize_trap
    2901          238 :           |= (SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT);
    2902              :       else
    2903            0 :         opts->x_flag_sanitize_trap
    2904            0 :           &= ~(SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT);
    2905              :       break;
    2906              : 
    2907              :     case OPT_O:
    2908              :     case OPT_Os:
    2909              :     case OPT_Ofast:
    2910              :     case OPT_Og:
    2911              :     case OPT_Oz:
    2912              :       /* Currently handled in a prescan.  */
    2913              :       break;
    2914              : 
    2915          100 :     case OPT_Wattributes_:
    2916          100 :       if (lang_mask == CL_DRIVER)
    2917              :         break;
    2918              : 
    2919          100 :       if (value)
    2920              :         {
    2921            0 :           error_at (loc, "arguments ignored for %<-Wattributes=%>; use "
    2922              :                     "%<-Wno-attributes=%> instead");
    2923            0 :           break;
    2924              :         }
    2925          100 :       else if (arg[strlen (arg) - 1] == ',')
    2926              :         {
    2927            0 :           error_at (loc, "trailing %<,%> in arguments for "
    2928              :                     "%<-Wno-attributes=%>");
    2929            0 :           break;
    2930              :         }
    2931              : 
    2932          100 :       add_comma_separated_to_vector (&opts->x_flag_ignored_attributes, arg);
    2933          100 :       break;
    2934              : 
    2935         4353 :     case OPT_Werror:
    2936         4353 :       dc->set_warning_as_error_requested (value);
    2937         4353 :       break;
    2938              : 
    2939         7065 :     case OPT_Werror_:
    2940         7065 :       if (lang_mask == CL_DRIVER)
    2941              :         break;
    2942              : 
    2943         7065 :       enable_warning_as_error (arg, value, lang_mask, handlers,
    2944              :                                opts, opts_set, loc, dc);
    2945         7065 :       break;
    2946              : 
    2947            8 :     case OPT_Wfatal_errors:
    2948            8 :       dc->set_fatal_errors (value);
    2949            8 :       break;
    2950              : 
    2951           12 :     case OPT_Wstack_usage_:
    2952           12 :       opts->x_flag_stack_usage_info = value != -1;
    2953           12 :       break;
    2954              : 
    2955           57 :     case OPT_Wstrict_aliasing:
    2956           57 :       set_Wstrict_aliasing (opts, value);
    2957           57 :       break;
    2958              : 
    2959           37 :     case OPT_Wsystem_headers:
    2960           37 :       dc->m_warn_system_headers = value;
    2961           37 :       break;
    2962              : 
    2963            0 :     case OPT_aux_info:
    2964            0 :       opts->x_flag_gen_aux_info = 1;
    2965            0 :       break;
    2966              : 
    2967         1701 :     case OPT_d:
    2968         1701 :       decode_d_option (arg, opts, loc, dc);
    2969         1701 :       break;
    2970              : 
    2971              :     case OPT_fcall_used_:
    2972              :     case OPT_fcall_saved_:
    2973              :       /* Deferred.  */
    2974              :       break;
    2975              : 
    2976              :     case OPT_fdbg_cnt_:
    2977              :       /* Deferred.  */
    2978              :       break;
    2979              : 
    2980              :     case OPT_fdebug_prefix_map_:
    2981              :     case OPT_ffile_prefix_map_:
    2982              :     case OPT_fprofile_prefix_map_:
    2983              :       /* Deferred.  */
    2984              :       break;
    2985              : 
    2986            0 :     case OPT_fcanon_prefix_map:
    2987            0 :       flag_canon_prefix_map = value;
    2988            0 :       break;
    2989              : 
    2990            1 :     case OPT_fcallgraph_info:
    2991            1 :       opts->x_flag_callgraph_info = CALLGRAPH_INFO_NAKED;
    2992            1 :       break;
    2993              : 
    2994            0 :     case OPT_fcallgraph_info_:
    2995            0 :       {
    2996            0 :         char *my_arg, *p;
    2997            0 :         my_arg = xstrdup (arg);
    2998            0 :         p = strtok (my_arg, ",");
    2999            0 :         while (p)
    3000              :           {
    3001            0 :             if (strcmp (p, "su") == 0)
    3002              :               {
    3003            0 :                 opts->x_flag_callgraph_info |= CALLGRAPH_INFO_STACK_USAGE;
    3004            0 :                 opts->x_flag_stack_usage_info = true;
    3005              :               }
    3006            0 :             else if (strcmp (p, "da") == 0)
    3007            0 :               opts->x_flag_callgraph_info |= CALLGRAPH_INFO_DYNAMIC_ALLOC;
    3008              :             else
    3009              :               return 0;
    3010            0 :             p = strtok (NULL, ",");
    3011              :           }
    3012            0 :         free (my_arg);
    3013              :       }
    3014            0 :       break;
    3015              : 
    3016          432 :     case OPT_fdiagnostics_show_location_:
    3017          432 :       dc->set_prefixing_rule ((diagnostic_prefixing_rule_t) value);
    3018          432 :       break;
    3019              : 
    3020       272854 :     case OPT_fdiagnostics_show_caret:
    3021       272854 :       dc->get_source_printing_options ().enabled = value;
    3022       272854 :       break;
    3023              : 
    3024       272854 :     case OPT_fdiagnostics_show_event_links:
    3025       272854 :       dc->get_source_printing_options ().show_event_links_p = value;
    3026       272854 :       break;
    3027              : 
    3028            1 :     case OPT_fdiagnostics_show_labels:
    3029            1 :       dc->get_source_printing_options ().show_labels_p = value;
    3030            1 :       break;
    3031              : 
    3032       272854 :     case OPT_fdiagnostics_show_line_numbers:
    3033       272854 :       dc->get_source_printing_options ().show_line_numbers_p = value;
    3034       272854 :       break;
    3035              : 
    3036       549895 :     case OPT_fdiagnostics_color_:
    3037       549895 :       diagnostic_color_init (dc, value);
    3038       549895 :       break;
    3039              : 
    3040       538150 :     case OPT_fdiagnostics_urls_:
    3041       538150 :       diagnostic_urls_init (dc, value);
    3042       538150 :       break;
    3043              : 
    3044           90 :     case OPT_fdiagnostics_format_:
    3045           90 :         {
    3046           90 :           const char *basename = get_diagnostic_file_output_basename (*opts);
    3047           90 :           gcc_assert (dc);
    3048           90 :           diagnostics::output_format_init (*dc,
    3049              :                                            opts->x_main_input_filename, basename,
    3050              :                                            (enum diagnostics_output_format)value,
    3051           90 :                                            opts->x_flag_diagnostics_json_formatting);
    3052           90 :           break;
    3053              :         }
    3054              : 
    3055           36 :     case OPT_fdiagnostics_add_output_:
    3056           36 :       handle_OPT_fdiagnostics_add_output_ (*opts, *dc, arg, loc);
    3057           36 :       break;
    3058              : 
    3059           14 :     case OPT_fdiagnostics_set_output_:
    3060           14 :       handle_OPT_fdiagnostics_set_output_ (*opts, *dc, arg, loc);
    3061           14 :       break;
    3062              : 
    3063       599592 :     case OPT_fdiagnostics_text_art_charset_:
    3064       599592 :       dc->set_text_art_charset ((enum diagnostic_text_art_charset)value);
    3065       599592 :       break;
    3066              : 
    3067            4 :     case OPT_fdiagnostics_parseable_fixits:
    3068            4 :       dc->set_extra_output_kind (value
    3069              :                                  ? EXTRA_DIAGNOSTIC_OUTPUT_fixits_v1
    3070              :                                  : EXTRA_DIAGNOSTIC_OUTPUT_none);
    3071            4 :       break;
    3072              : 
    3073           28 :     case OPT_fdiagnostics_column_unit_:
    3074           28 :       dc->get_column_options ().m_column_unit
    3075           28 :         = (enum diagnostics_column_unit)value;
    3076           28 :       break;
    3077              : 
    3078           12 :     case OPT_fdiagnostics_column_origin_:
    3079           12 :       dc->get_column_options ().m_column_origin = value;
    3080           12 :       break;
    3081              : 
    3082            4 :     case OPT_fdiagnostics_escape_format_:
    3083            4 :       dc->set_escape_format ((enum diagnostics_escape_format)value);
    3084            4 :       break;
    3085              : 
    3086            5 :     case OPT_fdiagnostics_show_highlight_colors:
    3087            5 :       dc->set_show_highlight_colors (value);
    3088            5 :       break;
    3089              : 
    3090            0 :     case OPT_fdiagnostics_show_cwe:
    3091            0 :       dc->set_show_cwe (value);
    3092            0 :       break;
    3093              : 
    3094            0 :     case OPT_fdiagnostics_show_rules:
    3095            0 :       dc->set_show_rules (value);
    3096            0 :       break;
    3097              : 
    3098       303232 :     case OPT_fdiagnostics_path_format_:
    3099       303232 :       dc->set_path_format ((enum diagnostic_path_format)value);
    3100       303232 :       break;
    3101              : 
    3102           76 :     case OPT_fdiagnostics_show_path_depths:
    3103           76 :       dc->set_show_path_depths (value);
    3104           76 :       break;
    3105              : 
    3106           54 :     case OPT_fdiagnostics_show_option:
    3107           54 :       dc->set_show_option_requested (value);
    3108           54 :       break;
    3109              : 
    3110       272854 :     case OPT_fdiagnostics_show_nesting:
    3111       272854 :       dc->set_show_nesting (value);
    3112       272854 :       break;
    3113              : 
    3114            0 :     case OPT_fdiagnostics_show_nesting_locations:
    3115            0 :       dc->set_show_nesting_locations (value);
    3116            0 :       break;
    3117              : 
    3118            0 :     case OPT_fdiagnostics_show_nesting_levels:
    3119            0 :       dc->set_show_nesting_levels (value);
    3120            0 :       break;
    3121              : 
    3122            1 :     case OPT_fdiagnostics_minimum_margin_width_:
    3123            1 :       dc->get_source_printing_options ().min_margin_width = value;
    3124            1 :       break;
    3125              : 
    3126              :     case OPT_fdump_:
    3127              :       /* Deferred.  */
    3128              :       break;
    3129              : 
    3130       639462 :     case OPT_ffast_math:
    3131       639462 :       set_fast_math_flags (opts, value);
    3132       639462 :       break;
    3133              : 
    3134          366 :     case OPT_funsafe_math_optimizations:
    3135          366 :       set_unsafe_math_optimizations_flags (opts, value);
    3136          366 :       break;
    3137              : 
    3138              :     case OPT_ffixed_:
    3139              :       /* Deferred.  */
    3140              :       break;
    3141              : 
    3142            9 :     case OPT_finline_limit_:
    3143            9 :       SET_OPTION_IF_UNSET (opts, opts_set, param_max_inline_insns_single,
    3144              :                            value / 2);
    3145            9 :       SET_OPTION_IF_UNSET (opts, opts_set, param_max_inline_insns_auto,
    3146              :                            value / 2);
    3147              :       break;
    3148              : 
    3149            1 :     case OPT_finstrument_functions_exclude_function_list_:
    3150            1 :       add_comma_separated_to_vector
    3151            1 :         (&opts->x_flag_instrument_functions_exclude_functions, arg);
    3152            1 :       break;
    3153              : 
    3154            1 :     case OPT_finstrument_functions_exclude_file_list_:
    3155            1 :       add_comma_separated_to_vector
    3156            1 :         (&opts->x_flag_instrument_functions_exclude_files, arg);
    3157            1 :       break;
    3158              : 
    3159       107066 :     case OPT_fmessage_length_:
    3160       107066 :       pp_set_line_maximum_length (dc->get_reference_printer (), value);
    3161       107066 :       dc->set_caret_max_width (value);
    3162       107066 :       break;
    3163              : 
    3164              :     case OPT_fopt_info:
    3165              :     case OPT_fopt_info_:
    3166              :       /* Deferred.  */
    3167              :       break;
    3168              : 
    3169              :     case OPT_foffload_options_:
    3170              :       /* Deferred.  */
    3171              :       break;
    3172              : 
    3173            0 :     case OPT_foffload_abi_:
    3174            0 :     case OPT_foffload_abi_host_opts_:
    3175              : #ifdef ACCEL_COMPILER
    3176              :       /* Handled in the 'mkoffload's.  */
    3177              : #else
    3178            0 :       error_at (loc,
    3179              :                 "%qs option can be specified only for offload compiler",
    3180              :                 (code == OPT_foffload_abi_) ? "-foffload-abi"
    3181              :                                             : "-foffload-abi-host-opts");
    3182              : #endif
    3183            0 :       break;
    3184              : 
    3185            1 :     case OPT_fpack_struct_:
    3186            1 :       if (value <= 0 || (value & (value - 1)) || value > 16)
    3187            0 :         error_at (loc,
    3188              :                   "structure alignment must be a small power of two, not %wu",
    3189              :                   value);
    3190              :       else
    3191            1 :         opts->x_initial_max_fld_align = value;
    3192              :       break;
    3193              : 
    3194              :     case OPT_fplugin_:
    3195              :     case OPT_fplugin_arg_:
    3196              :       /* Deferred.  */
    3197              :       break;
    3198              : 
    3199            0 :     case OPT_fprofile_use_:
    3200            0 :       opts->x_profile_data_prefix = xstrdup (arg);
    3201            0 :       opts->x_flag_profile_use = true;
    3202            0 :       value = true;
    3203              :       /* No break here - do -fprofile-use processing. */
    3204              :       /* FALLTHRU */
    3205          154 :     case OPT_fprofile_use:
    3206          154 :       enable_fdo_optimizations (opts, opts_set, value, false);
    3207          154 :       SET_OPTION_IF_UNSET (opts, opts_set, flag_profile_reorder_functions,
    3208              :                            value);
    3209              :         /* Indirect call profiling should do all useful transformations
    3210              :            speculative devirtualization does.  */
    3211          154 :       if (opts->x_flag_value_profile_transformations)
    3212              :         {
    3213          154 :           SET_OPTION_IF_UNSET (opts, opts_set, flag_devirtualize_speculatively,
    3214              :                                false);
    3215          154 :           SET_OPTION_IF_UNSET (opts, opts_set,
    3216              :                                flag_speculatively_call_stored_functions, false);
    3217              :         }
    3218              :       break;
    3219              : 
    3220            0 :     case OPT_fauto_profile_:
    3221            0 :       opts->x_auto_profile_file = xstrdup (arg);
    3222            0 :       opts->x_flag_auto_profile = true;
    3223            0 :       value = true;
    3224              :       /* No break here - do -fauto-profile processing. */
    3225              :       /* FALLTHRU */
    3226            0 :     case OPT_fauto_profile:
    3227            0 :       enable_fdo_optimizations (opts, opts_set, value, true);
    3228            0 :       SET_OPTION_IF_UNSET (opts, opts_set, flag_profile_correction, value);
    3229              :       break;
    3230              : 
    3231            2 :     case OPT_fprofile_generate_:
    3232            2 :       opts->x_profile_data_prefix = xstrdup (arg);
    3233            2 :       value = true;
    3234              :       /* No break here - do -fprofile-generate processing. */
    3235              :       /* FALLTHRU */
    3236          257 :     case OPT_fprofile_generate:
    3237          257 :       SET_OPTION_IF_UNSET (opts, opts_set, profile_arc_flag, value);
    3238          257 :       SET_OPTION_IF_UNSET (opts, opts_set, flag_profile_values, value);
    3239          257 :       SET_OPTION_IF_UNSET (opts, opts_set, flag_inline_functions, value);
    3240          257 :       SET_OPTION_IF_UNSET (opts, opts_set, flag_ipa_bit_cp, value);
    3241              :       break;
    3242              : 
    3243            2 :     case OPT_fprofile_info_section:
    3244            2 :       opts->x_profile_info_section = ".gcov_info";
    3245            2 :       break;
    3246              : 
    3247           36 :     case OPT_fpatchable_function_entry_:
    3248           36 :       {
    3249           36 :         HOST_WIDE_INT patch_area_size, patch_area_start;
    3250           36 :         parse_and_check_patch_area (arg, true, &patch_area_size,
    3251              :                                     &patch_area_start);
    3252              :       }
    3253           36 :       break;
    3254              : 
    3255              :     case OPT_ftree_vectorize:
    3256              :       /* Automatically sets -ftree-loop-vectorize and
    3257              :          -ftree-slp-vectorize.  Nothing more to do here.  */
    3258              :       break;
    3259           78 :     case OPT_fzero_call_used_regs_:
    3260           78 :       opts->x_flag_zero_call_used_regs
    3261           78 :         = parse_zero_call_used_regs_options (arg);
    3262           78 :       break;
    3263              : 
    3264        13340 :     case OPT_fshow_column:
    3265        13340 :       dc->m_show_column = value;
    3266        13340 :       break;
    3267              : 
    3268            0 :     case OPT_frandom_seed:
    3269              :       /* The real switch is -fno-random-seed.  */
    3270            0 :       if (value)
    3271              :         return false;
    3272              :       /* Deferred.  */
    3273              :       break;
    3274              : 
    3275              :     case OPT_frandom_seed_:
    3276              :       /* Deferred.  */
    3277              :       break;
    3278              : 
    3279              :     case OPT_fsched_verbose_:
    3280              : #ifdef INSN_SCHEDULING
    3281              :       /* Handled with Var in common.opt.  */
    3282              :       break;
    3283              : #else
    3284              :       return false;
    3285              : #endif
    3286              : 
    3287            1 :     case OPT_fsched_stalled_insns_:
    3288            1 :       opts->x_flag_sched_stalled_insns = value;
    3289            1 :       if (opts->x_flag_sched_stalled_insns == 0)
    3290            1 :         opts->x_flag_sched_stalled_insns = -1;
    3291              :       break;
    3292              : 
    3293            0 :     case OPT_fsched_stalled_insns_dep_:
    3294            0 :       opts->x_flag_sched_stalled_insns_dep = value;
    3295            0 :       break;
    3296              : 
    3297           68 :     case OPT_fstack_check_:
    3298           68 :       if (!strcmp (arg, "no"))
    3299            0 :         opts->x_flag_stack_check = NO_STACK_CHECK;
    3300           68 :       else if (!strcmp (arg, "generic"))
    3301              :         /* This is the old stack checking method.  */
    3302           35 :         opts->x_flag_stack_check = STACK_CHECK_BUILTIN
    3303              :                            ? FULL_BUILTIN_STACK_CHECK
    3304              :                            : GENERIC_STACK_CHECK;
    3305           33 :       else if (!strcmp (arg, "specific"))
    3306              :         /* This is the new stack checking method.  */
    3307           33 :         opts->x_flag_stack_check = STACK_CHECK_BUILTIN
    3308              :                            ? FULL_BUILTIN_STACK_CHECK
    3309              :                            : STACK_CHECK_STATIC_BUILTIN
    3310              :                              ? STATIC_BUILTIN_STACK_CHECK
    3311              :                              : GENERIC_STACK_CHECK;
    3312              :       else
    3313            0 :         warning_at (loc, 0, "unknown stack check parameter %qs", arg);
    3314              :       break;
    3315              : 
    3316            1 :     case OPT_fstack_limit:
    3317              :       /* The real switch is -fno-stack-limit.  */
    3318            1 :       if (value)
    3319              :         return false;
    3320              :       /* Deferred.  */
    3321              :       break;
    3322              : 
    3323              :     case OPT_fstack_limit_register_:
    3324              :     case OPT_fstack_limit_symbol_:
    3325              :       /* Deferred.  */
    3326              :       break;
    3327              : 
    3328          558 :     case OPT_fstack_usage:
    3329          558 :       opts->x_flag_stack_usage = value;
    3330          558 :       opts->x_flag_stack_usage_info = value != 0;
    3331          558 :       break;
    3332              : 
    3333       128382 :     case OPT_g:
    3334       128382 :       set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, arg, opts, opts_set,
    3335              :                        loc);
    3336       128382 :       break;
    3337              : 
    3338            0 :     case OPT_gcodeview:
    3339            0 :       set_debug_level (CODEVIEW_DEBUG, false, arg, opts, opts_set, loc);
    3340            0 :       if (opts->x_debug_info_level < DINFO_LEVEL_NORMAL)
    3341            0 :         opts->x_debug_info_level = DINFO_LEVEL_NORMAL;
    3342              :       break;
    3343              : 
    3344          158 :     case OPT_gbtf:
    3345          158 :       set_debug_level (BTF_DEBUG, false, arg, opts, opts_set, loc);
    3346              :       /* set the debug level to level 2, but if already at level 3,
    3347              :          don't lower it.  */
    3348          158 :       if (opts->x_debug_info_level < DINFO_LEVEL_NORMAL)
    3349          158 :         opts->x_debug_info_level = DINFO_LEVEL_NORMAL;
    3350              :       break;
    3351              : 
    3352          505 :     case OPT_gctf:
    3353          505 :       set_debug_level (CTF_DEBUG, false, arg, opts, opts_set, loc);
    3354              :       /* CTF generation feeds off DWARF dies.  For optimal CTF, switch debug
    3355              :          info level to 2.  If off or at level 1, set it to level 2, but if
    3356              :          already at level 3, don't lower it.  */
    3357          505 :       if (opts->x_debug_info_level < DINFO_LEVEL_NORMAL
    3358          499 :           && opts->x_ctf_debug_info_level > CTFINFO_LEVEL_NONE)
    3359          497 :         opts->x_debug_info_level = DINFO_LEVEL_NORMAL;
    3360              :       break;
    3361              : 
    3362          249 :     case OPT_gdwarf:
    3363          249 :       if (arg && strlen (arg) != 0)
    3364              :         {
    3365            0 :           error_at (loc, "%<-gdwarf%s%> is ambiguous; "
    3366              :                     "use %<-gdwarf-%s%> for DWARF version "
    3367              :                     "or %<-gdwarf%> %<-g%s%> for debug level", arg, arg, arg);
    3368            0 :           break;
    3369              :         }
    3370              :       else
    3371          249 :         value = opts->x_dwarf_version;
    3372              : 
    3373              :       /* FALLTHRU */
    3374         4737 :     case OPT_gdwarf_:
    3375         4737 :       if (value < 2 || value > 5)
    3376            0 :         error_at (loc, "dwarf version %wu is not supported", value);
    3377              :       else
    3378         4737 :         opts->x_dwarf_version = value;
    3379         4737 :       set_debug_level (DWARF2_DEBUG, false, "", opts, opts_set, loc);
    3380         4737 :       break;
    3381              : 
    3382           20 :     case OPT_ggdb:
    3383           20 :       set_debug_level (NO_DEBUG, 2, arg, opts, opts_set, loc);
    3384           20 :       break;
    3385              : 
    3386            0 :     case OPT_gvms:
    3387            0 :       set_debug_level (VMS_DEBUG, false, arg, opts, opts_set, loc);
    3388            0 :       break;
    3389              : 
    3390              :     case OPT_gz:
    3391              :     case OPT_gz_:
    3392              :       /* Handled completely via specs.  */
    3393              :       break;
    3394              : 
    3395        66875 :     case OPT_pedantic_errors:
    3396        66875 :       dc->m_pedantic_errors = 1;
    3397        66875 :       control_warning_option (OPT_Wpedantic,
    3398              :                               static_cast<int> (diagnostics::kind::error),
    3399              :                               NULL, value,
    3400              :                               loc, lang_mask,
    3401              :                               handlers, opts, opts_set,
    3402              :                               dc);
    3403        66875 :       break;
    3404              : 
    3405        24659 :     case OPT_flto:
    3406        24659 :       opts->x_flag_lto = value ? "" : NULL;
    3407        24659 :       break;
    3408              : 
    3409           13 :     case OPT_flto_:
    3410           13 :       if (strcmp (arg, "none") != 0
    3411           13 :           && strcmp (arg, "jobserver") != 0
    3412           13 :           && strcmp (arg, "auto") != 0
    3413            1 :           && atoi (arg) == 0)
    3414            1 :         error_at (loc,
    3415              :                   "unrecognized argument to %<-flto=%> option: %qs", arg);
    3416              :       break;
    3417              : 
    3418        44417 :     case OPT_w:
    3419        44417 :       dc->m_inhibit_warnings = true;
    3420        44417 :       break;
    3421              : 
    3422           44 :     case OPT_fmax_errors_:
    3423           44 :       dc->set_max_errors (value);
    3424           44 :       break;
    3425              : 
    3426              :     case OPT_fuse_ld_bfd:
    3427              :     case OPT_fuse_ld_gold:
    3428              :     case OPT_fuse_ld_lld:
    3429              :     case OPT_fuse_ld_mold:
    3430              :     case OPT_fuse_ld_wild:
    3431              :     case OPT_fuse_linker_plugin:
    3432              :       /* No-op. Used by the driver and passed to us because it starts with f.*/
    3433              :       break;
    3434              : 
    3435          510 :     case OPT_fwrapv:
    3436          510 :       if (value)
    3437          504 :         opts->x_flag_trapv = 0;
    3438              :       break;
    3439              : 
    3440          134 :     case OPT_ftrapv:
    3441          134 :       if (value)
    3442          134 :         opts->x_flag_wrapv = 0;
    3443              :       break;
    3444              : 
    3445          192 :     case OPT_fstrict_overflow:
    3446          192 :       opts->x_flag_wrapv = !value;
    3447          192 :       opts->x_flag_wrapv_pointer = !value;
    3448          192 :       if (!value)
    3449           62 :         opts->x_flag_trapv = 0;
    3450              :       break;
    3451              : 
    3452       638496 :     case OPT_fipa_icf:
    3453       638496 :       opts->x_flag_ipa_icf_functions = value;
    3454       638496 :       opts->x_flag_ipa_icf_variables = value;
    3455       638496 :       break;
    3456              : 
    3457            2 :     case OPT_falign_loops_:
    3458            2 :       check_alignment_argument (loc, arg, "loops",
    3459              :                                 &opts->x_flag_align_loops,
    3460              :                                 &opts->x_str_align_loops);
    3461            2 :       break;
    3462              : 
    3463            2 :     case OPT_falign_jumps_:
    3464            2 :       check_alignment_argument (loc, arg, "jumps",
    3465              :                                 &opts->x_flag_align_jumps,
    3466              :                                 &opts->x_str_align_jumps);
    3467            2 :       break;
    3468              : 
    3469            3 :     case OPT_falign_labels_:
    3470            3 :       check_alignment_argument (loc, arg, "labels",
    3471              :                                 &opts->x_flag_align_labels,
    3472              :                                 &opts->x_str_align_labels);
    3473            3 :       break;
    3474              : 
    3475           13 :     case OPT_falign_functions_:
    3476           13 :       check_alignment_argument (loc, arg, "functions",
    3477              :                                 &opts->x_flag_align_functions,
    3478              :                                 &opts->x_str_align_functions);
    3479           13 :       break;
    3480              : 
    3481           12 :     case OPT_ftabstop_:
    3482              :       /* It is documented that we silently ignore silly values.  */
    3483           12 :       if (value >= 1 && value <= 100)
    3484            8 :         dc->get_column_options ().m_tabstop = value;
    3485              :       break;
    3486              : 
    3487           16 :     case OPT_freport_bug:
    3488           16 :       dc->set_report_bug (value);
    3489           16 :       break;
    3490              : 
    3491            0 :     case OPT_fmultiflags:
    3492            0 :       gcc_checking_assert (lang_mask == CL_DRIVER);
    3493              :       break;
    3494              : 
    3495     76415521 :     default:
    3496              :       /* If the flag was handled in a standard way, assume the lack of
    3497              :          processing here is intentional.  */
    3498     76415521 :       gcc_assert (option_flag_var (scode, opts));
    3499              :       break;
    3500              :     }
    3501              : 
    3502     82524071 :   common_handle_option_auto (opts, opts_set, decoded, lang_mask, kind,
    3503              :                              loc, handlers, dc);
    3504     82524071 :   return true;
    3505              : }
    3506              : 
    3507              : /* Used to set the level of strict aliasing warnings in OPTS,
    3508              :    when no level is specified (i.e., when -Wstrict-aliasing, and not
    3509              :    -Wstrict-aliasing=level was given).
    3510              :    ONOFF is assumed to take value 1 when -Wstrict-aliasing is specified,
    3511              :    and 0 otherwise.  After calling this function, wstrict_aliasing will be
    3512              :    set to the default value of -Wstrict_aliasing=level, currently 3.  */
    3513              : static void
    3514           57 : set_Wstrict_aliasing (struct gcc_options *opts, int onoff)
    3515              : {
    3516           57 :   gcc_assert (onoff == 0 || onoff == 1);
    3517           57 :   if (onoff != 0)
    3518           56 :     opts->x_warn_strict_aliasing = 3;
    3519              :   else
    3520            1 :     opts->x_warn_strict_aliasing = 0;
    3521           57 : }
    3522              : 
    3523              : /* The following routines are useful in setting all the flags that
    3524              :    -ffast-math and -fno-fast-math imply.  */
    3525              : static void
    3526       639462 : set_fast_math_flags (struct gcc_options *opts, int set)
    3527              : {
    3528       639462 :   if (!opts->frontend_set_flag_unsafe_math_optimizations)
    3529              :     {
    3530       639462 :       opts->x_flag_unsafe_math_optimizations = set;
    3531       639462 :       set_unsafe_math_optimizations_flags (opts, set);
    3532              :     }
    3533       639462 :   if (!opts->frontend_set_flag_finite_math_only)
    3534       639462 :     opts->x_flag_finite_math_only = set;
    3535       639462 :   if (!opts->frontend_set_flag_errno_math)
    3536       585979 :     opts->x_flag_errno_math = !set;
    3537       639462 :   if (set)
    3538              :     {
    3539         2018 :       if (opts->frontend_set_flag_excess_precision == EXCESS_PRECISION_DEFAULT)
    3540         2018 :         opts->x_flag_excess_precision
    3541         2018 :           = set ? EXCESS_PRECISION_FAST : EXCESS_PRECISION_DEFAULT;
    3542         2018 :       if (!opts->frontend_set_flag_signaling_nans)
    3543         2018 :         opts->x_flag_signaling_nans = 0;
    3544         2018 :       if (!opts->frontend_set_flag_rounding_math)
    3545         2018 :         opts->x_flag_rounding_math = 0;
    3546         2018 :       if (!opts->frontend_set_flag_complex_method)
    3547         2018 :         opts->x_flag_complex_method = 0;
    3548              :     }
    3549       639462 : }
    3550              : 
    3551              : /* When -funsafe-math-optimizations is set the following
    3552              :    flags are set as well.  */
    3553              : static void
    3554       639828 : set_unsafe_math_optimizations_flags (struct gcc_options *opts, int set)
    3555              : {
    3556       639828 :   if (!opts->frontend_set_flag_trapping_math)
    3557       639828 :     opts->x_flag_trapping_math = !set;
    3558       639828 :   if (!opts->frontend_set_flag_signed_zeros)
    3559       639828 :     opts->x_flag_signed_zeros = !set;
    3560       639828 :   if (!opts->frontend_set_flag_associative_math)
    3561       607602 :     opts->x_flag_associative_math = set;
    3562       639828 :   if (!opts->frontend_set_flag_reciprocal_math)
    3563       639828 :     opts->x_flag_reciprocal_math = set;
    3564       639828 : }
    3565              : 
    3566              : /* Return true iff flags in OPTS are set as if -ffast-math.  */
    3567              : bool
    3568     47538231 : fast_math_flags_set_p (const struct gcc_options *opts)
    3569              : {
    3570     47538231 :   return (!opts->x_flag_trapping_math
    3571       963594 :           && opts->x_flag_unsafe_math_optimizations
    3572       956275 :           && opts->x_flag_finite_math_only
    3573       956211 :           && !opts->x_flag_signed_zeros
    3574       956197 :           && !opts->x_flag_errno_math
    3575     48494424 :           && opts->x_flag_excess_precision == EXCESS_PRECISION_FAST);
    3576              : }
    3577              : 
    3578              : /* Return true iff flags are set as if -ffast-math but using the flags stored
    3579              :    in the struct cl_optimization structure.  */
    3580              : bool
    3581         1268 : fast_math_flags_struct_set_p (struct cl_optimization *opt)
    3582              : {
    3583         1268 :   return (!opt->x_flag_trapping_math
    3584           39 :           && opt->x_flag_unsafe_math_optimizations
    3585           19 :           && opt->x_flag_finite_math_only
    3586           19 :           && !opt->x_flag_signed_zeros
    3587         1287 :           && !opt->x_flag_errno_math);
    3588              : }
    3589              : 
    3590              : /* Handle a debug output -g switch for options OPTS
    3591              :    (OPTS_SET->x_write_symbols storing whether a debug format was passed
    3592              :    explicitly), location LOC.  EXTENDED is true or false to support
    3593              :    extended output (2 is special and means "-ggdb" was given).  */
    3594              : static void
    3595       133802 : set_debug_level (uint32_t dinfo, int extended, const char *arg,
    3596              :                  struct gcc_options *opts, struct gcc_options *opts_set,
    3597              :                  location_t loc)
    3598              : {
    3599       133802 :   if (dinfo == NO_DEBUG)
    3600              :     {
    3601       128402 :       if (opts->x_write_symbols == NO_DEBUG)
    3602              :         {
    3603       112281 :           opts->x_write_symbols = PREFERRED_DEBUGGING_TYPE;
    3604              : 
    3605       112281 :           if (extended == 2)
    3606              :             {
    3607              : #if defined DWARF2_DEBUGGING_INFO || defined DWARF2_LINENO_DEBUGGING_INFO
    3608       112281 :               if (opts->x_write_symbols & CTF_DEBUG)
    3609              :                 opts->x_write_symbols |= DWARF2_DEBUG;
    3610              :               else
    3611       112281 :                 opts->x_write_symbols = DWARF2_DEBUG;
    3612              : #endif
    3613              :             }
    3614              : 
    3615       112281 :           if (opts->x_write_symbols == NO_DEBUG)
    3616              :             warning_at (loc, 0, "target system does not support debug output");
    3617              :         }
    3618        16121 :       else if ((opts->x_write_symbols & CTF_DEBUG)
    3619        16087 :                || (opts->x_write_symbols & BTF_DEBUG)
    3620        16087 :                || (opts->x_write_symbols & CODEVIEW_DEBUG))
    3621              :         {
    3622           34 :           opts->x_write_symbols |= DWARF2_DEBUG;
    3623           34 :           opts_set->x_write_symbols |= DWARF2_DEBUG;
    3624              :         }
    3625              :     }
    3626              :   else
    3627              :     {
    3628              :       /* Make and retain the choice if both CTF and DWARF debug info are to
    3629              :          be generated.  */
    3630         5400 :       if (((dinfo == DWARF2_DEBUG) || (dinfo == CTF_DEBUG))
    3631         5242 :           && ((opts->x_write_symbols == (DWARF2_DEBUG|CTF_DEBUG))
    3632              :               || (opts->x_write_symbols == DWARF2_DEBUG)
    3633              :               || (opts->x_write_symbols == CTF_DEBUG)))
    3634              :         {
    3635          122 :           opts->x_write_symbols |= dinfo;
    3636          122 :           opts_set->x_write_symbols |= dinfo;
    3637              :         }
    3638              :       /* However, CTF and BTF are not allowed together at this time.  */
    3639         5278 :       else if (((dinfo == DWARF2_DEBUG) || (dinfo == BTF_DEBUG))
    3640         4779 :                && ((opts->x_write_symbols == (DWARF2_DEBUG|BTF_DEBUG))
    3641              :                    || (opts->x_write_symbols == DWARF2_DEBUG)
    3642              :                    || (opts->x_write_symbols == BTF_DEBUG)))
    3643              :         {
    3644            0 :           opts->x_write_symbols |= dinfo;
    3645            0 :           opts_set->x_write_symbols |= dinfo;
    3646              :         }
    3647              :       else
    3648              :         {
    3649              :           /* Does it conflict with an already selected debug format?  */
    3650         5278 :           if (opts_set->x_write_symbols != NO_DEBUG
    3651            0 :               && opts->x_write_symbols != NO_DEBUG
    3652            0 :               && dinfo != opts->x_write_symbols)
    3653              :             {
    3654            0 :               gcc_assert (debug_set_count (dinfo) <= 1);
    3655            0 :               error_at (loc, "debug format %qs conflicts with prior selection",
    3656            0 :                         debug_type_names[debug_set_to_format (dinfo)]);
    3657              :             }
    3658         5278 :           opts->x_write_symbols = dinfo;
    3659         5278 :           opts_set->x_write_symbols = dinfo;
    3660              :         }
    3661              :     }
    3662              : 
    3663       133802 :   if (dinfo != BTF_DEBUG)
    3664              :     {
    3665              :       /* A debug flag without a level defaults to level 2.
    3666              :          If off or at level 1, set it to level 2, but if already
    3667              :          at level 3, don't lower it.  */
    3668       133644 :       if (*arg == '\0')
    3669              :         {
    3670       128247 :           if (dinfo == CTF_DEBUG)
    3671          503 :             opts->x_ctf_debug_info_level = CTFINFO_LEVEL_NORMAL;
    3672       127744 :           else if (opts->x_debug_info_level < DINFO_LEVEL_NORMAL)
    3673       114145 :             opts->x_debug_info_level = DINFO_LEVEL_NORMAL;
    3674              :         }
    3675              :       else
    3676              :         {
    3677         5397 :           int argval = integral_argument (arg);
    3678         5397 :           if (argval == -1)
    3679            0 :             error_at (loc, "unrecognized debug output level %qs", arg);
    3680         5397 :           else if (argval > 3)
    3681            0 :             error_at (loc, "debug output level %qs is too high", arg);
    3682              :           else
    3683              :             {
    3684         5397 :               if (dinfo == CTF_DEBUG)
    3685            2 :                 opts->x_ctf_debug_info_level
    3686            2 :                   = (enum ctf_debug_info_levels) argval;
    3687              :               else
    3688         5395 :                 opts->x_debug_info_level = (enum debug_info_levels) argval;
    3689              :             }
    3690              :         }
    3691              :     }
    3692          158 :   else if (*arg != '\0')
    3693            0 :     error_at (loc, "unrecognized btf debug output level %qs", arg);
    3694       133802 : }
    3695              : 
    3696              : /* Arrange to dump core on error for diagnostic context DC.  (The
    3697              :    regular error message is still printed first, except in the case of
    3698              :    abort ().)  */
    3699              : 
    3700              : static void
    3701           13 : setup_core_dumping (diagnostics::context *dc)
    3702              : {
    3703              : #ifdef SIGABRT
    3704           13 :   signal (SIGABRT, SIG_DFL);
    3705              : #endif
    3706              : #if defined(HAVE_SETRLIMIT)
    3707           13 :   {
    3708           13 :     struct rlimit rlim;
    3709           13 :     if (getrlimit (RLIMIT_CORE, &rlim) != 0)
    3710            0 :       fatal_error (input_location, "getting core file size maximum limit: %m");
    3711           13 :     rlim.rlim_cur = rlim.rlim_max;
    3712           13 :     if (setrlimit (RLIMIT_CORE, &rlim) != 0)
    3713            0 :       fatal_error (input_location,
    3714              :                    "setting core file size limit to maximum: %m");
    3715              :   }
    3716              : #endif
    3717           13 :   dc->set_abort_on_error (true);
    3718           13 : }
    3719              : 
    3720              : /* Parse a -d<ARG> command line switch for OPTS, location LOC,
    3721              :    diagnostic context DC.  */
    3722              : 
    3723              : static void
    3724         1701 : decode_d_option (const char *arg, struct gcc_options *opts,
    3725              :                  location_t loc, diagnostics::context *dc)
    3726              : {
    3727         1701 :   int c;
    3728              : 
    3729         3402 :   while (*arg)
    3730         1701 :     switch (c = *arg++)
    3731              :       {
    3732          703 :       case 'A':
    3733          703 :         opts->x_flag_debug_asm = 1;
    3734          703 :         break;
    3735          123 :       case 'p':
    3736          123 :         opts->x_flag_print_asm_name = 1;
    3737          123 :         break;
    3738            5 :       case 'P':
    3739            5 :         opts->x_flag_dump_rtl_in_asm = 1;
    3740            5 :         opts->x_flag_print_asm_name = 1;
    3741            5 :         break;
    3742           10 :       case 'x':
    3743           10 :         opts->x_rtl_dump_and_exit = 1;
    3744           10 :         break;
    3745              :       case 'D': /* These are handled by the preprocessor.  */
    3746              :       case 'I':
    3747              :       case 'M':
    3748              :       case 'N':
    3749              :       case 'U':
    3750              :         break;
    3751           13 :       case 'H':
    3752           13 :         setup_core_dumping (dc);
    3753           13 :         break;
    3754            4 :       case 'a':
    3755            4 :         opts->x_flag_dump_all_passed = true;
    3756            4 :         break;
    3757              : 
    3758            0 :       default:
    3759            0 :           warning_at (loc, 0, "unrecognized gcc debugging option: %c", c);
    3760            0 :         break;
    3761              :       }
    3762         1701 : }
    3763              : 
    3764              : /* Enable (or disable if VALUE is 0) a warning option ARG (language
    3765              :    mask LANG_MASK, option handlers HANDLERS) as an error for option
    3766              :    structures OPTS and OPTS_SET, diagnostic context DC (possibly
    3767              :    NULL), location LOC.  This is used by -Werror=.  */
    3768              : 
    3769              : static void
    3770         7065 : enable_warning_as_error (const char *arg, int value, unsigned int lang_mask,
    3771              :                          const struct cl_option_handlers *handlers,
    3772              :                          struct gcc_options *opts,
    3773              :                          struct gcc_options *opts_set,
    3774              :                          location_t loc, diagnostics::context *dc)
    3775              : {
    3776         7065 :   char *new_option;
    3777         7065 :   int option_index;
    3778              : 
    3779         7065 :   new_option = XNEWVEC (char, strlen (arg) + 2);
    3780         7065 :   new_option[0] = 'W';
    3781         7065 :   strcpy (new_option + 1, arg);
    3782         7065 :   option_index = find_opt (new_option, lang_mask);
    3783         7065 :   if (option_index == OPT_SPECIAL_unknown)
    3784              :     {
    3785            2 :       option_proposer op;
    3786            2 :       const char *hint = op.suggest_option (new_option);
    3787            2 :       if (hint)
    3788            3 :         error_at (loc, "%<-W%serror=%s%>: no option %<-%s%>;"
    3789              :                   " did you mean %<-%s%>?", value ? "" : "no-",
    3790              :                   arg, new_option, hint);
    3791              :       else
    3792            0 :         error_at (loc, "%<-W%serror=%s%>: no option %<-%s%>",
    3793              :                   value ? "" : "no-", arg, new_option);
    3794            2 :     }
    3795         7063 :   else if (!(cl_options[option_index].flags & CL_WARNING))
    3796            4 :     error_at (loc, "%<-Werror=%s%>: %<-%s%> is not an option that "
    3797              :               "controls warnings", arg, new_option);
    3798              :   else
    3799              :     {
    3800         1113 :       const enum diagnostics::kind kind = (value
    3801         7059 :                                            ? diagnostics::kind::error
    3802              :                                            : diagnostics::kind::warning);
    3803         7059 :       const char *arg = NULL;
    3804              : 
    3805         7059 :       if (cl_options[option_index].flags & CL_JOINED)
    3806           17 :         arg = new_option + cl_options[option_index].opt_len;
    3807         7059 :       control_warning_option (option_index, (int) kind, arg, value,
    3808              :                               loc, lang_mask,
    3809              :                               handlers, opts, opts_set, dc);
    3810              :     }
    3811         7065 :   free (new_option);
    3812         7065 : }
    3813              : 
    3814              : /* Return the name of the option OPTION_INDEX which enabled a diagnostic,
    3815              :    originally of type ORIG_DIAG_KIND but possibly converted to DIAG_KIND by
    3816              :    options such as -Werror.   Can return null if OPTION_ID is zero.  */
    3817              : 
    3818              : label_text
    3819      1609173 : compiler_diagnostic_option_id_manager::
    3820              : get_option_name (diagnostics::option_id option_id,
    3821              :                  enum diagnostics::kind orig_diag_kind,
    3822              :                  enum diagnostics::kind diag_kind) const
    3823              : {
    3824      1609173 :   if (option_id.m_idx)
    3825              :     {
    3826              :       /* A warning classified as an error.  */
    3827        94749 :       if ((orig_diag_kind == diagnostics::kind::warning
    3828        94749 :            || orig_diag_kind == diagnostics::kind::pedwarn)
    3829        79702 :           && diag_kind == diagnostics::kind::error)
    3830          216 :         return label_text::take
    3831          216 :           (concat (cl_options[OPT_Werror_].opt_text,
    3832              :                    /* Skip over "-W".  */
    3833          216 :                    cl_options[option_id.m_idx].opt_text + 2,
    3834          216 :                    NULL));
    3835              :       /* A warning with option.  */
    3836              :       else
    3837        94533 :         return label_text::take
    3838        94533 :           (xstrdup (cl_options[option_id.m_idx].opt_text));
    3839              :     }
    3840              :   /* A warning without option classified as an error.  */
    3841      1514424 :   else if ((orig_diag_kind == diagnostics::kind::warning
    3842      1514424 :             || orig_diag_kind == diagnostics::kind::pedwarn
    3843      1483366 :             || diag_kind == diagnostics::kind::warning)
    3844      1514424 :            && m_context.warning_as_error_requested_p ())
    3845          102 :     return label_text::borrow (cl_options[OPT_Werror].opt_text);
    3846              :   else
    3847      1514322 :     return label_text ();
    3848              : }
    3849              : 
    3850              : /* Get the page within the documentation for this option.  */
    3851              : 
    3852              : static const char *
    3853        12329 : get_option_html_page (int option_index)
    3854              : {
    3855        12329 :   const cl_option *cl_opt = &cl_options[option_index];
    3856              : 
    3857              : #ifdef CL_Fortran
    3858        12329 :   if ((cl_opt->flags & CL_Fortran) != 0
    3859              :       /* If it is option common to both C/C++ and Fortran, it is documented
    3860              :          in gcc/ rather than gfortran/ docs.  */
    3861           90 :       && (cl_opt->flags & CL_C) == 0
    3862              : #ifdef CL_CXX
    3863           80 :       && (cl_opt->flags & CL_CXX) == 0
    3864              : #endif
    3865              :      )
    3866           80 :     return "gfortran/Error-and-Warning-Options.html";
    3867              : #endif
    3868              : 
    3869              :   return nullptr;
    3870              : }
    3871              : 
    3872              : /* Get the url within the documentation for this option, or NULL.  */
    3873              : 
    3874              : label_text
    3875        26530 : get_option_url_suffix (int option_index, unsigned lang_mask)
    3876              : {
    3877        26530 :   if (const char *url = get_opt_url_suffix (option_index, lang_mask))
    3878              : 
    3879        14201 :     return label_text::borrow (url);
    3880              : 
    3881              :   /* Fallback code for some options that aren't handled byt opt_url_suffixes
    3882              :      e.g. links below "gfortran/".  */
    3883        12329 :   if (const char *html_page = get_option_html_page (option_index))
    3884           80 :     return label_text::take
    3885              :       (concat (html_page,
    3886              :                /* Expect an anchor of the form "index-Wfoo" e.g.
    3887              :                   <a name="index-Wformat"></a>, and thus an id within
    3888              :                   the page of "#index-Wformat".  */
    3889              :                "#index",
    3890           80 :                cl_options[option_index].opt_text,
    3891           80 :                NULL));
    3892              : 
    3893        12249 :   return label_text ();
    3894              : }
    3895              : 
    3896              : /* Return a URL describing the option OPTION_INDEX which enabled
    3897              :    a diagnostic, or null.  */
    3898              : 
    3899              : label_text
    3900          123 : gcc_diagnostic_option_id_manager::
    3901              : get_option_url (diagnostics::option_id option_id) const
    3902              : {
    3903          123 :   if (option_id.m_idx)
    3904              :     {
    3905          123 :       label_text url_suffix = get_option_url_suffix (option_id.m_idx,
    3906          123 :                                                      m_lang_mask);
    3907          123 :       if (url_suffix.get ())
    3908          123 :         return label_text::take
    3909          123 :           (concat (DOCUMENTATION_ROOT_URL, url_suffix.get (), nullptr));
    3910          123 :     }
    3911              : 
    3912            0 :   return label_text ();
    3913              : }
    3914              : 
    3915              : /* Return a heap allocated producer with command line options.  */
    3916              : 
    3917              : char *
    3918        53548 : gen_command_line_string (cl_decoded_option *options,
    3919              :                          unsigned int options_count)
    3920              : {
    3921        53548 :   auto_vec<const char *> switches;
    3922        53548 :   char *options_string, *tail;
    3923        53548 :   const char *p;
    3924        53548 :   size_t len = 0;
    3925              : 
    3926      1864782 :   for (unsigned i = 0; i < options_count; i++)
    3927      1811234 :     switch (options[i].opt_index)
    3928              :       {
    3929       813205 :       case OPT_o:
    3930       813205 :       case OPT_d:
    3931       813205 :       case OPT_dumpbase:
    3932       813205 :       case OPT_dumpbase_ext:
    3933       813205 :       case OPT_dumpdir:
    3934       813205 :       case OPT_quiet:
    3935       813205 :       case OPT_version:
    3936       813205 :       case OPT_v:
    3937       813205 :       case OPT_w:
    3938       813205 :       case OPT_L:
    3939       813205 :       case OPT_I:
    3940       813205 :       case OPT_SPECIAL_unknown:
    3941       813205 :       case OPT_SPECIAL_ignore:
    3942       813205 :       case OPT_SPECIAL_warn_removed:
    3943       813205 :       case OPT_SPECIAL_program_name:
    3944       813205 :       case OPT_SPECIAL_input_file:
    3945       813205 :       case OPT_grecord_gcc_switches:
    3946       813205 :       case OPT_frecord_gcc_switches:
    3947       813205 :       case OPT__output_pch:
    3948       813205 :       case OPT_fdiagnostics_show_highlight_colors:
    3949       813205 :       case OPT_fdiagnostics_show_location_:
    3950       813205 :       case OPT_fdiagnostics_show_option:
    3951       813205 :       case OPT_fdiagnostics_show_caret:
    3952       813205 :       case OPT_fdiagnostics_show_event_links:
    3953       813205 :       case OPT_fdiagnostics_show_labels:
    3954       813205 :       case OPT_fdiagnostics_show_line_numbers:
    3955       813205 :       case OPT_fdiagnostics_color_:
    3956       813205 :       case OPT_fdiagnostics_format_:
    3957       813205 :       case OPT_fdiagnostics_show_nesting:
    3958       813205 :       case OPT_fdiagnostics_show_nesting_locations:
    3959       813205 :       case OPT_fdiagnostics_show_nesting_levels:
    3960       813205 :       case OPT_fverbose_asm:
    3961       813205 :       case OPT____:
    3962       813205 :       case OPT__sysroot_:
    3963       813205 :       case OPT_nostdinc:
    3964       813205 :       case OPT_nostdinc__:
    3965       813205 :       case OPT_fpreprocessed:
    3966       813205 :       case OPT_fltrans_output_list_:
    3967       813205 :       case OPT_fresolution_:
    3968       813205 :       case OPT_fdebug_prefix_map_:
    3969       813205 :       case OPT_fmacro_prefix_map_:
    3970       813205 :       case OPT_ffile_prefix_map_:
    3971       813205 :       case OPT_fprofile_prefix_map_:
    3972       813205 :       case OPT_fcanon_prefix_map:
    3973       813205 :       case OPT_fcompare_debug:
    3974       813205 :       case OPT_fchecking:
    3975       813205 :       case OPT_fchecking_:
    3976              :         /* Ignore these.  */
    3977       813205 :         continue;
    3978        68679 :       case OPT_D:
    3979        68679 :       case OPT_U:
    3980        68679 :         if (startswith (options[i].arg, "_FORTIFY_SOURCE")
    3981        68679 :             && (options[i].arg[sizeof ("_FORTIFY_SOURCE") - 1] == '\0'
    3982            0 :                 || (options[i].opt_index == OPT_D
    3983            0 :                     && options[i].arg[sizeof ("_FORTIFY_SOURCE") - 1] == '=')))
    3984              :           {
    3985            0 :             switches.safe_push (options[i].orig_option_with_args_text);
    3986            0 :             len += strlen (options[i].orig_option_with_args_text) + 1;
    3987              :           }
    3988              :         /* Otherwise ignore these. */
    3989        68679 :         continue;
    3990            0 :       case OPT_flto_:
    3991            0 :         {
    3992            0 :           const char *lto_canonical = "-flto";
    3993            0 :           switches.safe_push (lto_canonical);
    3994            0 :           len += strlen (lto_canonical) + 1;
    3995            0 :           break;
    3996              :         }
    3997       929350 :       default:
    3998       930130 :         if (cl_options[options[i].opt_index].flags
    3999       929350 :             & CL_NO_DWARF_RECORD)
    4000          780 :           continue;
    4001       928570 :         gcc_checking_assert (options[i].canonical_option[0][0] == '-');
    4002       928570 :         switch (options[i].canonical_option[0][1])
    4003              :           {
    4004       276762 :           case 'M':
    4005       276762 :           case 'i':
    4006       276762 :           case 'W':
    4007       276762 :             continue;
    4008       370508 :           case 'f':
    4009       370508 :             if (strncmp (options[i].canonical_option[0] + 2,
    4010              :                          "dump", 4) == 0)
    4011         1808 :               continue;
    4012              :             break;
    4013              :           default:
    4014              :             break;
    4015              :           }
    4016       650000 :         switches.safe_push (options[i].orig_option_with_args_text);
    4017       650000 :         len += strlen (options[i].orig_option_with_args_text) + 1;
    4018       650000 :         break;
    4019       881884 :       }
    4020              : 
    4021        53548 :   options_string = XNEWVEC (char, len + 1);
    4022        53548 :   tail = options_string;
    4023              : 
    4024        53548 :   unsigned i;
    4025       757096 :   FOR_EACH_VEC_ELT (switches, i, p)
    4026              :     {
    4027       650000 :       len = strlen (p);
    4028       650000 :       memcpy (tail, p, len);
    4029       650000 :       tail += len;
    4030       650000 :       if (i != switches.length () - 1)
    4031              :         {
    4032       596452 :           *tail = ' ';
    4033       596452 :           ++tail;
    4034              :         }
    4035              :     }
    4036              : 
    4037        53548 :   *tail = '\0';
    4038        53548 :   return options_string;
    4039        53548 : }
    4040              : 
    4041              : /* Return a heap allocated producer string including command line options.  */
    4042              : 
    4043              : char *
    4044        53537 : gen_producer_string (const char *language_string, cl_decoded_option *options,
    4045              :                      unsigned int options_count)
    4046              : {
    4047        53537 :   char *cmdline = gen_command_line_string (options, options_count);
    4048        53537 :   char *combined = concat (language_string, " ", version_string, " ",
    4049              :                            cmdline, NULL);
    4050        53537 :   free (cmdline);
    4051        53537 :   return combined;
    4052              : }
    4053              : 
    4054              : #if CHECKING_P
    4055              : 
    4056              : namespace selftest {
    4057              : 
    4058              : /* Verify that get_option_url_suffix works as expected.  */
    4059              : 
    4060              : static void
    4061            4 : test_get_option_url_suffix ()
    4062              : {
    4063            4 :   ASSERT_STREQ (get_option_url_suffix (OPT_Wcpp, 0).get (),
    4064              :                 "gcc/Warning-Options.html#index-Wcpp");
    4065            4 :   ASSERT_STREQ (get_option_url_suffix (OPT_Wanalyzer_double_free, 0).get (),
    4066              :                 "gcc/Static-Analyzer-Options.html#index-Wanalyzer-double-free");
    4067              : 
    4068              :   /* Test of a D-specific option.  */
    4069              : #ifdef CL_D
    4070            4 :   ASSERT_EQ (get_option_url_suffix (OPT_fbounds_check_, 0).get (), nullptr);
    4071            4 :   ASSERT_STREQ (get_option_url_suffix (OPT_fbounds_check_, CL_D).get (),
    4072              :                 "gdc/Runtime-Options.html#index-fbounds-check");
    4073              : 
    4074              :   /* Test of a D-specific override to an option URL.  */
    4075              :   /* Generic URL.  */
    4076            4 :   ASSERT_STREQ (get_option_url_suffix (OPT_fmax_errors_, 0).get (),
    4077              :                 "gcc/Warning-Options.html#index-fmax-errors");
    4078              :   /* D-specific URL.  */
    4079            4 :   ASSERT_STREQ (get_option_url_suffix (OPT_fmax_errors_, CL_D).get (),
    4080              :                 "gdc/Warnings.html#index-fmax-errors");
    4081              : #endif
    4082              : 
    4083              : #ifdef CL_Fortran
    4084            4 :   ASSERT_STREQ
    4085              :     (get_option_url_suffix (OPT_Wline_truncation, CL_Fortran).get (),
    4086              :      "gfortran/Error-and-Warning-Options.html#index-Wline-truncation");
    4087              : #endif
    4088            4 : }
    4089              : 
    4090              : /* Verify EnumSet and EnumBitSet requirements.  */
    4091              : 
    4092              : static void
    4093            4 : test_enum_sets ()
    4094              : {
    4095        10304 :   for (unsigned i = 0; i < cl_options_count; ++i)
    4096        10300 :     if (cl_options[i].var_type == CLVC_ENUM
    4097          364 :         && cl_options[i].var_value != CLEV_NORMAL)
    4098              :       {
    4099           32 :         const struct cl_enum *e = &cl_enums[cl_options[i].var_enum];
    4100           32 :         unsigned HOST_WIDE_INT used_sets = 0;
    4101           32 :         unsigned HOST_WIDE_INT mask = 0;
    4102           32 :         unsigned highest_set = 0;
    4103          180 :         for (unsigned j = 0; e->values[j].arg; ++j)
    4104              :           {
    4105          148 :             unsigned set = e->values[j].flags >> CL_ENUM_SET_SHIFT;
    4106          148 :             if (cl_options[i].var_value == CLEV_BITSET)
    4107              :               {
    4108              :                 /* For EnumBitSet Set shouldn't be used and Value should
    4109              :                    be a power of two.  */
    4110           28 :                 ASSERT_TRUE (set == 0);
    4111           56 :                 ASSERT_TRUE (pow2p_hwi (e->values[j].value));
    4112           28 :                 continue;
    4113           28 :               }
    4114              :             /* Test that enumerators referenced in EnumSet have all
    4115              :                Set(n) on them within the valid range.  */
    4116          120 :             ASSERT_TRUE (set >= 1 && set <= HOST_BITS_PER_WIDE_INT);
    4117          120 :             highest_set = MAX (set, highest_set);
    4118          120 :             used_sets |= HOST_WIDE_INT_1U << (set - 1);
    4119              :           }
    4120           32 :         if (cl_options[i].var_value == CLEV_BITSET)
    4121            8 :           continue;
    4122              :         /* If there is just one set, no point to using EnumSet.  */
    4123           24 :         ASSERT_TRUE (highest_set >= 2);
    4124              :         /* Test that there are no gaps in between the sets.  */
    4125           24 :         if (highest_set == HOST_BITS_PER_WIDE_INT)
    4126            0 :           ASSERT_TRUE (used_sets == HOST_WIDE_INT_M1U);
    4127              :         else
    4128           24 :           ASSERT_TRUE (used_sets == (HOST_WIDE_INT_1U << highest_set) - 1);
    4129          112 :         for (unsigned int j = 1; j <= highest_set; ++j)
    4130              :           {
    4131              :             unsigned HOST_WIDE_INT this_mask = 0;
    4132          616 :             for (unsigned k = 0; e->values[k].arg; ++k)
    4133              :               {
    4134          528 :                 unsigned set = e->values[j].flags >> CL_ENUM_SET_SHIFT;
    4135          528 :                 if (set == j)
    4136          128 :                   this_mask |= e->values[j].value;
    4137              :               }
    4138           88 :             ASSERT_TRUE ((mask & this_mask) == 0);
    4139           88 :             mask |= this_mask;
    4140              :           }
    4141              :       }
    4142            4 : }
    4143              : 
    4144              : /* Run all of the selftests within this file.  */
    4145              : 
    4146              : void
    4147            4 : opts_cc_tests ()
    4148              : {
    4149            4 :   test_get_option_url_suffix ();
    4150            4 :   test_enum_sets ();
    4151            4 : }
    4152              : 
    4153              : } // namespace selftest
    4154              : 
    4155              : #endif /* #if CHECKING_P */
        

Generated by: LCOV version 2.4-beta

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,rust,m2 --enable-host-shared. GCC test suite is run with the built compiler.