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