xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/opts.c (revision f3cfa6f6ce31685c6c4a758bc430e69eb99f50a4)
1 /* Command line option handling.
2    Copyright (C) 2002-2016 Free Software Foundation, Inc.
3    Contributed by Neil Booth.
4 
5 This file is part of GCC.
6 
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
11 
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.  */
20 
21 #include "config.h"
22 #include "system.h"
23 #include "intl.h"
24 #include "coretypes.h"
25 #include "opts.h"
26 #include "tm.h"
27 #include "flags.h"
28 #include "params.h"
29 #include "diagnostic.h"
30 #include "opts-diagnostic.h"
31 #include "insn-attr-common.h"
32 #include "common/common-target.h"
33 
34 static void set_Wstrict_aliasing (struct gcc_options *opts, int onoff);
35 
36 /* Indexed by enum debug_info_type.  */
37 const char *const debug_type_names[] =
38 {
39   "none", "stabs", "coff", "dwarf-2", "xcoff", "vms"
40 };
41 
42 /* Parse the -femit-struct-debug-detailed option value
43    and set the flag variables. */
44 
45 #define MATCH( prefix, string ) \
46   ((strncmp (prefix, string, sizeof prefix - 1) == 0) \
47    ? ((string += sizeof prefix - 1), 1) : 0)
48 
49 void
50 set_struct_debug_option (struct gcc_options *opts, location_t loc,
51 			 const char *spec)
52 {
53   /* various labels for comparison */
54   static const char dfn_lbl[] = "dfn:", dir_lbl[] = "dir:", ind_lbl[] = "ind:";
55   static const char ord_lbl[] = "ord:", gen_lbl[] = "gen:";
56   static const char none_lbl[] = "none", any_lbl[] = "any";
57   static const char base_lbl[] = "base", sys_lbl[] = "sys";
58 
59   enum debug_struct_file files = DINFO_STRUCT_FILE_ANY;
60   /* Default is to apply to as much as possible. */
61   enum debug_info_usage usage = DINFO_USAGE_NUM_ENUMS;
62   int ord = 1, gen = 1;
63 
64   /* What usage? */
65   if (MATCH (dfn_lbl, spec))
66     usage = DINFO_USAGE_DFN;
67   else if (MATCH (dir_lbl, spec))
68     usage = DINFO_USAGE_DIR_USE;
69   else if (MATCH (ind_lbl, spec))
70     usage = DINFO_USAGE_IND_USE;
71 
72   /* Generics or not? */
73   if (MATCH (ord_lbl, spec))
74     gen = 0;
75   else if (MATCH (gen_lbl, spec))
76     ord = 0;
77 
78   /* What allowable environment? */
79   if (MATCH (none_lbl, spec))
80     files = DINFO_STRUCT_FILE_NONE;
81   else if (MATCH (any_lbl, spec))
82     files = DINFO_STRUCT_FILE_ANY;
83   else if (MATCH (sys_lbl, spec))
84     files = DINFO_STRUCT_FILE_SYS;
85   else if (MATCH (base_lbl, spec))
86     files = DINFO_STRUCT_FILE_BASE;
87   else
88     error_at (loc,
89 	      "argument %qs to %<-femit-struct-debug-detailed%> "
90 	      "not recognized",
91 	      spec);
92 
93   /* Effect the specification. */
94   if (usage == DINFO_USAGE_NUM_ENUMS)
95     {
96       if (ord)
97         {
98           opts->x_debug_struct_ordinary[DINFO_USAGE_DFN] = files;
99           opts->x_debug_struct_ordinary[DINFO_USAGE_DIR_USE] = files;
100           opts->x_debug_struct_ordinary[DINFO_USAGE_IND_USE] = files;
101         }
102       if (gen)
103         {
104           opts->x_debug_struct_generic[DINFO_USAGE_DFN] = files;
105           opts->x_debug_struct_generic[DINFO_USAGE_DIR_USE] = files;
106           opts->x_debug_struct_generic[DINFO_USAGE_IND_USE] = files;
107         }
108     }
109   else
110     {
111       if (ord)
112         opts->x_debug_struct_ordinary[usage] = files;
113       if (gen)
114         opts->x_debug_struct_generic[usage] = files;
115     }
116 
117   if (*spec == ',')
118     set_struct_debug_option (opts, loc, spec+1);
119   else
120     {
121       /* No more -femit-struct-debug-detailed specifications.
122          Do final checks. */
123       if (*spec != '\0')
124 	error_at (loc,
125 		  "argument %qs to %<-femit-struct-debug-detailed%> unknown",
126 		  spec);
127       if (opts->x_debug_struct_ordinary[DINFO_USAGE_DIR_USE]
128 		< opts->x_debug_struct_ordinary[DINFO_USAGE_IND_USE]
129 	  || opts->x_debug_struct_generic[DINFO_USAGE_DIR_USE]
130 		< opts->x_debug_struct_generic[DINFO_USAGE_IND_USE])
131 	error_at (loc,
132 		  "%<-femit-struct-debug-detailed=dir:...%> must allow "
133 		  "at least as much as "
134 		  "%<-femit-struct-debug-detailed=ind:...%>");
135     }
136 }
137 
138 /* Strip off a legitimate source ending from the input string NAME of
139    length LEN.  Rather than having to know the names used by all of
140    our front ends, we strip off an ending of a period followed by
141    up to five characters.  (Java uses ".class".)  */
142 
143 void
144 strip_off_ending (char *name, int len)
145 {
146   int i;
147   for (i = 2; i < 6 && len > i; i++)
148     {
149       if (name[len - i] == '.')
150 	{
151 	  name[len - i] = '\0';
152 	  break;
153 	}
154     }
155 }
156 
157 /* Find the base name of a path, stripping off both directories and
158    a single final extension. */
159 int
160 base_of_path (const char *path, const char **base_out)
161 {
162   const char *base = path;
163   const char *dot = 0;
164   const char *p = path;
165   char c = *p;
166   while (c)
167     {
168       if (IS_DIR_SEPARATOR (c))
169         {
170           base = p + 1;
171           dot = 0;
172         }
173       else if (c == '.')
174         dot = p;
175       c = *++p;
176     }
177   if (!dot)
178     dot = p;
179   *base_out = base;
180   return dot - base;
181 }
182 
183 /* What to print when a switch has no documentation.  */
184 static const char undocumented_msg[] = N_("This option lacks documentation.");
185 static const char use_diagnosed_msg[] = N_("Uses of this option are diagnosed.");
186 
187 typedef char *char_p; /* For DEF_VEC_P.  */
188 
189 static void handle_param (struct gcc_options *opts,
190 			  struct gcc_options *opts_set, location_t loc,
191 			  const char *carg);
192 static void set_debug_level (enum debug_info_type type, int extended,
193 			     const char *arg, struct gcc_options *opts,
194 			     struct gcc_options *opts_set,
195 			     location_t loc);
196 static void set_fast_math_flags (struct gcc_options *opts, int set);
197 static void decode_d_option (const char *arg, struct gcc_options *opts,
198 			     location_t loc, diagnostic_context *dc);
199 static void set_unsafe_math_optimizations_flags (struct gcc_options *opts,
200 						 int set);
201 static void enable_warning_as_error (const char *arg, int value,
202 				     unsigned int lang_mask,
203 				     const struct cl_option_handlers *handlers,
204 				     struct gcc_options *opts,
205 				     struct gcc_options *opts_set,
206 				     location_t loc,
207 				     diagnostic_context *dc);
208 
209 /* Handle a back-end option; arguments and return value as for
210    handle_option.  */
211 
212 bool
213 target_handle_option (struct gcc_options *opts,
214 		      struct gcc_options *opts_set,
215 		      const struct cl_decoded_option *decoded,
216 		      unsigned int lang_mask ATTRIBUTE_UNUSED, int kind,
217 		      location_t loc,
218 		      const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED,
219 		      diagnostic_context *dc, void (*) (void))
220 {
221   gcc_assert (dc == global_dc);
222   gcc_assert (kind == DK_UNSPECIFIED);
223   return targetm_common.handle_option (opts, opts_set, decoded, loc);
224 }
225 
226 /* Add comma-separated strings to a char_p vector.  */
227 
228 static void
229 add_comma_separated_to_vector (void **pvec, const char *arg)
230 {
231   char *tmp;
232   char *r;
233   char *w;
234   char *token_start;
235   vec<char_p> *v = (vec<char_p> *) *pvec;
236 
237   vec_check_alloc (v, 1);
238 
239   /* We never free this string.  */
240   tmp = xstrdup (arg);
241 
242   r = tmp;
243   w = tmp;
244   token_start = tmp;
245 
246   while (*r != '\0')
247     {
248       if (*r == ',')
249 	{
250 	  *w++ = '\0';
251 	  ++r;
252 	  v->safe_push (token_start);
253 	  token_start = w;
254 	}
255       if (*r == '\\' && r[1] == ',')
256 	{
257 	  *w++ = ',';
258 	  r += 2;
259 	}
260       else
261 	*w++ = *r++;
262     }
263   if (*token_start != '\0')
264     v->safe_push (token_start);
265 
266   *pvec = v;
267 }
268 
269 /* Initialize opts_obstack.  */
270 
271 void
272 init_opts_obstack (void)
273 {
274   gcc_obstack_init (&opts_obstack);
275 }
276 
277 /* Initialize OPTS and OPTS_SET before using them in parsing options.  */
278 
279 void
280 init_options_struct (struct gcc_options *opts, struct gcc_options *opts_set)
281 {
282   size_t num_params = get_num_compiler_params ();
283 
284   /* Ensure that opts_obstack has already been initialized by the time
285      that we initialize any gcc_options instances (PR jit/68446).  */
286   gcc_assert (opts_obstack.chunk_size > 0);
287 
288   *opts = global_options_init;
289 
290   if (opts_set)
291     memset (opts_set, 0, sizeof (*opts_set));
292 
293   opts->x_param_values = XNEWVEC (int, num_params);
294 
295   if (opts_set)
296     opts_set->x_param_values = XCNEWVEC (int, num_params);
297 
298   init_param_values (opts->x_param_values);
299 
300   /* Initialize whether `char' is signed.  */
301   opts->x_flag_signed_char = DEFAULT_SIGNED_CHAR;
302   /* Set this to a special "uninitialized" value.  The actual default
303      is set after target options have been processed.  */
304   opts->x_flag_short_enums = 2;
305 
306   /* Initialize target_flags before default_options_optimization
307      so the latter can modify it.  */
308   opts->x_target_flags = targetm_common.default_target_flags;
309 
310   /* Some targets have ABI-specified unwind tables.  */
311   opts->x_flag_unwind_tables = targetm_common.unwind_tables_default;
312 
313   /* Some targets have other target-specific initialization.  */
314   targetm_common.option_init_struct (opts);
315 }
316 
317 /* Release any allocations owned by OPTS.  */
318 
319 void
320 finalize_options_struct (struct gcc_options *opts)
321 {
322   XDELETEVEC (opts->x_param_values);
323 }
324 
325 /* If indicated by the optimization level LEVEL (-Os if SIZE is set,
326    -Ofast if FAST is set, -Og if DEBUG is set), apply the option DEFAULT_OPT
327    to OPTS and OPTS_SET, diagnostic context DC, location LOC, with language
328    mask LANG_MASK and option handlers HANDLERS.  */
329 
330 static void
331 maybe_default_option (struct gcc_options *opts,
332 		      struct gcc_options *opts_set,
333 		      const struct default_options *default_opt,
334 		      int level, bool size, bool fast, bool debug,
335 		      unsigned int lang_mask,
336 		      const struct cl_option_handlers *handlers,
337 		      location_t loc,
338 		      diagnostic_context *dc)
339 {
340   const struct cl_option *option = &cl_options[default_opt->opt_index];
341   bool enabled;
342 
343   if (size)
344     gcc_assert (level == 2);
345   if (fast)
346     gcc_assert (level == 3);
347   if (debug)
348     gcc_assert (level == 1);
349 
350   switch (default_opt->levels)
351     {
352     case OPT_LEVELS_ALL:
353       enabled = true;
354       break;
355 
356     case OPT_LEVELS_0_ONLY:
357       enabled = (level == 0);
358       break;
359 
360     case OPT_LEVELS_1_PLUS:
361       enabled = (level >= 1);
362       break;
363 
364     case OPT_LEVELS_1_PLUS_SPEED_ONLY:
365       enabled = (level >= 1 && !size && !debug);
366       break;
367 
368     case OPT_LEVELS_1_PLUS_NOT_DEBUG:
369       enabled = (level >= 1 && !debug);
370       break;
371 
372     case OPT_LEVELS_2_PLUS:
373       enabled = (level >= 2);
374       break;
375 
376     case OPT_LEVELS_2_PLUS_SPEED_ONLY:
377       enabled = (level >= 2 && !size && !debug);
378       break;
379 
380     case OPT_LEVELS_3_PLUS:
381       enabled = (level >= 3);
382       break;
383 
384     case OPT_LEVELS_3_PLUS_AND_SIZE:
385       enabled = (level >= 3 || size);
386       break;
387 
388     case OPT_LEVELS_SIZE:
389       enabled = size;
390       break;
391 
392     case OPT_LEVELS_FAST:
393       enabled = fast;
394       break;
395 
396     case OPT_LEVELS_NONE:
397     default:
398       gcc_unreachable ();
399     }
400 
401   if (enabled)
402     handle_generated_option (opts, opts_set, default_opt->opt_index,
403 			     default_opt->arg, default_opt->value,
404 			     lang_mask, DK_UNSPECIFIED, loc,
405 			     handlers, dc);
406   else if (default_opt->arg == NULL
407 	   && !option->cl_reject_negative)
408     handle_generated_option (opts, opts_set, default_opt->opt_index,
409 			     default_opt->arg, !default_opt->value,
410 			     lang_mask, DK_UNSPECIFIED, loc,
411 			     handlers, dc);
412 }
413 
414 /* As indicated by the optimization level LEVEL (-Os if SIZE is set,
415    -Ofast if FAST is set), apply the options in array DEFAULT_OPTS to
416    OPTS and OPTS_SET, diagnostic context DC, location LOC, with
417    language mask LANG_MASK and option handlers HANDLERS.  */
418 
419 static void
420 maybe_default_options (struct gcc_options *opts,
421 		       struct gcc_options *opts_set,
422 		       const struct default_options *default_opts,
423 		       int level, bool size, bool fast, bool debug,
424 		       unsigned int lang_mask,
425 		       const struct cl_option_handlers *handlers,
426 		       location_t loc,
427 		       diagnostic_context *dc)
428 {
429   size_t i;
430 
431   for (i = 0; default_opts[i].levels != OPT_LEVELS_NONE; i++)
432     maybe_default_option (opts, opts_set, &default_opts[i],
433 			  level, size, fast, debug,
434 			  lang_mask, handlers, loc, dc);
435 }
436 
437 /* Table of options enabled by default at different levels.  */
438 
439 static const struct default_options default_options_table[] =
440   {
441     /* -O1 optimizations.  */
442     { OPT_LEVELS_1_PLUS, OPT_fdefer_pop, NULL, 1 },
443 #if DELAY_SLOTS
444     { OPT_LEVELS_1_PLUS, OPT_fdelayed_branch, NULL, 1 },
445 #endif
446     { OPT_LEVELS_1_PLUS, OPT_fguess_branch_probability, NULL, 1 },
447     { OPT_LEVELS_1_PLUS, OPT_fcprop_registers, NULL, 1 },
448     { OPT_LEVELS_1_PLUS, OPT_fforward_propagate, NULL, 1 },
449     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fif_conversion, NULL, 1 },
450     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fif_conversion2, NULL, 1 },
451     { OPT_LEVELS_1_PLUS, OPT_fipa_pure_const, NULL, 1 },
452     { OPT_LEVELS_1_PLUS, OPT_fipa_reference, NULL, 1 },
453     { OPT_LEVELS_1_PLUS, OPT_fipa_profile, NULL, 1 },
454     { OPT_LEVELS_1_PLUS, OPT_fmerge_constants, NULL, 1 },
455     { OPT_LEVELS_1_PLUS, OPT_freorder_blocks, NULL, 1 },
456     { OPT_LEVELS_1_PLUS, OPT_fshrink_wrap, NULL, 1 },
457     { OPT_LEVELS_1_PLUS, OPT_fsplit_wide_types, NULL, 1 },
458     { OPT_LEVELS_1_PLUS, OPT_ftree_ccp, NULL, 1 },
459     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_bit_ccp, NULL, 1 },
460     { OPT_LEVELS_1_PLUS, OPT_ftree_coalesce_vars, NULL, 1 },
461     { OPT_LEVELS_1_PLUS, OPT_ftree_dce, NULL, 1 },
462     { OPT_LEVELS_1_PLUS, OPT_ftree_dominator_opts, NULL, 1 },
463     { OPT_LEVELS_1_PLUS, OPT_ftree_dse, NULL, 1 },
464     { OPT_LEVELS_1_PLUS, OPT_ftree_ter, NULL, 1 },
465     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_sra, NULL, 1 },
466     { OPT_LEVELS_1_PLUS, OPT_ftree_fre, NULL, 1 },
467     { OPT_LEVELS_1_PLUS, OPT_ftree_copy_prop, NULL, 1 },
468     { OPT_LEVELS_1_PLUS, OPT_ftree_sink, NULL, 1 },
469     { OPT_LEVELS_1_PLUS, OPT_ftree_ch, NULL, 1 },
470     { OPT_LEVELS_1_PLUS, OPT_fcombine_stack_adjustments, NULL, 1 },
471     { OPT_LEVELS_1_PLUS, OPT_fcompare_elim, NULL, 1 },
472     { OPT_LEVELS_1_PLUS, OPT_ftree_slsr, NULL, 1 },
473     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fbranch_count_reg, NULL, 1 },
474     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fmove_loop_invariants, NULL, 1 },
475     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_pta, NULL, 1 },
476     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fssa_phiopt, NULL, 1 },
477     { OPT_LEVELS_1_PLUS, OPT_ftree_builtin_call_dce, NULL, 1 },
478 
479     /* -O2 optimizations.  */
480     { OPT_LEVELS_2_PLUS, OPT_finline_small_functions, NULL, 1 },
481     { OPT_LEVELS_2_PLUS, OPT_findirect_inlining, NULL, 1 },
482     { OPT_LEVELS_2_PLUS, OPT_fpartial_inlining, NULL, 1 },
483     { OPT_LEVELS_2_PLUS, OPT_fthread_jumps, NULL, 1 },
484     { OPT_LEVELS_2_PLUS, OPT_fcrossjumping, NULL, 1 },
485     { OPT_LEVELS_2_PLUS, OPT_foptimize_sibling_calls, NULL, 1 },
486     { OPT_LEVELS_2_PLUS, OPT_fcse_follow_jumps, NULL, 1 },
487     { OPT_LEVELS_2_PLUS, OPT_fgcse, NULL, 1 },
488     { OPT_LEVELS_2_PLUS, OPT_fexpensive_optimizations, NULL, 1 },
489     { OPT_LEVELS_2_PLUS, OPT_frerun_cse_after_loop, NULL, 1 },
490     { OPT_LEVELS_2_PLUS, OPT_fcaller_saves, NULL, 1 },
491     { OPT_LEVELS_2_PLUS, OPT_fpeephole2, NULL, 1 },
492 #ifdef INSN_SCHEDULING
493   /* Only run the pre-regalloc scheduling pass if optimizing for speed.  */
494     { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_fschedule_insns, NULL, 1 },
495     { OPT_LEVELS_2_PLUS, OPT_fschedule_insns2, NULL, 1 },
496 #endif
497     { OPT_LEVELS_2_PLUS, OPT_fstrict_aliasing, NULL, 1 },
498     { OPT_LEVELS_2_PLUS, OPT_fstrict_overflow, NULL, 1 },
499     { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_freorder_blocks_algorithm_, NULL,
500       REORDER_BLOCKS_ALGORITHM_STC },
501     { OPT_LEVELS_2_PLUS, OPT_freorder_functions, NULL, 1 },
502     { OPT_LEVELS_2_PLUS, OPT_ftree_vrp, NULL, 1 },
503     { OPT_LEVELS_2_PLUS, OPT_ftree_pre, NULL, 1 },
504     { OPT_LEVELS_2_PLUS, OPT_ftree_switch_conversion, NULL, 1 },
505     { OPT_LEVELS_2_PLUS, OPT_fipa_cp, NULL, 1 },
506     { OPT_LEVELS_2_PLUS, OPT_fipa_cp_alignment, NULL, 1 },
507     { OPT_LEVELS_2_PLUS, OPT_fdevirtualize, NULL, 1 },
508     { OPT_LEVELS_2_PLUS, OPT_fdevirtualize_speculatively, NULL, 1 },
509     { OPT_LEVELS_2_PLUS, OPT_fipa_sra, NULL, 1 },
510     { OPT_LEVELS_2_PLUS, OPT_falign_loops, NULL, 1 },
511     { OPT_LEVELS_2_PLUS, OPT_falign_jumps, NULL, 1 },
512     { OPT_LEVELS_2_PLUS, OPT_falign_labels, NULL, 1 },
513     { OPT_LEVELS_2_PLUS, OPT_falign_functions, NULL, 1 },
514     { OPT_LEVELS_2_PLUS, OPT_ftree_tail_merge, NULL, 1 },
515     { OPT_LEVELS_2_PLUS, OPT_fvect_cost_model_, NULL, VECT_COST_MODEL_CHEAP },
516     { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_foptimize_strlen, NULL, 1 },
517     { OPT_LEVELS_2_PLUS, OPT_fhoist_adjacent_loads, NULL, 1 },
518     { OPT_LEVELS_2_PLUS, OPT_fipa_icf, NULL, 1 },
519     { OPT_LEVELS_2_PLUS, OPT_fisolate_erroneous_paths_dereference, NULL, 1 },
520     { OPT_LEVELS_2_PLUS, OPT_fipa_ra, NULL, 1 },
521     { OPT_LEVELS_2_PLUS, OPT_flra_remat, NULL, 1 },
522 
523     /* -O3 optimizations.  */
524     { OPT_LEVELS_3_PLUS, OPT_ftree_loop_distribute_patterns, NULL, 1 },
525     { OPT_LEVELS_3_PLUS, OPT_fpredictive_commoning, NULL, 1 },
526     { OPT_LEVELS_3_PLUS, OPT_fsplit_paths, NULL, 1 },
527     /* Inlining of functions reducing size is a good idea with -Os
528        regardless of them being declared inline.  */
529     { OPT_LEVELS_3_PLUS_AND_SIZE, OPT_finline_functions, NULL, 1 },
530     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_finline_functions_called_once, NULL, 1 },
531     { OPT_LEVELS_3_PLUS, OPT_funswitch_loops, NULL, 1 },
532     { OPT_LEVELS_3_PLUS, OPT_fgcse_after_reload, NULL, 1 },
533     { OPT_LEVELS_3_PLUS, OPT_ftree_loop_vectorize, NULL, 1 },
534     { OPT_LEVELS_3_PLUS, OPT_ftree_slp_vectorize, NULL, 1 },
535     { OPT_LEVELS_3_PLUS, OPT_fvect_cost_model_, NULL, VECT_COST_MODEL_DYNAMIC },
536     { OPT_LEVELS_3_PLUS, OPT_fipa_cp_clone, NULL, 1 },
537     { OPT_LEVELS_3_PLUS, OPT_ftree_partial_pre, NULL, 1 },
538 
539     /* -Ofast adds optimizations to -O3.  */
540     { OPT_LEVELS_FAST, OPT_ffast_math, NULL, 1 },
541 
542     { OPT_LEVELS_NONE, 0, NULL, 0 }
543   };
544 
545 /* Default the options in OPTS and OPTS_SET based on the optimization
546    settings in DECODED_OPTIONS and DECODED_OPTIONS_COUNT.  */
547 void
548 default_options_optimization (struct gcc_options *opts,
549 			      struct gcc_options *opts_set,
550 			      struct cl_decoded_option *decoded_options,
551 			      unsigned int decoded_options_count,
552 			      location_t loc,
553 			      unsigned int lang_mask,
554 			      const struct cl_option_handlers *handlers,
555 			      diagnostic_context *dc)
556 {
557   unsigned int i;
558   int opt2;
559   bool openacc_mode = false;
560 
561   /* Scan to see what optimization level has been specified.  That will
562      determine the default value of many flags.  */
563   for (i = 1; i < decoded_options_count; i++)
564     {
565       struct cl_decoded_option *opt = &decoded_options[i];
566       switch (opt->opt_index)
567 	{
568 	case OPT_O:
569 	  if (*opt->arg == '\0')
570 	    {
571 	      opts->x_optimize = 1;
572 	      opts->x_optimize_size = 0;
573 	      opts->x_optimize_fast = 0;
574 	      opts->x_optimize_debug = 0;
575 	    }
576 	  else
577 	    {
578 	      const int optimize_val = integral_argument (opt->arg);
579 	      if (optimize_val == -1)
580 		error_at (loc, "argument to %<-O%> should be a non-negative "
581 			       "integer, %<g%>, %<s%> or %<fast%>");
582 	      else
583 		{
584 		  opts->x_optimize = optimize_val;
585 		  if ((unsigned int) opts->x_optimize > 255)
586 		    opts->x_optimize = 255;
587 		  opts->x_optimize_size = 0;
588 		  opts->x_optimize_fast = 0;
589 		  opts->x_optimize_debug = 0;
590 		}
591 	    }
592 	  break;
593 
594 	case OPT_Os:
595 	  opts->x_optimize_size = 1;
596 
597 	  /* Optimizing for size forces optimize to be 2.  */
598 	  opts->x_optimize = 2;
599 	  opts->x_optimize_fast = 0;
600 	  opts->x_optimize_debug = 0;
601 	  break;
602 
603 	case OPT_Ofast:
604 	  /* -Ofast only adds flags to -O3.  */
605 	  opts->x_optimize_size = 0;
606 	  opts->x_optimize = 3;
607 	  opts->x_optimize_fast = 1;
608 	  opts->x_optimize_debug = 0;
609 	  break;
610 
611 	case OPT_Og:
612 	  /* -Og selects optimization level 1.  */
613 	  opts->x_optimize_size = 0;
614 	  opts->x_optimize = 1;
615 	  opts->x_optimize_fast = 0;
616 	  opts->x_optimize_debug = 1;
617 	  break;
618 
619 	case OPT_fopenacc:
620 	  if (opt->value)
621 	    openacc_mode = true;
622 	  break;
623 
624 	default:
625 	  /* Ignore other options in this prescan.  */
626 	  break;
627 	}
628     }
629 
630   maybe_default_options (opts, opts_set, default_options_table,
631 			 opts->x_optimize, opts->x_optimize_size,
632 			 opts->x_optimize_fast, opts->x_optimize_debug,
633 			 lang_mask, handlers, loc, dc);
634 
635   /* -O2 param settings.  */
636   opt2 = (opts->x_optimize >= 2);
637 
638   if (openacc_mode
639       && !opts_set->x_flag_ipa_pta)
640     opts->x_flag_ipa_pta = true;
641 
642   /* Track fields in field-sensitive alias analysis.  */
643   maybe_set_param_value
644     (PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE,
645      opt2 ? 100 : default_param_value (PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE),
646      opts->x_param_values, opts_set->x_param_values);
647 
648   /* For -O1 only do loop invariant motion for very small loops.  */
649   maybe_set_param_value
650     (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP,
651      opt2 ? default_param_value (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP) : 1000,
652      opts->x_param_values, opts_set->x_param_values);
653 
654   /* At -Ofast, allow store motion to introduce potential race conditions.  */
655   maybe_set_param_value
656     (PARAM_ALLOW_STORE_DATA_RACES,
657      opts->x_optimize_fast ? 1
658      : default_param_value (PARAM_ALLOW_STORE_DATA_RACES),
659      opts->x_param_values, opts_set->x_param_values);
660 
661   if (opts->x_optimize_size)
662     /* We want to crossjump as much as possible.  */
663     maybe_set_param_value (PARAM_MIN_CROSSJUMP_INSNS, 1,
664 			   opts->x_param_values, opts_set->x_param_values);
665   else
666     maybe_set_param_value (PARAM_MIN_CROSSJUMP_INSNS,
667 			   default_param_value (PARAM_MIN_CROSSJUMP_INSNS),
668 			   opts->x_param_values, opts_set->x_param_values);
669 
670   /* Restrict the amount of work combine does at -Og while retaining
671      most of its useful transforms.  */
672   if (opts->x_optimize_debug)
673     maybe_set_param_value (PARAM_MAX_COMBINE_INSNS, 2,
674 			   opts->x_param_values, opts_set->x_param_values);
675 
676   /* Allow default optimizations to be specified on a per-machine basis.  */
677   maybe_default_options (opts, opts_set,
678 			 targetm_common.option_optimization_table,
679 			 opts->x_optimize, opts->x_optimize_size,
680 			 opts->x_optimize_fast, opts->x_optimize_debug,
681 			 lang_mask, handlers, loc, dc);
682 }
683 
684 /* After all options at LOC have been read into OPTS and OPTS_SET,
685    finalize settings of those options and diagnose incompatible
686    combinations.  */
687 void
688 finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
689 		location_t loc)
690 {
691   enum unwind_info_type ui_except;
692 
693   if (opts->x_dump_base_name
694       && ! IS_ABSOLUTE_PATH (opts->x_dump_base_name)
695       && ! opts->x_dump_base_name_prefixed)
696     {
697       /* First try to make OPTS->X_DUMP_BASE_NAME relative to the
698 	 OPTS->X_DUMP_DIR_NAME directory.  Then try to make
699 	 OPTS->X_DUMP_BASE_NAME relative to the OPTS->X_AUX_BASE_NAME
700 	 directory, typically the directory to contain the object
701 	 file.  */
702       if (opts->x_dump_dir_name)
703 	opts->x_dump_base_name = opts_concat (opts->x_dump_dir_name,
704 					      opts->x_dump_base_name, NULL);
705       else if (opts->x_aux_base_name
706 	       && strcmp (opts->x_aux_base_name, HOST_BIT_BUCKET) != 0)
707 	{
708 	  const char *aux_base;
709 
710 	  base_of_path (opts->x_aux_base_name, &aux_base);
711 	  if (opts->x_aux_base_name != aux_base)
712 	    {
713 	      int dir_len = aux_base - opts->x_aux_base_name;
714 	      char *new_dump_base_name
715 		= XOBNEWVEC (&opts_obstack, char,
716 			     strlen (opts->x_dump_base_name) + dir_len + 1);
717 
718 	      /* Copy directory component from OPTS->X_AUX_BASE_NAME.  */
719 	      memcpy (new_dump_base_name, opts->x_aux_base_name, dir_len);
720 	      /* Append existing OPTS->X_DUMP_BASE_NAME.  */
721 	      strcpy (new_dump_base_name + dir_len, opts->x_dump_base_name);
722 	      opts->x_dump_base_name = new_dump_base_name;
723 	    }
724 	}
725 	opts->x_dump_base_name_prefixed = true;
726     }
727 
728   /* Handle related options for unit-at-a-time, toplevel-reorder, and
729      section-anchors.  */
730   if (!opts->x_flag_unit_at_a_time)
731     {
732       if (opts->x_flag_section_anchors && opts_set->x_flag_section_anchors)
733 	error_at (loc, "section anchors must be disabled when unit-at-a-time "
734 		  "is disabled");
735       opts->x_flag_section_anchors = 0;
736       if (opts->x_flag_toplevel_reorder == 1)
737 	error_at (loc, "toplevel reorder must be disabled when unit-at-a-time "
738 		  "is disabled");
739       opts->x_flag_toplevel_reorder = 0;
740     }
741 
742   if (opts->x_flag_tm && opts->x_flag_non_call_exceptions)
743     sorry ("transactional memory is not supported with non-call exceptions");
744 
745   /* Unless the user has asked for section anchors, we disable toplevel
746      reordering at -O0 to disable transformations that might be surprising
747      to end users and to get -fno-toplevel-reorder tested.  */
748   if (!opts->x_optimize
749       && opts->x_flag_toplevel_reorder == 2
750       && !(opts->x_flag_section_anchors && opts_set->x_flag_section_anchors))
751     {
752       opts->x_flag_toplevel_reorder = 0;
753       opts->x_flag_section_anchors = 0;
754     }
755   if (!opts->x_flag_toplevel_reorder)
756     {
757       if (opts->x_flag_section_anchors && opts_set->x_flag_section_anchors)
758 	error_at (loc, "section anchors must be disabled when toplevel reorder"
759 		  " is disabled");
760       opts->x_flag_section_anchors = 0;
761     }
762 
763   if (!opts->x_flag_opts_finished)
764     {
765       /* We initialize opts->x_flag_pie to -1 so that targets can set a
766 	 default value.  */
767       if (opts->x_flag_pie == -1)
768 	{
769 	  /* We initialize opts->x_flag_pic to -1 so that we can tell if
770 	     -fpic, -fPIC, -fno-pic or -fno-PIC is used.  */
771 	  if (opts->x_flag_pic == -1)
772 	    opts->x_flag_pie = DEFAULT_FLAG_PIE;
773 	  else
774 	    opts->x_flag_pie = 0;
775 	}
776       /* If -fPIE or -fpie is used, turn on PIC.  */
777       if (opts->x_flag_pie)
778 	opts->x_flag_pic = opts->x_flag_pie;
779       else if (opts->x_flag_pic == -1)
780 	opts->x_flag_pic = 0;
781       if (opts->x_flag_pic && !opts->x_flag_pie)
782 	opts->x_flag_shlib = 1;
783       opts->x_flag_opts_finished = true;
784     }
785 
786   /* We initialize opts->x_flag_stack_protect to -1 so that targets
787      can set a default value.  */
788   if (opts->x_flag_stack_protect == -1)
789     opts->x_flag_stack_protect = DEFAULT_FLAG_SSP;
790 
791   if (opts->x_optimize == 0)
792     {
793       /* Inlining does not work if not optimizing,
794 	 so force it not to be done.  */
795       opts->x_warn_inline = 0;
796       opts->x_flag_no_inline = 1;
797     }
798 
799   /* The optimization to partition hot and cold basic blocks into separate
800      sections of the .o and executable files does not work (currently)
801      with exception handling.  This is because there is no support for
802      generating unwind info.  If opts->x_flag_exceptions is turned on
803      we need to turn off the partitioning optimization.  */
804 
805   ui_except = targetm_common.except_unwind_info (opts);
806 
807   if (opts->x_flag_exceptions
808       && opts->x_flag_reorder_blocks_and_partition
809       && (ui_except == UI_SJLJ || ui_except >= UI_TARGET))
810     {
811       if (opts_set->x_flag_reorder_blocks_and_partition)
812         inform (loc,
813                 "-freorder-blocks-and-partition does not work "
814                 "with exceptions on this architecture");
815       opts->x_flag_reorder_blocks_and_partition = 0;
816       opts->x_flag_reorder_blocks = 1;
817     }
818 
819   /* If user requested unwind info, then turn off the partitioning
820      optimization.  */
821 
822   if (opts->x_flag_unwind_tables
823       && !targetm_common.unwind_tables_default
824       && opts->x_flag_reorder_blocks_and_partition
825       && (ui_except == UI_SJLJ || ui_except >= UI_TARGET))
826     {
827       if (opts_set->x_flag_reorder_blocks_and_partition)
828         inform (loc,
829                 "-freorder-blocks-and-partition does not support "
830                 "unwind info on this architecture");
831       opts->x_flag_reorder_blocks_and_partition = 0;
832       opts->x_flag_reorder_blocks = 1;
833     }
834 
835   /* If the target requested unwind info, then turn off the partitioning
836      optimization with a different message.  Likewise, if the target does not
837      support named sections.  */
838 
839   if (opts->x_flag_reorder_blocks_and_partition
840       && (!targetm_common.have_named_sections
841 	  || (opts->x_flag_unwind_tables
842 	      && targetm_common.unwind_tables_default
843 	      && (ui_except == UI_SJLJ || ui_except >= UI_TARGET))))
844     {
845       if (opts_set->x_flag_reorder_blocks_and_partition)
846         inform (loc,
847                 "-freorder-blocks-and-partition does not work "
848                 "on this architecture");
849       opts->x_flag_reorder_blocks_and_partition = 0;
850       opts->x_flag_reorder_blocks = 1;
851     }
852 
853   /* Disable -freorder-blocks-and-partition when -fprofile-use is not in
854      effect. Function splitting was not actually being performed in that case,
855      as probably_never_executed_bb_p does not distinguish any basic blocks as
856      being cold vs hot when there is no profile data. Leaving it enabled,
857      however, causes the assembly code generator to create (empty) cold
858      sections and labels, leading to unnecessary size overhead.  */
859   if (opts->x_flag_reorder_blocks_and_partition
860       && !opts_set->x_flag_profile_use)
861     opts->x_flag_reorder_blocks_and_partition = 0;
862 
863   if (opts->x_flag_reorder_blocks_and_partition
864       && !opts_set->x_flag_reorder_functions)
865     opts->x_flag_reorder_functions = 1;
866 
867   /* Pipelining of outer loops is only possible when general pipelining
868      capabilities are requested.  */
869   if (!opts->x_flag_sel_sched_pipelining)
870     opts->x_flag_sel_sched_pipelining_outer_loops = 0;
871 
872   if (opts->x_flag_conserve_stack)
873     {
874       maybe_set_param_value (PARAM_LARGE_STACK_FRAME, 100,
875 			     opts->x_param_values, opts_set->x_param_values);
876       maybe_set_param_value (PARAM_STACK_FRAME_GROWTH, 40,
877 			     opts->x_param_values, opts_set->x_param_values);
878     }
879 
880   if (opts->x_flag_lto)
881     {
882 #ifdef ENABLE_LTO
883       opts->x_flag_generate_lto = 1;
884 
885       /* When generating IL, do not operate in whole-program mode.
886 	 Otherwise, symbols will be privatized too early, causing link
887 	 errors later.  */
888       opts->x_flag_whole_program = 0;
889 #else
890       error_at (loc, "LTO support has not been enabled in this configuration");
891 #endif
892       if (!opts->x_flag_fat_lto_objects
893 	  && (!HAVE_LTO_PLUGIN
894 	      || (opts_set->x_flag_use_linker_plugin
895 		  && !opts->x_flag_use_linker_plugin)))
896 	{
897 	  if (opts_set->x_flag_fat_lto_objects)
898             error_at (loc, "-fno-fat-lto-objects are supported only with linker plugin");
899 	  opts->x_flag_fat_lto_objects = 1;
900 	}
901     }
902 
903   /* We initialize opts->x_flag_split_stack to -1 so that targets can set a
904      default value if they choose based on other options.  */
905   if (opts->x_flag_split_stack == -1)
906     opts->x_flag_split_stack = 0;
907   else if (opts->x_flag_split_stack)
908     {
909       if (!targetm_common.supports_split_stack (true, opts))
910 	{
911 	  error_at (loc, "%<-fsplit-stack%> is not supported by "
912 		    "this compiler configuration");
913 	  opts->x_flag_split_stack = 0;
914 	}
915     }
916 
917   /* Tune vectorization related parametees according to cost model.  */
918   if (opts->x_flag_vect_cost_model == VECT_COST_MODEL_CHEAP)
919     {
920       maybe_set_param_value (PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS,
921             6, opts->x_param_values, opts_set->x_param_values);
922       maybe_set_param_value (PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS,
923             0, opts->x_param_values, opts_set->x_param_values);
924       maybe_set_param_value (PARAM_VECT_MAX_PEELING_FOR_ALIGNMENT,
925             0, opts->x_param_values, opts_set->x_param_values);
926     }
927 
928   /* Set PARAM_MAX_STORES_TO_SINK to 0 if either vectorization or if-conversion
929      is disabled.  */
930   if ((!opts->x_flag_tree_loop_vectorize && !opts->x_flag_tree_slp_vectorize)
931        || !opts->x_flag_tree_loop_if_convert)
932     maybe_set_param_value (PARAM_MAX_STORES_TO_SINK, 0,
933                            opts->x_param_values, opts_set->x_param_values);
934 
935   /* The -gsplit-dwarf option requires -ggnu-pubnames.  */
936   if (opts->x_dwarf_split_debug_info)
937     opts->x_debug_generate_pub_sections = 2;
938 
939   /* Userspace and kernel ASan conflict with each other.  */
940 
941   if ((opts->x_flag_sanitize & SANITIZE_USER_ADDRESS)
942       && (opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS))
943     error_at (loc,
944 	      "-fsanitize=address is incompatible with "
945 	      "-fsanitize=kernel-address");
946 
947   /* And with TSan.  */
948 
949   if ((opts->x_flag_sanitize & SANITIZE_ADDRESS)
950       && (opts->x_flag_sanitize & SANITIZE_THREAD))
951     error_at (loc,
952 	      "-fsanitize=address and -fsanitize=kernel-address "
953 	      "are incompatible with -fsanitize=thread");
954 
955   /* Error recovery is not allowed for LSan and TSan.  */
956 
957   if (opts->x_flag_sanitize_recover & SANITIZE_THREAD)
958     error_at (loc, "-fsanitize-recover=thread is not supported");
959 
960   if (opts->x_flag_sanitize_recover & SANITIZE_LEAK)
961     error_at (loc, "-fsanitize-recover=leak is not supported");
962 
963   /* When instrumenting the pointers, we don't want to remove
964      the null pointer checks.  */
965   if (opts->x_flag_sanitize & (SANITIZE_NULL | SANITIZE_NONNULL_ATTRIBUTE
966 				| SANITIZE_RETURNS_NONNULL_ATTRIBUTE))
967     opts->x_flag_delete_null_pointer_checks = 0;
968 
969   /* Aggressive compiler optimizations may cause false negatives.  */
970   if (opts->x_flag_sanitize)
971     {
972       opts->x_flag_aggressive_loop_optimizations = 0;
973       opts->x_flag_strict_overflow = 0;
974     }
975 
976   /* Comes from final.c -- no real reason to change it.  */
977 #define MAX_CODE_ALIGN 16
978 #define MAX_CODE_ALIGN_VALUE (1 << MAX_CODE_ALIGN)
979 
980   if (opts->x_align_loops > MAX_CODE_ALIGN_VALUE)
981     error_at (loc, "-falign-loops=%d is not between 0 and %d",
982 	      opts->x_align_loops, MAX_CODE_ALIGN_VALUE);
983 
984   if (opts->x_align_jumps > MAX_CODE_ALIGN_VALUE)
985     error_at (loc, "-falign-jumps=%d is not between 0 and %d",
986 	      opts->x_align_jumps, MAX_CODE_ALIGN_VALUE);
987 
988   if (opts->x_align_functions > MAX_CODE_ALIGN_VALUE)
989     error_at (loc, "-falign-functions=%d is not between 0 and %d",
990 	      opts->x_align_functions, MAX_CODE_ALIGN_VALUE);
991 
992   if (opts->x_align_labels > MAX_CODE_ALIGN_VALUE)
993     error_at (loc, "-falign-labels=%d is not between 0 and %d",
994 	      opts->x_align_labels, MAX_CODE_ALIGN_VALUE);
995 }
996 
997 #define LEFT_COLUMN	27
998 
999 /* Output ITEM, of length ITEM_WIDTH, in the left column,
1000    followed by word-wrapped HELP in a second column.  */
1001 static void
1002 wrap_help (const char *help,
1003 	   const char *item,
1004 	   unsigned int item_width,
1005 	   unsigned int columns)
1006 {
1007   unsigned int col_width = LEFT_COLUMN;
1008   unsigned int remaining, room, len;
1009 
1010   remaining = strlen (help);
1011 
1012   do
1013     {
1014       room = columns - 3 - MAX (col_width, item_width);
1015       if (room > columns)
1016 	room = 0;
1017       len = remaining;
1018 
1019       if (room < len)
1020 	{
1021 	  unsigned int i;
1022 
1023 	  for (i = 0; help[i]; i++)
1024 	    {
1025 	      if (i >= room && len != remaining)
1026 		break;
1027 	      if (help[i] == ' ')
1028 		len = i;
1029 	      else if ((help[i] == '-' || help[i] == '/')
1030 		       && help[i + 1] != ' '
1031 		       && i > 0 && ISALPHA (help[i - 1]))
1032 		len = i + 1;
1033 	    }
1034 	}
1035 
1036       printf ("  %-*.*s %.*s\n", col_width, item_width, item, len, help);
1037       item_width = 0;
1038       while (help[len] == ' ')
1039 	len++;
1040       help += len;
1041       remaining -= len;
1042     }
1043   while (remaining);
1044 }
1045 
1046 /* Print help for a specific front-end, etc.  */
1047 static void
1048 print_filtered_help (unsigned int include_flags,
1049 		     unsigned int exclude_flags,
1050 		     unsigned int any_flags,
1051 		     unsigned int columns,
1052 		     struct gcc_options *opts,
1053 		     unsigned int lang_mask)
1054 {
1055   unsigned int i;
1056   const char *help;
1057   bool found = false;
1058   bool displayed = false;
1059   char new_help[256];
1060 
1061   if (include_flags == CL_PARAMS)
1062     {
1063       for (i = 0; i < LAST_PARAM; i++)
1064 	{
1065 	  const char *param = compiler_params[i].option;
1066 
1067 	  help = compiler_params[i].help;
1068 	  if (help == NULL || *help == '\0')
1069 	    {
1070 	      if (exclude_flags & CL_UNDOCUMENTED)
1071 		continue;
1072 	      help = undocumented_msg;
1073 	    }
1074 
1075 	  /* Get the translation.  */
1076 	  help = _(help);
1077 
1078 	  if (!opts->x_quiet_flag)
1079 	    {
1080 	      snprintf (new_help, sizeof (new_help),
1081 			_("default %d minimum %d maximum %d"),
1082 			compiler_params[i].default_value,
1083 			compiler_params[i].min_value,
1084 			compiler_params[i].max_value);
1085 	      help = new_help;
1086 	    }
1087 	  wrap_help (help, param, strlen (param), columns);
1088 	}
1089       putchar ('\n');
1090       return;
1091     }
1092 
1093   if (!opts->x_help_printed)
1094     opts->x_help_printed = XCNEWVAR (char, cl_options_count);
1095 
1096   if (!opts->x_help_enum_printed)
1097     opts->x_help_enum_printed = XCNEWVAR (char, cl_enums_count);
1098 
1099   for (i = 0; i < cl_options_count; i++)
1100     {
1101       const struct cl_option *option = cl_options + i;
1102       unsigned int len;
1103       const char *opt;
1104       const char *tab;
1105 
1106       if (include_flags == 0
1107 	  || ((option->flags & include_flags) != include_flags))
1108 	{
1109 	  if ((option->flags & any_flags) == 0)
1110 	    continue;
1111 	}
1112 
1113       /* Skip unwanted switches.  */
1114       if ((option->flags & exclude_flags) != 0)
1115 	continue;
1116 
1117       /* The driver currently prints its own help text.  */
1118       if ((option->flags & CL_DRIVER) != 0
1119 	  && (option->flags & (((1U << cl_lang_count) - 1)
1120 			       | CL_COMMON | CL_TARGET)) == 0)
1121 	continue;
1122 
1123       found = true;
1124       /* Skip switches that have already been printed.  */
1125       if (opts->x_help_printed[i])
1126 	continue;
1127 
1128       opts->x_help_printed[i] = true;
1129 
1130       help = option->help;
1131       if (help == NULL)
1132 	{
1133 	  if (exclude_flags & CL_UNDOCUMENTED)
1134 	    continue;
1135 
1136 	  help = undocumented_msg;
1137 	}
1138 
1139       if (option->alias_target < N_OPTS
1140 	  && cl_options [option->alias_target].help)
1141 	{
1142 	  if (help == undocumented_msg)
1143 	    {
1144 	      /* For undocumented options that are aliases for other options
1145 		 that are documented, point the reader to the other option in
1146 		 preference of the former.  */
1147 	      snprintf (new_help, sizeof new_help,
1148 			_("Same as %s.  Use the latter option instead."),
1149 			cl_options [option->alias_target].opt_text);
1150 	    }
1151 	  else
1152 	    {
1153 	      /* For documented options with aliases, mention the aliased
1154 		 option's name for reference.  */
1155 	      snprintf (new_help, sizeof new_help,
1156 			_("%s  Same as %s."),
1157 			help, cl_options [option->alias_target].opt_text);
1158 	    }
1159 
1160 	  help = new_help;
1161 	}
1162 
1163       if (option->warn_message)
1164 	{
1165 	  /* Mention that the use of the option will trigger a warning.  */
1166 	  if (help == new_help)
1167 	    snprintf (new_help + strlen (new_help),
1168 		      sizeof new_help - strlen (new_help),
1169 		      "  %s", _(use_diagnosed_msg));
1170 	  else
1171 	    snprintf (new_help, sizeof new_help,
1172 		      "%s  %s", help, _(use_diagnosed_msg));
1173 
1174 	  help = new_help;
1175 	}
1176 
1177       /* Get the translation.  */
1178       help = _(help);
1179 
1180       /* Find the gap between the name of the
1181 	 option and its descriptive text.  */
1182       tab = strchr (help, '\t');
1183       if (tab)
1184 	{
1185 	  len = tab - help;
1186 	  opt = help;
1187 	  help = tab + 1;
1188 	}
1189       else
1190 	{
1191 	  opt = option->opt_text;
1192 	  len = strlen (opt);
1193 	}
1194 
1195       /* With the -Q option enabled we change the descriptive text associated
1196 	 with an option to be an indication of its current setting.  */
1197       if (!opts->x_quiet_flag)
1198 	{
1199 	  void *flag_var = option_flag_var (i, opts);
1200 
1201 	  if (len < (LEFT_COLUMN + 2))
1202 	    strcpy (new_help, "\t\t");
1203 	  else
1204 	    strcpy (new_help, "\t");
1205 
1206 	  if (flag_var != NULL
1207 	      && option->var_type != CLVC_DEFER)
1208 	    {
1209 	      if (option->flags & CL_JOINED)
1210 		{
1211 		  if (option->var_type == CLVC_STRING)
1212 		    {
1213 		      if (* (const char **) flag_var != NULL)
1214 			snprintf (new_help + strlen (new_help),
1215 				  sizeof (new_help) - strlen (new_help),
1216 				  "%s", * (const char **) flag_var);
1217 		    }
1218 		  else if (option->var_type == CLVC_ENUM)
1219 		    {
1220 		      const struct cl_enum *e = &cl_enums[option->var_enum];
1221 		      int value;
1222 		      const char *arg = NULL;
1223 
1224 		      value = e->get (flag_var);
1225 		      enum_value_to_arg (e->values, &arg, value, lang_mask);
1226 		      if (arg == NULL)
1227 			arg = _("[default]");
1228 		      snprintf (new_help + strlen (new_help),
1229 				sizeof (new_help) - strlen (new_help),
1230 				"%s", arg);
1231 		    }
1232 		  else
1233 		    sprintf (new_help + strlen (new_help),
1234 			     "%#x", * (int *) flag_var);
1235 		}
1236 	      else
1237 		strcat (new_help, option_enabled (i, opts)
1238 			? _("[enabled]") : _("[disabled]"));
1239 	    }
1240 
1241 	  help = new_help;
1242 	}
1243 
1244       wrap_help (help, opt, len, columns);
1245       displayed = true;
1246 
1247       if (option->var_type == CLVC_ENUM
1248 	  && opts->x_help_enum_printed[option->var_enum] != 2)
1249 	opts->x_help_enum_printed[option->var_enum] = 1;
1250     }
1251 
1252   if (! found)
1253     {
1254       unsigned int langs = include_flags & CL_LANG_ALL;
1255 
1256       if (langs == 0)
1257 	printf (_(" No options with the desired characteristics were found\n"));
1258       else
1259 	{
1260 	  unsigned int i;
1261 
1262 	  /* PR 31349: Tell the user how to see all of the
1263 	     options supported by a specific front end.  */
1264 	  for (i = 0; (1U << i) < CL_LANG_ALL; i ++)
1265 	    if ((1U << i) & langs)
1266 	      printf (_(" None found.  Use --help=%s to show *all* the options supported by the %s front-end.\n"),
1267 		      lang_names[i], lang_names[i]);
1268 	}
1269 
1270     }
1271   else if (! displayed)
1272     printf (_(" All options with the desired characteristics have already been displayed\n"));
1273 
1274   putchar ('\n');
1275 
1276   /* Print details of enumerated option arguments, if those
1277      enumerations have help text headings provided.  If no help text
1278      is provided, presume that the possible values are listed in the
1279      help text for the relevant options.  */
1280   for (i = 0; i < cl_enums_count; i++)
1281     {
1282       unsigned int j, pos;
1283 
1284       if (opts->x_help_enum_printed[i] != 1)
1285 	continue;
1286       if (cl_enums[i].help == NULL)
1287 	continue;
1288       printf ("  %s\n    ", _(cl_enums[i].help));
1289       pos = 4;
1290       for (j = 0; cl_enums[i].values[j].arg != NULL; j++)
1291 	{
1292 	  unsigned int len = strlen (cl_enums[i].values[j].arg);
1293 
1294 	  if (pos > 4 && pos + 1 + len <= columns)
1295 	    {
1296 	      printf (" %s", cl_enums[i].values[j].arg);
1297 	      pos += 1 + len;
1298 	    }
1299 	  else
1300 	    {
1301 	      if (pos > 4)
1302 		{
1303 		  printf ("\n    ");
1304 		  pos = 4;
1305 		}
1306 	      printf ("%s", cl_enums[i].values[j].arg);
1307 	      pos += len;
1308 	    }
1309 	}
1310       printf ("\n\n");
1311       opts->x_help_enum_printed[i] = 2;
1312     }
1313 }
1314 
1315 /* Display help for a specified type of option.
1316    The options must have ALL of the INCLUDE_FLAGS set
1317    ANY of the flags in the ANY_FLAGS set
1318    and NONE of the EXCLUDE_FLAGS set.  The current option state is in
1319    OPTS; LANG_MASK is used for interpreting enumerated option state.  */
1320 static void
1321 print_specific_help (unsigned int include_flags,
1322 		     unsigned int exclude_flags,
1323 		     unsigned int any_flags,
1324 		     struct gcc_options *opts,
1325 		     unsigned int lang_mask)
1326 {
1327   unsigned int all_langs_mask = (1U << cl_lang_count) - 1;
1328   const char * description = NULL;
1329   const char * descrip_extra = "";
1330   size_t i;
1331   unsigned int flag;
1332 
1333   /* Sanity check: Make sure that we do not have more
1334      languages than we have bits available to enumerate them.  */
1335   gcc_assert ((1U << cl_lang_count) <= CL_MIN_OPTION_CLASS);
1336 
1337   /* If we have not done so already, obtain
1338      the desired maximum width of the output.  */
1339   if (opts->x_help_columns == 0)
1340     {
1341       opts->x_help_columns = get_terminal_width ();
1342       if (opts->x_help_columns == INT_MAX)
1343 	/* Use a reasonable default.  */
1344 	opts->x_help_columns = 80;
1345     }
1346 
1347   /* Decide upon the title for the options that we are going to display.  */
1348   for (i = 0, flag = 1; flag <= CL_MAX_OPTION_CLASS; flag <<= 1, i ++)
1349     {
1350       switch (flag & include_flags)
1351 	{
1352 	case 0:
1353 	case CL_DRIVER:
1354 	  break;
1355 
1356 	case CL_TARGET:
1357 	  description = _("The following options are target specific");
1358 	  break;
1359 	case CL_WARNING:
1360 	  description = _("The following options control compiler warning messages");
1361 	  break;
1362 	case CL_OPTIMIZATION:
1363 	  description = _("The following options control optimizations");
1364 	  break;
1365 	case CL_COMMON:
1366 	  description = _("The following options are language-independent");
1367 	  break;
1368 	case CL_PARAMS:
1369 	  description = _("The --param option recognizes the following as parameters");
1370 	  break;
1371 	default:
1372 	  if (i >= cl_lang_count)
1373 	    break;
1374 	  if (exclude_flags & all_langs_mask)
1375 	    description = _("The following options are specific to just the language ");
1376 	  else
1377 	    description = _("The following options are supported by the language ");
1378 	  descrip_extra = lang_names [i];
1379 	  break;
1380 	}
1381     }
1382 
1383   if (description == NULL)
1384     {
1385       if (any_flags == 0)
1386 	{
1387 	  if (include_flags & CL_UNDOCUMENTED)
1388 	    description = _("The following options are not documented");
1389 	  else if (include_flags & CL_SEPARATE)
1390 	    description = _("The following options take separate arguments");
1391 	  else if (include_flags & CL_JOINED)
1392 	    description = _("The following options take joined arguments");
1393 	  else
1394 	    {
1395 	      internal_error ("unrecognized include_flags 0x%x passed to print_specific_help",
1396 			      include_flags);
1397 	      return;
1398 	    }
1399 	}
1400       else
1401 	{
1402 	  if (any_flags & all_langs_mask)
1403 	    description = _("The following options are language-related");
1404 	  else
1405 	    description = _("The following options are language-independent");
1406 	}
1407     }
1408 
1409   printf ("%s%s:\n", description, descrip_extra);
1410   print_filtered_help (include_flags, exclude_flags, any_flags,
1411 		       opts->x_help_columns, opts, lang_mask);
1412 }
1413 
1414 /* Enable FDO-related flags.  */
1415 
1416 static void
1417 enable_fdo_optimizations (struct gcc_options *opts,
1418 			  struct gcc_options *opts_set,
1419 			  int value)
1420 {
1421   if (!opts_set->x_flag_branch_probabilities)
1422     opts->x_flag_branch_probabilities = value;
1423   if (!opts_set->x_flag_profile_values)
1424     opts->x_flag_profile_values = value;
1425   if (!opts_set->x_flag_unroll_loops)
1426     opts->x_flag_unroll_loops = value;
1427   if (!opts_set->x_flag_peel_loops)
1428     opts->x_flag_peel_loops = value;
1429   if (!opts_set->x_flag_tracer)
1430     opts->x_flag_tracer = value;
1431   if (!opts_set->x_flag_value_profile_transformations)
1432     opts->x_flag_value_profile_transformations = value;
1433   if (!opts_set->x_flag_inline_functions)
1434     opts->x_flag_inline_functions = value;
1435   if (!opts_set->x_flag_ipa_cp)
1436     opts->x_flag_ipa_cp = value;
1437   if (!opts_set->x_flag_ipa_cp_clone
1438       && value && opts->x_flag_ipa_cp)
1439     opts->x_flag_ipa_cp_clone = value;
1440   if (!opts_set->x_flag_ipa_cp_alignment
1441       && value && opts->x_flag_ipa_cp)
1442     opts->x_flag_ipa_cp_alignment = value;
1443   if (!opts_set->x_flag_predictive_commoning)
1444     opts->x_flag_predictive_commoning = value;
1445   if (!opts_set->x_flag_unswitch_loops)
1446     opts->x_flag_unswitch_loops = value;
1447   if (!opts_set->x_flag_gcse_after_reload)
1448     opts->x_flag_gcse_after_reload = value;
1449   if (!opts_set->x_flag_tree_loop_vectorize
1450       && !opts_set->x_flag_tree_vectorize)
1451     opts->x_flag_tree_loop_vectorize = value;
1452   if (!opts_set->x_flag_tree_slp_vectorize
1453       && !opts_set->x_flag_tree_vectorize)
1454     opts->x_flag_tree_slp_vectorize = value;
1455   if (!opts_set->x_flag_vect_cost_model)
1456     opts->x_flag_vect_cost_model = VECT_COST_MODEL_DYNAMIC;
1457   if (!opts_set->x_flag_tree_loop_distribute_patterns)
1458     opts->x_flag_tree_loop_distribute_patterns = value;
1459 }
1460 
1461 /* -f{,no-}sanitize{,-recover}= suboptions.  */
1462 const struct sanitizer_opts_s sanitizer_opts[] =
1463 {
1464 #define SANITIZER_OPT(name, flags) { #name, flags, sizeof #name - 1 }
1465   SANITIZER_OPT (address, SANITIZE_ADDRESS | SANITIZE_USER_ADDRESS),
1466   SANITIZER_OPT (kernel-address, SANITIZE_ADDRESS | SANITIZE_KERNEL_ADDRESS),
1467   SANITIZER_OPT (thread, SANITIZE_THREAD),
1468   SANITIZER_OPT (leak, SANITIZE_LEAK),
1469   SANITIZER_OPT (shift, SANITIZE_SHIFT),
1470   SANITIZER_OPT (integer-divide-by-zero, SANITIZE_DIVIDE),
1471   SANITIZER_OPT (undefined, SANITIZE_UNDEFINED),
1472   SANITIZER_OPT (unreachable, SANITIZE_UNREACHABLE),
1473   SANITIZER_OPT (vla-bound, SANITIZE_VLA),
1474   SANITIZER_OPT (return, SANITIZE_RETURN),
1475   SANITIZER_OPT (null, SANITIZE_NULL),
1476   SANITIZER_OPT (signed-integer-overflow, SANITIZE_SI_OVERFLOW),
1477   SANITIZER_OPT (bool, SANITIZE_BOOL),
1478   SANITIZER_OPT (enum, SANITIZE_ENUM),
1479   SANITIZER_OPT (float-divide-by-zero, SANITIZE_FLOAT_DIVIDE),
1480   SANITIZER_OPT (float-cast-overflow, SANITIZE_FLOAT_CAST),
1481   SANITIZER_OPT (bounds, SANITIZE_BOUNDS),
1482   SANITIZER_OPT (bounds-strict, SANITIZE_BOUNDS | SANITIZE_BOUNDS_STRICT),
1483   SANITIZER_OPT (alignment, SANITIZE_ALIGNMENT),
1484   SANITIZER_OPT (nonnull-attribute, SANITIZE_NONNULL_ATTRIBUTE),
1485   SANITIZER_OPT (returns-nonnull-attribute, SANITIZE_RETURNS_NONNULL_ATTRIBUTE),
1486   SANITIZER_OPT (object-size, SANITIZE_OBJECT_SIZE),
1487   SANITIZER_OPT (vptr, SANITIZE_VPTR),
1488   SANITIZER_OPT (all, ~0),
1489 #undef SANITIZER_OPT
1490   { NULL, 0, 0 }
1491 };
1492 
1493 /* Parse comma separated sanitizer suboptions from P for option SCODE,
1494    adjust previous FLAGS and return new ones.  If COMPLAIN is false,
1495    don't issue diagnostics.  */
1496 
1497 unsigned int
1498 parse_sanitizer_options (const char *p, location_t loc, int scode,
1499 			 unsigned int flags, int value, bool complain)
1500 {
1501   enum opt_code code = (enum opt_code) scode;
1502   while (*p != 0)
1503     {
1504       size_t len, i;
1505       bool found = false;
1506       const char *comma = strchr (p, ',');
1507 
1508       if (comma == NULL)
1509 	len = strlen (p);
1510       else
1511 	len = comma - p;
1512       if (len == 0)
1513 	{
1514 	  p = comma + 1;
1515 	  continue;
1516 	}
1517 
1518       /* Check to see if the string matches an option class name.  */
1519       for (i = 0; sanitizer_opts[i].name != NULL; ++i)
1520 	if (len == sanitizer_opts[i].len
1521 	    && memcmp (p, sanitizer_opts[i].name, len) == 0)
1522 	  {
1523 	    /* Handle both -fsanitize and -fno-sanitize cases.  */
1524 	    if (value && sanitizer_opts[i].flag == ~0U)
1525 	      {
1526 		if (code == OPT_fsanitize_)
1527 		  {
1528 		    if (complain)
1529 		      error_at (loc, "-fsanitize=all option is not valid");
1530 		  }
1531 		else
1532 		  flags |= ~(SANITIZE_USER_ADDRESS | SANITIZE_THREAD
1533 			     | SANITIZE_LEAK);
1534 	      }
1535 	    else if (value)
1536 	      flags |= sanitizer_opts[i].flag;
1537 	    else
1538 	      flags &= ~sanitizer_opts[i].flag;
1539 	    found = true;
1540 	    break;
1541 	  }
1542 
1543       if (! found && complain)
1544 	error_at (loc, "unrecognized argument to -fsanitize%s= option: %q.*s",
1545 		  code == OPT_fsanitize_ ? "" : "-recover", (int) len, p);
1546 
1547       if (comma == NULL)
1548 	break;
1549       p = comma + 1;
1550     }
1551   return flags;
1552 }
1553 
1554 /* Handle target- and language-independent options.  Return zero to
1555    generate an "unknown option" message.  Only options that need
1556    extra handling need to be listed here; if you simply want
1557    DECODED->value assigned to a variable, it happens automatically.  */
1558 
1559 bool
1560 common_handle_option (struct gcc_options *opts,
1561 		      struct gcc_options *opts_set,
1562 		      const struct cl_decoded_option *decoded,
1563 		      unsigned int lang_mask, int kind ATTRIBUTE_UNUSED,
1564 		      location_t loc,
1565 		      const struct cl_option_handlers *handlers,
1566 		      diagnostic_context *dc,
1567 		      void (*target_option_override_hook) (void))
1568 {
1569   size_t scode = decoded->opt_index;
1570   const char *arg = decoded->arg;
1571   int value = decoded->value;
1572   enum opt_code code = (enum opt_code) scode;
1573 
1574   gcc_assert (decoded->canonical_option_num_elements <= 2);
1575 
1576   switch (code)
1577     {
1578     case OPT__param:
1579       handle_param (opts, opts_set, loc, arg);
1580       break;
1581 
1582     case OPT__help:
1583       {
1584 	unsigned int all_langs_mask = (1U << cl_lang_count) - 1;
1585 	unsigned int undoc_mask;
1586 	unsigned int i;
1587 
1588 	if (lang_mask == CL_DRIVER)
1589 	  break;
1590 
1591 	undoc_mask = ((opts->x_verbose_flag | opts->x_extra_warnings)
1592 		      ? 0
1593 		      : CL_UNDOCUMENTED);
1594 	target_option_override_hook ();
1595 	/* First display any single language specific options.  */
1596 	for (i = 0; i < cl_lang_count; i++)
1597 	  print_specific_help
1598 	    (1U << i, (all_langs_mask & (~ (1U << i))) | undoc_mask, 0, opts,
1599 	     lang_mask);
1600 	/* Next display any multi language specific options.  */
1601 	print_specific_help (0, undoc_mask, all_langs_mask, opts, lang_mask);
1602 	/* Then display any remaining, non-language options.  */
1603 	for (i = CL_MIN_OPTION_CLASS; i <= CL_MAX_OPTION_CLASS; i <<= 1)
1604 	  if (i != CL_DRIVER)
1605 	    print_specific_help (i, undoc_mask, 0, opts, lang_mask);
1606 	opts->x_exit_after_options = true;
1607 	break;
1608       }
1609 
1610     case OPT__target_help:
1611       if (lang_mask == CL_DRIVER)
1612 	break;
1613 
1614       target_option_override_hook ();
1615       print_specific_help (CL_TARGET, CL_UNDOCUMENTED, 0, opts, lang_mask);
1616       opts->x_exit_after_options = true;
1617       break;
1618 
1619     case OPT__help_:
1620       {
1621 	const char * a = arg;
1622 	unsigned int include_flags = 0;
1623 	/* Note - by default we include undocumented options when listing
1624 	   specific classes.  If you only want to see documented options
1625 	   then add ",^undocumented" to the --help= option.  E.g.:
1626 
1627 	   --help=target,^undocumented  */
1628 	unsigned int exclude_flags = 0;
1629 
1630 	if (lang_mask == CL_DRIVER)
1631 	  break;
1632 
1633 	/* Walk along the argument string, parsing each word in turn.
1634 	   The format is:
1635 	   arg = [^]{word}[,{arg}]
1636 	   word = {optimizers|target|warnings|undocumented|
1637 		   params|common|<language>}  */
1638 	while (* a != 0)
1639 	  {
1640 	    static const struct
1641 	    {
1642 	      const char * string;
1643 	      unsigned int flag;
1644 	    }
1645 	    specifics[] =
1646 	    {
1647 	      { "optimizers", CL_OPTIMIZATION },
1648 	      { "target", CL_TARGET },
1649 	      { "warnings", CL_WARNING },
1650 	      { "undocumented", CL_UNDOCUMENTED },
1651 	      { "params", CL_PARAMS },
1652 	      { "joined", CL_JOINED },
1653 	      { "separate", CL_SEPARATE },
1654 	      { "common", CL_COMMON },
1655 	      { NULL, 0 }
1656 	    };
1657 	    unsigned int * pflags;
1658 	    const char * comma;
1659 	    unsigned int lang_flag, specific_flag;
1660 	    unsigned int len;
1661 	    unsigned int i;
1662 
1663 	    if (* a == '^')
1664 	      {
1665 		++ a;
1666 		pflags = & exclude_flags;
1667 	      }
1668 	    else
1669 	      pflags = & include_flags;
1670 
1671 	    comma = strchr (a, ',');
1672 	    if (comma == NULL)
1673 	      len = strlen (a);
1674 	    else
1675 	      len = comma - a;
1676 	    if (len == 0)
1677 	      {
1678 		a = comma + 1;
1679 		continue;
1680 	      }
1681 
1682 	    /* Check to see if the string matches an option class name.  */
1683 	    for (i = 0, specific_flag = 0; specifics[i].string != NULL; i++)
1684 	      if (strncasecmp (a, specifics[i].string, len) == 0)
1685 		{
1686 		  specific_flag = specifics[i].flag;
1687 		  break;
1688 		}
1689 
1690 	    /* Check to see if the string matches a language name.
1691 	       Note - we rely upon the alpha-sorted nature of the entries in
1692 	       the lang_names array, specifically that shorter names appear
1693 	       before their longer variants.  (i.e. C before C++).  That way
1694 	       when we are attempting to match --help=c for example we will
1695 	       match with C first and not C++.  */
1696 	    for (i = 0, lang_flag = 0; i < cl_lang_count; i++)
1697 	      if (strncasecmp (a, lang_names[i], len) == 0)
1698 		{
1699 		  lang_flag = 1U << i;
1700 		  break;
1701 		}
1702 
1703 	    if (specific_flag != 0)
1704 	      {
1705 		if (lang_flag == 0)
1706 		  * pflags |= specific_flag;
1707 		else
1708 		  {
1709 		    /* The option's argument matches both the start of a
1710 		       language name and the start of an option class name.
1711 		       We have a special case for when the user has
1712 		       specified "--help=c", but otherwise we have to issue
1713 		       a warning.  */
1714 		    if (strncasecmp (a, "c", len) == 0)
1715 		      * pflags |= lang_flag;
1716 		    else
1717 		      warning_at (loc, 0,
1718 				  "--help argument %q.*s is ambiguous, "
1719 				  "please be more specific",
1720 				  len, a);
1721 		  }
1722 	      }
1723 	    else if (lang_flag != 0)
1724 	      * pflags |= lang_flag;
1725 	    else
1726 	      warning_at (loc, 0,
1727 			  "unrecognized argument to --help= option: %q.*s",
1728 			  len, a);
1729 
1730 	    if (comma == NULL)
1731 	      break;
1732 	    a = comma + 1;
1733 	  }
1734 
1735 	if (include_flags)
1736 	  {
1737 	    target_option_override_hook ();
1738 	    print_specific_help (include_flags, exclude_flags, 0, opts,
1739 				 lang_mask);
1740 	  }
1741 	opts->x_exit_after_options = true;
1742 	break;
1743       }
1744 
1745     case OPT__version:
1746       if (lang_mask == CL_DRIVER)
1747 	break;
1748 
1749       opts->x_exit_after_options = true;
1750       break;
1751 
1752     case OPT_fsanitize_:
1753       opts->x_flag_sanitize
1754 	= parse_sanitizer_options (arg, loc, code,
1755 				   opts->x_flag_sanitize, value, true);
1756 
1757       /* Kernel ASan implies normal ASan but does not yet support
1758 	 all features.  */
1759       if (opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS)
1760 	{
1761 	  maybe_set_param_value (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD,
1762 				 0, opts->x_param_values,
1763 				 opts_set->x_param_values);
1764 	  maybe_set_param_value (PARAM_ASAN_GLOBALS, 0, opts->x_param_values,
1765 				 opts_set->x_param_values);
1766 	  maybe_set_param_value (PARAM_ASAN_STACK, 0, opts->x_param_values,
1767 				 opts_set->x_param_values);
1768 	  maybe_set_param_value (PARAM_ASAN_USE_AFTER_RETURN, 0,
1769 				 opts->x_param_values,
1770 				 opts_set->x_param_values);
1771 	}
1772       break;
1773 
1774     case OPT_fsanitize_recover_:
1775       opts->x_flag_sanitize_recover
1776 	= parse_sanitizer_options (arg, loc, code,
1777 				   opts->x_flag_sanitize_recover, value, true);
1778       break;
1779 
1780     case OPT_fasan_shadow_offset_:
1781       /* Deferred.  */
1782       break;
1783 
1784     case OPT_fsanitize_recover:
1785       if (value)
1786 	opts->x_flag_sanitize_recover
1787 	  |= SANITIZE_UNDEFINED | SANITIZE_NONDEFAULT;
1788       else
1789 	opts->x_flag_sanitize_recover
1790 	  &= ~(SANITIZE_UNDEFINED | SANITIZE_NONDEFAULT);
1791       break;
1792 
1793     case OPT_O:
1794     case OPT_Os:
1795     case OPT_Ofast:
1796     case OPT_Og:
1797       /* Currently handled in a prescan.  */
1798       break;
1799 
1800     case OPT_Werror:
1801       dc->warning_as_error_requested = value;
1802       break;
1803 
1804     case OPT_Werror_:
1805       if (lang_mask == CL_DRIVER)
1806 	break;
1807 
1808       enable_warning_as_error (arg, value, lang_mask, handlers,
1809 			       opts, opts_set, loc, dc);
1810       break;
1811 
1812     case OPT_Wlarger_than_:
1813       opts->x_larger_than_size = value;
1814       opts->x_warn_larger_than = value != -1;
1815       break;
1816 
1817     case OPT_Wfatal_errors:
1818       dc->fatal_errors = value;
1819       break;
1820 
1821     case OPT_Wframe_larger_than_:
1822       opts->x_frame_larger_than_size = value;
1823       opts->x_warn_frame_larger_than = value != -1;
1824       break;
1825 
1826     case OPT_Wstack_usage_:
1827       opts->x_warn_stack_usage = value;
1828       opts->x_flag_stack_usage_info = value != -1;
1829       break;
1830 
1831     case OPT_Wstrict_aliasing:
1832       set_Wstrict_aliasing (opts, value);
1833       break;
1834 
1835     case OPT_Wstrict_overflow:
1836       opts->x_warn_strict_overflow = (value
1837 				      ? (int) WARN_STRICT_OVERFLOW_CONDITIONAL
1838 				      : 0);
1839       break;
1840 
1841     case OPT_Wsystem_headers:
1842       dc->dc_warn_system_headers = value;
1843       break;
1844 
1845     case OPT_aux_info:
1846       opts->x_flag_gen_aux_info = 1;
1847       break;
1848 
1849     case OPT_auxbase_strip:
1850       {
1851 	char *tmp = xstrdup (arg);
1852 	strip_off_ending (tmp, strlen (tmp));
1853 	if (tmp[0])
1854 	  opts->x_aux_base_name = tmp;
1855 	else
1856 	  free (tmp);
1857       }
1858       break;
1859 
1860     case OPT_d:
1861       decode_d_option (arg, opts, loc, dc);
1862       break;
1863 
1864     case OPT_fcall_used_:
1865     case OPT_fcall_saved_:
1866       /* Deferred.  */
1867       break;
1868 
1869     case OPT_fdbg_cnt_:
1870       /* Deferred.  */
1871       break;
1872 
1873     case OPT_fdbg_cnt_list:
1874       /* Deferred.  */
1875       opts->x_exit_after_options = true;
1876       break;
1877 
1878     case OPT_fdebug_prefix_map_:
1879       /* Deferred.  */
1880       break;
1881 
1882     case OPT_fdebug_regex_map_:
1883       /* Deferred.  */
1884       break;
1885 
1886     case OPT_fdiagnostics_show_location_:
1887       diagnostic_prefixing_rule (dc) = (diagnostic_prefixing_rule_t) value;
1888       break;
1889 
1890     case OPT_fdiagnostics_show_caret:
1891       dc->show_caret = value;
1892       break;
1893 
1894     case OPT_fdiagnostics_color_:
1895       diagnostic_color_init (dc, value);
1896       break;
1897 
1898     case OPT_fdiagnostics_show_option:
1899       dc->show_option_requested = value;
1900       break;
1901 
1902     case OPT_fdump_:
1903       /* Deferred.  */
1904       break;
1905 
1906     case OPT_ffast_math:
1907       set_fast_math_flags (opts, value);
1908       break;
1909 
1910     case OPT_funsafe_math_optimizations:
1911       set_unsafe_math_optimizations_flags (opts, value);
1912       break;
1913 
1914     case OPT_ffixed_:
1915       /* Deferred.  */
1916       break;
1917 
1918     case OPT_finline_limit_:
1919       set_param_value ("max-inline-insns-single", value / 2,
1920 		       opts->x_param_values, opts_set->x_param_values);
1921       set_param_value ("max-inline-insns-auto", value / 2,
1922 		       opts->x_param_values, opts_set->x_param_values);
1923       break;
1924 
1925     case OPT_finstrument_functions_exclude_function_list_:
1926       add_comma_separated_to_vector
1927 	(&opts->x_flag_instrument_functions_exclude_functions, arg);
1928       break;
1929 
1930     case OPT_finstrument_functions_exclude_file_list_:
1931       add_comma_separated_to_vector
1932 	(&opts->x_flag_instrument_functions_exclude_files, arg);
1933       break;
1934 
1935     case OPT_fmessage_length_:
1936       pp_set_line_maximum_length (dc->printer, value);
1937       diagnostic_set_caret_max_width (dc, value);
1938       break;
1939 
1940     case OPT_fopt_info:
1941     case OPT_fopt_info_:
1942       /* Deferred.  */
1943       break;
1944 
1945     case OPT_foffload_:
1946       {
1947 	const char *p = arg;
1948 	opts->x_flag_disable_hsa = true;
1949 	while (*p != 0)
1950 	  {
1951 	    const char *comma = strchr (p, ',');
1952 
1953 	    if ((strncmp (p, "disable", 7) == 0)
1954 		&& (p[7] == ',' || p[7] == '\0'))
1955 	      {
1956 		opts->x_flag_disable_hsa = true;
1957 		break;
1958 	      }
1959 
1960 	    if ((strncmp (p, "hsa", 3) == 0)
1961 		&& (p[3] == ',' || p[3] == '\0'))
1962 	      {
1963 #ifdef ENABLE_HSA
1964 		opts->x_flag_disable_hsa = false;
1965 #else
1966 		sorry ("HSA has not been enabled during configuration");
1967 #endif
1968 	      }
1969 	    if (!comma)
1970 	      break;
1971 	    p = comma + 1;
1972 	  }
1973 	break;
1974       }
1975 
1976 #ifndef ACCEL_COMPILER
1977     case OPT_foffload_abi_:
1978       error_at (loc, "-foffload-abi option can be specified only for "
1979 		"offload compiler");
1980       break;
1981 #endif
1982 
1983     case OPT_fpack_struct_:
1984       if (value <= 0 || (value & (value - 1)) || value > 16)
1985 	error_at (loc,
1986 		  "structure alignment must be a small power of two, not %d",
1987 		  value);
1988       else
1989 	opts->x_initial_max_fld_align = value;
1990       break;
1991 
1992     case OPT_fplugin_:
1993     case OPT_fplugin_arg_:
1994       /* Deferred.  */
1995       break;
1996 
1997     case OPT_fprofile_use_:
1998       opts->x_profile_data_prefix = xstrdup (arg);
1999       opts->x_flag_profile_use = true;
2000       value = true;
2001       /* No break here - do -fprofile-use processing. */
2002     case OPT_fprofile_use:
2003       enable_fdo_optimizations (opts, opts_set, value);
2004       if (!opts_set->x_flag_profile_reorder_functions)
2005 	  opts->x_flag_profile_reorder_functions = value;
2006 	/* Indirect call profiling should do all useful transformations
2007 	   speculative devirtualization does.  */
2008       if (!opts_set->x_flag_devirtualize_speculatively
2009 	  && opts->x_flag_value_profile_transformations)
2010 	opts->x_flag_devirtualize_speculatively = false;
2011       break;
2012 
2013     case OPT_fauto_profile_:
2014       opts->x_auto_profile_file = xstrdup (arg);
2015       opts->x_flag_auto_profile = true;
2016       value = true;
2017       /* No break here - do -fauto-profile processing. */
2018     case OPT_fauto_profile:
2019       enable_fdo_optimizations (opts, opts_set, value);
2020       if (!opts_set->x_flag_profile_correction)
2021 	opts->x_flag_profile_correction = value;
2022       maybe_set_param_value (
2023 	PARAM_EARLY_INLINER_MAX_ITERATIONS, 10,
2024 	opts->x_param_values, opts_set->x_param_values);
2025       break;
2026 
2027     case OPT_fprofile_generate_:
2028       opts->x_profile_data_prefix = xstrdup (arg);
2029       value = true;
2030       /* No break here - do -fprofile-generate processing. */
2031     case OPT_fprofile_generate:
2032       if (!opts_set->x_profile_arc_flag)
2033 	opts->x_profile_arc_flag = value;
2034       if (!opts_set->x_flag_profile_values)
2035 	opts->x_flag_profile_values = value;
2036       if (!opts_set->x_flag_inline_functions)
2037 	opts->x_flag_inline_functions = value;
2038       /* FIXME: Instrumentation we insert makes ipa-reference bitmaps
2039 	 quadratic.  Disable the pass until better memory representation
2040 	 is done.  */
2041       if (!opts_set->x_flag_ipa_reference)
2042         opts->x_flag_ipa_reference = false;
2043       break;
2044 
2045     case OPT_ftree_vectorize:
2046       if (!opts_set->x_flag_tree_loop_vectorize)
2047         opts->x_flag_tree_loop_vectorize = value;
2048       if (!opts_set->x_flag_tree_slp_vectorize)
2049         opts->x_flag_tree_slp_vectorize = value;
2050       break;
2051     case OPT_fshow_column:
2052       dc->show_column = value;
2053       break;
2054 
2055     case OPT_frandom_seed:
2056       /* The real switch is -fno-random-seed.  */
2057       if (value)
2058 	return false;
2059       /* Deferred.  */
2060       break;
2061 
2062     case OPT_frandom_seed_:
2063       /* Deferred.  */
2064       break;
2065 
2066     case OPT_fsched_verbose_:
2067 #ifdef INSN_SCHEDULING
2068       /* Handled with Var in common.opt.  */
2069       break;
2070 #else
2071       return false;
2072 #endif
2073 
2074     case OPT_fsched_stalled_insns_:
2075       opts->x_flag_sched_stalled_insns = value;
2076       if (opts->x_flag_sched_stalled_insns == 0)
2077 	opts->x_flag_sched_stalled_insns = -1;
2078       break;
2079 
2080     case OPT_fsched_stalled_insns_dep_:
2081       opts->x_flag_sched_stalled_insns_dep = value;
2082       break;
2083 
2084     case OPT_fstack_check_:
2085       if (!strcmp (arg, "no"))
2086 	opts->x_flag_stack_check = NO_STACK_CHECK;
2087       else if (!strcmp (arg, "generic"))
2088 	/* This is the old stack checking method.  */
2089 	opts->x_flag_stack_check = STACK_CHECK_BUILTIN
2090 			   ? FULL_BUILTIN_STACK_CHECK
2091 			   : GENERIC_STACK_CHECK;
2092       else if (!strcmp (arg, "specific"))
2093 	/* This is the new stack checking method.  */
2094 	opts->x_flag_stack_check = STACK_CHECK_BUILTIN
2095 			   ? FULL_BUILTIN_STACK_CHECK
2096 			   : STACK_CHECK_STATIC_BUILTIN
2097 			     ? STATIC_BUILTIN_STACK_CHECK
2098 			     : GENERIC_STACK_CHECK;
2099       else
2100 	warning_at (loc, 0, "unknown stack check parameter %qs", arg);
2101       break;
2102 
2103     case OPT_fstack_limit:
2104       /* The real switch is -fno-stack-limit.  */
2105       if (value)
2106 	return false;
2107       /* Deferred.  */
2108       break;
2109 
2110     case OPT_fstack_limit_register_:
2111     case OPT_fstack_limit_symbol_:
2112       /* Deferred.  */
2113       break;
2114 
2115     case OPT_fstack_usage:
2116       opts->x_flag_stack_usage = value;
2117       opts->x_flag_stack_usage_info = value != 0;
2118       break;
2119 
2120     case OPT_g:
2121       set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, arg, opts, opts_set,
2122                        loc);
2123       break;
2124 
2125     case OPT_gcoff:
2126       set_debug_level (SDB_DEBUG, false, arg, opts, opts_set, loc);
2127       break;
2128 
2129     case OPT_gdwarf:
2130       if (arg && strlen (arg) != 0)
2131         {
2132           error_at (loc, "%<-gdwarf%s%> is ambiguous; "
2133                     "use %<-gdwarf-%s%> for DWARF version "
2134                     "or %<-gdwarf -g%s%> for debug level", arg, arg, arg);
2135           break;
2136         }
2137       else
2138         value = opts->x_dwarf_version;
2139 
2140       /* FALLTHRU */
2141     case OPT_gdwarf_:
2142       if (value < 2 || value > 5)
2143 	error_at (loc, "dwarf version %d is not supported", value);
2144       else
2145 	opts->x_dwarf_version = value;
2146       set_debug_level (DWARF2_DEBUG, false, "", opts, opts_set, loc);
2147       break;
2148 
2149     case OPT_gsplit_dwarf:
2150       set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, "", opts, opts_set,
2151 		       loc);
2152       break;
2153 
2154     case OPT_ggdb:
2155       set_debug_level (NO_DEBUG, 2, arg, opts, opts_set, loc);
2156       break;
2157 
2158     case OPT_gstabs:
2159     case OPT_gstabs_:
2160       set_debug_level (DBX_DEBUG, code == OPT_gstabs_, arg, opts, opts_set,
2161 		       loc);
2162       break;
2163 
2164     case OPT_gvms:
2165       set_debug_level (VMS_DEBUG, false, arg, opts, opts_set, loc);
2166       break;
2167 
2168     case OPT_gxcoff:
2169     case OPT_gxcoff_:
2170       set_debug_level (XCOFF_DEBUG, code == OPT_gxcoff_, arg, opts, opts_set,
2171 		       loc);
2172       break;
2173 
2174     case OPT_gz:
2175     case OPT_gz_:
2176       /* Handled completely via specs.  */
2177       break;
2178 
2179     case OPT_pedantic_errors:
2180       dc->pedantic_errors = 1;
2181       control_warning_option (OPT_Wpedantic, DK_ERROR, NULL, value,
2182 			      loc, lang_mask,
2183 			      handlers, opts, opts_set,
2184                               dc);
2185       break;
2186 
2187     case OPT_flto:
2188       opts->x_flag_lto = value ? "" : NULL;
2189       break;
2190 
2191     case OPT_w:
2192       dc->dc_inhibit_warnings = true;
2193       break;
2194 
2195     case OPT_fmax_errors_:
2196       dc->max_errors = value;
2197       break;
2198 
2199     case OPT_fuse_ld_bfd:
2200     case OPT_fuse_ld_gold:
2201     case OPT_fuse_linker_plugin:
2202       /* No-op. Used by the driver and passed to us because it starts with f.*/
2203       break;
2204 
2205     case OPT_fwrapv:
2206       if (value)
2207 	opts->x_flag_trapv = 0;
2208       break;
2209 
2210     case OPT_ftrapv:
2211       if (value)
2212 	opts->x_flag_wrapv = 0;
2213       break;
2214 
2215     case OPT_fipa_icf:
2216       opts->x_flag_ipa_icf_functions = value;
2217       opts->x_flag_ipa_icf_variables = value;
2218       break;
2219 
2220     default:
2221       /* If the flag was handled in a standard way, assume the lack of
2222 	 processing here is intentional.  */
2223       gcc_assert (option_flag_var (scode, opts));
2224       break;
2225     }
2226 
2227   common_handle_option_auto (opts, opts_set, decoded, lang_mask, kind,
2228                              loc, handlers, dc);
2229   return true;
2230 }
2231 
2232 /* Handle --param NAME=VALUE.  */
2233 static void
2234 handle_param (struct gcc_options *opts, struct gcc_options *opts_set,
2235 	      location_t loc, const char *carg)
2236 {
2237   char *equal, *arg;
2238   int value;
2239 
2240   arg = xstrdup (carg);
2241   equal = strchr (arg, '=');
2242   if (!equal)
2243     error_at (loc, "%s: --param arguments should be of the form NAME=VALUE",
2244 	      arg);
2245   else
2246     {
2247       *equal = '\0';
2248 
2249       enum compiler_param index;
2250       if (!find_param (arg, &index))
2251 	error_at (loc, "invalid --param name %qs", arg);
2252       else
2253 	{
2254 	  if (!param_string_value_p (index, equal + 1, &value))
2255 	    value = integral_argument (equal + 1);
2256 
2257 	  if (value == -1)
2258 	    error_at (loc, "invalid --param value %qs", equal + 1);
2259 	  else
2260 	    set_param_value (arg, value,
2261 			     opts->x_param_values, opts_set->x_param_values);
2262 	}
2263     }
2264 
2265   free (arg);
2266 }
2267 
2268 /* Used to set the level of strict aliasing warnings in OPTS,
2269    when no level is specified (i.e., when -Wstrict-aliasing, and not
2270    -Wstrict-aliasing=level was given).
2271    ONOFF is assumed to take value 1 when -Wstrict-aliasing is specified,
2272    and 0 otherwise.  After calling this function, wstrict_aliasing will be
2273    set to the default value of -Wstrict_aliasing=level, currently 3.  */
2274 static void
2275 set_Wstrict_aliasing (struct gcc_options *opts, int onoff)
2276 {
2277   gcc_assert (onoff == 0 || onoff == 1);
2278   if (onoff != 0)
2279     opts->x_warn_strict_aliasing = 3;
2280   else
2281     opts->x_warn_strict_aliasing = 0;
2282 }
2283 
2284 /* The following routines are useful in setting all the flags that
2285    -ffast-math and -fno-fast-math imply.  */
2286 static void
2287 set_fast_math_flags (struct gcc_options *opts, int set)
2288 {
2289   if (!opts->frontend_set_flag_unsafe_math_optimizations)
2290     {
2291       opts->x_flag_unsafe_math_optimizations = set;
2292       set_unsafe_math_optimizations_flags (opts, set);
2293     }
2294   if (!opts->frontend_set_flag_finite_math_only)
2295     opts->x_flag_finite_math_only = set;
2296   if (!opts->frontend_set_flag_errno_math)
2297     opts->x_flag_errno_math = !set;
2298   if (set)
2299     {
2300       if (!opts->frontend_set_flag_signaling_nans)
2301 	opts->x_flag_signaling_nans = 0;
2302       if (!opts->frontend_set_flag_rounding_math)
2303 	opts->x_flag_rounding_math = 0;
2304       if (!opts->frontend_set_flag_cx_limited_range)
2305 	opts->x_flag_cx_limited_range = 1;
2306     }
2307 }
2308 
2309 /* When -funsafe-math-optimizations is set the following
2310    flags are set as well.  */
2311 static void
2312 set_unsafe_math_optimizations_flags (struct gcc_options *opts, int set)
2313 {
2314   if (!opts->frontend_set_flag_trapping_math)
2315     opts->x_flag_trapping_math = !set;
2316   if (!opts->frontend_set_flag_signed_zeros)
2317     opts->x_flag_signed_zeros = !set;
2318   if (!opts->frontend_set_flag_associative_math)
2319     opts->x_flag_associative_math = set;
2320   if (!opts->frontend_set_flag_reciprocal_math)
2321     opts->x_flag_reciprocal_math = set;
2322 }
2323 
2324 /* Return true iff flags in OPTS are set as if -ffast-math.  */
2325 bool
2326 fast_math_flags_set_p (const struct gcc_options *opts)
2327 {
2328   return (!opts->x_flag_trapping_math
2329 	  && opts->x_flag_unsafe_math_optimizations
2330 	  && opts->x_flag_finite_math_only
2331 	  && !opts->x_flag_signed_zeros
2332 	  && !opts->x_flag_errno_math);
2333 }
2334 
2335 /* Return true iff flags are set as if -ffast-math but using the flags stored
2336    in the struct cl_optimization structure.  */
2337 bool
2338 fast_math_flags_struct_set_p (struct cl_optimization *opt)
2339 {
2340   return (!opt->x_flag_trapping_math
2341 	  && opt->x_flag_unsafe_math_optimizations
2342 	  && opt->x_flag_finite_math_only
2343 	  && !opt->x_flag_signed_zeros
2344 	  && !opt->x_flag_errno_math);
2345 }
2346 
2347 /* Handle a debug output -g switch for options OPTS
2348    (OPTS_SET->x_write_symbols storing whether a debug type was passed
2349    explicitly), location LOC.  EXTENDED is true or false to support
2350    extended output (2 is special and means "-ggdb" was given).  */
2351 static void
2352 set_debug_level (enum debug_info_type type, int extended, const char *arg,
2353 		 struct gcc_options *opts, struct gcc_options *opts_set,
2354 		 location_t loc)
2355 {
2356   opts->x_use_gnu_debug_info_extensions = extended;
2357 
2358   if (type == NO_DEBUG)
2359     {
2360       if (opts->x_write_symbols == NO_DEBUG)
2361 	{
2362 	  opts->x_write_symbols = PREFERRED_DEBUGGING_TYPE;
2363 
2364 	  if (extended == 2)
2365 	    {
2366 #if defined DWARF2_DEBUGGING_INFO || defined DWARF2_LINENO_DEBUGGING_INFO
2367 	      opts->x_write_symbols = DWARF2_DEBUG;
2368 #elif defined DBX_DEBUGGING_INFO
2369 	      opts->x_write_symbols = DBX_DEBUG;
2370 #endif
2371 	    }
2372 
2373 	  if (opts->x_write_symbols == NO_DEBUG)
2374 	    warning_at (loc, 0, "target system does not support debug output");
2375 	}
2376     }
2377   else
2378     {
2379       /* Does it conflict with an already selected type?  */
2380       if (opts_set->x_write_symbols != NO_DEBUG
2381 	  && opts->x_write_symbols != NO_DEBUG
2382 	  && type != opts->x_write_symbols)
2383 	error_at (loc, "debug format %qs conflicts with prior selection",
2384 		  debug_type_names[type]);
2385       opts->x_write_symbols = type;
2386       opts_set->x_write_symbols = type;
2387     }
2388 
2389   /* A debug flag without a level defaults to level 2.
2390      If off or at level 1, set it to level 2, but if already
2391      at level 3, don't lower it.  */
2392   if (*arg == '\0')
2393     {
2394       if (opts->x_debug_info_level < DINFO_LEVEL_NORMAL)
2395 	opts->x_debug_info_level = DINFO_LEVEL_NORMAL;
2396     }
2397   else
2398     {
2399       int argval = integral_argument (arg);
2400       if (argval == -1)
2401 	error_at (loc, "unrecognised debug output level %qs", arg);
2402       else if (argval > 3)
2403 	error_at (loc, "debug output level %qs is too high", arg);
2404       else
2405 	opts->x_debug_info_level = (enum debug_info_levels) argval;
2406     }
2407 }
2408 
2409 /* Arrange to dump core on error for diagnostic context DC.  (The
2410    regular error message is still printed first, except in the case of
2411    abort ().)  */
2412 
2413 static void
2414 setup_core_dumping (diagnostic_context *dc)
2415 {
2416 #ifdef SIGABRT
2417   signal (SIGABRT, SIG_DFL);
2418 #endif
2419 #if defined(HAVE_SETRLIMIT)
2420   {
2421     struct rlimit rlim;
2422     if (getrlimit (RLIMIT_CORE, &rlim) != 0)
2423       fatal_error (input_location, "getting core file size maximum limit: %m");
2424     rlim.rlim_cur = rlim.rlim_max;
2425     if (setrlimit (RLIMIT_CORE, &rlim) != 0)
2426       fatal_error (input_location,
2427 		   "setting core file size limit to maximum: %m");
2428   }
2429 #endif
2430   diagnostic_abort_on_error (dc);
2431 }
2432 
2433 /* Parse a -d<ARG> command line switch for OPTS, location LOC,
2434    diagnostic context DC.  */
2435 
2436 static void
2437 decode_d_option (const char *arg, struct gcc_options *opts,
2438 		 location_t loc, diagnostic_context *dc)
2439 {
2440   int c;
2441 
2442   while (*arg)
2443     switch (c = *arg++)
2444       {
2445       case 'A':
2446 	opts->x_flag_debug_asm = 1;
2447 	break;
2448       case 'p':
2449 	opts->x_flag_print_asm_name = 1;
2450 	break;
2451       case 'P':
2452 	opts->x_flag_dump_rtl_in_asm = 1;
2453 	opts->x_flag_print_asm_name = 1;
2454 	break;
2455       case 'x':
2456 	opts->x_rtl_dump_and_exit = 1;
2457 	break;
2458       case 'D':	/* These are handled by the preprocessor.  */
2459       case 'I':
2460       case 'M':
2461       case 'N':
2462       case 'U':
2463 	break;
2464       case 'H':
2465 	setup_core_dumping (dc);
2466 	break;
2467       case 'a':
2468 	opts->x_flag_dump_all_passed = true;
2469 	break;
2470 
2471       default:
2472 	  warning_at (loc, 0, "unrecognized gcc debugging option: %c", c);
2473 	break;
2474       }
2475 }
2476 
2477 /* Enable (or disable if VALUE is 0) a warning option ARG (language
2478    mask LANG_MASK, option handlers HANDLERS) as an error for option
2479    structures OPTS and OPTS_SET, diagnostic context DC (possibly
2480    NULL), location LOC.  This is used by -Werror=.  */
2481 
2482 static void
2483 enable_warning_as_error (const char *arg, int value, unsigned int lang_mask,
2484 			 const struct cl_option_handlers *handlers,
2485 			 struct gcc_options *opts,
2486 			 struct gcc_options *opts_set,
2487 			 location_t loc, diagnostic_context *dc)
2488 {
2489   char *new_option;
2490   int option_index;
2491 
2492   new_option = XNEWVEC (char, strlen (arg) + 2);
2493   new_option[0] = 'W';
2494   strcpy (new_option + 1, arg);
2495   option_index = find_opt (new_option, lang_mask);
2496   if (option_index == OPT_SPECIAL_unknown)
2497     error_at (loc, "-Werror=%s: no option -%s", arg, new_option);
2498   else if (!(cl_options[option_index].flags & CL_WARNING))
2499     error_at (loc, "-Werror=%s: -%s is not an option that controls warnings",
2500 	      arg, new_option);
2501   else
2502     {
2503       const diagnostic_t kind = value ? DK_ERROR : DK_WARNING;
2504       const char *arg = NULL;
2505 
2506       if (cl_options[option_index].flags & CL_JOINED)
2507 	arg = new_option + cl_options[option_index].opt_len;
2508       control_warning_option (option_index, (int) kind, arg, value,
2509 			      loc, lang_mask,
2510 			      handlers, opts, opts_set, dc);
2511     }
2512   free (new_option);
2513 }
2514 
2515 /* Return malloced memory for the name of the option OPTION_INDEX
2516    which enabled a diagnostic (context CONTEXT), originally of type
2517    ORIG_DIAG_KIND but possibly converted to DIAG_KIND by options such
2518    as -Werror.  */
2519 
2520 char *
2521 option_name (diagnostic_context *context, int option_index,
2522 	     diagnostic_t orig_diag_kind, diagnostic_t diag_kind)
2523 {
2524   if (option_index)
2525     {
2526       /* A warning classified as an error.  */
2527       if ((orig_diag_kind == DK_WARNING || orig_diag_kind == DK_PEDWARN)
2528 	  && diag_kind == DK_ERROR)
2529 	return concat (cl_options[OPT_Werror_].opt_text,
2530 		       /* Skip over "-W".  */
2531 		       cl_options[option_index].opt_text + 2,
2532 		       NULL);
2533       /* A warning with option.  */
2534       else
2535 	return xstrdup (cl_options[option_index].opt_text);
2536     }
2537   /* A warning without option classified as an error.  */
2538   else if ((orig_diag_kind == DK_WARNING || orig_diag_kind == DK_PEDWARN
2539 	    || diag_kind == DK_WARNING)
2540 	   && context->warning_as_error_requested)
2541     return xstrdup (cl_options[OPT_Werror].opt_text);
2542   else
2543     return NULL;
2544 }
2545