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