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