xref: /dragonfly/contrib/gcc-8.0/gcc/opts.c (revision e215fc28)
138fd1498Szrj /* Command line option handling.
238fd1498Szrj    Copyright (C) 2002-2018 Free Software Foundation, Inc.
338fd1498Szrj    Contributed by Neil Booth.
438fd1498Szrj 
538fd1498Szrj This file is part of GCC.
638fd1498Szrj 
738fd1498Szrj GCC is free software; you can redistribute it and/or modify it under
838fd1498Szrj the terms of the GNU General Public License as published by the Free
938fd1498Szrj Software Foundation; either version 3, or (at your option) any later
1038fd1498Szrj version.
1138fd1498Szrj 
1238fd1498Szrj GCC is distributed in the hope that it will be useful, but WITHOUT ANY
1338fd1498Szrj WARRANTY; without even the implied warranty of MERCHANTABILITY or
1438fd1498Szrj FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1538fd1498Szrj for more details.
1638fd1498Szrj 
1738fd1498Szrj You should have received a copy of the GNU General Public License
1838fd1498Szrj along with GCC; see the file COPYING3.  If not see
1938fd1498Szrj <http://www.gnu.org/licenses/>.  */
2038fd1498Szrj 
2138fd1498Szrj #include "config.h"
2238fd1498Szrj #include "system.h"
2338fd1498Szrj #include "intl.h"
2438fd1498Szrj #include "coretypes.h"
2538fd1498Szrj #include "opts.h"
2638fd1498Szrj #include "tm.h"
2738fd1498Szrj #include "flags.h"
2838fd1498Szrj #include "params.h"
2938fd1498Szrj #include "diagnostic.h"
3038fd1498Szrj #include "opts-diagnostic.h"
3138fd1498Szrj #include "insn-attr-common.h"
3238fd1498Szrj #include "common/common-target.h"
3338fd1498Szrj #include "spellcheck.h"
3438fd1498Szrj 
3538fd1498Szrj static void set_Wstrict_aliasing (struct gcc_options *opts, int onoff);
3638fd1498Szrj 
3738fd1498Szrj /* Indexed by enum debug_info_type.  */
3838fd1498Szrj const char *const debug_type_names[] =
3938fd1498Szrj {
4038fd1498Szrj   "none", "stabs", "dwarf-2", "xcoff", "vms"
4138fd1498Szrj };
4238fd1498Szrj 
4338fd1498Szrj /* Parse the -femit-struct-debug-detailed option value
4438fd1498Szrj    and set the flag variables. */
4538fd1498Szrj 
4638fd1498Szrj #define MATCH( prefix, string ) \
4738fd1498Szrj   ((strncmp (prefix, string, sizeof prefix - 1) == 0) \
4838fd1498Szrj    ? ((string += sizeof prefix - 1), 1) : 0)
4938fd1498Szrj 
5038fd1498Szrj void
set_struct_debug_option(struct gcc_options * opts,location_t loc,const char * spec)5138fd1498Szrj set_struct_debug_option (struct gcc_options *opts, location_t loc,
5238fd1498Szrj 			 const char *spec)
5338fd1498Szrj {
5438fd1498Szrj   /* various labels for comparison */
5538fd1498Szrj   static const char dfn_lbl[] = "dfn:", dir_lbl[] = "dir:", ind_lbl[] = "ind:";
5638fd1498Szrj   static const char ord_lbl[] = "ord:", gen_lbl[] = "gen:";
5738fd1498Szrj   static const char none_lbl[] = "none", any_lbl[] = "any";
5838fd1498Szrj   static const char base_lbl[] = "base", sys_lbl[] = "sys";
5938fd1498Szrj 
6038fd1498Szrj   enum debug_struct_file files = DINFO_STRUCT_FILE_ANY;
6138fd1498Szrj   /* Default is to apply to as much as possible. */
6238fd1498Szrj   enum debug_info_usage usage = DINFO_USAGE_NUM_ENUMS;
6338fd1498Szrj   int ord = 1, gen = 1;
6438fd1498Szrj 
6538fd1498Szrj   /* What usage? */
6638fd1498Szrj   if (MATCH (dfn_lbl, spec))
6738fd1498Szrj     usage = DINFO_USAGE_DFN;
6838fd1498Szrj   else if (MATCH (dir_lbl, spec))
6938fd1498Szrj     usage = DINFO_USAGE_DIR_USE;
7038fd1498Szrj   else if (MATCH (ind_lbl, spec))
7138fd1498Szrj     usage = DINFO_USAGE_IND_USE;
7238fd1498Szrj 
7338fd1498Szrj   /* Generics or not? */
7438fd1498Szrj   if (MATCH (ord_lbl, spec))
7538fd1498Szrj     gen = 0;
7638fd1498Szrj   else if (MATCH (gen_lbl, spec))
7738fd1498Szrj     ord = 0;
7838fd1498Szrj 
7938fd1498Szrj   /* What allowable environment? */
8038fd1498Szrj   if (MATCH (none_lbl, spec))
8138fd1498Szrj     files = DINFO_STRUCT_FILE_NONE;
8238fd1498Szrj   else if (MATCH (any_lbl, spec))
8338fd1498Szrj     files = DINFO_STRUCT_FILE_ANY;
8438fd1498Szrj   else if (MATCH (sys_lbl, spec))
8538fd1498Szrj     files = DINFO_STRUCT_FILE_SYS;
8638fd1498Szrj   else if (MATCH (base_lbl, spec))
8738fd1498Szrj     files = DINFO_STRUCT_FILE_BASE;
8838fd1498Szrj   else
8938fd1498Szrj     error_at (loc,
9038fd1498Szrj 	      "argument %qs to %<-femit-struct-debug-detailed%> "
9138fd1498Szrj 	      "not recognized",
9238fd1498Szrj 	      spec);
9338fd1498Szrj 
9438fd1498Szrj   /* Effect the specification. */
9538fd1498Szrj   if (usage == DINFO_USAGE_NUM_ENUMS)
9638fd1498Szrj     {
9738fd1498Szrj       if (ord)
9838fd1498Szrj         {
9938fd1498Szrj           opts->x_debug_struct_ordinary[DINFO_USAGE_DFN] = files;
10038fd1498Szrj           opts->x_debug_struct_ordinary[DINFO_USAGE_DIR_USE] = files;
10138fd1498Szrj           opts->x_debug_struct_ordinary[DINFO_USAGE_IND_USE] = files;
10238fd1498Szrj         }
10338fd1498Szrj       if (gen)
10438fd1498Szrj         {
10538fd1498Szrj           opts->x_debug_struct_generic[DINFO_USAGE_DFN] = files;
10638fd1498Szrj           opts->x_debug_struct_generic[DINFO_USAGE_DIR_USE] = files;
10738fd1498Szrj           opts->x_debug_struct_generic[DINFO_USAGE_IND_USE] = files;
10838fd1498Szrj         }
10938fd1498Szrj     }
11038fd1498Szrj   else
11138fd1498Szrj     {
11238fd1498Szrj       if (ord)
11338fd1498Szrj         opts->x_debug_struct_ordinary[usage] = files;
11438fd1498Szrj       if (gen)
11538fd1498Szrj         opts->x_debug_struct_generic[usage] = files;
11638fd1498Szrj     }
11738fd1498Szrj 
11838fd1498Szrj   if (*spec == ',')
11938fd1498Szrj     set_struct_debug_option (opts, loc, spec+1);
12038fd1498Szrj   else
12138fd1498Szrj     {
12238fd1498Szrj       /* No more -femit-struct-debug-detailed specifications.
12338fd1498Szrj          Do final checks. */
12438fd1498Szrj       if (*spec != '\0')
12538fd1498Szrj 	error_at (loc,
12638fd1498Szrj 		  "argument %qs to %<-femit-struct-debug-detailed%> unknown",
12738fd1498Szrj 		  spec);
12838fd1498Szrj       if (opts->x_debug_struct_ordinary[DINFO_USAGE_DIR_USE]
12938fd1498Szrj 		< opts->x_debug_struct_ordinary[DINFO_USAGE_IND_USE]
13038fd1498Szrj 	  || opts->x_debug_struct_generic[DINFO_USAGE_DIR_USE]
13138fd1498Szrj 		< opts->x_debug_struct_generic[DINFO_USAGE_IND_USE])
13238fd1498Szrj 	error_at (loc,
13338fd1498Szrj 		  "%<-femit-struct-debug-detailed=dir:...%> must allow "
13438fd1498Szrj 		  "at least as much as "
13538fd1498Szrj 		  "%<-femit-struct-debug-detailed=ind:...%>");
13638fd1498Szrj     }
13738fd1498Szrj }
13838fd1498Szrj 
13938fd1498Szrj /* Strip off a legitimate source ending from the input string NAME of
14038fd1498Szrj    length LEN.  Rather than having to know the names used by all of
14138fd1498Szrj    our front ends, we strip off an ending of a period followed by
14238fd1498Szrj    up to fource characters.  (C++ uses ".cpp".)  */
14338fd1498Szrj 
14438fd1498Szrj void
strip_off_ending(char * name,int len)14538fd1498Szrj strip_off_ending (char *name, int len)
14638fd1498Szrj {
14738fd1498Szrj   int i;
14838fd1498Szrj   for (i = 2; i < 5 && len > i; i++)
14938fd1498Szrj     {
15038fd1498Szrj       if (name[len - i] == '.')
15138fd1498Szrj 	{
15238fd1498Szrj 	  name[len - i] = '\0';
15338fd1498Szrj 	  break;
15438fd1498Szrj 	}
15538fd1498Szrj     }
15638fd1498Szrj }
15738fd1498Szrj 
15838fd1498Szrj /* Find the base name of a path, stripping off both directories and
15938fd1498Szrj    a single final extension. */
16038fd1498Szrj int
base_of_path(const char * path,const char ** base_out)16138fd1498Szrj base_of_path (const char *path, const char **base_out)
16238fd1498Szrj {
16338fd1498Szrj   const char *base = path;
16438fd1498Szrj   const char *dot = 0;
16538fd1498Szrj   const char *p = path;
16638fd1498Szrj   char c = *p;
16738fd1498Szrj   while (c)
16838fd1498Szrj     {
16938fd1498Szrj       if (IS_DIR_SEPARATOR (c))
17038fd1498Szrj         {
17138fd1498Szrj           base = p + 1;
17238fd1498Szrj           dot = 0;
17338fd1498Szrj         }
17438fd1498Szrj       else if (c == '.')
17538fd1498Szrj         dot = p;
17638fd1498Szrj       c = *++p;
17738fd1498Szrj     }
17838fd1498Szrj   if (!dot)
17938fd1498Szrj     dot = p;
18038fd1498Szrj   *base_out = base;
18138fd1498Szrj   return dot - base;
18238fd1498Szrj }
18338fd1498Szrj 
18438fd1498Szrj /* What to print when a switch has no documentation.  */
18538fd1498Szrj static const char undocumented_msg[] = N_("This option lacks documentation.");
18638fd1498Szrj static const char use_diagnosed_msg[] = N_("Uses of this option are diagnosed.");
18738fd1498Szrj 
18838fd1498Szrj typedef char *char_p; /* For DEF_VEC_P.  */
18938fd1498Szrj 
19038fd1498Szrj static void handle_param (struct gcc_options *opts,
19138fd1498Szrj 			  struct gcc_options *opts_set, location_t loc,
19238fd1498Szrj 			  const char *carg);
19338fd1498Szrj static void set_debug_level (enum debug_info_type type, int extended,
19438fd1498Szrj 			     const char *arg, struct gcc_options *opts,
19538fd1498Szrj 			     struct gcc_options *opts_set,
19638fd1498Szrj 			     location_t loc);
19738fd1498Szrj static void set_fast_math_flags (struct gcc_options *opts, int set);
19838fd1498Szrj static void decode_d_option (const char *arg, struct gcc_options *opts,
19938fd1498Szrj 			     location_t loc, diagnostic_context *dc);
20038fd1498Szrj static void set_unsafe_math_optimizations_flags (struct gcc_options *opts,
20138fd1498Szrj 						 int set);
20238fd1498Szrj static void enable_warning_as_error (const char *arg, int value,
20338fd1498Szrj 				     unsigned int lang_mask,
20438fd1498Szrj 				     const struct cl_option_handlers *handlers,
20538fd1498Szrj 				     struct gcc_options *opts,
20638fd1498Szrj 				     struct gcc_options *opts_set,
20738fd1498Szrj 				     location_t loc,
20838fd1498Szrj 				     diagnostic_context *dc);
20938fd1498Szrj 
21038fd1498Szrj /* Handle a back-end option; arguments and return value as for
21138fd1498Szrj    handle_option.  */
21238fd1498Szrj 
21338fd1498Szrj bool
target_handle_option(struct gcc_options * opts,struct gcc_options * opts_set,const struct cl_decoded_option * decoded,unsigned int lang_mask ATTRIBUTE_UNUSED,int kind,location_t loc,const struct cl_option_handlers * handlers ATTRIBUTE_UNUSED,diagnostic_context * dc,void (*)(void))21438fd1498Szrj target_handle_option (struct gcc_options *opts,
21538fd1498Szrj 		      struct gcc_options *opts_set,
21638fd1498Szrj 		      const struct cl_decoded_option *decoded,
21738fd1498Szrj 		      unsigned int lang_mask ATTRIBUTE_UNUSED, int kind,
21838fd1498Szrj 		      location_t loc,
21938fd1498Szrj 		      const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED,
22038fd1498Szrj 		      diagnostic_context *dc, void (*) (void))
22138fd1498Szrj {
22238fd1498Szrj   gcc_assert (dc == global_dc);
22338fd1498Szrj   gcc_assert (kind == DK_UNSPECIFIED);
22438fd1498Szrj   return targetm_common.handle_option (opts, opts_set, decoded, loc);
22538fd1498Szrj }
22638fd1498Szrj 
22738fd1498Szrj /* Add comma-separated strings to a char_p vector.  */
22838fd1498Szrj 
22938fd1498Szrj static void
add_comma_separated_to_vector(void ** pvec,const char * arg)23038fd1498Szrj add_comma_separated_to_vector (void **pvec, const char *arg)
23138fd1498Szrj {
23238fd1498Szrj   char *tmp;
23338fd1498Szrj   char *r;
23438fd1498Szrj   char *w;
23538fd1498Szrj   char *token_start;
23638fd1498Szrj   vec<char_p> *v = (vec<char_p> *) *pvec;
23738fd1498Szrj 
23838fd1498Szrj   vec_check_alloc (v, 1);
23938fd1498Szrj 
24038fd1498Szrj   /* We never free this string.  */
24138fd1498Szrj   tmp = xstrdup (arg);
24238fd1498Szrj 
24338fd1498Szrj   r = tmp;
24438fd1498Szrj   w = tmp;
24538fd1498Szrj   token_start = tmp;
24638fd1498Szrj 
24738fd1498Szrj   while (*r != '\0')
24838fd1498Szrj     {
24938fd1498Szrj       if (*r == ',')
25038fd1498Szrj 	{
25138fd1498Szrj 	  *w++ = '\0';
25238fd1498Szrj 	  ++r;
25338fd1498Szrj 	  v->safe_push (token_start);
25438fd1498Szrj 	  token_start = w;
25538fd1498Szrj 	}
25638fd1498Szrj       if (*r == '\\' && r[1] == ',')
25738fd1498Szrj 	{
25838fd1498Szrj 	  *w++ = ',';
25938fd1498Szrj 	  r += 2;
26038fd1498Szrj 	}
26138fd1498Szrj       else
26238fd1498Szrj 	*w++ = *r++;
26338fd1498Szrj     }
26438fd1498Szrj   if (*token_start != '\0')
26538fd1498Szrj     v->safe_push (token_start);
26638fd1498Szrj 
26738fd1498Szrj   *pvec = v;
26838fd1498Szrj }
26938fd1498Szrj 
27038fd1498Szrj /* Initialize opts_obstack.  */
27138fd1498Szrj 
27238fd1498Szrj void
init_opts_obstack(void)27338fd1498Szrj init_opts_obstack (void)
27438fd1498Szrj {
27538fd1498Szrj   gcc_obstack_init (&opts_obstack);
27638fd1498Szrj }
27738fd1498Szrj 
27838fd1498Szrj /* Initialize OPTS and OPTS_SET before using them in parsing options.  */
27938fd1498Szrj 
28038fd1498Szrj void
init_options_struct(struct gcc_options * opts,struct gcc_options * opts_set)28138fd1498Szrj init_options_struct (struct gcc_options *opts, struct gcc_options *opts_set)
28238fd1498Szrj {
28338fd1498Szrj   size_t num_params = get_num_compiler_params ();
28438fd1498Szrj 
28538fd1498Szrj   /* Ensure that opts_obstack has already been initialized by the time
28638fd1498Szrj      that we initialize any gcc_options instances (PR jit/68446).  */
28738fd1498Szrj   gcc_assert (opts_obstack.chunk_size > 0);
28838fd1498Szrj 
28938fd1498Szrj   *opts = global_options_init;
29038fd1498Szrj 
29138fd1498Szrj   if (opts_set)
29238fd1498Szrj     memset (opts_set, 0, sizeof (*opts_set));
29338fd1498Szrj 
29438fd1498Szrj   opts->x_param_values = XNEWVEC (int, num_params);
29538fd1498Szrj 
29638fd1498Szrj   if (opts_set)
29738fd1498Szrj     opts_set->x_param_values = XCNEWVEC (int, num_params);
29838fd1498Szrj 
29938fd1498Szrj   init_param_values (opts->x_param_values);
30038fd1498Szrj 
30138fd1498Szrj   /* Initialize whether `char' is signed.  */
30238fd1498Szrj   opts->x_flag_signed_char = DEFAULT_SIGNED_CHAR;
30338fd1498Szrj   /* Set this to a special "uninitialized" value.  The actual default
30438fd1498Szrj      is set after target options have been processed.  */
30538fd1498Szrj   opts->x_flag_short_enums = 2;
30638fd1498Szrj 
30738fd1498Szrj   /* Initialize target_flags before default_options_optimization
30838fd1498Szrj      so the latter can modify it.  */
30938fd1498Szrj   opts->x_target_flags = targetm_common.default_target_flags;
31038fd1498Szrj 
31138fd1498Szrj   /* Some targets have ABI-specified unwind tables.  */
31238fd1498Szrj   opts->x_flag_unwind_tables = targetm_common.unwind_tables_default;
31338fd1498Szrj 
31438fd1498Szrj   /* Some targets have other target-specific initialization.  */
31538fd1498Szrj   targetm_common.option_init_struct (opts);
31638fd1498Szrj }
31738fd1498Szrj 
31838fd1498Szrj /* Release any allocations owned by OPTS.  */
31938fd1498Szrj 
32038fd1498Szrj void
finalize_options_struct(struct gcc_options * opts)32138fd1498Szrj finalize_options_struct (struct gcc_options *opts)
32238fd1498Szrj {
32338fd1498Szrj   XDELETEVEC (opts->x_param_values);
32438fd1498Szrj }
32538fd1498Szrj 
32638fd1498Szrj /* If indicated by the optimization level LEVEL (-Os if SIZE is set,
32738fd1498Szrj    -Ofast if FAST is set, -Og if DEBUG is set), apply the option DEFAULT_OPT
32838fd1498Szrj    to OPTS and OPTS_SET, diagnostic context DC, location LOC, with language
32938fd1498Szrj    mask LANG_MASK and option handlers HANDLERS.  */
33038fd1498Szrj 
33138fd1498Szrj static void
maybe_default_option(struct gcc_options * opts,struct gcc_options * opts_set,const struct default_options * default_opt,int level,bool size,bool fast,bool debug,unsigned int lang_mask,const struct cl_option_handlers * handlers,location_t loc,diagnostic_context * dc)33238fd1498Szrj maybe_default_option (struct gcc_options *opts,
33338fd1498Szrj 		      struct gcc_options *opts_set,
33438fd1498Szrj 		      const struct default_options *default_opt,
33538fd1498Szrj 		      int level, bool size, bool fast, bool debug,
33638fd1498Szrj 		      unsigned int lang_mask,
33738fd1498Szrj 		      const struct cl_option_handlers *handlers,
33838fd1498Szrj 		      location_t loc,
33938fd1498Szrj 		      diagnostic_context *dc)
34038fd1498Szrj {
34138fd1498Szrj   const struct cl_option *option = &cl_options[default_opt->opt_index];
34238fd1498Szrj   bool enabled;
34338fd1498Szrj 
34438fd1498Szrj   if (size)
34538fd1498Szrj     gcc_assert (level == 2);
34638fd1498Szrj   if (fast)
34738fd1498Szrj     gcc_assert (level == 3);
34838fd1498Szrj   if (debug)
34938fd1498Szrj     gcc_assert (level == 1);
35038fd1498Szrj 
35138fd1498Szrj   switch (default_opt->levels)
35238fd1498Szrj     {
35338fd1498Szrj     case OPT_LEVELS_ALL:
35438fd1498Szrj       enabled = true;
35538fd1498Szrj       break;
35638fd1498Szrj 
35738fd1498Szrj     case OPT_LEVELS_0_ONLY:
35838fd1498Szrj       enabled = (level == 0);
35938fd1498Szrj       break;
36038fd1498Szrj 
36138fd1498Szrj     case OPT_LEVELS_1_PLUS:
36238fd1498Szrj       enabled = (level >= 1);
36338fd1498Szrj       break;
36438fd1498Szrj 
36538fd1498Szrj     case OPT_LEVELS_1_PLUS_SPEED_ONLY:
36638fd1498Szrj       enabled = (level >= 1 && !size && !debug);
36738fd1498Szrj       break;
36838fd1498Szrj 
36938fd1498Szrj     case OPT_LEVELS_1_PLUS_NOT_DEBUG:
37038fd1498Szrj       enabled = (level >= 1 && !debug);
37138fd1498Szrj       break;
37238fd1498Szrj 
37338fd1498Szrj     case OPT_LEVELS_2_PLUS:
37438fd1498Szrj       enabled = (level >= 2);
37538fd1498Szrj       break;
37638fd1498Szrj 
37738fd1498Szrj     case OPT_LEVELS_2_PLUS_SPEED_ONLY:
37838fd1498Szrj       enabled = (level >= 2 && !size && !debug);
37938fd1498Szrj       break;
38038fd1498Szrj 
38138fd1498Szrj     case OPT_LEVELS_3_PLUS:
38238fd1498Szrj       enabled = (level >= 3);
38338fd1498Szrj       break;
38438fd1498Szrj 
38538fd1498Szrj     case OPT_LEVELS_3_PLUS_AND_SIZE:
38638fd1498Szrj       enabled = (level >= 3 || size);
38738fd1498Szrj       break;
38838fd1498Szrj 
38938fd1498Szrj     case OPT_LEVELS_SIZE:
39038fd1498Szrj       enabled = size;
39138fd1498Szrj       break;
39238fd1498Szrj 
39338fd1498Szrj     case OPT_LEVELS_FAST:
39438fd1498Szrj       enabled = fast;
39538fd1498Szrj       break;
39638fd1498Szrj 
39738fd1498Szrj     case OPT_LEVELS_NONE:
39838fd1498Szrj     default:
39938fd1498Szrj       gcc_unreachable ();
40038fd1498Szrj     }
40138fd1498Szrj 
40238fd1498Szrj   if (enabled)
40338fd1498Szrj     handle_generated_option (opts, opts_set, default_opt->opt_index,
40438fd1498Szrj 			     default_opt->arg, default_opt->value,
40538fd1498Szrj 			     lang_mask, DK_UNSPECIFIED, loc,
40638fd1498Szrj 			     handlers, true, dc);
40738fd1498Szrj   else if (default_opt->arg == NULL
40838fd1498Szrj 	   && !option->cl_reject_negative)
40938fd1498Szrj     handle_generated_option (opts, opts_set, default_opt->opt_index,
41038fd1498Szrj 			     default_opt->arg, !default_opt->value,
41138fd1498Szrj 			     lang_mask, DK_UNSPECIFIED, loc,
41238fd1498Szrj 			     handlers, true, dc);
41338fd1498Szrj }
41438fd1498Szrj 
41538fd1498Szrj /* As indicated by the optimization level LEVEL (-Os if SIZE is set,
41638fd1498Szrj    -Ofast if FAST is set), apply the options in array DEFAULT_OPTS to
41738fd1498Szrj    OPTS and OPTS_SET, diagnostic context DC, location LOC, with
41838fd1498Szrj    language mask LANG_MASK and option handlers HANDLERS.  */
41938fd1498Szrj 
42038fd1498Szrj static void
maybe_default_options(struct gcc_options * opts,struct gcc_options * opts_set,const struct default_options * default_opts,int level,bool size,bool fast,bool debug,unsigned int lang_mask,const struct cl_option_handlers * handlers,location_t loc,diagnostic_context * dc)42138fd1498Szrj maybe_default_options (struct gcc_options *opts,
42238fd1498Szrj 		       struct gcc_options *opts_set,
42338fd1498Szrj 		       const struct default_options *default_opts,
42438fd1498Szrj 		       int level, bool size, bool fast, bool debug,
42538fd1498Szrj 		       unsigned int lang_mask,
42638fd1498Szrj 		       const struct cl_option_handlers *handlers,
42738fd1498Szrj 		       location_t loc,
42838fd1498Szrj 		       diagnostic_context *dc)
42938fd1498Szrj {
43038fd1498Szrj   size_t i;
43138fd1498Szrj 
43238fd1498Szrj   for (i = 0; default_opts[i].levels != OPT_LEVELS_NONE; i++)
43338fd1498Szrj     maybe_default_option (opts, opts_set, &default_opts[i],
43438fd1498Szrj 			  level, size, fast, debug,
43538fd1498Szrj 			  lang_mask, handlers, loc, dc);
43638fd1498Szrj }
43738fd1498Szrj 
43838fd1498Szrj /* Table of options enabled by default at different levels.  */
43938fd1498Szrj 
44038fd1498Szrj static const struct default_options default_options_table[] =
44138fd1498Szrj   {
44238fd1498Szrj     /* -O1 optimizations.  */
44338fd1498Szrj     { OPT_LEVELS_1_PLUS, OPT_fdefer_pop, NULL, 1 },
44438fd1498Szrj #if DELAY_SLOTS
44538fd1498Szrj     { OPT_LEVELS_1_PLUS, OPT_fdelayed_branch, NULL, 1 },
44638fd1498Szrj #endif
44738fd1498Szrj     { OPT_LEVELS_1_PLUS, OPT_fguess_branch_probability, NULL, 1 },
44838fd1498Szrj     { OPT_LEVELS_1_PLUS, OPT_fcprop_registers, NULL, 1 },
44938fd1498Szrj     { OPT_LEVELS_1_PLUS, OPT_fforward_propagate, NULL, 1 },
45038fd1498Szrj     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fif_conversion, NULL, 1 },
45138fd1498Szrj     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fif_conversion2, NULL, 1 },
45238fd1498Szrj     { OPT_LEVELS_1_PLUS, OPT_fipa_pure_const, NULL, 1 },
45338fd1498Szrj     { OPT_LEVELS_1_PLUS, OPT_fipa_reference, NULL, 1 },
45438fd1498Szrj     { OPT_LEVELS_1_PLUS, OPT_fipa_profile, NULL, 1 },
45538fd1498Szrj     { OPT_LEVELS_1_PLUS, OPT_fmerge_constants, NULL, 1 },
45638fd1498Szrj     { OPT_LEVELS_1_PLUS, OPT_freorder_blocks, NULL, 1 },
45738fd1498Szrj     { OPT_LEVELS_1_PLUS, OPT_fshrink_wrap, NULL, 1 },
45838fd1498Szrj     { OPT_LEVELS_1_PLUS, OPT_fsplit_wide_types, NULL, 1 },
45938fd1498Szrj     { OPT_LEVELS_1_PLUS, OPT_ftree_ccp, NULL, 1 },
46038fd1498Szrj     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_bit_ccp, NULL, 1 },
46138fd1498Szrj     { OPT_LEVELS_1_PLUS, OPT_ftree_coalesce_vars, NULL, 1 },
46238fd1498Szrj     { OPT_LEVELS_1_PLUS, OPT_ftree_dce, NULL, 1 },
46338fd1498Szrj     { OPT_LEVELS_1_PLUS, OPT_ftree_dominator_opts, NULL, 1 },
46438fd1498Szrj     { OPT_LEVELS_1_PLUS, OPT_ftree_dse, NULL, 1 },
46538fd1498Szrj     { OPT_LEVELS_1_PLUS, OPT_ftree_ter, NULL, 1 },
46638fd1498Szrj     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_sra, NULL, 1 },
46738fd1498Szrj     { OPT_LEVELS_1_PLUS, OPT_ftree_fre, NULL, 1 },
46838fd1498Szrj     { OPT_LEVELS_1_PLUS, OPT_ftree_copy_prop, NULL, 1 },
46938fd1498Szrj     { OPT_LEVELS_1_PLUS, OPT_ftree_sink, NULL, 1 },
47038fd1498Szrj     { OPT_LEVELS_1_PLUS, OPT_ftree_ch, NULL, 1 },
47138fd1498Szrj     { OPT_LEVELS_1_PLUS, OPT_fcombine_stack_adjustments, NULL, 1 },
47238fd1498Szrj     { OPT_LEVELS_1_PLUS, OPT_fcompare_elim, NULL, 1 },
47338fd1498Szrj     { OPT_LEVELS_1_PLUS, OPT_ftree_slsr, NULL, 1 },
47438fd1498Szrj     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fbranch_count_reg, NULL, 1 },
47538fd1498Szrj     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fmove_loop_invariants, NULL, 1 },
47638fd1498Szrj     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_pta, NULL, 1 },
47738fd1498Szrj     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fssa_phiopt, NULL, 1 },
47838fd1498Szrj     { OPT_LEVELS_1_PLUS, OPT_ftree_builtin_call_dce, NULL, 1 },
47938fd1498Szrj     { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
48038fd1498Szrj 
48138fd1498Szrj     /* -O2 optimizations.  */
48238fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_finline_small_functions, NULL, 1 },
48338fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_findirect_inlining, NULL, 1 },
48438fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_fpartial_inlining, NULL, 1 },
48538fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_fthread_jumps, NULL, 1 },
48638fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_fcrossjumping, NULL, 1 },
48738fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_foptimize_sibling_calls, NULL, 1 },
48838fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_fcse_follow_jumps, NULL, 1 },
48938fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_fgcse, NULL, 1 },
49038fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_fexpensive_optimizations, NULL, 1 },
49138fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_frerun_cse_after_loop, NULL, 1 },
49238fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_fcaller_saves, NULL, 1 },
49338fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_fpeephole2, NULL, 1 },
49438fd1498Szrj #ifdef INSN_SCHEDULING
49538fd1498Szrj   /* Only run the pre-regalloc scheduling pass if optimizing for speed.  */
49638fd1498Szrj     { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_fschedule_insns, NULL, 1 },
49738fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_fschedule_insns2, NULL, 1 },
49838fd1498Szrj #endif
49938fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_fstrict_aliasing, NULL, 1 },
50038fd1498Szrj     { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_freorder_blocks_algorithm_, NULL,
50138fd1498Szrj       REORDER_BLOCKS_ALGORITHM_STC },
50238fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_freorder_functions, NULL, 1 },
50338fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_ftree_vrp, NULL, 1 },
50438fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_fcode_hoisting, NULL, 1 },
50538fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_ftree_pre, NULL, 1 },
50638fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_ftree_switch_conversion, NULL, 1 },
50738fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_fipa_cp, NULL, 1 },
50838fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_fipa_bit_cp, NULL, 1 },
50938fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_fipa_vrp, NULL, 1 },
51038fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_fdevirtualize, NULL, 1 },
51138fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_fdevirtualize_speculatively, NULL, 1 },
51238fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_fipa_sra, NULL, 1 },
51338fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_falign_loops, NULL, 1 },
51438fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_falign_jumps, NULL, 1 },
51538fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_falign_labels, NULL, 1 },
51638fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_falign_functions, NULL, 1 },
51738fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_ftree_tail_merge, NULL, 1 },
51838fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_fvect_cost_model_, NULL, VECT_COST_MODEL_CHEAP },
51938fd1498Szrj     { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_foptimize_strlen, NULL, 1 },
52038fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_fhoist_adjacent_loads, NULL, 1 },
52138fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_fipa_icf, NULL, 1 },
52238fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_fisolate_erroneous_paths_dereference, NULL, 1 },
52338fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_fipa_ra, NULL, 1 },
52438fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_flra_remat, NULL, 1 },
52538fd1498Szrj     { OPT_LEVELS_2_PLUS, OPT_fstore_merging, NULL, 1 },
52638fd1498Szrj 
52738fd1498Szrj     /* -O3 optimizations.  */
52838fd1498Szrj     { OPT_LEVELS_3_PLUS, OPT_ftree_loop_distribute_patterns, NULL, 1 },
52938fd1498Szrj     { OPT_LEVELS_3_PLUS, OPT_ftree_loop_distribution, NULL, 1 },
53038fd1498Szrj     { OPT_LEVELS_3_PLUS, OPT_floop_interchange, NULL, 1 },
53138fd1498Szrj     { OPT_LEVELS_3_PLUS, OPT_fpredictive_commoning, NULL, 1 },
53238fd1498Szrj     { OPT_LEVELS_3_PLUS, OPT_fsplit_paths, NULL, 1 },
53338fd1498Szrj     /* Inlining of functions reducing size is a good idea with -Os
53438fd1498Szrj        regardless of them being declared inline.  */
53538fd1498Szrj     { OPT_LEVELS_3_PLUS_AND_SIZE, OPT_finline_functions, NULL, 1 },
53638fd1498Szrj     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_finline_functions_called_once, NULL, 1 },
53738fd1498Szrj     { OPT_LEVELS_3_PLUS, OPT_fsplit_loops, NULL, 1 },
53838fd1498Szrj     { OPT_LEVELS_3_PLUS, OPT_funswitch_loops, NULL, 1 },
53938fd1498Szrj     { OPT_LEVELS_3_PLUS, OPT_floop_unroll_and_jam, NULL, 1 },
54038fd1498Szrj     { OPT_LEVELS_3_PLUS, OPT_fgcse_after_reload, NULL, 1 },
54138fd1498Szrj     { OPT_LEVELS_3_PLUS, OPT_ftree_loop_vectorize, NULL, 1 },
54238fd1498Szrj     { OPT_LEVELS_3_PLUS, OPT_ftree_slp_vectorize, NULL, 1 },
54338fd1498Szrj     { OPT_LEVELS_3_PLUS, OPT_fvect_cost_model_, NULL, VECT_COST_MODEL_DYNAMIC },
54438fd1498Szrj     { OPT_LEVELS_3_PLUS, OPT_fipa_cp_clone, NULL, 1 },
54538fd1498Szrj     { OPT_LEVELS_3_PLUS, OPT_ftree_partial_pre, NULL, 1 },
54638fd1498Szrj     { OPT_LEVELS_3_PLUS, OPT_fpeel_loops, NULL, 1 },
54738fd1498Szrj 
54838fd1498Szrj     /* -Ofast adds optimizations to -O3.  */
54938fd1498Szrj     { OPT_LEVELS_FAST, OPT_ffast_math, NULL, 1 },
55038fd1498Szrj 
55138fd1498Szrj     { OPT_LEVELS_NONE, 0, NULL, 0 }
55238fd1498Szrj   };
55338fd1498Szrj 
55438fd1498Szrj /* Default the options in OPTS and OPTS_SET based on the optimization
55538fd1498Szrj    settings in DECODED_OPTIONS and DECODED_OPTIONS_COUNT.  */
55638fd1498Szrj void
default_options_optimization(struct gcc_options * opts,struct gcc_options * opts_set,struct cl_decoded_option * decoded_options,unsigned int decoded_options_count,location_t loc,unsigned int lang_mask,const struct cl_option_handlers * handlers,diagnostic_context * dc)55738fd1498Szrj default_options_optimization (struct gcc_options *opts,
55838fd1498Szrj 			      struct gcc_options *opts_set,
55938fd1498Szrj 			      struct cl_decoded_option *decoded_options,
56038fd1498Szrj 			      unsigned int decoded_options_count,
56138fd1498Szrj 			      location_t loc,
56238fd1498Szrj 			      unsigned int lang_mask,
56338fd1498Szrj 			      const struct cl_option_handlers *handlers,
56438fd1498Szrj 			      diagnostic_context *dc)
56538fd1498Szrj {
56638fd1498Szrj   unsigned int i;
56738fd1498Szrj   int opt2;
56838fd1498Szrj   bool openacc_mode = false;
56938fd1498Szrj 
57038fd1498Szrj   /* Scan to see what optimization level has been specified.  That will
57138fd1498Szrj      determine the default value of many flags.  */
57238fd1498Szrj   for (i = 1; i < decoded_options_count; i++)
57338fd1498Szrj     {
57438fd1498Szrj       struct cl_decoded_option *opt = &decoded_options[i];
57538fd1498Szrj       switch (opt->opt_index)
57638fd1498Szrj 	{
57738fd1498Szrj 	case OPT_O:
57838fd1498Szrj 	  if (*opt->arg == '\0')
57938fd1498Szrj 	    {
58038fd1498Szrj 	      opts->x_optimize = 1;
58138fd1498Szrj 	      opts->x_optimize_size = 0;
58238fd1498Szrj 	      opts->x_optimize_fast = 0;
58338fd1498Szrj 	      opts->x_optimize_debug = 0;
58438fd1498Szrj 	    }
58538fd1498Szrj 	  else
58638fd1498Szrj 	    {
58738fd1498Szrj 	      const int optimize_val = integral_argument (opt->arg);
58838fd1498Szrj 	      if (optimize_val == -1)
58938fd1498Szrj 		error_at (loc, "argument to %<-O%> should be a non-negative "
59038fd1498Szrj 			       "integer, %<g%>, %<s%> or %<fast%>");
59138fd1498Szrj 	      else
59238fd1498Szrj 		{
59338fd1498Szrj 		  opts->x_optimize = optimize_val;
59438fd1498Szrj 		  if ((unsigned int) opts->x_optimize > 255)
59538fd1498Szrj 		    opts->x_optimize = 255;
59638fd1498Szrj 		  opts->x_optimize_size = 0;
59738fd1498Szrj 		  opts->x_optimize_fast = 0;
59838fd1498Szrj 		  opts->x_optimize_debug = 0;
59938fd1498Szrj 		}
60038fd1498Szrj 	    }
60138fd1498Szrj 	  break;
60238fd1498Szrj 
60338fd1498Szrj 	case OPT_Os:
60438fd1498Szrj 	  opts->x_optimize_size = 1;
60538fd1498Szrj 
60638fd1498Szrj 	  /* Optimizing for size forces optimize to be 2.  */
60738fd1498Szrj 	  opts->x_optimize = 2;
60838fd1498Szrj 	  opts->x_optimize_fast = 0;
60938fd1498Szrj 	  opts->x_optimize_debug = 0;
61038fd1498Szrj 	  break;
61138fd1498Szrj 
61238fd1498Szrj 	case OPT_Ofast:
61338fd1498Szrj 	  /* -Ofast only adds flags to -O3.  */
61438fd1498Szrj 	  opts->x_optimize_size = 0;
61538fd1498Szrj 	  opts->x_optimize = 3;
61638fd1498Szrj 	  opts->x_optimize_fast = 1;
61738fd1498Szrj 	  opts->x_optimize_debug = 0;
61838fd1498Szrj 	  break;
61938fd1498Szrj 
62038fd1498Szrj 	case OPT_Og:
62138fd1498Szrj 	  /* -Og selects optimization level 1.  */
62238fd1498Szrj 	  opts->x_optimize_size = 0;
62338fd1498Szrj 	  opts->x_optimize = 1;
62438fd1498Szrj 	  opts->x_optimize_fast = 0;
62538fd1498Szrj 	  opts->x_optimize_debug = 1;
62638fd1498Szrj 	  break;
62738fd1498Szrj 
62838fd1498Szrj 	case OPT_fopenacc:
62938fd1498Szrj 	  if (opt->value)
63038fd1498Szrj 	    openacc_mode = true;
63138fd1498Szrj 	  break;
63238fd1498Szrj 
63338fd1498Szrj 	default:
63438fd1498Szrj 	  /* Ignore other options in this prescan.  */
63538fd1498Szrj 	  break;
63638fd1498Szrj 	}
63738fd1498Szrj     }
63838fd1498Szrj 
63938fd1498Szrj   maybe_default_options (opts, opts_set, default_options_table,
64038fd1498Szrj 			 opts->x_optimize, opts->x_optimize_size,
64138fd1498Szrj 			 opts->x_optimize_fast, opts->x_optimize_debug,
64238fd1498Szrj 			 lang_mask, handlers, loc, dc);
64338fd1498Szrj 
64438fd1498Szrj   /* -O2 param settings.  */
64538fd1498Szrj   opt2 = (opts->x_optimize >= 2);
64638fd1498Szrj 
64738fd1498Szrj   if (openacc_mode
64838fd1498Szrj       && !opts_set->x_flag_ipa_pta)
64938fd1498Szrj     opts->x_flag_ipa_pta = true;
65038fd1498Szrj 
65138fd1498Szrj   /* Track fields in field-sensitive alias analysis.  */
65238fd1498Szrj   maybe_set_param_value
65338fd1498Szrj     (PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE,
65438fd1498Szrj      opt2 ? 100 : default_param_value (PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE),
65538fd1498Szrj      opts->x_param_values, opts_set->x_param_values);
65638fd1498Szrj 
65738fd1498Szrj   /* For -O1 only do loop invariant motion for very small loops.  */
65838fd1498Szrj   maybe_set_param_value
65938fd1498Szrj     (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP,
66058e805e6Szrj      opt2 ? default_param_value (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP)
66158e805e6Szrj      : default_param_value (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP) / 10,
66258e805e6Szrj      opts->x_param_values, opts_set->x_param_values);
66358e805e6Szrj 
66458e805e6Szrj   /* For -O1 reduce the maximum number of active local stores for RTL DSE
66558e805e6Szrj      since this can consume huge amounts of memory (PR89115).  */
66658e805e6Szrj   maybe_set_param_value
66758e805e6Szrj     (PARAM_MAX_DSE_ACTIVE_LOCAL_STORES,
66858e805e6Szrj      opt2 ? default_param_value (PARAM_MAX_DSE_ACTIVE_LOCAL_STORES)
66958e805e6Szrj      : default_param_value (PARAM_MAX_DSE_ACTIVE_LOCAL_STORES) / 10,
67038fd1498Szrj      opts->x_param_values, opts_set->x_param_values);
67138fd1498Szrj 
67238fd1498Szrj   /* At -Ofast, allow store motion to introduce potential race conditions.  */
67338fd1498Szrj   maybe_set_param_value
67438fd1498Szrj     (PARAM_ALLOW_STORE_DATA_RACES,
67538fd1498Szrj      opts->x_optimize_fast ? 1
67638fd1498Szrj      : default_param_value (PARAM_ALLOW_STORE_DATA_RACES),
67738fd1498Szrj      opts->x_param_values, opts_set->x_param_values);
67838fd1498Szrj 
67938fd1498Szrj   if (opts->x_optimize_size)
68038fd1498Szrj     /* We want to crossjump as much as possible.  */
68138fd1498Szrj     maybe_set_param_value (PARAM_MIN_CROSSJUMP_INSNS, 1,
68238fd1498Szrj 			   opts->x_param_values, opts_set->x_param_values);
68338fd1498Szrj   else
68438fd1498Szrj     maybe_set_param_value (PARAM_MIN_CROSSJUMP_INSNS,
68538fd1498Szrj 			   default_param_value (PARAM_MIN_CROSSJUMP_INSNS),
68638fd1498Szrj 			   opts->x_param_values, opts_set->x_param_values);
68738fd1498Szrj 
68838fd1498Szrj   /* Restrict the amount of work combine does at -Og while retaining
68938fd1498Szrj      most of its useful transforms.  */
69038fd1498Szrj   if (opts->x_optimize_debug)
69138fd1498Szrj     maybe_set_param_value (PARAM_MAX_COMBINE_INSNS, 2,
69238fd1498Szrj 			   opts->x_param_values, opts_set->x_param_values);
69338fd1498Szrj 
69438fd1498Szrj   /* Allow default optimizations to be specified on a per-machine basis.  */
69538fd1498Szrj   maybe_default_options (opts, opts_set,
69638fd1498Szrj 			 targetm_common.option_optimization_table,
69738fd1498Szrj 			 opts->x_optimize, opts->x_optimize_size,
69838fd1498Szrj 			 opts->x_optimize_fast, opts->x_optimize_debug,
69938fd1498Szrj 			 lang_mask, handlers, loc, dc);
70038fd1498Szrj }
70138fd1498Szrj 
70238fd1498Szrj /* After all options at LOC have been read into OPTS and OPTS_SET,
70338fd1498Szrj    finalize settings of those options and diagnose incompatible
70438fd1498Szrj    combinations.  */
70538fd1498Szrj void
finish_options(struct gcc_options * opts,struct gcc_options * opts_set,location_t loc)70638fd1498Szrj finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
70738fd1498Szrj 		location_t loc)
70838fd1498Szrj {
70938fd1498Szrj   enum unwind_info_type ui_except;
71038fd1498Szrj 
71138fd1498Szrj   if (opts->x_dump_base_name
71238fd1498Szrj       && ! opts->x_dump_base_name_prefixed)
71338fd1498Szrj     {
71438fd1498Szrj       const char *sep = opts->x_dump_base_name;
71538fd1498Szrj 
71638fd1498Szrj       for (; *sep; sep++)
71738fd1498Szrj 	if (IS_DIR_SEPARATOR (*sep))
71838fd1498Szrj 	  break;
71938fd1498Szrj 
72038fd1498Szrj       if (*sep)
72138fd1498Szrj 	/* If dump_base_path contains subdirectories, don't prepend
72238fd1498Szrj 	   anything.  */;
72338fd1498Szrj       else if (opts->x_dump_dir_name)
72438fd1498Szrj 	/* We have a DUMP_DIR_NAME, prepend that.  */
72538fd1498Szrj 	opts->x_dump_base_name = opts_concat (opts->x_dump_dir_name,
72638fd1498Szrj 					      opts->x_dump_base_name, NULL);
72738fd1498Szrj       else if (opts->x_aux_base_name
72838fd1498Szrj 	       && strcmp (opts->x_aux_base_name, HOST_BIT_BUCKET) != 0)
72938fd1498Szrj 	/* AUX_BASE_NAME is set and is not the bit bucket.  If it
73038fd1498Szrj 	   contains a directory component, prepend those directories.
73138fd1498Szrj 	   Typically this places things in the same directory as the
73238fd1498Szrj 	   object file.  */
73338fd1498Szrj 	{
73438fd1498Szrj 	  const char *aux_base;
73538fd1498Szrj 
73638fd1498Szrj 	  base_of_path (opts->x_aux_base_name, &aux_base);
73738fd1498Szrj 	  if (opts->x_aux_base_name != aux_base)
73838fd1498Szrj 	    {
73938fd1498Szrj 	      int dir_len = aux_base - opts->x_aux_base_name;
74038fd1498Szrj 	      char *new_dump_base_name
74138fd1498Szrj 		= XOBNEWVEC (&opts_obstack, char,
74238fd1498Szrj 			     strlen (opts->x_dump_base_name) + dir_len + 1);
74338fd1498Szrj 
74438fd1498Szrj 	      /* Copy directory component from OPTS->X_AUX_BASE_NAME.  */
74538fd1498Szrj 	      memcpy (new_dump_base_name, opts->x_aux_base_name, dir_len);
74638fd1498Szrj 	      /* Append existing OPTS->X_DUMP_BASE_NAME.  */
74738fd1498Szrj 	      strcpy (new_dump_base_name + dir_len, opts->x_dump_base_name);
74838fd1498Szrj 	      opts->x_dump_base_name = new_dump_base_name;
74938fd1498Szrj 	    }
75038fd1498Szrj 	}
75138fd1498Szrj 
75238fd1498Szrj       /* It is definitely prefixed now.  */
75338fd1498Szrj       opts->x_dump_base_name_prefixed = true;
75438fd1498Szrj     }
75538fd1498Szrj 
75638fd1498Szrj   /* Handle related options for unit-at-a-time, toplevel-reorder, and
75738fd1498Szrj      section-anchors.  */
75838fd1498Szrj   if (!opts->x_flag_unit_at_a_time)
75938fd1498Szrj     {
76038fd1498Szrj       if (opts->x_flag_section_anchors && opts_set->x_flag_section_anchors)
76138fd1498Szrj 	error_at (loc, "section anchors must be disabled when unit-at-a-time "
76238fd1498Szrj 		  "is disabled");
76338fd1498Szrj       opts->x_flag_section_anchors = 0;
76438fd1498Szrj       if (opts->x_flag_toplevel_reorder == 1)
76538fd1498Szrj 	error_at (loc, "toplevel reorder must be disabled when unit-at-a-time "
76638fd1498Szrj 		  "is disabled");
76738fd1498Szrj       opts->x_flag_toplevel_reorder = 0;
76838fd1498Szrj     }
76938fd1498Szrj 
77038fd1498Szrj   /* -fself-test depends on the state of the compiler prior to
77138fd1498Szrj      compiling anything.  Ideally it should be run on an empty source
77238fd1498Szrj      file.  However, in case we get run with actual source, assume
77338fd1498Szrj      -fsyntax-only which will inhibit any compiler initialization
77438fd1498Szrj      which may confuse the self tests.  */
77538fd1498Szrj   if (opts->x_flag_self_test)
77638fd1498Szrj     opts->x_flag_syntax_only = 1;
77738fd1498Szrj 
77838fd1498Szrj   if (opts->x_flag_tm && opts->x_flag_non_call_exceptions)
77938fd1498Szrj     sorry ("transactional memory is not supported with non-call exceptions");
78038fd1498Szrj 
78138fd1498Szrj   /* Unless the user has asked for section anchors, we disable toplevel
78238fd1498Szrj      reordering at -O0 to disable transformations that might be surprising
78338fd1498Szrj      to end users and to get -fno-toplevel-reorder tested.  */
78438fd1498Szrj   if (!opts->x_optimize
78538fd1498Szrj       && opts->x_flag_toplevel_reorder == 2
78638fd1498Szrj       && !(opts->x_flag_section_anchors && opts_set->x_flag_section_anchors))
78738fd1498Szrj     {
78838fd1498Szrj       opts->x_flag_toplevel_reorder = 0;
78938fd1498Szrj       opts->x_flag_section_anchors = 0;
79038fd1498Szrj     }
79138fd1498Szrj   if (!opts->x_flag_toplevel_reorder)
79238fd1498Szrj     {
79338fd1498Szrj       if (opts->x_flag_section_anchors && opts_set->x_flag_section_anchors)
79438fd1498Szrj 	error_at (loc, "section anchors must be disabled when toplevel reorder"
79538fd1498Szrj 		  " is disabled");
79638fd1498Szrj       opts->x_flag_section_anchors = 0;
79738fd1498Szrj     }
79838fd1498Szrj 
79938fd1498Szrj   if (!opts->x_flag_opts_finished)
80038fd1498Szrj     {
80138fd1498Szrj       /* We initialize opts->x_flag_pie to -1 so that targets can set a
80238fd1498Szrj 	 default value.  */
80338fd1498Szrj       if (opts->x_flag_pie == -1)
80438fd1498Szrj 	{
80538fd1498Szrj 	  /* We initialize opts->x_flag_pic to -1 so that we can tell if
80638fd1498Szrj 	     -fpic, -fPIC, -fno-pic or -fno-PIC is used.  */
80738fd1498Szrj 	  if (opts->x_flag_pic == -1)
80838fd1498Szrj 	    opts->x_flag_pie = DEFAULT_FLAG_PIE;
80938fd1498Szrj 	  else
81038fd1498Szrj 	    opts->x_flag_pie = 0;
81138fd1498Szrj 	}
81238fd1498Szrj       /* If -fPIE or -fpie is used, turn on PIC.  */
81338fd1498Szrj       if (opts->x_flag_pie)
81438fd1498Szrj 	opts->x_flag_pic = opts->x_flag_pie;
81538fd1498Szrj       else if (opts->x_flag_pic == -1)
81638fd1498Szrj 	opts->x_flag_pic = 0;
81738fd1498Szrj       if (opts->x_flag_pic && !opts->x_flag_pie)
81838fd1498Szrj 	opts->x_flag_shlib = 1;
81938fd1498Szrj       opts->x_flag_opts_finished = true;
82038fd1498Szrj     }
82138fd1498Szrj 
82238fd1498Szrj   /* We initialize opts->x_flag_stack_protect to -1 so that targets
82338fd1498Szrj      can set a default value.  */
82438fd1498Szrj   if (opts->x_flag_stack_protect == -1)
82538fd1498Szrj     opts->x_flag_stack_protect = DEFAULT_FLAG_SSP;
82638fd1498Szrj 
82738fd1498Szrj   if (opts->x_optimize == 0)
82838fd1498Szrj     {
82938fd1498Szrj       /* Inlining does not work if not optimizing,
83038fd1498Szrj 	 so force it not to be done.  */
83138fd1498Szrj       opts->x_warn_inline = 0;
83238fd1498Szrj       opts->x_flag_no_inline = 1;
83338fd1498Szrj     }
83438fd1498Szrj 
83538fd1498Szrj   /* The optimization to partition hot and cold basic blocks into separate
83638fd1498Szrj      sections of the .o and executable files does not work (currently)
83738fd1498Szrj      with exception handling.  This is because there is no support for
83838fd1498Szrj      generating unwind info.  If opts->x_flag_exceptions is turned on
83938fd1498Szrj      we need to turn off the partitioning optimization.  */
84038fd1498Szrj 
84138fd1498Szrj   ui_except = targetm_common.except_unwind_info (opts);
84238fd1498Szrj 
84338fd1498Szrj   if (opts->x_flag_exceptions
84438fd1498Szrj       && opts->x_flag_reorder_blocks_and_partition
84538fd1498Szrj       && (ui_except == UI_SJLJ || ui_except >= UI_TARGET))
84638fd1498Szrj     {
84738fd1498Szrj       if (opts_set->x_flag_reorder_blocks_and_partition)
84838fd1498Szrj         inform (loc,
84938fd1498Szrj 		"%<-freorder-blocks-and-partition%> does not work "
85038fd1498Szrj 		"with exceptions on this architecture");
85138fd1498Szrj       opts->x_flag_reorder_blocks_and_partition = 0;
85238fd1498Szrj       opts->x_flag_reorder_blocks = 1;
85338fd1498Szrj     }
85438fd1498Szrj 
85538fd1498Szrj   /* If user requested unwind info, then turn off the partitioning
85638fd1498Szrj      optimization.  */
85738fd1498Szrj 
85838fd1498Szrj   if (opts->x_flag_unwind_tables
85938fd1498Szrj       && !targetm_common.unwind_tables_default
86038fd1498Szrj       && opts->x_flag_reorder_blocks_and_partition
86138fd1498Szrj       && (ui_except == UI_SJLJ || ui_except >= UI_TARGET))
86238fd1498Szrj     {
86338fd1498Szrj       if (opts_set->x_flag_reorder_blocks_and_partition)
86438fd1498Szrj         inform (loc,
86538fd1498Szrj 		"%<-freorder-blocks-and-partition%> does not support "
86638fd1498Szrj 		"unwind info on this architecture");
86738fd1498Szrj       opts->x_flag_reorder_blocks_and_partition = 0;
86838fd1498Szrj       opts->x_flag_reorder_blocks = 1;
86938fd1498Szrj     }
87038fd1498Szrj 
87138fd1498Szrj   /* If the target requested unwind info, then turn off the partitioning
87238fd1498Szrj      optimization with a different message.  Likewise, if the target does not
87338fd1498Szrj      support named sections.  */
87438fd1498Szrj 
87538fd1498Szrj   if (opts->x_flag_reorder_blocks_and_partition
87638fd1498Szrj       && (!targetm_common.have_named_sections
87738fd1498Szrj 	  || (opts->x_flag_unwind_tables
87838fd1498Szrj 	      && targetm_common.unwind_tables_default
87938fd1498Szrj 	      && (ui_except == UI_SJLJ || ui_except >= UI_TARGET))))
88038fd1498Szrj     {
88138fd1498Szrj       if (opts_set->x_flag_reorder_blocks_and_partition)
88238fd1498Szrj         inform (loc,
88338fd1498Szrj 		"%<-freorder-blocks-and-partition%> does not work "
88438fd1498Szrj 		"on this architecture");
88538fd1498Szrj       opts->x_flag_reorder_blocks_and_partition = 0;
88638fd1498Szrj       opts->x_flag_reorder_blocks = 1;
88738fd1498Szrj     }
88838fd1498Szrj 
88938fd1498Szrj 
89038fd1498Szrj   /* Pipelining of outer loops is only possible when general pipelining
89138fd1498Szrj      capabilities are requested.  */
89238fd1498Szrj   if (!opts->x_flag_sel_sched_pipelining)
89338fd1498Szrj     opts->x_flag_sel_sched_pipelining_outer_loops = 0;
89438fd1498Szrj 
89538fd1498Szrj   if (opts->x_flag_conserve_stack)
89638fd1498Szrj     {
89738fd1498Szrj       maybe_set_param_value (PARAM_LARGE_STACK_FRAME, 100,
89838fd1498Szrj 			     opts->x_param_values, opts_set->x_param_values);
89938fd1498Szrj       maybe_set_param_value (PARAM_STACK_FRAME_GROWTH, 40,
90038fd1498Szrj 			     opts->x_param_values, opts_set->x_param_values);
90138fd1498Szrj     }
90238fd1498Szrj 
90338fd1498Szrj   if (opts->x_flag_lto)
90438fd1498Szrj     {
90538fd1498Szrj #ifdef ENABLE_LTO
90638fd1498Szrj       opts->x_flag_generate_lto = 1;
90738fd1498Szrj 
90838fd1498Szrj       /* When generating IL, do not operate in whole-program mode.
90938fd1498Szrj 	 Otherwise, symbols will be privatized too early, causing link
91038fd1498Szrj 	 errors later.  */
91138fd1498Szrj       opts->x_flag_whole_program = 0;
91238fd1498Szrj #else
91338fd1498Szrj       error_at (loc, "LTO support has not been enabled in this configuration");
91438fd1498Szrj #endif
91538fd1498Szrj       if (!opts->x_flag_fat_lto_objects
91638fd1498Szrj 	  && (!HAVE_LTO_PLUGIN
91738fd1498Szrj 	      || (opts_set->x_flag_use_linker_plugin
91838fd1498Szrj 		  && !opts->x_flag_use_linker_plugin)))
91938fd1498Szrj 	{
92038fd1498Szrj 	  if (opts_set->x_flag_fat_lto_objects)
92138fd1498Szrj 	    error_at (loc, "%<-fno-fat-lto-objects%> are supported only with "
92238fd1498Szrj 		      "linker plugin");
92338fd1498Szrj 	  opts->x_flag_fat_lto_objects = 1;
92438fd1498Szrj 	}
925*e215fc28Szrj 
926*e215fc28Szrj       /* -gsplit-dwarf isn't compatible with LTO, see PR88389.  */
927*e215fc28Szrj       if (opts->x_dwarf_split_debug_info)
928*e215fc28Szrj 	{
929*e215fc28Szrj 	  inform (loc, "%<-gsplit-dwarf%> is not supported with LTO,"
930*e215fc28Szrj 		  " disabling");
931*e215fc28Szrj 	  opts->x_dwarf_split_debug_info = 0;
932*e215fc28Szrj 	}
93338fd1498Szrj     }
93438fd1498Szrj 
93538fd1498Szrj   /* We initialize opts->x_flag_split_stack to -1 so that targets can set a
93638fd1498Szrj      default value if they choose based on other options.  */
93738fd1498Szrj   if (opts->x_flag_split_stack == -1)
93838fd1498Szrj     opts->x_flag_split_stack = 0;
93938fd1498Szrj   else if (opts->x_flag_split_stack)
94038fd1498Szrj     {
94138fd1498Szrj       if (!targetm_common.supports_split_stack (true, opts))
94238fd1498Szrj 	{
94338fd1498Szrj 	  error_at (loc, "%<-fsplit-stack%> is not supported by "
94438fd1498Szrj 		    "this compiler configuration");
94538fd1498Szrj 	  opts->x_flag_split_stack = 0;
94638fd1498Szrj 	}
94738fd1498Szrj     }
94838fd1498Szrj 
94938fd1498Szrj   /* If stack splitting is turned on, and the user did not explicitly
95038fd1498Szrj      request function partitioning, turn off partitioning, as it
95138fd1498Szrj      confuses the linker when trying to handle partitioned split-stack
95238fd1498Szrj      code that calls a non-split-stack functions.  But if partitioning
95338fd1498Szrj      was turned on explicitly just hope for the best.  */
95438fd1498Szrj   if (opts->x_flag_split_stack
95538fd1498Szrj       && opts->x_flag_reorder_blocks_and_partition
95638fd1498Szrj       && !opts_set->x_flag_reorder_blocks_and_partition)
95738fd1498Szrj     opts->x_flag_reorder_blocks_and_partition = 0;
95838fd1498Szrj 
95938fd1498Szrj   if (opts->x_flag_reorder_blocks_and_partition
96038fd1498Szrj       && !opts_set->x_flag_reorder_functions)
96138fd1498Szrj     opts->x_flag_reorder_functions = 1;
96238fd1498Szrj 
96338fd1498Szrj   /* Tune vectorization related parametees according to cost model.  */
96438fd1498Szrj   if (opts->x_flag_vect_cost_model == VECT_COST_MODEL_CHEAP)
96538fd1498Szrj     {
96638fd1498Szrj       maybe_set_param_value (PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS,
96738fd1498Szrj             6, opts->x_param_values, opts_set->x_param_values);
96838fd1498Szrj       maybe_set_param_value (PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS,
96938fd1498Szrj             0, opts->x_param_values, opts_set->x_param_values);
97038fd1498Szrj       maybe_set_param_value (PARAM_VECT_MAX_PEELING_FOR_ALIGNMENT,
97138fd1498Szrj             0, opts->x_param_values, opts_set->x_param_values);
97238fd1498Szrj     }
97338fd1498Szrj 
97438fd1498Szrj   /* Set PARAM_MAX_STORES_TO_SINK to 0 if either vectorization or if-conversion
97538fd1498Szrj      is disabled.  */
97638fd1498Szrj   if ((!opts->x_flag_tree_loop_vectorize && !opts->x_flag_tree_slp_vectorize)
97738fd1498Szrj        || !opts->x_flag_tree_loop_if_convert)
97838fd1498Szrj     maybe_set_param_value (PARAM_MAX_STORES_TO_SINK, 0,
97938fd1498Szrj                            opts->x_param_values, opts_set->x_param_values);
98038fd1498Szrj 
98138fd1498Szrj   /* The -gsplit-dwarf option requires -ggnu-pubnames.  */
98238fd1498Szrj   if (opts->x_dwarf_split_debug_info)
98338fd1498Szrj     opts->x_debug_generate_pub_sections = 2;
98438fd1498Szrj 
98538fd1498Szrj   if ((opts->x_flag_sanitize
98638fd1498Szrj        & (SANITIZE_USER_ADDRESS | SANITIZE_KERNEL_ADDRESS)) == 0)
98738fd1498Szrj     {
98838fd1498Szrj       if (opts->x_flag_sanitize & SANITIZE_POINTER_COMPARE)
98938fd1498Szrj 	error_at (loc,
99038fd1498Szrj 		  "%<-fsanitize=pointer-compare%> must be combined with "
99138fd1498Szrj 		  "%<-fsanitize=address%> or %<-fsanitize=kernel-address%>");
99238fd1498Szrj       if (opts->x_flag_sanitize & SANITIZE_POINTER_SUBTRACT)
99338fd1498Szrj 	error_at (loc,
99438fd1498Szrj 		  "%<-fsanitize=pointer-subtract%> must be combined with "
99538fd1498Szrj 		  "%<-fsanitize=address%> or %<-fsanitize=kernel-address%>");
99638fd1498Szrj     }
99738fd1498Szrj 
99838fd1498Szrj   /* Userspace and kernel ASan conflict with each other.  */
99938fd1498Szrj   if ((opts->x_flag_sanitize & SANITIZE_USER_ADDRESS)
100038fd1498Szrj       && (opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS))
100138fd1498Szrj     error_at (loc,
100238fd1498Szrj 	      "%<-fsanitize=address%> is incompatible with "
100338fd1498Szrj 	      "%<-fsanitize=kernel-address%>");
100438fd1498Szrj 
100538fd1498Szrj   /* And with TSan.  */
100638fd1498Szrj   if ((opts->x_flag_sanitize & SANITIZE_ADDRESS)
100738fd1498Szrj       && (opts->x_flag_sanitize & SANITIZE_THREAD))
100838fd1498Szrj     error_at (loc,
100938fd1498Szrj 	      "%<-fsanitize=address%> and %<-fsanitize=kernel-address%> "
101038fd1498Szrj 	      "are incompatible with %<-fsanitize=thread%>");
101138fd1498Szrj 
101238fd1498Szrj   if ((opts->x_flag_sanitize & SANITIZE_LEAK)
101338fd1498Szrj       && (opts->x_flag_sanitize & SANITIZE_THREAD))
101438fd1498Szrj     error_at (loc,
101538fd1498Szrj 	      "%<-fsanitize=leak%> is incompatible with %<-fsanitize=thread%>");
101638fd1498Szrj 
101738fd1498Szrj   /* Check error recovery for -fsanitize-recover option.  */
101838fd1498Szrj   for (int i = 0; sanitizer_opts[i].name != NULL; ++i)
101938fd1498Szrj     if ((opts->x_flag_sanitize_recover & sanitizer_opts[i].flag)
102038fd1498Szrj 	&& !sanitizer_opts[i].can_recover)
102138fd1498Szrj       error_at (loc, "%<-fsanitize-recover=%s%> is not supported",
102238fd1498Szrj 		sanitizer_opts[i].name);
102338fd1498Szrj 
102438fd1498Szrj   /* When instrumenting the pointers, we don't want to remove
102538fd1498Szrj      the null pointer checks.  */
102638fd1498Szrj   if (opts->x_flag_sanitize & (SANITIZE_NULL | SANITIZE_NONNULL_ATTRIBUTE
102738fd1498Szrj 				| SANITIZE_RETURNS_NONNULL_ATTRIBUTE))
102838fd1498Szrj     opts->x_flag_delete_null_pointer_checks = 0;
102938fd1498Szrj 
103038fd1498Szrj   /* Aggressive compiler optimizations may cause false negatives.  */
103138fd1498Szrj   if (opts->x_flag_sanitize & ~(SANITIZE_LEAK | SANITIZE_UNREACHABLE))
103238fd1498Szrj     opts->x_flag_aggressive_loop_optimizations = 0;
103338fd1498Szrj 
103438fd1498Szrj   /* Enable -fsanitize-address-use-after-scope if address sanitizer is
103538fd1498Szrj      enabled.  */
103638fd1498Szrj   if ((opts->x_flag_sanitize & SANITIZE_USER_ADDRESS)
103738fd1498Szrj       && !opts_set->x_flag_sanitize_address_use_after_scope)
103838fd1498Szrj     opts->x_flag_sanitize_address_use_after_scope = true;
103938fd1498Szrj 
104038fd1498Szrj   /* Force -fstack-reuse=none in case -fsanitize-address-use-after-scope
104138fd1498Szrj      is enabled.  */
104238fd1498Szrj   if (opts->x_flag_sanitize_address_use_after_scope)
104338fd1498Szrj     {
104438fd1498Szrj       if (opts->x_flag_stack_reuse != SR_NONE
104538fd1498Szrj 	  && opts_set->x_flag_stack_reuse != SR_NONE)
104638fd1498Szrj 	error_at (loc,
104738fd1498Szrj 		  "%<-fsanitize-address-use-after-scope%> requires "
104838fd1498Szrj 		  "%<-fstack-reuse=none%> option");
104938fd1498Szrj 
105038fd1498Szrj       opts->x_flag_stack_reuse = SR_NONE;
105138fd1498Szrj     }
105238fd1498Szrj 
105338fd1498Szrj   if ((opts->x_flag_sanitize & SANITIZE_USER_ADDRESS) && opts->x_flag_tm)
105438fd1498Szrj     sorry ("transactional memory is not supported with %<-fsanitize=address%>");
105538fd1498Szrj 
105638fd1498Szrj   if ((opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS) && opts->x_flag_tm)
105738fd1498Szrj     sorry ("transactional memory is not supported with "
105838fd1498Szrj 	   "%<-fsanitize=kernel-address%>");
105938fd1498Szrj 
106038fd1498Szrj   /* Comes from final.c -- no real reason to change it.  */
106138fd1498Szrj #define MAX_CODE_ALIGN 16
106238fd1498Szrj #define MAX_CODE_ALIGN_VALUE (1 << MAX_CODE_ALIGN)
106338fd1498Szrj 
106438fd1498Szrj   if (opts->x_align_loops > MAX_CODE_ALIGN_VALUE)
106538fd1498Szrj     error_at (loc, "-falign-loops=%d is not between 0 and %d",
106638fd1498Szrj 	      opts->x_align_loops, MAX_CODE_ALIGN_VALUE);
106738fd1498Szrj 
106838fd1498Szrj   if (opts->x_align_jumps > MAX_CODE_ALIGN_VALUE)
106938fd1498Szrj     error_at (loc, "-falign-jumps=%d is not between 0 and %d",
107038fd1498Szrj 	      opts->x_align_jumps, MAX_CODE_ALIGN_VALUE);
107138fd1498Szrj 
107238fd1498Szrj   if (opts->x_align_functions > MAX_CODE_ALIGN_VALUE)
107338fd1498Szrj     error_at (loc, "-falign-functions=%d is not between 0 and %d",
107438fd1498Szrj 	      opts->x_align_functions, MAX_CODE_ALIGN_VALUE);
107538fd1498Szrj 
107638fd1498Szrj   if (opts->x_align_labels > MAX_CODE_ALIGN_VALUE)
107738fd1498Szrj     error_at (loc, "-falign-labels=%d is not between 0 and %d",
107838fd1498Szrj 	      opts->x_align_labels, MAX_CODE_ALIGN_VALUE);
107938fd1498Szrj }
108038fd1498Szrj 
108138fd1498Szrj #define LEFT_COLUMN	27
108238fd1498Szrj 
108338fd1498Szrj /* Output ITEM, of length ITEM_WIDTH, in the left column,
108438fd1498Szrj    followed by word-wrapped HELP in a second column.  */
108538fd1498Szrj static void
wrap_help(const char * help,const char * item,unsigned int item_width,unsigned int columns)108638fd1498Szrj wrap_help (const char *help,
108738fd1498Szrj 	   const char *item,
108838fd1498Szrj 	   unsigned int item_width,
108938fd1498Szrj 	   unsigned int columns)
109038fd1498Szrj {
109138fd1498Szrj   unsigned int col_width = LEFT_COLUMN;
109238fd1498Szrj   unsigned int remaining, room, len;
109338fd1498Szrj 
109438fd1498Szrj   remaining = strlen (help);
109538fd1498Szrj 
109638fd1498Szrj   do
109738fd1498Szrj     {
109838fd1498Szrj       room = columns - 3 - MAX (col_width, item_width);
109938fd1498Szrj       if (room > columns)
110038fd1498Szrj 	room = 0;
110138fd1498Szrj       len = remaining;
110238fd1498Szrj 
110338fd1498Szrj       if (room < len)
110438fd1498Szrj 	{
110538fd1498Szrj 	  unsigned int i;
110638fd1498Szrj 
110738fd1498Szrj 	  for (i = 0; help[i]; i++)
110838fd1498Szrj 	    {
110938fd1498Szrj 	      if (i >= room && len != remaining)
111038fd1498Szrj 		break;
111138fd1498Szrj 	      if (help[i] == ' ')
111238fd1498Szrj 		len = i;
111338fd1498Szrj 	      else if ((help[i] == '-' || help[i] == '/')
111438fd1498Szrj 		       && help[i + 1] != ' '
111538fd1498Szrj 		       && i > 0 && ISALPHA (help[i - 1]))
111638fd1498Szrj 		len = i + 1;
111738fd1498Szrj 	    }
111838fd1498Szrj 	}
111938fd1498Szrj 
112038fd1498Szrj       printf ("  %-*.*s %.*s\n", col_width, item_width, item, len, help);
112138fd1498Szrj       item_width = 0;
112238fd1498Szrj       while (help[len] == ' ')
112338fd1498Szrj 	len++;
112438fd1498Szrj       help += len;
112538fd1498Szrj       remaining -= len;
112638fd1498Szrj     }
112738fd1498Szrj   while (remaining);
112838fd1498Szrj }
112938fd1498Szrj 
113038fd1498Szrj /* Print help for a specific front-end, etc.  */
113138fd1498Szrj static void
print_filtered_help(unsigned int include_flags,unsigned int exclude_flags,unsigned int any_flags,unsigned int columns,struct gcc_options * opts,unsigned int lang_mask)113238fd1498Szrj print_filtered_help (unsigned int include_flags,
113338fd1498Szrj 		     unsigned int exclude_flags,
113438fd1498Szrj 		     unsigned int any_flags,
113538fd1498Szrj 		     unsigned int columns,
113638fd1498Szrj 		     struct gcc_options *opts,
113738fd1498Szrj 		     unsigned int lang_mask)
113838fd1498Szrj {
113938fd1498Szrj   unsigned int i;
114038fd1498Szrj   const char *help;
114138fd1498Szrj   bool found = false;
114238fd1498Szrj   bool displayed = false;
114338fd1498Szrj   char new_help[256];
114438fd1498Szrj 
114538fd1498Szrj   if (include_flags == CL_PARAMS)
114638fd1498Szrj     {
114738fd1498Szrj       for (i = 0; i < LAST_PARAM; i++)
114838fd1498Szrj 	{
114938fd1498Szrj 	  const char *param = compiler_params[i].option;
115038fd1498Szrj 
115138fd1498Szrj 	  help = compiler_params[i].help;
115238fd1498Szrj 	  if (help == NULL || *help == '\0')
115338fd1498Szrj 	    {
115438fd1498Szrj 	      if (exclude_flags & CL_UNDOCUMENTED)
115538fd1498Szrj 		continue;
115638fd1498Szrj 	      help = undocumented_msg;
115738fd1498Szrj 	    }
115838fd1498Szrj 
115938fd1498Szrj 	  /* Get the translation.  */
116038fd1498Szrj 	  help = _(help);
116138fd1498Szrj 
116238fd1498Szrj 	  if (!opts->x_quiet_flag)
116338fd1498Szrj 	    {
116438fd1498Szrj 	      snprintf (new_help, sizeof (new_help),
116538fd1498Szrj 			_("default %d minimum %d maximum %d"),
116638fd1498Szrj 			compiler_params[i].default_value,
116738fd1498Szrj 			compiler_params[i].min_value,
116838fd1498Szrj 			compiler_params[i].max_value);
116938fd1498Szrj 	      help = new_help;
117038fd1498Szrj 	    }
117138fd1498Szrj 	  wrap_help (help, param, strlen (param), columns);
117238fd1498Szrj 	}
117338fd1498Szrj       putchar ('\n');
117438fd1498Szrj       return;
117538fd1498Szrj     }
117638fd1498Szrj 
117738fd1498Szrj   if (!opts->x_help_printed)
117838fd1498Szrj     opts->x_help_printed = XCNEWVAR (char, cl_options_count);
117938fd1498Szrj 
118038fd1498Szrj   if (!opts->x_help_enum_printed)
118138fd1498Szrj     opts->x_help_enum_printed = XCNEWVAR (char, cl_enums_count);
118238fd1498Szrj 
118338fd1498Szrj   for (i = 0; i < cl_options_count; i++)
118438fd1498Szrj     {
118538fd1498Szrj       const struct cl_option *option = cl_options + i;
118638fd1498Szrj       unsigned int len;
118738fd1498Szrj       const char *opt;
118838fd1498Szrj       const char *tab;
118938fd1498Szrj 
119038fd1498Szrj       if (include_flags == 0
119138fd1498Szrj 	  || ((option->flags & include_flags) != include_flags))
119238fd1498Szrj 	{
119338fd1498Szrj 	  if ((option->flags & any_flags) == 0)
119438fd1498Szrj 	    continue;
119538fd1498Szrj 	}
119638fd1498Szrj 
119738fd1498Szrj       /* Skip unwanted switches.  */
119838fd1498Szrj       if ((option->flags & exclude_flags) != 0)
119938fd1498Szrj 	continue;
120038fd1498Szrj 
120138fd1498Szrj       /* The driver currently prints its own help text.  */
120238fd1498Szrj       if ((option->flags & CL_DRIVER) != 0
120338fd1498Szrj 	  && (option->flags & (((1U << cl_lang_count) - 1)
120438fd1498Szrj 			       | CL_COMMON | CL_TARGET)) == 0)
120538fd1498Szrj 	continue;
120638fd1498Szrj 
120738fd1498Szrj       found = true;
120838fd1498Szrj       /* Skip switches that have already been printed.  */
120938fd1498Szrj       if (opts->x_help_printed[i])
121038fd1498Szrj 	continue;
121138fd1498Szrj 
121238fd1498Szrj       opts->x_help_printed[i] = true;
121338fd1498Szrj 
121438fd1498Szrj       help = option->help;
121538fd1498Szrj       if (help == NULL)
121638fd1498Szrj 	{
121738fd1498Szrj 	  if (exclude_flags & CL_UNDOCUMENTED)
121838fd1498Szrj 	    continue;
121938fd1498Szrj 
122038fd1498Szrj 	  help = undocumented_msg;
122138fd1498Szrj 	}
122238fd1498Szrj 
122338fd1498Szrj       if (option->alias_target < N_OPTS
122438fd1498Szrj 	  && cl_options [option->alias_target].help)
122538fd1498Szrj 	{
122638fd1498Szrj 	  if (help == undocumented_msg)
122738fd1498Szrj 	    {
122838fd1498Szrj 	      /* For undocumented options that are aliases for other options
122938fd1498Szrj 		 that are documented, point the reader to the other option in
123038fd1498Szrj 		 preference of the former.  */
123138fd1498Szrj 	      snprintf (new_help, sizeof new_help,
123238fd1498Szrj 			_("Same as %s.  Use the latter option instead."),
123338fd1498Szrj 			cl_options [option->alias_target].opt_text);
123438fd1498Szrj 	    }
123538fd1498Szrj 	  else
123638fd1498Szrj 	    {
123738fd1498Szrj 	      /* For documented options with aliases, mention the aliased
123838fd1498Szrj 		 option's name for reference.  */
123938fd1498Szrj 	      snprintf (new_help, sizeof new_help,
124038fd1498Szrj 			_("%s  Same as %s."),
124138fd1498Szrj 			help, cl_options [option->alias_target].opt_text);
124238fd1498Szrj 	    }
124338fd1498Szrj 
124438fd1498Szrj 	  help = new_help;
124538fd1498Szrj 	}
124638fd1498Szrj 
124738fd1498Szrj       if (option->warn_message)
124838fd1498Szrj 	{
124938fd1498Szrj 	  /* Mention that the use of the option will trigger a warning.  */
125038fd1498Szrj 	  if (help == new_help)
125138fd1498Szrj 	    snprintf (new_help + strlen (new_help),
125238fd1498Szrj 		      sizeof new_help - strlen (new_help),
125338fd1498Szrj 		      "  %s", _(use_diagnosed_msg));
125438fd1498Szrj 	  else
125538fd1498Szrj 	    snprintf (new_help, sizeof new_help,
125638fd1498Szrj 		      "%s  %s", help, _(use_diagnosed_msg));
125738fd1498Szrj 
125838fd1498Szrj 	  help = new_help;
125938fd1498Szrj 	}
126038fd1498Szrj 
126138fd1498Szrj       /* Get the translation.  */
126238fd1498Szrj       help = _(help);
126338fd1498Szrj 
126438fd1498Szrj       /* Find the gap between the name of the
126538fd1498Szrj 	 option and its descriptive text.  */
126638fd1498Szrj       tab = strchr (help, '\t');
126738fd1498Szrj       if (tab)
126838fd1498Szrj 	{
126938fd1498Szrj 	  len = tab - help;
127038fd1498Szrj 	  opt = help;
127138fd1498Szrj 	  help = tab + 1;
127238fd1498Szrj 	}
127338fd1498Szrj       else
127438fd1498Szrj 	{
127538fd1498Szrj 	  opt = option->opt_text;
127638fd1498Szrj 	  len = strlen (opt);
127738fd1498Szrj 	}
127838fd1498Szrj 
127938fd1498Szrj       /* With the -Q option enabled we change the descriptive text associated
128038fd1498Szrj 	 with an option to be an indication of its current setting.  */
128138fd1498Szrj       if (!opts->x_quiet_flag)
128238fd1498Szrj 	{
128338fd1498Szrj 	  void *flag_var = option_flag_var (i, opts);
128438fd1498Szrj 
128538fd1498Szrj 	  if (len < (LEFT_COLUMN + 2))
128638fd1498Szrj 	    strcpy (new_help, "\t\t");
128738fd1498Szrj 	  else
128838fd1498Szrj 	    strcpy (new_help, "\t");
128938fd1498Szrj 
129038fd1498Szrj 	  if (flag_var != NULL
129138fd1498Szrj 	      && option->var_type != CLVC_DEFER)
129238fd1498Szrj 	    {
129338fd1498Szrj 	      if (option->flags & CL_JOINED)
129438fd1498Szrj 		{
129538fd1498Szrj 		  if (option->var_type == CLVC_STRING)
129638fd1498Szrj 		    {
129738fd1498Szrj 		      if (* (const char **) flag_var != NULL)
129838fd1498Szrj 			snprintf (new_help + strlen (new_help),
129938fd1498Szrj 				  sizeof (new_help) - strlen (new_help),
130038fd1498Szrj 				  "%s", * (const char **) flag_var);
130138fd1498Szrj 		    }
130238fd1498Szrj 		  else if (option->var_type == CLVC_ENUM)
130338fd1498Szrj 		    {
130438fd1498Szrj 		      const struct cl_enum *e = &cl_enums[option->var_enum];
130538fd1498Szrj 		      int value;
130638fd1498Szrj 		      const char *arg = NULL;
130738fd1498Szrj 
130838fd1498Szrj 		      value = e->get (flag_var);
130938fd1498Szrj 		      enum_value_to_arg (e->values, &arg, value, lang_mask);
131038fd1498Szrj 		      if (arg == NULL)
131138fd1498Szrj 			arg = _("[default]");
131238fd1498Szrj 		      snprintf (new_help + strlen (new_help),
131338fd1498Szrj 				sizeof (new_help) - strlen (new_help),
131438fd1498Szrj 				"%s", arg);
131538fd1498Szrj 		    }
131638fd1498Szrj 		  else
131738fd1498Szrj 		    sprintf (new_help + strlen (new_help),
131838fd1498Szrj 			     "%d", * (int *) flag_var);
131938fd1498Szrj 		}
132038fd1498Szrj 	      else
132138fd1498Szrj 		strcat (new_help, option_enabled (i, opts)
132238fd1498Szrj 			? _("[enabled]") : _("[disabled]"));
132338fd1498Szrj 	    }
132438fd1498Szrj 
132538fd1498Szrj 	  help = new_help;
132638fd1498Szrj 	}
132738fd1498Szrj 
132838fd1498Szrj       if (option->range_max != -1)
132938fd1498Szrj 	{
133038fd1498Szrj 	  char b[128];
133138fd1498Szrj 	  snprintf (b, sizeof (b), "<%d,%d>", option->range_min,
133238fd1498Szrj 		    option->range_max);
133338fd1498Szrj 	  opt = concat (opt, b, NULL);
133438fd1498Szrj 	  len += strlen (b);
133538fd1498Szrj 	}
133638fd1498Szrj 
133738fd1498Szrj       wrap_help (help, opt, len, columns);
133838fd1498Szrj       displayed = true;
133938fd1498Szrj 
134038fd1498Szrj       if (option->var_type == CLVC_ENUM
134138fd1498Szrj 	  && opts->x_help_enum_printed[option->var_enum] != 2)
134238fd1498Szrj 	opts->x_help_enum_printed[option->var_enum] = 1;
134338fd1498Szrj     }
134438fd1498Szrj 
134538fd1498Szrj   if (! found)
134638fd1498Szrj     {
134738fd1498Szrj       unsigned int langs = include_flags & CL_LANG_ALL;
134838fd1498Szrj 
134938fd1498Szrj       if (langs == 0)
135038fd1498Szrj 	printf (_(" No options with the desired characteristics were found\n"));
135138fd1498Szrj       else
135238fd1498Szrj 	{
135338fd1498Szrj 	  unsigned int i;
135438fd1498Szrj 
135538fd1498Szrj 	  /* PR 31349: Tell the user how to see all of the
135638fd1498Szrj 	     options supported by a specific front end.  */
135738fd1498Szrj 	  for (i = 0; (1U << i) < CL_LANG_ALL; i ++)
135838fd1498Szrj 	    if ((1U << i) & langs)
135938fd1498Szrj 	      printf (_(" None found.  Use --help=%s to show *all* the options supported by the %s front-end.\n"),
136038fd1498Szrj 		      lang_names[i], lang_names[i]);
136138fd1498Szrj 	}
136238fd1498Szrj 
136338fd1498Szrj     }
136438fd1498Szrj   else if (! displayed)
136538fd1498Szrj     printf (_(" All options with the desired characteristics have already been displayed\n"));
136638fd1498Szrj 
136738fd1498Szrj   putchar ('\n');
136838fd1498Szrj 
136938fd1498Szrj   /* Print details of enumerated option arguments, if those
137038fd1498Szrj      enumerations have help text headings provided.  If no help text
137138fd1498Szrj      is provided, presume that the possible values are listed in the
137238fd1498Szrj      help text for the relevant options.  */
137338fd1498Szrj   for (i = 0; i < cl_enums_count; i++)
137438fd1498Szrj     {
137538fd1498Szrj       unsigned int j, pos;
137638fd1498Szrj 
137738fd1498Szrj       if (opts->x_help_enum_printed[i] != 1)
137838fd1498Szrj 	continue;
137938fd1498Szrj       if (cl_enums[i].help == NULL)
138038fd1498Szrj 	continue;
138138fd1498Szrj       printf ("  %s\n    ", _(cl_enums[i].help));
138238fd1498Szrj       pos = 4;
138338fd1498Szrj       for (j = 0; cl_enums[i].values[j].arg != NULL; j++)
138438fd1498Szrj 	{
138538fd1498Szrj 	  unsigned int len = strlen (cl_enums[i].values[j].arg);
138638fd1498Szrj 
138738fd1498Szrj 	  if (pos > 4 && pos + 1 + len <= columns)
138838fd1498Szrj 	    {
138938fd1498Szrj 	      printf (" %s", cl_enums[i].values[j].arg);
139038fd1498Szrj 	      pos += 1 + len;
139138fd1498Szrj 	    }
139238fd1498Szrj 	  else
139338fd1498Szrj 	    {
139438fd1498Szrj 	      if (pos > 4)
139538fd1498Szrj 		{
139638fd1498Szrj 		  printf ("\n    ");
139738fd1498Szrj 		  pos = 4;
139838fd1498Szrj 		}
139938fd1498Szrj 	      printf ("%s", cl_enums[i].values[j].arg);
140038fd1498Szrj 	      pos += len;
140138fd1498Szrj 	    }
140238fd1498Szrj 	}
140338fd1498Szrj       printf ("\n\n");
140438fd1498Szrj       opts->x_help_enum_printed[i] = 2;
140538fd1498Szrj     }
140638fd1498Szrj }
140738fd1498Szrj 
140838fd1498Szrj /* Display help for a specified type of option.
140938fd1498Szrj    The options must have ALL of the INCLUDE_FLAGS set
141038fd1498Szrj    ANY of the flags in the ANY_FLAGS set
141138fd1498Szrj    and NONE of the EXCLUDE_FLAGS set.  The current option state is in
141238fd1498Szrj    OPTS; LANG_MASK is used for interpreting enumerated option state.  */
141338fd1498Szrj static void
print_specific_help(unsigned int include_flags,unsigned int exclude_flags,unsigned int any_flags,struct gcc_options * opts,unsigned int lang_mask)141438fd1498Szrj print_specific_help (unsigned int include_flags,
141538fd1498Szrj 		     unsigned int exclude_flags,
141638fd1498Szrj 		     unsigned int any_flags,
141738fd1498Szrj 		     struct gcc_options *opts,
141838fd1498Szrj 		     unsigned int lang_mask)
141938fd1498Szrj {
142038fd1498Szrj   unsigned int all_langs_mask = (1U << cl_lang_count) - 1;
142138fd1498Szrj   const char * description = NULL;
142238fd1498Szrj   const char * descrip_extra = "";
142338fd1498Szrj   size_t i;
142438fd1498Szrj   unsigned int flag;
142538fd1498Szrj 
142638fd1498Szrj   /* Sanity check: Make sure that we do not have more
142738fd1498Szrj      languages than we have bits available to enumerate them.  */
142838fd1498Szrj   gcc_assert ((1U << cl_lang_count) <= CL_MIN_OPTION_CLASS);
142938fd1498Szrj 
143038fd1498Szrj   /* If we have not done so already, obtain
143138fd1498Szrj      the desired maximum width of the output.  */
143238fd1498Szrj   if (opts->x_help_columns == 0)
143338fd1498Szrj     {
143438fd1498Szrj       opts->x_help_columns = get_terminal_width ();
143538fd1498Szrj       if (opts->x_help_columns == INT_MAX)
143638fd1498Szrj 	/* Use a reasonable default.  */
143738fd1498Szrj 	opts->x_help_columns = 80;
143838fd1498Szrj     }
143938fd1498Szrj 
144038fd1498Szrj   /* Decide upon the title for the options that we are going to display.  */
144138fd1498Szrj   for (i = 0, flag = 1; flag <= CL_MAX_OPTION_CLASS; flag <<= 1, i ++)
144238fd1498Szrj     {
144338fd1498Szrj       switch (flag & include_flags)
144438fd1498Szrj 	{
144538fd1498Szrj 	case 0:
144638fd1498Szrj 	case CL_DRIVER:
144738fd1498Szrj 	  break;
144838fd1498Szrj 
144938fd1498Szrj 	case CL_TARGET:
145038fd1498Szrj 	  description = _("The following options are target specific");
145138fd1498Szrj 	  break;
145238fd1498Szrj 	case CL_WARNING:
145338fd1498Szrj 	  description = _("The following options control compiler warning messages");
145438fd1498Szrj 	  break;
145538fd1498Szrj 	case CL_OPTIMIZATION:
145638fd1498Szrj 	  description = _("The following options control optimizations");
145738fd1498Szrj 	  break;
145838fd1498Szrj 	case CL_COMMON:
145938fd1498Szrj 	  description = _("The following options are language-independent");
146038fd1498Szrj 	  break;
146138fd1498Szrj 	case CL_PARAMS:
146238fd1498Szrj 	  description = _("The --param option recognizes the following as parameters");
146338fd1498Szrj 	  break;
146438fd1498Szrj 	default:
146538fd1498Szrj 	  if (i >= cl_lang_count)
146638fd1498Szrj 	    break;
146738fd1498Szrj 	  if (exclude_flags & all_langs_mask)
146838fd1498Szrj 	    description = _("The following options are specific to just the language ");
146938fd1498Szrj 	  else
147038fd1498Szrj 	    description = _("The following options are supported by the language ");
147138fd1498Szrj 	  descrip_extra = lang_names [i];
147238fd1498Szrj 	  break;
147338fd1498Szrj 	}
147438fd1498Szrj     }
147538fd1498Szrj 
147638fd1498Szrj   if (description == NULL)
147738fd1498Szrj     {
147838fd1498Szrj       if (any_flags == 0)
147938fd1498Szrj 	{
148038fd1498Szrj 	  if (include_flags & CL_UNDOCUMENTED)
148138fd1498Szrj 	    description = _("The following options are not documented");
148238fd1498Szrj 	  else if (include_flags & CL_SEPARATE)
148338fd1498Szrj 	    description = _("The following options take separate arguments");
148438fd1498Szrj 	  else if (include_flags & CL_JOINED)
148538fd1498Szrj 	    description = _("The following options take joined arguments");
148638fd1498Szrj 	  else
148738fd1498Szrj 	    {
148838fd1498Szrj 	      internal_error ("unrecognized include_flags 0x%x passed to print_specific_help",
148938fd1498Szrj 			      include_flags);
149038fd1498Szrj 	      return;
149138fd1498Szrj 	    }
149238fd1498Szrj 	}
149338fd1498Szrj       else
149438fd1498Szrj 	{
149538fd1498Szrj 	  if (any_flags & all_langs_mask)
149638fd1498Szrj 	    description = _("The following options are language-related");
149738fd1498Szrj 	  else
149838fd1498Szrj 	    description = _("The following options are language-independent");
149938fd1498Szrj 	}
150038fd1498Szrj     }
150138fd1498Szrj 
150238fd1498Szrj   printf ("%s%s:\n", description, descrip_extra);
150338fd1498Szrj   print_filtered_help (include_flags, exclude_flags, any_flags,
150438fd1498Szrj 		       opts->x_help_columns, opts, lang_mask);
150538fd1498Szrj }
150638fd1498Szrj 
150738fd1498Szrj /* Enable FDO-related flags.  */
150838fd1498Szrj 
150938fd1498Szrj static void
enable_fdo_optimizations(struct gcc_options * opts,struct gcc_options * opts_set,int value)151038fd1498Szrj enable_fdo_optimizations (struct gcc_options *opts,
151138fd1498Szrj 			  struct gcc_options *opts_set,
151238fd1498Szrj 			  int value)
151338fd1498Szrj {
151438fd1498Szrj   if (!opts_set->x_flag_branch_probabilities)
151538fd1498Szrj     opts->x_flag_branch_probabilities = value;
151638fd1498Szrj   if (!opts_set->x_flag_profile_values)
151738fd1498Szrj     opts->x_flag_profile_values = value;
151838fd1498Szrj   if (!opts_set->x_flag_unroll_loops)
151938fd1498Szrj     opts->x_flag_unroll_loops = value;
152038fd1498Szrj   if (!opts_set->x_flag_peel_loops)
152138fd1498Szrj     opts->x_flag_peel_loops = value;
152238fd1498Szrj   if (!opts_set->x_flag_tracer)
152338fd1498Szrj     opts->x_flag_tracer = value;
152438fd1498Szrj   if (!opts_set->x_flag_value_profile_transformations)
152538fd1498Szrj     opts->x_flag_value_profile_transformations = value;
152638fd1498Szrj   if (!opts_set->x_flag_inline_functions)
152738fd1498Szrj     opts->x_flag_inline_functions = value;
152838fd1498Szrj   if (!opts_set->x_flag_ipa_cp)
152938fd1498Szrj     opts->x_flag_ipa_cp = value;
153038fd1498Szrj   if (!opts_set->x_flag_ipa_cp_clone
153138fd1498Szrj       && value && opts->x_flag_ipa_cp)
153238fd1498Szrj     opts->x_flag_ipa_cp_clone = value;
153338fd1498Szrj   if (!opts_set->x_flag_ipa_bit_cp
153438fd1498Szrj       && value && opts->x_flag_ipa_cp)
153538fd1498Szrj     opts->x_flag_ipa_bit_cp = value;
153638fd1498Szrj   if (!opts_set->x_flag_predictive_commoning)
153738fd1498Szrj     opts->x_flag_predictive_commoning = value;
153838fd1498Szrj   if (!opts_set->x_flag_split_loops)
153938fd1498Szrj     opts->x_flag_split_loops = value;
154038fd1498Szrj   if (!opts_set->x_flag_unswitch_loops)
154138fd1498Szrj     opts->x_flag_unswitch_loops = value;
154238fd1498Szrj   if (!opts_set->x_flag_gcse_after_reload)
154338fd1498Szrj     opts->x_flag_gcse_after_reload = value;
154438fd1498Szrj   if (!opts_set->x_flag_tree_loop_vectorize)
154538fd1498Szrj     opts->x_flag_tree_loop_vectorize = value;
154638fd1498Szrj   if (!opts_set->x_flag_tree_slp_vectorize)
154738fd1498Szrj     opts->x_flag_tree_slp_vectorize = value;
154838fd1498Szrj   if (!opts_set->x_flag_vect_cost_model)
154938fd1498Szrj     opts->x_flag_vect_cost_model = VECT_COST_MODEL_DYNAMIC;
155038fd1498Szrj   if (!opts_set->x_flag_tree_loop_distribute_patterns)
155138fd1498Szrj     opts->x_flag_tree_loop_distribute_patterns = value;
155238fd1498Szrj }
155338fd1498Szrj 
155438fd1498Szrj /* -f{,no-}sanitize{,-recover}= suboptions.  */
155538fd1498Szrj const struct sanitizer_opts_s sanitizer_opts[] =
155638fd1498Szrj {
155738fd1498Szrj #define SANITIZER_OPT(name, flags, recover) \
155838fd1498Szrj     { #name, flags, sizeof #name - 1, recover }
155938fd1498Szrj   SANITIZER_OPT (address, (SANITIZE_ADDRESS | SANITIZE_USER_ADDRESS), true),
156038fd1498Szrj   SANITIZER_OPT (kernel-address, (SANITIZE_ADDRESS | SANITIZE_KERNEL_ADDRESS),
156138fd1498Szrj 		 true),
156238fd1498Szrj   SANITIZER_OPT (pointer-compare, SANITIZE_POINTER_COMPARE, true),
156338fd1498Szrj   SANITIZER_OPT (pointer-subtract, SANITIZE_POINTER_SUBTRACT, true),
156438fd1498Szrj   SANITIZER_OPT (thread, SANITIZE_THREAD, false),
156538fd1498Szrj   SANITIZER_OPT (leak, SANITIZE_LEAK, false),
156638fd1498Szrj   SANITIZER_OPT (shift, SANITIZE_SHIFT, true),
156738fd1498Szrj   SANITIZER_OPT (shift-base, SANITIZE_SHIFT_BASE, true),
156838fd1498Szrj   SANITIZER_OPT (shift-exponent, SANITIZE_SHIFT_EXPONENT, true),
156938fd1498Szrj   SANITIZER_OPT (integer-divide-by-zero, SANITIZE_DIVIDE, true),
157038fd1498Szrj   SANITIZER_OPT (undefined, SANITIZE_UNDEFINED, true),
157138fd1498Szrj   SANITIZER_OPT (unreachable, SANITIZE_UNREACHABLE, false),
157238fd1498Szrj   SANITIZER_OPT (vla-bound, SANITIZE_VLA, true),
157338fd1498Szrj   SANITIZER_OPT (return, SANITIZE_RETURN, false),
157438fd1498Szrj   SANITIZER_OPT (null, SANITIZE_NULL, true),
157538fd1498Szrj   SANITIZER_OPT (signed-integer-overflow, SANITIZE_SI_OVERFLOW, true),
157638fd1498Szrj   SANITIZER_OPT (bool, SANITIZE_BOOL, true),
157738fd1498Szrj   SANITIZER_OPT (enum, SANITIZE_ENUM, true),
157838fd1498Szrj   SANITIZER_OPT (float-divide-by-zero, SANITIZE_FLOAT_DIVIDE, true),
157938fd1498Szrj   SANITIZER_OPT (float-cast-overflow, SANITIZE_FLOAT_CAST, true),
158038fd1498Szrj   SANITIZER_OPT (bounds, SANITIZE_BOUNDS, true),
158138fd1498Szrj   SANITIZER_OPT (bounds-strict, SANITIZE_BOUNDS | SANITIZE_BOUNDS_STRICT, true),
158238fd1498Szrj   SANITIZER_OPT (alignment, SANITIZE_ALIGNMENT, true),
158338fd1498Szrj   SANITIZER_OPT (nonnull-attribute, SANITIZE_NONNULL_ATTRIBUTE, true),
158438fd1498Szrj   SANITIZER_OPT (returns-nonnull-attribute, SANITIZE_RETURNS_NONNULL_ATTRIBUTE,
158538fd1498Szrj 		 true),
158638fd1498Szrj   SANITIZER_OPT (object-size, SANITIZE_OBJECT_SIZE, true),
158738fd1498Szrj   SANITIZER_OPT (vptr, SANITIZE_VPTR, true),
158838fd1498Szrj   SANITIZER_OPT (pointer-overflow, SANITIZE_POINTER_OVERFLOW, true),
158938fd1498Szrj   SANITIZER_OPT (builtin, SANITIZE_BUILTIN, true),
159038fd1498Szrj   SANITIZER_OPT (all, ~0U, true),
159138fd1498Szrj #undef SANITIZER_OPT
159238fd1498Szrj   { NULL, 0U, 0UL, false }
159338fd1498Szrj };
159438fd1498Szrj 
159538fd1498Szrj /* -f{,no-}sanitize-coverage= suboptions.  */
159638fd1498Szrj const struct sanitizer_opts_s coverage_sanitizer_opts[] =
159738fd1498Szrj {
159838fd1498Szrj #define COVERAGE_SANITIZER_OPT(name, flags) \
159938fd1498Szrj     { #name, flags, sizeof #name - 1, true }
160038fd1498Szrj   COVERAGE_SANITIZER_OPT (trace-pc, SANITIZE_COV_TRACE_PC),
160138fd1498Szrj   COVERAGE_SANITIZER_OPT (trace-cmp, SANITIZE_COV_TRACE_CMP),
160238fd1498Szrj #undef COVERAGE_SANITIZER_OPT
160338fd1498Szrj   { NULL, 0U, 0UL, false }
160438fd1498Szrj };
160538fd1498Szrj 
160638fd1498Szrj /* A struct for describing a run of chars within a string.  */
160738fd1498Szrj 
160838fd1498Szrj struct string_fragment
160938fd1498Szrj {
string_fragmentstring_fragment161038fd1498Szrj   string_fragment (const char *start, size_t len)
161138fd1498Szrj   : m_start (start), m_len (len) {}
161238fd1498Szrj 
161338fd1498Szrj   const char *m_start;
161438fd1498Szrj   size_t m_len;
161538fd1498Szrj };
161638fd1498Szrj 
161738fd1498Szrj /* Specialization of edit_distance_traits for string_fragment,
161838fd1498Szrj    for use by get_closest_sanitizer_option.  */
161938fd1498Szrj 
162038fd1498Szrj template <>
162138fd1498Szrj struct edit_distance_traits<const string_fragment &>
162238fd1498Szrj {
162338fd1498Szrj   static size_t get_length (const string_fragment &fragment)
162438fd1498Szrj   {
162538fd1498Szrj     return fragment.m_len;
162638fd1498Szrj   }
162738fd1498Szrj 
162838fd1498Szrj   static const char *get_string (const string_fragment &fragment)
162938fd1498Szrj   {
163038fd1498Szrj     return fragment.m_start;
163138fd1498Szrj   }
163238fd1498Szrj };
163338fd1498Szrj 
163438fd1498Szrj /* Given ARG, an unrecognized sanitizer option, return the best
163538fd1498Szrj    matching sanitizer option, or NULL if there isn't one.
163638fd1498Szrj    OPTS is array of candidate sanitizer options.
163738fd1498Szrj    CODE is OPT_fsanitize_, OPT_fsanitize_recover_ or
163838fd1498Szrj    OPT_fsanitize_coverage_.
163938fd1498Szrj    VALUE is non-zero for the regular form of the option, zero
164038fd1498Szrj    for the "no-" form (e.g. "-fno-sanitize-recover=").  */
164138fd1498Szrj 
164238fd1498Szrj static const char *
164338fd1498Szrj get_closest_sanitizer_option (const string_fragment &arg,
164438fd1498Szrj 			      const struct sanitizer_opts_s *opts,
164538fd1498Szrj 			      enum opt_code code, int value)
164638fd1498Szrj {
164738fd1498Szrj   best_match <const string_fragment &, const char*> bm (arg);
164838fd1498Szrj   for (int i = 0; opts[i].name != NULL; ++i)
164938fd1498Szrj     {
165038fd1498Szrj       /* -fsanitize=all is not valid, so don't offer it.  */
165138fd1498Szrj       if (code == OPT_fsanitize_
165238fd1498Szrj 	  && opts[i].flag == ~0U
165338fd1498Szrj 	  && value)
165438fd1498Szrj 	continue;
165538fd1498Szrj 
165638fd1498Szrj       /* For -fsanitize-recover= (and not -fno-sanitize-recover=),
165738fd1498Szrj 	 don't offer the non-recoverable options.  */
165838fd1498Szrj       if (code == OPT_fsanitize_recover_
165938fd1498Szrj 	  && !opts[i].can_recover
166038fd1498Szrj 	  && value)
166138fd1498Szrj 	continue;
166238fd1498Szrj 
166338fd1498Szrj       bm.consider (opts[i].name);
166438fd1498Szrj     }
166538fd1498Szrj   return bm.get_best_meaningful_candidate ();
166638fd1498Szrj }
166738fd1498Szrj 
166838fd1498Szrj /* Parse comma separated sanitizer suboptions from P for option SCODE,
166938fd1498Szrj    adjust previous FLAGS and return new ones.  If COMPLAIN is false,
167038fd1498Szrj    don't issue diagnostics.  */
167138fd1498Szrj 
167238fd1498Szrj unsigned int
167338fd1498Szrj parse_sanitizer_options (const char *p, location_t loc, int scode,
167438fd1498Szrj 			 unsigned int flags, int value, bool complain)
167538fd1498Szrj {
167638fd1498Szrj   enum opt_code code = (enum opt_code) scode;
167738fd1498Szrj 
167838fd1498Szrj   const struct sanitizer_opts_s *opts;
167938fd1498Szrj   if (code == OPT_fsanitize_coverage_)
168038fd1498Szrj     opts = coverage_sanitizer_opts;
168138fd1498Szrj   else
168238fd1498Szrj     opts = sanitizer_opts;
168338fd1498Szrj 
168438fd1498Szrj   while (*p != 0)
168538fd1498Szrj     {
168638fd1498Szrj       size_t len, i;
168738fd1498Szrj       bool found = false;
168838fd1498Szrj       const char *comma = strchr (p, ',');
168938fd1498Szrj 
169038fd1498Szrj       if (comma == NULL)
169138fd1498Szrj 	len = strlen (p);
169238fd1498Szrj       else
169338fd1498Szrj 	len = comma - p;
169438fd1498Szrj       if (len == 0)
169538fd1498Szrj 	{
169638fd1498Szrj 	  p = comma + 1;
169738fd1498Szrj 	  continue;
169838fd1498Szrj 	}
169938fd1498Szrj 
170038fd1498Szrj       /* Check to see if the string matches an option class name.  */
170138fd1498Szrj       for (i = 0; opts[i].name != NULL; ++i)
170238fd1498Szrj 	if (len == opts[i].len && memcmp (p, opts[i].name, len) == 0)
170338fd1498Szrj 	  {
170438fd1498Szrj 	    /* Handle both -fsanitize and -fno-sanitize cases.  */
170538fd1498Szrj 	    if (value && opts[i].flag == ~0U)
170638fd1498Szrj 	      {
170738fd1498Szrj 		if (code == OPT_fsanitize_)
170838fd1498Szrj 		  {
170938fd1498Szrj 		    if (complain)
171038fd1498Szrj 		      error_at (loc, "%<-fsanitize=all%> option is not valid");
171138fd1498Szrj 		  }
171238fd1498Szrj 		else
171338fd1498Szrj 		  flags |= ~(SANITIZE_THREAD | SANITIZE_LEAK
171438fd1498Szrj 			     | SANITIZE_UNREACHABLE | SANITIZE_RETURN);
171538fd1498Szrj 	      }
171638fd1498Szrj 	    else if (value)
171738fd1498Szrj 	      {
171838fd1498Szrj 		/* Do not enable -fsanitize-recover=unreachable and
171938fd1498Szrj 		   -fsanitize-recover=return if -fsanitize-recover=undefined
172038fd1498Szrj 		   is selected.  */
172138fd1498Szrj 		if (code == OPT_fsanitize_recover_
172238fd1498Szrj 		    && opts[i].flag == SANITIZE_UNDEFINED)
172338fd1498Szrj 		  flags |= (SANITIZE_UNDEFINED
172438fd1498Szrj 			    & ~(SANITIZE_UNREACHABLE | SANITIZE_RETURN));
172538fd1498Szrj 		else
172638fd1498Szrj 		  flags |= opts[i].flag;
172738fd1498Szrj 	      }
172838fd1498Szrj 	    else
172938fd1498Szrj 	      flags &= ~opts[i].flag;
173038fd1498Szrj 	    found = true;
173138fd1498Szrj 	    break;
173238fd1498Szrj 	  }
173338fd1498Szrj 
173438fd1498Szrj       if (! found && complain)
173538fd1498Szrj 	{
173638fd1498Szrj 	  const char *hint
173738fd1498Szrj 	    = get_closest_sanitizer_option (string_fragment (p, len),
173838fd1498Szrj 					    opts, code, value);
173938fd1498Szrj 
174038fd1498Szrj 	  const char *suffix;
174138fd1498Szrj 	  if (code == OPT_fsanitize_recover_)
174238fd1498Szrj 	    suffix = "-recover";
174338fd1498Szrj 	  else if (code == OPT_fsanitize_coverage_)
174438fd1498Szrj 	    suffix = "-coverage";
174538fd1498Szrj 	  else
174638fd1498Szrj 	    suffix = "";
174738fd1498Szrj 
174838fd1498Szrj 	  if (hint)
174938fd1498Szrj 	    error_at (loc,
175038fd1498Szrj 		      "unrecognized argument to -f%ssanitize%s= option: %q.*s;"
175138fd1498Szrj 		      " did you mean %qs?",
175238fd1498Szrj 		      value ? "" : "no-",
175338fd1498Szrj 		      suffix, (int) len, p, hint);
175438fd1498Szrj 	  else
175538fd1498Szrj 	    error_at (loc,
175638fd1498Szrj 		      "unrecognized argument to -f%ssanitize%s= option: %q.*s",
175738fd1498Szrj 		      value ? "" : "no-",
175838fd1498Szrj 		      suffix, (int) len, p);
175938fd1498Szrj 	}
176038fd1498Szrj 
176138fd1498Szrj       if (comma == NULL)
176238fd1498Szrj 	break;
176338fd1498Szrj       p = comma + 1;
176438fd1498Szrj     }
176538fd1498Szrj   return flags;
176638fd1498Szrj }
176738fd1498Szrj 
176838fd1498Szrj /* Parse string values of no_sanitize attribute passed in VALUE.
176938fd1498Szrj    Values are separated with comma.  */
177038fd1498Szrj 
177138fd1498Szrj unsigned int
177238fd1498Szrj parse_no_sanitize_attribute (char *value)
177338fd1498Szrj {
177438fd1498Szrj   unsigned int flags = 0;
177538fd1498Szrj   unsigned int i;
177638fd1498Szrj   char *q = strtok (value, ",");
177738fd1498Szrj 
177838fd1498Szrj   while (q != NULL)
177938fd1498Szrj     {
178038fd1498Szrj       for (i = 0; sanitizer_opts[i].name != NULL; ++i)
178138fd1498Szrj 	if (strcmp (sanitizer_opts[i].name, q) == 0)
178238fd1498Szrj 	  {
178338fd1498Szrj 	    flags |= sanitizer_opts[i].flag;
178438fd1498Szrj 	    if (sanitizer_opts[i].flag == SANITIZE_UNDEFINED)
178538fd1498Szrj 	      flags |= SANITIZE_UNDEFINED_NONDEFAULT;
178638fd1498Szrj 	    break;
178738fd1498Szrj 	  }
178838fd1498Szrj 
178938fd1498Szrj       if (sanitizer_opts[i].name == NULL)
179038fd1498Szrj 	warning (OPT_Wattributes,
179138fd1498Szrj 		 "%<%s%> attribute directive ignored", q);
179238fd1498Szrj 
179338fd1498Szrj       q = strtok (NULL, ",");
179438fd1498Szrj     }
179538fd1498Szrj 
179638fd1498Szrj   return flags;
179738fd1498Szrj }
179838fd1498Szrj 
179938fd1498Szrj /* Handle target- and language-independent options.  Return zero to
180038fd1498Szrj    generate an "unknown option" message.  Only options that need
180138fd1498Szrj    extra handling need to be listed here; if you simply want
180238fd1498Szrj    DECODED->value assigned to a variable, it happens automatically.  */
180338fd1498Szrj 
180438fd1498Szrj bool
180538fd1498Szrj common_handle_option (struct gcc_options *opts,
180638fd1498Szrj 		      struct gcc_options *opts_set,
180738fd1498Szrj 		      const struct cl_decoded_option *decoded,
180838fd1498Szrj 		      unsigned int lang_mask, int kind ATTRIBUTE_UNUSED,
180938fd1498Szrj 		      location_t loc,
181038fd1498Szrj 		      const struct cl_option_handlers *handlers,
181138fd1498Szrj 		      diagnostic_context *dc,
181238fd1498Szrj 		      void (*target_option_override_hook) (void))
181338fd1498Szrj {
181438fd1498Szrj   size_t scode = decoded->opt_index;
181538fd1498Szrj   const char *arg = decoded->arg;
181638fd1498Szrj   int value = decoded->value;
181738fd1498Szrj   enum opt_code code = (enum opt_code) scode;
181838fd1498Szrj 
181938fd1498Szrj   gcc_assert (decoded->canonical_option_num_elements <= 2);
182038fd1498Szrj 
182138fd1498Szrj   switch (code)
182238fd1498Szrj     {
182338fd1498Szrj     case OPT__param:
182438fd1498Szrj       handle_param (opts, opts_set, loc, arg);
182538fd1498Szrj       break;
182638fd1498Szrj 
182738fd1498Szrj     case OPT__help:
182838fd1498Szrj       {
182938fd1498Szrj 	unsigned int all_langs_mask = (1U << cl_lang_count) - 1;
183038fd1498Szrj 	unsigned int undoc_mask;
183138fd1498Szrj 	unsigned int i;
183238fd1498Szrj 
183338fd1498Szrj 	if (lang_mask == CL_DRIVER)
183438fd1498Szrj 	  break;
183538fd1498Szrj 
183638fd1498Szrj 	undoc_mask = ((opts->x_verbose_flag | opts->x_extra_warnings)
183738fd1498Szrj 		      ? 0
183838fd1498Szrj 		      : CL_UNDOCUMENTED);
183938fd1498Szrj 	target_option_override_hook ();
184038fd1498Szrj 	/* First display any single language specific options.  */
184138fd1498Szrj 	for (i = 0; i < cl_lang_count; i++)
184238fd1498Szrj 	  print_specific_help
184338fd1498Szrj 	    (1U << i, (all_langs_mask & (~ (1U << i))) | undoc_mask, 0, opts,
184438fd1498Szrj 	     lang_mask);
184538fd1498Szrj 	/* Next display any multi language specific options.  */
184638fd1498Szrj 	print_specific_help (0, undoc_mask, all_langs_mask, opts, lang_mask);
184738fd1498Szrj 	/* Then display any remaining, non-language options.  */
184838fd1498Szrj 	for (i = CL_MIN_OPTION_CLASS; i <= CL_MAX_OPTION_CLASS; i <<= 1)
184938fd1498Szrj 	  if (i != CL_DRIVER)
185038fd1498Szrj 	    print_specific_help (i, undoc_mask, 0, opts, lang_mask);
185138fd1498Szrj 	opts->x_exit_after_options = true;
185238fd1498Szrj 	break;
185338fd1498Szrj       }
185438fd1498Szrj 
185538fd1498Szrj     case OPT__target_help:
185638fd1498Szrj       if (lang_mask == CL_DRIVER)
185738fd1498Szrj 	break;
185838fd1498Szrj 
185938fd1498Szrj       target_option_override_hook ();
186038fd1498Szrj       print_specific_help (CL_TARGET, CL_UNDOCUMENTED, 0, opts, lang_mask);
186138fd1498Szrj       opts->x_exit_after_options = true;
186238fd1498Szrj       break;
186338fd1498Szrj 
186438fd1498Szrj     case OPT__help_:
186538fd1498Szrj       {
186638fd1498Szrj 	const char *a = arg;
186738fd1498Szrj 	unsigned int include_flags = 0;
186838fd1498Szrj 	/* Note - by default we include undocumented options when listing
186938fd1498Szrj 	   specific classes.  If you only want to see documented options
187038fd1498Szrj 	   then add ",^undocumented" to the --help= option.  E.g.:
187138fd1498Szrj 
187238fd1498Szrj 	   --help=target,^undocumented  */
187338fd1498Szrj 	unsigned int exclude_flags = 0;
187438fd1498Szrj 
187538fd1498Szrj 	if (lang_mask == CL_DRIVER)
187638fd1498Szrj 	  break;
187738fd1498Szrj 
187838fd1498Szrj 	/* Walk along the argument string, parsing each word in turn.
187938fd1498Szrj 	   The format is:
188038fd1498Szrj 	   arg = [^]{word}[,{arg}]
188138fd1498Szrj 	   word = {optimizers|target|warnings|undocumented|
188238fd1498Szrj 		   params|common|<language>}  */
188338fd1498Szrj 	while (*a != 0)
188438fd1498Szrj 	  {
188538fd1498Szrj 	    static const struct
188638fd1498Szrj 	    {
188738fd1498Szrj 	      const char *string;
188838fd1498Szrj 	      unsigned int flag;
188938fd1498Szrj 	    }
189038fd1498Szrj 	    specifics[] =
189138fd1498Szrj 	    {
189238fd1498Szrj 	      { "optimizers", CL_OPTIMIZATION },
189338fd1498Szrj 	      { "target", CL_TARGET },
189438fd1498Szrj 	      { "warnings", CL_WARNING },
189538fd1498Szrj 	      { "undocumented", CL_UNDOCUMENTED },
189638fd1498Szrj 	      { "params", CL_PARAMS },
189738fd1498Szrj 	      { "joined", CL_JOINED },
189838fd1498Szrj 	      { "separate", CL_SEPARATE },
189938fd1498Szrj 	      { "common", CL_COMMON },
190038fd1498Szrj 	      { NULL, 0 }
190138fd1498Szrj 	    };
190238fd1498Szrj 	    unsigned int *pflags;
190338fd1498Szrj 	    const char *comma;
190438fd1498Szrj 	    unsigned int lang_flag, specific_flag;
190538fd1498Szrj 	    unsigned int len;
190638fd1498Szrj 	    unsigned int i;
190738fd1498Szrj 
190838fd1498Szrj 	    if (*a == '^')
190938fd1498Szrj 	      {
191038fd1498Szrj 		++a;
191138fd1498Szrj 		if (*a == '\0')
191238fd1498Szrj 		  {
191338fd1498Szrj 		    error_at (loc, "missing argument to %qs", "--help=^");
191438fd1498Szrj 		    break;
191538fd1498Szrj 		  }
191638fd1498Szrj 		pflags = &exclude_flags;
191738fd1498Szrj 	      }
191838fd1498Szrj 	    else
191938fd1498Szrj 	      pflags = &include_flags;
192038fd1498Szrj 
192138fd1498Szrj 	    comma = strchr (a, ',');
192238fd1498Szrj 	    if (comma == NULL)
192338fd1498Szrj 	      len = strlen (a);
192438fd1498Szrj 	    else
192538fd1498Szrj 	      len = comma - a;
192638fd1498Szrj 	    if (len == 0)
192738fd1498Szrj 	      {
192838fd1498Szrj 		a = comma + 1;
192938fd1498Szrj 		continue;
193038fd1498Szrj 	      }
193138fd1498Szrj 
193238fd1498Szrj 	    /* Check to see if the string matches an option class name.  */
193338fd1498Szrj 	    for (i = 0, specific_flag = 0; specifics[i].string != NULL; i++)
193438fd1498Szrj 	      if (strncasecmp (a, specifics[i].string, len) == 0)
193538fd1498Szrj 		{
193638fd1498Szrj 		  specific_flag = specifics[i].flag;
193738fd1498Szrj 		  break;
193838fd1498Szrj 		}
193938fd1498Szrj 
194038fd1498Szrj 	    /* Check to see if the string matches a language name.
194138fd1498Szrj 	       Note - we rely upon the alpha-sorted nature of the entries in
194238fd1498Szrj 	       the lang_names array, specifically that shorter names appear
194338fd1498Szrj 	       before their longer variants.  (i.e. C before C++).  That way
194438fd1498Szrj 	       when we are attempting to match --help=c for example we will
194538fd1498Szrj 	       match with C first and not C++.  */
194638fd1498Szrj 	    for (i = 0, lang_flag = 0; i < cl_lang_count; i++)
194738fd1498Szrj 	      if (strncasecmp (a, lang_names[i], len) == 0)
194838fd1498Szrj 		{
194938fd1498Szrj 		  lang_flag = 1U << i;
195038fd1498Szrj 		  break;
195138fd1498Szrj 		}
195238fd1498Szrj 
195338fd1498Szrj 	    if (specific_flag != 0)
195438fd1498Szrj 	      {
195538fd1498Szrj 		if (lang_flag == 0)
195638fd1498Szrj 		  *pflags |= specific_flag;
195738fd1498Szrj 		else
195838fd1498Szrj 		  {
195938fd1498Szrj 		    /* The option's argument matches both the start of a
196038fd1498Szrj 		       language name and the start of an option class name.
196138fd1498Szrj 		       We have a special case for when the user has
196238fd1498Szrj 		       specified "--help=c", but otherwise we have to issue
196338fd1498Szrj 		       a warning.  */
196438fd1498Szrj 		    if (strncasecmp (a, "c", len) == 0)
196538fd1498Szrj 		      *pflags |= lang_flag;
196638fd1498Szrj 		    else
196738fd1498Szrj 		      warning_at (loc, 0,
196838fd1498Szrj 				  "--help argument %q.*s is ambiguous, "
196938fd1498Szrj 				  "please be more specific",
197038fd1498Szrj 				  len, a);
197138fd1498Szrj 		  }
197238fd1498Szrj 	      }
197338fd1498Szrj 	    else if (lang_flag != 0)
197438fd1498Szrj 	      *pflags |= lang_flag;
197538fd1498Szrj 	    else
197638fd1498Szrj 	      warning_at (loc, 0,
197738fd1498Szrj 			  "unrecognized argument to --help= option: %q.*s",
197838fd1498Szrj 			  len, a);
197938fd1498Szrj 
198038fd1498Szrj 	    if (comma == NULL)
198138fd1498Szrj 	      break;
198238fd1498Szrj 	    a = comma + 1;
198338fd1498Szrj 	  }
198438fd1498Szrj 
198538fd1498Szrj 	if (include_flags)
198638fd1498Szrj 	  {
198738fd1498Szrj 	    target_option_override_hook ();
198838fd1498Szrj 	    print_specific_help (include_flags, exclude_flags, 0, opts,
198938fd1498Szrj 				 lang_mask);
199038fd1498Szrj 	  }
199138fd1498Szrj 	opts->x_exit_after_options = true;
199238fd1498Szrj 	break;
199338fd1498Szrj       }
199438fd1498Szrj 
199538fd1498Szrj     case OPT__version:
199638fd1498Szrj       if (lang_mask == CL_DRIVER)
199738fd1498Szrj 	break;
199838fd1498Szrj 
199938fd1498Szrj       opts->x_exit_after_options = true;
200038fd1498Szrj       break;
200138fd1498Szrj 
200238fd1498Szrj     case OPT_fsanitize_:
200338fd1498Szrj       opts->x_flag_sanitize
200438fd1498Szrj 	= parse_sanitizer_options (arg, loc, code,
200538fd1498Szrj 				   opts->x_flag_sanitize, value, true);
200638fd1498Szrj 
200738fd1498Szrj       /* Kernel ASan implies normal ASan but does not yet support
200838fd1498Szrj 	 all features.  */
200938fd1498Szrj       if (opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS)
201038fd1498Szrj 	{
201138fd1498Szrj 	  maybe_set_param_value (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD,
201238fd1498Szrj 				 0, opts->x_param_values,
201338fd1498Szrj 				 opts_set->x_param_values);
201438fd1498Szrj 	  maybe_set_param_value (PARAM_ASAN_GLOBALS, 0, opts->x_param_values,
201538fd1498Szrj 				 opts_set->x_param_values);
201638fd1498Szrj 	  maybe_set_param_value (PARAM_ASAN_STACK, 0, opts->x_param_values,
201738fd1498Szrj 				 opts_set->x_param_values);
201838fd1498Szrj 	  maybe_set_param_value (PARAM_ASAN_PROTECT_ALLOCAS, 0,
201938fd1498Szrj 				 opts->x_param_values,
202038fd1498Szrj 				 opts_set->x_param_values);
202138fd1498Szrj 	  maybe_set_param_value (PARAM_ASAN_USE_AFTER_RETURN, 0,
202238fd1498Szrj 				 opts->x_param_values,
202338fd1498Szrj 				 opts_set->x_param_values);
202438fd1498Szrj 	}
202538fd1498Szrj       break;
202638fd1498Szrj 
202738fd1498Szrj     case OPT_fsanitize_recover_:
202838fd1498Szrj       opts->x_flag_sanitize_recover
202938fd1498Szrj 	= parse_sanitizer_options (arg, loc, code,
203038fd1498Szrj 				   opts->x_flag_sanitize_recover, value, true);
203138fd1498Szrj       break;
203238fd1498Szrj 
203338fd1498Szrj     case OPT_fasan_shadow_offset_:
203438fd1498Szrj       /* Deferred.  */
203538fd1498Szrj       break;
203638fd1498Szrj 
203738fd1498Szrj     case OPT_fsanitize_address_use_after_scope:
203838fd1498Szrj       opts->x_flag_sanitize_address_use_after_scope = value;
203938fd1498Szrj       break;
204038fd1498Szrj 
204138fd1498Szrj     case OPT_fsanitize_recover:
204238fd1498Szrj       if (value)
204338fd1498Szrj 	opts->x_flag_sanitize_recover
204438fd1498Szrj 	  |= (SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT)
204538fd1498Szrj 	     & ~(SANITIZE_UNREACHABLE | SANITIZE_RETURN);
204638fd1498Szrj       else
204738fd1498Szrj 	opts->x_flag_sanitize_recover
204838fd1498Szrj 	  &= ~(SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT);
204938fd1498Szrj       break;
205038fd1498Szrj 
205138fd1498Szrj     case OPT_fsanitize_coverage_:
205238fd1498Szrj       opts->x_flag_sanitize_coverage
205338fd1498Szrj 	= parse_sanitizer_options (arg, loc, code,
205438fd1498Szrj 				   opts->x_flag_sanitize_coverage, value, true);
205538fd1498Szrj       break;
205638fd1498Szrj 
205738fd1498Szrj     case OPT_O:
205838fd1498Szrj     case OPT_Os:
205938fd1498Szrj     case OPT_Ofast:
206038fd1498Szrj     case OPT_Og:
206138fd1498Szrj       /* Currently handled in a prescan.  */
206238fd1498Szrj       break;
206338fd1498Szrj 
206438fd1498Szrj     case OPT_Werror:
206538fd1498Szrj       dc->warning_as_error_requested = value;
206638fd1498Szrj       break;
206738fd1498Szrj 
206838fd1498Szrj     case OPT_Werror_:
206938fd1498Szrj       if (lang_mask == CL_DRIVER)
207038fd1498Szrj 	break;
207138fd1498Szrj 
207238fd1498Szrj       enable_warning_as_error (arg, value, lang_mask, handlers,
207338fd1498Szrj 			       opts, opts_set, loc, dc);
207438fd1498Szrj       break;
207538fd1498Szrj 
207638fd1498Szrj     case OPT_Wlarger_than_:
207738fd1498Szrj       opts->x_larger_than_size = value;
207838fd1498Szrj       opts->x_warn_larger_than = value != -1;
207938fd1498Szrj       break;
208038fd1498Szrj 
208138fd1498Szrj     case OPT_Wfatal_errors:
208238fd1498Szrj       dc->fatal_errors = value;
208338fd1498Szrj       break;
208438fd1498Szrj 
208538fd1498Szrj     case OPT_Wframe_larger_than_:
208638fd1498Szrj       opts->x_frame_larger_than_size = value;
208738fd1498Szrj       opts->x_warn_frame_larger_than = value != -1;
208838fd1498Szrj       break;
208938fd1498Szrj 
209038fd1498Szrj     case OPT_Wstack_usage_:
209138fd1498Szrj       opts->x_warn_stack_usage = value;
209238fd1498Szrj       opts->x_flag_stack_usage_info = value != -1;
209338fd1498Szrj       break;
209438fd1498Szrj 
209538fd1498Szrj     case OPT_Wstrict_aliasing:
209638fd1498Szrj       set_Wstrict_aliasing (opts, value);
209738fd1498Szrj       break;
209838fd1498Szrj 
209938fd1498Szrj     case OPT_Wstrict_overflow:
210038fd1498Szrj       opts->x_warn_strict_overflow = (value
210138fd1498Szrj 				      ? (int) WARN_STRICT_OVERFLOW_CONDITIONAL
210238fd1498Szrj 				      : 0);
210338fd1498Szrj       break;
210438fd1498Szrj 
210538fd1498Szrj     case OPT_Wsystem_headers:
210638fd1498Szrj       dc->dc_warn_system_headers = value;
210738fd1498Szrj       break;
210838fd1498Szrj 
210938fd1498Szrj     case OPT_aux_info:
211038fd1498Szrj       opts->x_flag_gen_aux_info = 1;
211138fd1498Szrj       break;
211238fd1498Szrj 
211338fd1498Szrj     case OPT_auxbase_strip:
211438fd1498Szrj       {
211538fd1498Szrj 	char *tmp = xstrdup (arg);
211638fd1498Szrj 	strip_off_ending (tmp, strlen (tmp));
211738fd1498Szrj 	if (tmp[0])
211838fd1498Szrj 	  opts->x_aux_base_name = tmp;
211938fd1498Szrj 	else
212038fd1498Szrj 	  free (tmp);
212138fd1498Szrj       }
212238fd1498Szrj       break;
212338fd1498Szrj 
212438fd1498Szrj     case OPT_d:
212538fd1498Szrj       decode_d_option (arg, opts, loc, dc);
212638fd1498Szrj       break;
212738fd1498Szrj 
212838fd1498Szrj     case OPT_fcall_used_:
212938fd1498Szrj     case OPT_fcall_saved_:
213038fd1498Szrj       /* Deferred.  */
213138fd1498Szrj       break;
213238fd1498Szrj 
213338fd1498Szrj     case OPT_fdbg_cnt_:
213438fd1498Szrj       /* Deferred.  */
213538fd1498Szrj       break;
213638fd1498Szrj 
213738fd1498Szrj     case OPT_fdbg_cnt_list:
213838fd1498Szrj       /* Deferred.  */
213938fd1498Szrj       opts->x_exit_after_options = true;
214038fd1498Szrj       break;
214138fd1498Szrj 
214238fd1498Szrj     case OPT_fdebug_prefix_map_:
214338fd1498Szrj     case OPT_ffile_prefix_map_:
214438fd1498Szrj       /* Deferred.  */
214538fd1498Szrj       break;
214638fd1498Szrj 
214738fd1498Szrj     case OPT_fdiagnostics_show_location_:
214838fd1498Szrj       diagnostic_prefixing_rule (dc) = (diagnostic_prefixing_rule_t) value;
214938fd1498Szrj       break;
215038fd1498Szrj 
215138fd1498Szrj     case OPT_fdiagnostics_show_caret:
215238fd1498Szrj       dc->show_caret = value;
215338fd1498Szrj       break;
215438fd1498Szrj 
215538fd1498Szrj     case OPT_fdiagnostics_color_:
215638fd1498Szrj       diagnostic_color_init (dc, value);
215738fd1498Szrj       break;
215838fd1498Szrj 
215938fd1498Szrj     case OPT_fdiagnostics_parseable_fixits:
216038fd1498Szrj       dc->parseable_fixits_p = value;
216138fd1498Szrj       break;
216238fd1498Szrj 
216338fd1498Szrj     case OPT_fdiagnostics_show_option:
216438fd1498Szrj       dc->show_option_requested = value;
216538fd1498Szrj       break;
216638fd1498Szrj 
216738fd1498Szrj     case OPT_fdump_:
216838fd1498Szrj       /* Deferred.  */
216938fd1498Szrj       break;
217038fd1498Szrj 
217138fd1498Szrj     case OPT_ffast_math:
217238fd1498Szrj       set_fast_math_flags (opts, value);
217338fd1498Szrj       break;
217438fd1498Szrj 
217538fd1498Szrj     case OPT_funsafe_math_optimizations:
217638fd1498Szrj       set_unsafe_math_optimizations_flags (opts, value);
217738fd1498Szrj       break;
217838fd1498Szrj 
217938fd1498Szrj     case OPT_ffixed_:
218038fd1498Szrj       /* Deferred.  */
218138fd1498Szrj       break;
218238fd1498Szrj 
218338fd1498Szrj     case OPT_finline_limit_:
218438fd1498Szrj       set_param_value ("max-inline-insns-single", value / 2,
218538fd1498Szrj 		       opts->x_param_values, opts_set->x_param_values);
218638fd1498Szrj       set_param_value ("max-inline-insns-auto", value / 2,
218738fd1498Szrj 		       opts->x_param_values, opts_set->x_param_values);
218838fd1498Szrj       break;
218938fd1498Szrj 
219038fd1498Szrj     case OPT_finstrument_functions_exclude_function_list_:
219138fd1498Szrj       add_comma_separated_to_vector
219238fd1498Szrj 	(&opts->x_flag_instrument_functions_exclude_functions, arg);
219338fd1498Szrj       break;
219438fd1498Szrj 
219538fd1498Szrj     case OPT_finstrument_functions_exclude_file_list_:
219638fd1498Szrj       add_comma_separated_to_vector
219738fd1498Szrj 	(&opts->x_flag_instrument_functions_exclude_files, arg);
219838fd1498Szrj       break;
219938fd1498Szrj 
220038fd1498Szrj     case OPT_fmessage_length_:
220138fd1498Szrj       pp_set_line_maximum_length (dc->printer, value);
220238fd1498Szrj       diagnostic_set_caret_max_width (dc, value);
220338fd1498Szrj       break;
220438fd1498Szrj 
220538fd1498Szrj     case OPT_fopt_info:
220638fd1498Szrj     case OPT_fopt_info_:
220738fd1498Szrj       /* Deferred.  */
220838fd1498Szrj       break;
220938fd1498Szrj 
221038fd1498Szrj     case OPT_foffload_:
221138fd1498Szrj       {
221238fd1498Szrj 	const char *p = arg;
221338fd1498Szrj 	opts->x_flag_disable_hsa = true;
221438fd1498Szrj 	while (*p != 0)
221538fd1498Szrj 	  {
221638fd1498Szrj 	    const char *comma = strchr (p, ',');
221738fd1498Szrj 
221838fd1498Szrj 	    if ((strncmp (p, "disable", 7) == 0)
221938fd1498Szrj 		&& (p[7] == ',' || p[7] == '\0'))
222038fd1498Szrj 	      {
222138fd1498Szrj 		opts->x_flag_disable_hsa = true;
222238fd1498Szrj 		break;
222338fd1498Szrj 	      }
222438fd1498Szrj 
222538fd1498Szrj 	    if ((strncmp (p, "hsa", 3) == 0)
222638fd1498Szrj 		&& (p[3] == ',' || p[3] == '\0'))
222738fd1498Szrj 	      {
222838fd1498Szrj #ifdef ENABLE_HSA
222938fd1498Szrj 		opts->x_flag_disable_hsa = false;
223038fd1498Szrj #else
223138fd1498Szrj 		sorry ("HSA has not been enabled during configuration");
223238fd1498Szrj #endif
223338fd1498Szrj 	      }
223438fd1498Szrj 	    if (!comma)
223538fd1498Szrj 	      break;
223638fd1498Szrj 	    p = comma + 1;
223738fd1498Szrj 	  }
223838fd1498Szrj 	break;
223938fd1498Szrj       }
224038fd1498Szrj 
224138fd1498Szrj #ifndef ACCEL_COMPILER
224238fd1498Szrj     case OPT_foffload_abi_:
224338fd1498Szrj       error_at (loc, "%<-foffload-abi%> option can be specified only for "
224438fd1498Szrj 		"offload compiler");
224538fd1498Szrj       break;
224638fd1498Szrj #endif
224738fd1498Szrj 
224838fd1498Szrj     case OPT_fpack_struct_:
224938fd1498Szrj       if (value <= 0 || (value & (value - 1)) || value > 16)
225038fd1498Szrj 	error_at (loc,
225138fd1498Szrj 		  "structure alignment must be a small power of two, not %d",
225238fd1498Szrj 		  value);
225338fd1498Szrj       else
225438fd1498Szrj 	opts->x_initial_max_fld_align = value;
225538fd1498Szrj       break;
225638fd1498Szrj 
225738fd1498Szrj     case OPT_fplugin_:
225838fd1498Szrj     case OPT_fplugin_arg_:
225938fd1498Szrj       /* Deferred.  */
226038fd1498Szrj       break;
226138fd1498Szrj 
226238fd1498Szrj     case OPT_fprofile_use_:
226338fd1498Szrj       opts->x_profile_data_prefix = xstrdup (arg);
226438fd1498Szrj       opts->x_flag_profile_use = true;
226538fd1498Szrj       value = true;
226638fd1498Szrj       /* No break here - do -fprofile-use processing. */
226738fd1498Szrj       /* FALLTHRU */
226838fd1498Szrj     case OPT_fprofile_use:
226938fd1498Szrj       enable_fdo_optimizations (opts, opts_set, value);
227038fd1498Szrj       if (!opts_set->x_flag_profile_reorder_functions)
227138fd1498Szrj 	  opts->x_flag_profile_reorder_functions = value;
227238fd1498Szrj 	/* Indirect call profiling should do all useful transformations
227338fd1498Szrj 	   speculative devirtualization does.  */
227438fd1498Szrj       if (!opts_set->x_flag_devirtualize_speculatively
227538fd1498Szrj 	  && opts->x_flag_value_profile_transformations)
227638fd1498Szrj 	opts->x_flag_devirtualize_speculatively = false;
227738fd1498Szrj       break;
227838fd1498Szrj 
227938fd1498Szrj     case OPT_fauto_profile_:
228038fd1498Szrj       opts->x_auto_profile_file = xstrdup (arg);
228138fd1498Szrj       opts->x_flag_auto_profile = true;
228238fd1498Szrj       value = true;
228338fd1498Szrj       /* No break here - do -fauto-profile processing. */
228438fd1498Szrj       /* FALLTHRU */
228538fd1498Szrj     case OPT_fauto_profile:
228638fd1498Szrj       enable_fdo_optimizations (opts, opts_set, value);
228738fd1498Szrj       if (!opts_set->x_flag_profile_correction)
228838fd1498Szrj 	opts->x_flag_profile_correction = value;
228938fd1498Szrj       maybe_set_param_value (
229038fd1498Szrj 	PARAM_EARLY_INLINER_MAX_ITERATIONS, 10,
229138fd1498Szrj 	opts->x_param_values, opts_set->x_param_values);
229238fd1498Szrj       break;
229338fd1498Szrj 
229438fd1498Szrj     case OPT_fprofile_generate_:
229538fd1498Szrj       opts->x_profile_data_prefix = xstrdup (arg);
229638fd1498Szrj       value = true;
229738fd1498Szrj       /* No break here - do -fprofile-generate processing. */
229838fd1498Szrj       /* FALLTHRU */
229938fd1498Szrj     case OPT_fprofile_generate:
230038fd1498Szrj       if (!opts_set->x_profile_arc_flag)
230138fd1498Szrj 	opts->x_profile_arc_flag = value;
230238fd1498Szrj       if (!opts_set->x_flag_profile_values)
230338fd1498Szrj 	opts->x_flag_profile_values = value;
230438fd1498Szrj       if (!opts_set->x_flag_inline_functions)
230538fd1498Szrj 	opts->x_flag_inline_functions = value;
230638fd1498Szrj       if (!opts_set->x_flag_ipa_bit_cp)
230738fd1498Szrj 	opts->x_flag_ipa_bit_cp = value;
230838fd1498Szrj       /* FIXME: Instrumentation we insert makes ipa-reference bitmaps
230938fd1498Szrj 	 quadratic.  Disable the pass until better memory representation
231038fd1498Szrj 	 is done.  */
231138fd1498Szrj       if (!opts_set->x_flag_ipa_reference)
231238fd1498Szrj         opts->x_flag_ipa_reference = false;
231338fd1498Szrj       break;
231438fd1498Szrj 
231538fd1498Szrj     case OPT_fpatchable_function_entry_:
231638fd1498Szrj       {
231738fd1498Szrj 	char *patch_area_arg = xstrdup (arg);
231838fd1498Szrj 	char *comma = strchr (patch_area_arg, ',');
231938fd1498Szrj 	if (comma)
232038fd1498Szrj 	  {
232138fd1498Szrj 	    *comma = '\0';
232238fd1498Szrj 	    function_entry_patch_area_size =
232338fd1498Szrj 	      integral_argument (patch_area_arg);
232438fd1498Szrj 	    function_entry_patch_area_start =
232538fd1498Szrj 	      integral_argument (comma + 1);
232638fd1498Szrj 	  }
232738fd1498Szrj 	else
232838fd1498Szrj 	  {
232938fd1498Szrj 	    function_entry_patch_area_size =
233038fd1498Szrj 	      integral_argument (patch_area_arg);
233138fd1498Szrj 	    function_entry_patch_area_start = 0;
233238fd1498Szrj 	  }
233338fd1498Szrj 	if (function_entry_patch_area_size < 0
233438fd1498Szrj 	    || function_entry_patch_area_start < 0
233538fd1498Szrj 	    || function_entry_patch_area_size
233638fd1498Szrj 		< function_entry_patch_area_start)
233738fd1498Szrj 	  error ("invalid arguments for %<-fpatchable_function_entry%>");
233838fd1498Szrj 	free (patch_area_arg);
233938fd1498Szrj       }
234038fd1498Szrj       break;
234138fd1498Szrj 
234238fd1498Szrj     case OPT_ftree_vectorize:
234338fd1498Szrj       /* Automatically sets -ftree-loop-vectorize and
234438fd1498Szrj 	 -ftree-slp-vectorize.  Nothing more to do here.  */
234538fd1498Szrj       break;
234638fd1498Szrj     case OPT_fshow_column:
234738fd1498Szrj       dc->show_column = value;
234838fd1498Szrj       break;
234938fd1498Szrj 
235038fd1498Szrj     case OPT_frandom_seed:
235138fd1498Szrj       /* The real switch is -fno-random-seed.  */
235238fd1498Szrj       if (value)
235338fd1498Szrj 	return false;
235438fd1498Szrj       /* Deferred.  */
235538fd1498Szrj       break;
235638fd1498Szrj 
235738fd1498Szrj     case OPT_frandom_seed_:
235838fd1498Szrj       /* Deferred.  */
235938fd1498Szrj       break;
236038fd1498Szrj 
236138fd1498Szrj     case OPT_fsched_verbose_:
236238fd1498Szrj #ifdef INSN_SCHEDULING
236338fd1498Szrj       /* Handled with Var in common.opt.  */
236438fd1498Szrj       break;
236538fd1498Szrj #else
236638fd1498Szrj       return false;
236738fd1498Szrj #endif
236838fd1498Szrj 
236938fd1498Szrj     case OPT_fsched_stalled_insns_:
237038fd1498Szrj       opts->x_flag_sched_stalled_insns = value;
237138fd1498Szrj       if (opts->x_flag_sched_stalled_insns == 0)
237238fd1498Szrj 	opts->x_flag_sched_stalled_insns = -1;
237338fd1498Szrj       break;
237438fd1498Szrj 
237538fd1498Szrj     case OPT_fsched_stalled_insns_dep_:
237638fd1498Szrj       opts->x_flag_sched_stalled_insns_dep = value;
237738fd1498Szrj       break;
237838fd1498Szrj 
237938fd1498Szrj     case OPT_fstack_check_:
238038fd1498Szrj       if (!strcmp (arg, "no"))
238138fd1498Szrj 	opts->x_flag_stack_check = NO_STACK_CHECK;
238238fd1498Szrj       else if (!strcmp (arg, "generic"))
238338fd1498Szrj 	/* This is the old stack checking method.  */
238438fd1498Szrj 	opts->x_flag_stack_check = STACK_CHECK_BUILTIN
238538fd1498Szrj 			   ? FULL_BUILTIN_STACK_CHECK
238638fd1498Szrj 			   : GENERIC_STACK_CHECK;
238738fd1498Szrj       else if (!strcmp (arg, "specific"))
238838fd1498Szrj 	/* This is the new stack checking method.  */
238938fd1498Szrj 	opts->x_flag_stack_check = STACK_CHECK_BUILTIN
239038fd1498Szrj 			   ? FULL_BUILTIN_STACK_CHECK
239138fd1498Szrj 			   : STACK_CHECK_STATIC_BUILTIN
239238fd1498Szrj 			     ? STATIC_BUILTIN_STACK_CHECK
239338fd1498Szrj 			     : GENERIC_STACK_CHECK;
239438fd1498Szrj       else
239538fd1498Szrj 	warning_at (loc, 0, "unknown stack check parameter %qs", arg);
239638fd1498Szrj       break;
239738fd1498Szrj 
239838fd1498Szrj     case OPT_fstack_limit:
239938fd1498Szrj       /* The real switch is -fno-stack-limit.  */
240038fd1498Szrj       if (value)
240138fd1498Szrj 	return false;
240238fd1498Szrj       /* Deferred.  */
240338fd1498Szrj       break;
240438fd1498Szrj 
240538fd1498Szrj     case OPT_fstack_limit_register_:
240638fd1498Szrj     case OPT_fstack_limit_symbol_:
240738fd1498Szrj       /* Deferred.  */
240838fd1498Szrj       break;
240938fd1498Szrj 
241038fd1498Szrj     case OPT_fstack_usage:
241138fd1498Szrj       opts->x_flag_stack_usage = value;
241238fd1498Szrj       opts->x_flag_stack_usage_info = value != 0;
241338fd1498Szrj       break;
241438fd1498Szrj 
241538fd1498Szrj     case OPT_g:
241638fd1498Szrj       set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, arg, opts, opts_set,
241738fd1498Szrj                        loc);
241838fd1498Szrj       break;
241938fd1498Szrj 
242038fd1498Szrj     case OPT_gdwarf:
242138fd1498Szrj       if (arg && strlen (arg) != 0)
242238fd1498Szrj         {
242338fd1498Szrj           error_at (loc, "%<-gdwarf%s%> is ambiguous; "
242438fd1498Szrj                     "use %<-gdwarf-%s%> for DWARF version "
242538fd1498Szrj                     "or %<-gdwarf -g%s%> for debug level", arg, arg, arg);
242638fd1498Szrj           break;
242738fd1498Szrj         }
242838fd1498Szrj       else
242938fd1498Szrj         value = opts->x_dwarf_version;
243038fd1498Szrj 
243138fd1498Szrj       /* FALLTHRU */
243238fd1498Szrj     case OPT_gdwarf_:
243338fd1498Szrj       if (value < 2 || value > 5)
243438fd1498Szrj 	error_at (loc, "dwarf version %d is not supported", value);
243538fd1498Szrj       else
243638fd1498Szrj 	opts->x_dwarf_version = value;
243738fd1498Szrj       set_debug_level (DWARF2_DEBUG, false, "", opts, opts_set, loc);
243838fd1498Szrj       break;
243938fd1498Szrj 
244038fd1498Szrj     case OPT_gsplit_dwarf:
244138fd1498Szrj       set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, "", opts, opts_set,
244238fd1498Szrj 		       loc);
244338fd1498Szrj       break;
244438fd1498Szrj 
244538fd1498Szrj     case OPT_ggdb:
244638fd1498Szrj       set_debug_level (NO_DEBUG, 2, arg, opts, opts_set, loc);
244738fd1498Szrj       break;
244838fd1498Szrj 
244938fd1498Szrj     case OPT_gstabs:
245038fd1498Szrj     case OPT_gstabs_:
245138fd1498Szrj       set_debug_level (DBX_DEBUG, code == OPT_gstabs_, arg, opts, opts_set,
245238fd1498Szrj 		       loc);
245338fd1498Szrj       break;
245438fd1498Szrj 
245538fd1498Szrj     case OPT_gvms:
245638fd1498Szrj       set_debug_level (VMS_DEBUG, false, arg, opts, opts_set, loc);
245738fd1498Szrj       break;
245838fd1498Szrj 
245938fd1498Szrj     case OPT_gxcoff:
246038fd1498Szrj     case OPT_gxcoff_:
246138fd1498Szrj       set_debug_level (XCOFF_DEBUG, code == OPT_gxcoff_, arg, opts, opts_set,
246238fd1498Szrj 		       loc);
246338fd1498Szrj       break;
246438fd1498Szrj 
246538fd1498Szrj     case OPT_gz:
246638fd1498Szrj     case OPT_gz_:
246738fd1498Szrj       /* Handled completely via specs.  */
246838fd1498Szrj       break;
246938fd1498Szrj 
247038fd1498Szrj     case OPT_pedantic_errors:
247138fd1498Szrj       dc->pedantic_errors = 1;
247238fd1498Szrj       control_warning_option (OPT_Wpedantic, DK_ERROR, NULL, value,
247338fd1498Szrj 			      loc, lang_mask,
247438fd1498Szrj 			      handlers, opts, opts_set,
247538fd1498Szrj                               dc);
247638fd1498Szrj       break;
247738fd1498Szrj 
247838fd1498Szrj     case OPT_flto:
247938fd1498Szrj       opts->x_flag_lto = value ? "" : NULL;
248038fd1498Szrj       break;
248138fd1498Szrj 
248238fd1498Szrj     case OPT_w:
248338fd1498Szrj       dc->dc_inhibit_warnings = true;
248438fd1498Szrj       break;
248538fd1498Szrj 
248638fd1498Szrj     case OPT_fmax_errors_:
248738fd1498Szrj       dc->max_errors = value;
248838fd1498Szrj       break;
248938fd1498Szrj 
249038fd1498Szrj     case OPT_fuse_ld_bfd:
249138fd1498Szrj     case OPT_fuse_ld_gold:
249238fd1498Szrj     case OPT_fuse_linker_plugin:
249338fd1498Szrj       /* No-op. Used by the driver and passed to us because it starts with f.*/
249438fd1498Szrj       break;
249538fd1498Szrj 
249638fd1498Szrj     case OPT_fwrapv:
249738fd1498Szrj       if (value)
249838fd1498Szrj 	opts->x_flag_trapv = 0;
249938fd1498Szrj       break;
250038fd1498Szrj 
250138fd1498Szrj     case OPT_ftrapv:
250238fd1498Szrj       if (value)
250338fd1498Szrj 	opts->x_flag_wrapv = 0;
250438fd1498Szrj       break;
250538fd1498Szrj 
250638fd1498Szrj     case OPT_fstrict_overflow:
250738fd1498Szrj       opts->x_flag_wrapv = !value;
250838fd1498Szrj       opts->x_flag_wrapv_pointer = !value;
250938fd1498Szrj       if (!value)
251038fd1498Szrj 	opts->x_flag_trapv = 0;
251138fd1498Szrj       break;
251238fd1498Szrj 
251338fd1498Szrj     case OPT_fipa_icf:
251438fd1498Szrj       opts->x_flag_ipa_icf_functions = value;
251538fd1498Szrj       opts->x_flag_ipa_icf_variables = value;
251638fd1498Szrj       break;
251738fd1498Szrj 
251838fd1498Szrj     default:
251938fd1498Szrj       /* If the flag was handled in a standard way, assume the lack of
252038fd1498Szrj 	 processing here is intentional.  */
252138fd1498Szrj       gcc_assert (option_flag_var (scode, opts));
252238fd1498Szrj       break;
252338fd1498Szrj     }
252438fd1498Szrj 
252538fd1498Szrj   common_handle_option_auto (opts, opts_set, decoded, lang_mask, kind,
252638fd1498Szrj                              loc, handlers, dc);
252738fd1498Szrj   return true;
252838fd1498Szrj }
252938fd1498Szrj 
253038fd1498Szrj /* Handle --param NAME=VALUE.  */
253138fd1498Szrj static void
253238fd1498Szrj handle_param (struct gcc_options *opts, struct gcc_options *opts_set,
253338fd1498Szrj 	      location_t loc, const char *carg)
253438fd1498Szrj {
253538fd1498Szrj   char *equal, *arg;
253638fd1498Szrj   int value;
253738fd1498Szrj 
253838fd1498Szrj   arg = xstrdup (carg);
253938fd1498Szrj   equal = strchr (arg, '=');
254038fd1498Szrj   if (!equal)
254138fd1498Szrj     error_at (loc, "%s: --param arguments should be of the form NAME=VALUE",
254238fd1498Szrj 	      arg);
254338fd1498Szrj   else
254438fd1498Szrj     {
254538fd1498Szrj       *equal = '\0';
254638fd1498Szrj 
254738fd1498Szrj       enum compiler_param index;
254838fd1498Szrj       if (!find_param (arg, &index))
254938fd1498Szrj 	{
255038fd1498Szrj 	  const char *suggestion = find_param_fuzzy (arg);
255138fd1498Szrj 	  if (suggestion)
255238fd1498Szrj 	    error_at (loc, "invalid --param name %qs; did you mean %qs?",
255338fd1498Szrj 		      arg, suggestion);
255438fd1498Szrj 	  else
255538fd1498Szrj 	    error_at (loc, "invalid --param name %qs", arg);
255638fd1498Szrj 	}
255738fd1498Szrj       else
255838fd1498Szrj 	{
255938fd1498Szrj 	  if (!param_string_value_p (index, equal + 1, &value))
256038fd1498Szrj 	    value = integral_argument (equal + 1);
256138fd1498Szrj 
256238fd1498Szrj 	  if (value == -1)
256338fd1498Szrj 	    error_at (loc, "invalid --param value %qs", equal + 1);
256438fd1498Szrj 	  else
256538fd1498Szrj 	    set_param_value (arg, value,
256638fd1498Szrj 			     opts->x_param_values, opts_set->x_param_values);
256738fd1498Szrj 	}
256838fd1498Szrj     }
256938fd1498Szrj 
257038fd1498Szrj   free (arg);
257138fd1498Szrj }
257238fd1498Szrj 
257338fd1498Szrj /* Used to set the level of strict aliasing warnings in OPTS,
257438fd1498Szrj    when no level is specified (i.e., when -Wstrict-aliasing, and not
257538fd1498Szrj    -Wstrict-aliasing=level was given).
257638fd1498Szrj    ONOFF is assumed to take value 1 when -Wstrict-aliasing is specified,
257738fd1498Szrj    and 0 otherwise.  After calling this function, wstrict_aliasing will be
257838fd1498Szrj    set to the default value of -Wstrict_aliasing=level, currently 3.  */
257938fd1498Szrj static void
258038fd1498Szrj set_Wstrict_aliasing (struct gcc_options *opts, int onoff)
258138fd1498Szrj {
258238fd1498Szrj   gcc_assert (onoff == 0 || onoff == 1);
258338fd1498Szrj   if (onoff != 0)
258438fd1498Szrj     opts->x_warn_strict_aliasing = 3;
258538fd1498Szrj   else
258638fd1498Szrj     opts->x_warn_strict_aliasing = 0;
258738fd1498Szrj }
258838fd1498Szrj 
258938fd1498Szrj /* The following routines are useful in setting all the flags that
259038fd1498Szrj    -ffast-math and -fno-fast-math imply.  */
259138fd1498Szrj static void
259238fd1498Szrj set_fast_math_flags (struct gcc_options *opts, int set)
259338fd1498Szrj {
259438fd1498Szrj   if (!opts->frontend_set_flag_unsafe_math_optimizations)
259538fd1498Szrj     {
259638fd1498Szrj       opts->x_flag_unsafe_math_optimizations = set;
259738fd1498Szrj       set_unsafe_math_optimizations_flags (opts, set);
259838fd1498Szrj     }
259938fd1498Szrj   if (!opts->frontend_set_flag_finite_math_only)
260038fd1498Szrj     opts->x_flag_finite_math_only = set;
260138fd1498Szrj   if (!opts->frontend_set_flag_errno_math)
260238fd1498Szrj     opts->x_flag_errno_math = !set;
260338fd1498Szrj   if (set)
260438fd1498Szrj     {
260538fd1498Szrj       if (opts->frontend_set_flag_excess_precision_cmdline
260638fd1498Szrj 	  == EXCESS_PRECISION_DEFAULT)
260738fd1498Szrj 	opts->x_flag_excess_precision_cmdline
260838fd1498Szrj 	  = set ? EXCESS_PRECISION_FAST : EXCESS_PRECISION_DEFAULT;
260938fd1498Szrj       if (!opts->frontend_set_flag_signaling_nans)
261038fd1498Szrj 	opts->x_flag_signaling_nans = 0;
261138fd1498Szrj       if (!opts->frontend_set_flag_rounding_math)
261238fd1498Szrj 	opts->x_flag_rounding_math = 0;
261338fd1498Szrj       if (!opts->frontend_set_flag_cx_limited_range)
261438fd1498Szrj 	opts->x_flag_cx_limited_range = 1;
261538fd1498Szrj     }
261638fd1498Szrj }
261738fd1498Szrj 
261838fd1498Szrj /* When -funsafe-math-optimizations is set the following
261938fd1498Szrj    flags are set as well.  */
262038fd1498Szrj static void
262138fd1498Szrj set_unsafe_math_optimizations_flags (struct gcc_options *opts, int set)
262238fd1498Szrj {
262338fd1498Szrj   if (!opts->frontend_set_flag_trapping_math)
262438fd1498Szrj     opts->x_flag_trapping_math = !set;
262538fd1498Szrj   if (!opts->frontend_set_flag_signed_zeros)
262638fd1498Szrj     opts->x_flag_signed_zeros = !set;
262738fd1498Szrj   if (!opts->frontend_set_flag_associative_math)
262838fd1498Szrj     opts->x_flag_associative_math = set;
262938fd1498Szrj   if (!opts->frontend_set_flag_reciprocal_math)
263038fd1498Szrj     opts->x_flag_reciprocal_math = set;
263138fd1498Szrj }
263238fd1498Szrj 
263338fd1498Szrj /* Return true iff flags in OPTS are set as if -ffast-math.  */
263438fd1498Szrj bool
263538fd1498Szrj fast_math_flags_set_p (const struct gcc_options *opts)
263638fd1498Szrj {
263738fd1498Szrj   return (!opts->x_flag_trapping_math
263838fd1498Szrj 	  && opts->x_flag_unsafe_math_optimizations
263938fd1498Szrj 	  && opts->x_flag_finite_math_only
264038fd1498Szrj 	  && !opts->x_flag_signed_zeros
264138fd1498Szrj 	  && !opts->x_flag_errno_math
264238fd1498Szrj 	  && opts->x_flag_excess_precision_cmdline
264338fd1498Szrj 	     == EXCESS_PRECISION_FAST);
264438fd1498Szrj }
264538fd1498Szrj 
264638fd1498Szrj /* Return true iff flags are set as if -ffast-math but using the flags stored
264738fd1498Szrj    in the struct cl_optimization structure.  */
264838fd1498Szrj bool
264938fd1498Szrj fast_math_flags_struct_set_p (struct cl_optimization *opt)
265038fd1498Szrj {
265138fd1498Szrj   return (!opt->x_flag_trapping_math
265238fd1498Szrj 	  && opt->x_flag_unsafe_math_optimizations
265338fd1498Szrj 	  && opt->x_flag_finite_math_only
265438fd1498Szrj 	  && !opt->x_flag_signed_zeros
265538fd1498Szrj 	  && !opt->x_flag_errno_math);
265638fd1498Szrj }
265738fd1498Szrj 
265838fd1498Szrj /* Handle a debug output -g switch for options OPTS
265938fd1498Szrj    (OPTS_SET->x_write_symbols storing whether a debug type was passed
266038fd1498Szrj    explicitly), location LOC.  EXTENDED is true or false to support
266138fd1498Szrj    extended output (2 is special and means "-ggdb" was given).  */
266238fd1498Szrj static void
266338fd1498Szrj set_debug_level (enum debug_info_type type, int extended, const char *arg,
266438fd1498Szrj 		 struct gcc_options *opts, struct gcc_options *opts_set,
266538fd1498Szrj 		 location_t loc)
266638fd1498Szrj {
266738fd1498Szrj   opts->x_use_gnu_debug_info_extensions = extended;
266838fd1498Szrj 
266938fd1498Szrj   if (type == NO_DEBUG)
267038fd1498Szrj     {
267138fd1498Szrj       if (opts->x_write_symbols == NO_DEBUG)
267238fd1498Szrj 	{
267338fd1498Szrj 	  opts->x_write_symbols = PREFERRED_DEBUGGING_TYPE;
267438fd1498Szrj 
267538fd1498Szrj 	  if (extended == 2)
267638fd1498Szrj 	    {
267738fd1498Szrj #if defined DWARF2_DEBUGGING_INFO || defined DWARF2_LINENO_DEBUGGING_INFO
267838fd1498Szrj 	      opts->x_write_symbols = DWARF2_DEBUG;
267938fd1498Szrj #elif defined DBX_DEBUGGING_INFO
268038fd1498Szrj 	      opts->x_write_symbols = DBX_DEBUG;
268138fd1498Szrj #endif
268238fd1498Szrj 	    }
268338fd1498Szrj 
268438fd1498Szrj 	  if (opts->x_write_symbols == NO_DEBUG)
268538fd1498Szrj 	    warning_at (loc, 0, "target system does not support debug output");
268638fd1498Szrj 	}
268738fd1498Szrj     }
268838fd1498Szrj   else
268938fd1498Szrj     {
269038fd1498Szrj       /* Does it conflict with an already selected type?  */
269138fd1498Szrj       if (opts_set->x_write_symbols != NO_DEBUG
269238fd1498Szrj 	  && opts->x_write_symbols != NO_DEBUG
269338fd1498Szrj 	  && type != opts->x_write_symbols)
269438fd1498Szrj 	error_at (loc, "debug format %qs conflicts with prior selection",
269538fd1498Szrj 		  debug_type_names[type]);
269638fd1498Szrj       opts->x_write_symbols = type;
269738fd1498Szrj       opts_set->x_write_symbols = type;
269838fd1498Szrj     }
269938fd1498Szrj 
270038fd1498Szrj   /* A debug flag without a level defaults to level 2.
270138fd1498Szrj      If off or at level 1, set it to level 2, but if already
270238fd1498Szrj      at level 3, don't lower it.  */
270338fd1498Szrj   if (*arg == '\0')
270438fd1498Szrj     {
270538fd1498Szrj       if (opts->x_debug_info_level < DINFO_LEVEL_NORMAL)
270638fd1498Szrj 	opts->x_debug_info_level = DINFO_LEVEL_NORMAL;
270738fd1498Szrj     }
270838fd1498Szrj   else
270938fd1498Szrj     {
271038fd1498Szrj       int argval = integral_argument (arg);
271138fd1498Szrj       if (argval == -1)
271238fd1498Szrj 	error_at (loc, "unrecognized debug output level %qs", arg);
271338fd1498Szrj       else if (argval > 3)
271438fd1498Szrj 	error_at (loc, "debug output level %qs is too high", arg);
271538fd1498Szrj       else
271638fd1498Szrj 	opts->x_debug_info_level = (enum debug_info_levels) argval;
271738fd1498Szrj     }
271838fd1498Szrj }
271938fd1498Szrj 
272038fd1498Szrj /* Arrange to dump core on error for diagnostic context DC.  (The
272138fd1498Szrj    regular error message is still printed first, except in the case of
272238fd1498Szrj    abort ().)  */
272338fd1498Szrj 
272438fd1498Szrj static void
272538fd1498Szrj setup_core_dumping (diagnostic_context *dc)
272638fd1498Szrj {
272738fd1498Szrj #ifdef SIGABRT
272838fd1498Szrj   signal (SIGABRT, SIG_DFL);
272938fd1498Szrj #endif
273038fd1498Szrj #if defined(HAVE_SETRLIMIT)
273138fd1498Szrj   {
273238fd1498Szrj     struct rlimit rlim;
273338fd1498Szrj     if (getrlimit (RLIMIT_CORE, &rlim) != 0)
273438fd1498Szrj       fatal_error (input_location, "getting core file size maximum limit: %m");
273538fd1498Szrj     rlim.rlim_cur = rlim.rlim_max;
273638fd1498Szrj     if (setrlimit (RLIMIT_CORE, &rlim) != 0)
273738fd1498Szrj       fatal_error (input_location,
273838fd1498Szrj 		   "setting core file size limit to maximum: %m");
273938fd1498Szrj   }
274038fd1498Szrj #endif
274138fd1498Szrj   diagnostic_abort_on_error (dc);
274238fd1498Szrj }
274338fd1498Szrj 
274438fd1498Szrj /* Parse a -d<ARG> command line switch for OPTS, location LOC,
274538fd1498Szrj    diagnostic context DC.  */
274638fd1498Szrj 
274738fd1498Szrj static void
274838fd1498Szrj decode_d_option (const char *arg, struct gcc_options *opts,
274938fd1498Szrj 		 location_t loc, diagnostic_context *dc)
275038fd1498Szrj {
275138fd1498Szrj   int c;
275238fd1498Szrj 
275338fd1498Szrj   while (*arg)
275438fd1498Szrj     switch (c = *arg++)
275538fd1498Szrj       {
275638fd1498Szrj       case 'A':
275738fd1498Szrj 	opts->x_flag_debug_asm = 1;
275838fd1498Szrj 	break;
275938fd1498Szrj       case 'p':
276038fd1498Szrj 	opts->x_flag_print_asm_name = 1;
276138fd1498Szrj 	break;
276238fd1498Szrj       case 'P':
276338fd1498Szrj 	opts->x_flag_dump_rtl_in_asm = 1;
276438fd1498Szrj 	opts->x_flag_print_asm_name = 1;
276538fd1498Szrj 	break;
276638fd1498Szrj       case 'x':
276738fd1498Szrj 	opts->x_rtl_dump_and_exit = 1;
276838fd1498Szrj 	break;
276938fd1498Szrj       case 'D':	/* These are handled by the preprocessor.  */
277038fd1498Szrj       case 'I':
277138fd1498Szrj       case 'M':
277238fd1498Szrj       case 'N':
277338fd1498Szrj       case 'U':
277438fd1498Szrj 	break;
277538fd1498Szrj       case 'H':
277638fd1498Szrj 	setup_core_dumping (dc);
277738fd1498Szrj 	break;
277838fd1498Szrj       case 'a':
277938fd1498Szrj 	opts->x_flag_dump_all_passed = true;
278038fd1498Szrj 	break;
278138fd1498Szrj 
278238fd1498Szrj       default:
278338fd1498Szrj 	  warning_at (loc, 0, "unrecognized gcc debugging option: %c", c);
278438fd1498Szrj 	break;
278538fd1498Szrj       }
278638fd1498Szrj }
278738fd1498Szrj 
278838fd1498Szrj /* Enable (or disable if VALUE is 0) a warning option ARG (language
278938fd1498Szrj    mask LANG_MASK, option handlers HANDLERS) as an error for option
279038fd1498Szrj    structures OPTS and OPTS_SET, diagnostic context DC (possibly
279138fd1498Szrj    NULL), location LOC.  This is used by -Werror=.  */
279238fd1498Szrj 
279338fd1498Szrj static void
279438fd1498Szrj enable_warning_as_error (const char *arg, int value, unsigned int lang_mask,
279538fd1498Szrj 			 const struct cl_option_handlers *handlers,
279638fd1498Szrj 			 struct gcc_options *opts,
279738fd1498Szrj 			 struct gcc_options *opts_set,
279838fd1498Szrj 			 location_t loc, diagnostic_context *dc)
279938fd1498Szrj {
280038fd1498Szrj   char *new_option;
280138fd1498Szrj   int option_index;
280238fd1498Szrj 
280338fd1498Szrj   new_option = XNEWVEC (char, strlen (arg) + 2);
280438fd1498Szrj   new_option[0] = 'W';
280538fd1498Szrj   strcpy (new_option + 1, arg);
280638fd1498Szrj   option_index = find_opt (new_option, lang_mask);
280738fd1498Szrj   if (option_index == OPT_SPECIAL_unknown)
280838fd1498Szrj     error_at (loc, "-Werror=%s: no option -%s", arg, new_option);
280938fd1498Szrj   else if (!(cl_options[option_index].flags & CL_WARNING))
281038fd1498Szrj     error_at (loc, "-Werror=%s: -%s is not an option that controls warnings",
281138fd1498Szrj 	      arg, new_option);
281238fd1498Szrj   else
281338fd1498Szrj     {
281438fd1498Szrj       const diagnostic_t kind = value ? DK_ERROR : DK_WARNING;
281538fd1498Szrj       const char *arg = NULL;
281638fd1498Szrj 
281738fd1498Szrj       if (cl_options[option_index].flags & CL_JOINED)
281838fd1498Szrj 	arg = new_option + cl_options[option_index].opt_len;
281938fd1498Szrj       control_warning_option (option_index, (int) kind, arg, value,
282038fd1498Szrj 			      loc, lang_mask,
282138fd1498Szrj 			      handlers, opts, opts_set, dc);
282238fd1498Szrj     }
282338fd1498Szrj   free (new_option);
282438fd1498Szrj }
282538fd1498Szrj 
282638fd1498Szrj /* Return malloced memory for the name of the option OPTION_INDEX
282738fd1498Szrj    which enabled a diagnostic (context CONTEXT), originally of type
282838fd1498Szrj    ORIG_DIAG_KIND but possibly converted to DIAG_KIND by options such
282938fd1498Szrj    as -Werror.  */
283038fd1498Szrj 
283138fd1498Szrj char *
283238fd1498Szrj option_name (diagnostic_context *context, int option_index,
283338fd1498Szrj 	     diagnostic_t orig_diag_kind, diagnostic_t diag_kind)
283438fd1498Szrj {
283538fd1498Szrj   if (option_index)
283638fd1498Szrj     {
283738fd1498Szrj       /* A warning classified as an error.  */
283838fd1498Szrj       if ((orig_diag_kind == DK_WARNING || orig_diag_kind == DK_PEDWARN)
283938fd1498Szrj 	  && diag_kind == DK_ERROR)
284038fd1498Szrj 	return concat (cl_options[OPT_Werror_].opt_text,
284138fd1498Szrj 		       /* Skip over "-W".  */
284238fd1498Szrj 		       cl_options[option_index].opt_text + 2,
284338fd1498Szrj 		       NULL);
284438fd1498Szrj       /* A warning with option.  */
284538fd1498Szrj       else
284638fd1498Szrj 	return xstrdup (cl_options[option_index].opt_text);
284738fd1498Szrj     }
284838fd1498Szrj   /* A warning without option classified as an error.  */
284938fd1498Szrj   else if ((orig_diag_kind == DK_WARNING || orig_diag_kind == DK_PEDWARN
285038fd1498Szrj 	    || diag_kind == DK_WARNING)
285138fd1498Szrj 	   && context->warning_as_error_requested)
285238fd1498Szrj     return xstrdup (cl_options[OPT_Werror].opt_text);
285338fd1498Szrj   else
285438fd1498Szrj     return NULL;
285538fd1498Szrj }
2856