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

Generated by: LCOV version 2.5.0-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.