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