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
set_struct_debug_option(struct gcc_options * opts,location_t loc,const char * spec)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
strip_off_ending(char * name,int len)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
base_of_path(const char * path,const char ** base_out)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
target_handle_option(struct gcc_options * opts,struct gcc_options * opts_set,const struct cl_decoded_option * decoded,unsigned int lang_mask ATTRIBUTE_UNUSED,int kind,location_t loc,const struct cl_option_handlers * handlers ATTRIBUTE_UNUSED,diagnostic_context * dc,void (*)(void))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
add_comma_separated_to_vector(void ** pvec,const char * arg)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
init_opts_obstack(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
init_options_struct(struct gcc_options * opts,struct gcc_options * opts_set)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
finalize_options_struct(struct gcc_options * opts)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
maybe_default_option(struct gcc_options * opts,struct gcc_options * opts_set,const struct default_options * default_opt,int level,bool size,bool fast,bool debug,unsigned int lang_mask,const struct cl_option_handlers * handlers,location_t loc,diagnostic_context * dc)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
maybe_default_options(struct gcc_options * opts,struct gcc_options * opts_set,const struct default_options * default_opts,int level,bool size,bool fast,bool debug,unsigned int lang_mask,const struct cl_option_handlers * handlers,location_t loc,diagnostic_context * dc)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
default_options_optimization(struct gcc_options * opts,struct gcc_options * opts_set,struct cl_decoded_option * decoded_options,unsigned int decoded_options_count,location_t loc,unsigned int lang_mask,const struct cl_option_handlers * handlers,diagnostic_context * dc)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)
661      : default_param_value (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP) / 10,
662      opts->x_param_values, opts_set->x_param_values);
663 
664   /* For -O1 reduce the maximum number of active local stores for RTL DSE
665      since this can consume huge amounts of memory (PR89115).  */
666   maybe_set_param_value
667     (PARAM_MAX_DSE_ACTIVE_LOCAL_STORES,
668      opt2 ? default_param_value (PARAM_MAX_DSE_ACTIVE_LOCAL_STORES)
669      : default_param_value (PARAM_MAX_DSE_ACTIVE_LOCAL_STORES) / 10,
670      opts->x_param_values, opts_set->x_param_values);
671 
672   /* At -Ofast, allow store motion to introduce potential race conditions.  */
673   maybe_set_param_value
674     (PARAM_ALLOW_STORE_DATA_RACES,
675      opts->x_optimize_fast ? 1
676      : default_param_value (PARAM_ALLOW_STORE_DATA_RACES),
677      opts->x_param_values, opts_set->x_param_values);
678 
679   if (opts->x_optimize_size)
680     /* We want to crossjump as much as possible.  */
681     maybe_set_param_value (PARAM_MIN_CROSSJUMP_INSNS, 1,
682 			   opts->x_param_values, opts_set->x_param_values);
683   else
684     maybe_set_param_value (PARAM_MIN_CROSSJUMP_INSNS,
685 			   default_param_value (PARAM_MIN_CROSSJUMP_INSNS),
686 			   opts->x_param_values, opts_set->x_param_values);
687 
688   /* Restrict the amount of work combine does at -Og while retaining
689      most of its useful transforms.  */
690   if (opts->x_optimize_debug)
691     maybe_set_param_value (PARAM_MAX_COMBINE_INSNS, 2,
692 			   opts->x_param_values, opts_set->x_param_values);
693 
694   /* Allow default optimizations to be specified on a per-machine basis.  */
695   maybe_default_options (opts, opts_set,
696 			 targetm_common.option_optimization_table,
697 			 opts->x_optimize, opts->x_optimize_size,
698 			 opts->x_optimize_fast, opts->x_optimize_debug,
699 			 lang_mask, handlers, loc, dc);
700 }
701 
702 /* After all options at LOC have been read into OPTS and OPTS_SET,
703    finalize settings of those options and diagnose incompatible
704    combinations.  */
705 void
finish_options(struct gcc_options * opts,struct gcc_options * opts_set,location_t loc)706 finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
707 		location_t loc)
708 {
709   enum unwind_info_type ui_except;
710 
711   if (opts->x_dump_base_name
712       && ! opts->x_dump_base_name_prefixed)
713     {
714       const char *sep = opts->x_dump_base_name;
715 
716       for (; *sep; sep++)
717 	if (IS_DIR_SEPARATOR (*sep))
718 	  break;
719 
720       if (*sep)
721 	/* If dump_base_path contains subdirectories, don't prepend
722 	   anything.  */;
723       else if (opts->x_dump_dir_name)
724 	/* We have a DUMP_DIR_NAME, prepend that.  */
725 	opts->x_dump_base_name = opts_concat (opts->x_dump_dir_name,
726 					      opts->x_dump_base_name, NULL);
727       else if (opts->x_aux_base_name
728 	       && strcmp (opts->x_aux_base_name, HOST_BIT_BUCKET) != 0)
729 	/* AUX_BASE_NAME is set and is not the bit bucket.  If it
730 	   contains a directory component, prepend those directories.
731 	   Typically this places things in the same directory as the
732 	   object file.  */
733 	{
734 	  const char *aux_base;
735 
736 	  base_of_path (opts->x_aux_base_name, &aux_base);
737 	  if (opts->x_aux_base_name != aux_base)
738 	    {
739 	      int dir_len = aux_base - opts->x_aux_base_name;
740 	      char *new_dump_base_name
741 		= XOBNEWVEC (&opts_obstack, char,
742 			     strlen (opts->x_dump_base_name) + dir_len + 1);
743 
744 	      /* Copy directory component from OPTS->X_AUX_BASE_NAME.  */
745 	      memcpy (new_dump_base_name, opts->x_aux_base_name, dir_len);
746 	      /* Append existing OPTS->X_DUMP_BASE_NAME.  */
747 	      strcpy (new_dump_base_name + dir_len, opts->x_dump_base_name);
748 	      opts->x_dump_base_name = new_dump_base_name;
749 	    }
750 	}
751 
752       /* It is definitely prefixed now.  */
753       opts->x_dump_base_name_prefixed = true;
754     }
755 
756   /* Handle related options for unit-at-a-time, toplevel-reorder, and
757      section-anchors.  */
758   if (!opts->x_flag_unit_at_a_time)
759     {
760       if (opts->x_flag_section_anchors && opts_set->x_flag_section_anchors)
761 	error_at (loc, "section anchors must be disabled when unit-at-a-time "
762 		  "is disabled");
763       opts->x_flag_section_anchors = 0;
764       if (opts->x_flag_toplevel_reorder == 1)
765 	error_at (loc, "toplevel reorder must be disabled when unit-at-a-time "
766 		  "is disabled");
767       opts->x_flag_toplevel_reorder = 0;
768     }
769 
770   /* -fself-test depends on the state of the compiler prior to
771      compiling anything.  Ideally it should be run on an empty source
772      file.  However, in case we get run with actual source, assume
773      -fsyntax-only which will inhibit any compiler initialization
774      which may confuse the self tests.  */
775   if (opts->x_flag_self_test)
776     opts->x_flag_syntax_only = 1;
777 
778   if (opts->x_flag_tm && opts->x_flag_non_call_exceptions)
779     sorry ("transactional memory is not supported with non-call exceptions");
780 
781   /* Unless the user has asked for section anchors, we disable toplevel
782      reordering at -O0 to disable transformations that might be surprising
783      to end users and to get -fno-toplevel-reorder tested.  */
784   if (!opts->x_optimize
785       && opts->x_flag_toplevel_reorder == 2
786       && !(opts->x_flag_section_anchors && opts_set->x_flag_section_anchors))
787     {
788       opts->x_flag_toplevel_reorder = 0;
789       opts->x_flag_section_anchors = 0;
790     }
791   if (!opts->x_flag_toplevel_reorder)
792     {
793       if (opts->x_flag_section_anchors && opts_set->x_flag_section_anchors)
794 	error_at (loc, "section anchors must be disabled when toplevel reorder"
795 		  " is disabled");
796       opts->x_flag_section_anchors = 0;
797     }
798 
799   if (!opts->x_flag_opts_finished)
800     {
801       /* We initialize opts->x_flag_pie to -1 so that targets can set a
802 	 default value.  */
803       if (opts->x_flag_pie == -1)
804 	{
805 	  /* We initialize opts->x_flag_pic to -1 so that we can tell if
806 	     -fpic, -fPIC, -fno-pic or -fno-PIC is used.  */
807 	  if (opts->x_flag_pic == -1)
808 	    opts->x_flag_pie = DEFAULT_FLAG_PIE;
809 	  else
810 	    opts->x_flag_pie = 0;
811 	}
812       /* If -fPIE or -fpie is used, turn on PIC.  */
813       if (opts->x_flag_pie)
814 	opts->x_flag_pic = opts->x_flag_pie;
815       else if (opts->x_flag_pic == -1)
816 	opts->x_flag_pic = 0;
817       if (opts->x_flag_pic && !opts->x_flag_pie)
818 	opts->x_flag_shlib = 1;
819       opts->x_flag_opts_finished = true;
820     }
821 
822   /* We initialize opts->x_flag_stack_protect to -1 so that targets
823      can set a default value.  */
824   if (opts->x_flag_stack_protect == -1)
825     opts->x_flag_stack_protect = DEFAULT_FLAG_SSP;
826 
827   if (opts->x_optimize == 0)
828     {
829       /* Inlining does not work if not optimizing,
830 	 so force it not to be done.  */
831       opts->x_warn_inline = 0;
832       opts->x_flag_no_inline = 1;
833     }
834 
835   /* The optimization to partition hot and cold basic blocks into separate
836      sections of the .o and executable files does not work (currently)
837      with exception handling.  This is because there is no support for
838      generating unwind info.  If opts->x_flag_exceptions is turned on
839      we need to turn off the partitioning optimization.  */
840 
841   ui_except = targetm_common.except_unwind_info (opts);
842 
843   if (opts->x_flag_exceptions
844       && opts->x_flag_reorder_blocks_and_partition
845       && (ui_except == UI_SJLJ || ui_except >= UI_TARGET))
846     {
847       if (opts_set->x_flag_reorder_blocks_and_partition)
848         inform (loc,
849 		"%<-freorder-blocks-and-partition%> does not work "
850 		"with exceptions on this architecture");
851       opts->x_flag_reorder_blocks_and_partition = 0;
852       opts->x_flag_reorder_blocks = 1;
853     }
854 
855   /* If user requested unwind info, then turn off the partitioning
856      optimization.  */
857 
858   if (opts->x_flag_unwind_tables
859       && !targetm_common.unwind_tables_default
860       && opts->x_flag_reorder_blocks_and_partition
861       && (ui_except == UI_SJLJ || ui_except >= UI_TARGET))
862     {
863       if (opts_set->x_flag_reorder_blocks_and_partition)
864         inform (loc,
865 		"%<-freorder-blocks-and-partition%> does not support "
866 		"unwind info on this architecture");
867       opts->x_flag_reorder_blocks_and_partition = 0;
868       opts->x_flag_reorder_blocks = 1;
869     }
870 
871   /* If the target requested unwind info, then turn off the partitioning
872      optimization with a different message.  Likewise, if the target does not
873      support named sections.  */
874 
875   if (opts->x_flag_reorder_blocks_and_partition
876       && (!targetm_common.have_named_sections
877 	  || (opts->x_flag_unwind_tables
878 	      && targetm_common.unwind_tables_default
879 	      && (ui_except == UI_SJLJ || ui_except >= UI_TARGET))))
880     {
881       if (opts_set->x_flag_reorder_blocks_and_partition)
882         inform (loc,
883 		"%<-freorder-blocks-and-partition%> does not work "
884 		"on this architecture");
885       opts->x_flag_reorder_blocks_and_partition = 0;
886       opts->x_flag_reorder_blocks = 1;
887     }
888 
889 
890   /* Pipelining of outer loops is only possible when general pipelining
891      capabilities are requested.  */
892   if (!opts->x_flag_sel_sched_pipelining)
893     opts->x_flag_sel_sched_pipelining_outer_loops = 0;
894 
895   if (opts->x_flag_conserve_stack)
896     {
897       maybe_set_param_value (PARAM_LARGE_STACK_FRAME, 100,
898 			     opts->x_param_values, opts_set->x_param_values);
899       maybe_set_param_value (PARAM_STACK_FRAME_GROWTH, 40,
900 			     opts->x_param_values, opts_set->x_param_values);
901     }
902 
903   if (opts->x_flag_lto)
904     {
905 #ifdef ENABLE_LTO
906       opts->x_flag_generate_lto = 1;
907 
908       /* When generating IL, do not operate in whole-program mode.
909 	 Otherwise, symbols will be privatized too early, causing link
910 	 errors later.  */
911       opts->x_flag_whole_program = 0;
912 #else
913       error_at (loc, "LTO support has not been enabled in this configuration");
914 #endif
915       if (!opts->x_flag_fat_lto_objects
916 	  && (!HAVE_LTO_PLUGIN
917 	      || (opts_set->x_flag_use_linker_plugin
918 		  && !opts->x_flag_use_linker_plugin)))
919 	{
920 	  if (opts_set->x_flag_fat_lto_objects)
921 	    error_at (loc, "%<-fno-fat-lto-objects%> are supported only with "
922 		      "linker plugin");
923 	  opts->x_flag_fat_lto_objects = 1;
924 	}
925 
926       /* -gsplit-dwarf isn't compatible with LTO, see PR88389.  */
927       if (opts->x_dwarf_split_debug_info)
928 	{
929 	  inform (loc, "%<-gsplit-dwarf%> is not supported with LTO,"
930 		  " disabling");
931 	  opts->x_dwarf_split_debug_info = 0;
932 	}
933     }
934 
935   /* We initialize opts->x_flag_split_stack to -1 so that targets can set a
936      default value if they choose based on other options.  */
937   if (opts->x_flag_split_stack == -1)
938     opts->x_flag_split_stack = 0;
939   else if (opts->x_flag_split_stack)
940     {
941       if (!targetm_common.supports_split_stack (true, opts))
942 	{
943 	  error_at (loc, "%<-fsplit-stack%> is not supported by "
944 		    "this compiler configuration");
945 	  opts->x_flag_split_stack = 0;
946 	}
947     }
948 
949   /* If stack splitting is turned on, and the user did not explicitly
950      request function partitioning, turn off partitioning, as it
951      confuses the linker when trying to handle partitioned split-stack
952      code that calls a non-split-stack functions.  But if partitioning
953      was turned on explicitly just hope for the best.  */
954   if (opts->x_flag_split_stack
955       && opts->x_flag_reorder_blocks_and_partition
956       && !opts_set->x_flag_reorder_blocks_and_partition)
957     opts->x_flag_reorder_blocks_and_partition = 0;
958 
959   if (opts->x_flag_reorder_blocks_and_partition
960       && !opts_set->x_flag_reorder_functions)
961     opts->x_flag_reorder_functions = 1;
962 
963   /* Tune vectorization related parametees according to cost model.  */
964   if (opts->x_flag_vect_cost_model == VECT_COST_MODEL_CHEAP)
965     {
966       maybe_set_param_value (PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS,
967             6, opts->x_param_values, opts_set->x_param_values);
968       maybe_set_param_value (PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS,
969             0, opts->x_param_values, opts_set->x_param_values);
970       maybe_set_param_value (PARAM_VECT_MAX_PEELING_FOR_ALIGNMENT,
971             0, opts->x_param_values, opts_set->x_param_values);
972     }
973 
974   /* Set PARAM_MAX_STORES_TO_SINK to 0 if either vectorization or if-conversion
975      is disabled.  */
976   if ((!opts->x_flag_tree_loop_vectorize && !opts->x_flag_tree_slp_vectorize)
977        || !opts->x_flag_tree_loop_if_convert)
978     maybe_set_param_value (PARAM_MAX_STORES_TO_SINK, 0,
979                            opts->x_param_values, opts_set->x_param_values);
980 
981   /* The -gsplit-dwarf option requires -ggnu-pubnames.  */
982   if (opts->x_dwarf_split_debug_info)
983     opts->x_debug_generate_pub_sections = 2;
984 
985   if ((opts->x_flag_sanitize
986        & (SANITIZE_USER_ADDRESS | SANITIZE_KERNEL_ADDRESS)) == 0)
987     {
988       if (opts->x_flag_sanitize & SANITIZE_POINTER_COMPARE)
989 	error_at (loc,
990 		  "%<-fsanitize=pointer-compare%> must be combined with "
991 		  "%<-fsanitize=address%> or %<-fsanitize=kernel-address%>");
992       if (opts->x_flag_sanitize & SANITIZE_POINTER_SUBTRACT)
993 	error_at (loc,
994 		  "%<-fsanitize=pointer-subtract%> must be combined with "
995 		  "%<-fsanitize=address%> or %<-fsanitize=kernel-address%>");
996     }
997 
998   /* Userspace and kernel ASan conflict with each other.  */
999   if ((opts->x_flag_sanitize & SANITIZE_USER_ADDRESS)
1000       && (opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS))
1001     error_at (loc,
1002 	      "%<-fsanitize=address%> is incompatible with "
1003 	      "%<-fsanitize=kernel-address%>");
1004 
1005   /* And with TSan.  */
1006   if ((opts->x_flag_sanitize & SANITIZE_ADDRESS)
1007       && (opts->x_flag_sanitize & SANITIZE_THREAD))
1008     error_at (loc,
1009 	      "%<-fsanitize=address%> and %<-fsanitize=kernel-address%> "
1010 	      "are incompatible with %<-fsanitize=thread%>");
1011 
1012   if ((opts->x_flag_sanitize & SANITIZE_LEAK)
1013       && (opts->x_flag_sanitize & SANITIZE_THREAD))
1014     error_at (loc,
1015 	      "%<-fsanitize=leak%> is incompatible with %<-fsanitize=thread%>");
1016 
1017   /* Check error recovery for -fsanitize-recover option.  */
1018   for (int i = 0; sanitizer_opts[i].name != NULL; ++i)
1019     if ((opts->x_flag_sanitize_recover & sanitizer_opts[i].flag)
1020 	&& !sanitizer_opts[i].can_recover)
1021       error_at (loc, "%<-fsanitize-recover=%s%> is not supported",
1022 		sanitizer_opts[i].name);
1023 
1024   /* When instrumenting the pointers, we don't want to remove
1025      the null pointer checks.  */
1026   if (opts->x_flag_sanitize & (SANITIZE_NULL | SANITIZE_NONNULL_ATTRIBUTE
1027 				| SANITIZE_RETURNS_NONNULL_ATTRIBUTE))
1028     opts->x_flag_delete_null_pointer_checks = 0;
1029 
1030   /* Aggressive compiler optimizations may cause false negatives.  */
1031   if (opts->x_flag_sanitize & ~(SANITIZE_LEAK | SANITIZE_UNREACHABLE))
1032     opts->x_flag_aggressive_loop_optimizations = 0;
1033 
1034   /* Enable -fsanitize-address-use-after-scope if address sanitizer is
1035      enabled.  */
1036   if ((opts->x_flag_sanitize & SANITIZE_USER_ADDRESS)
1037       && !opts_set->x_flag_sanitize_address_use_after_scope)
1038     opts->x_flag_sanitize_address_use_after_scope = true;
1039 
1040   /* Force -fstack-reuse=none in case -fsanitize-address-use-after-scope
1041      is enabled.  */
1042   if (opts->x_flag_sanitize_address_use_after_scope)
1043     {
1044       if (opts->x_flag_stack_reuse != SR_NONE
1045 	  && opts_set->x_flag_stack_reuse != SR_NONE)
1046 	error_at (loc,
1047 		  "%<-fsanitize-address-use-after-scope%> requires "
1048 		  "%<-fstack-reuse=none%> option");
1049 
1050       opts->x_flag_stack_reuse = SR_NONE;
1051     }
1052 
1053   if ((opts->x_flag_sanitize & SANITIZE_USER_ADDRESS) && opts->x_flag_tm)
1054     sorry ("transactional memory is not supported with %<-fsanitize=address%>");
1055 
1056   if ((opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS) && opts->x_flag_tm)
1057     sorry ("transactional memory is not supported with "
1058 	   "%<-fsanitize=kernel-address%>");
1059 
1060   /* Comes from final.c -- no real reason to change it.  */
1061 #define MAX_CODE_ALIGN 16
1062 #define MAX_CODE_ALIGN_VALUE (1 << MAX_CODE_ALIGN)
1063 
1064   if (opts->x_align_loops > MAX_CODE_ALIGN_VALUE)
1065     error_at (loc, "-falign-loops=%d is not between 0 and %d",
1066 	      opts->x_align_loops, MAX_CODE_ALIGN_VALUE);
1067 
1068   if (opts->x_align_jumps > MAX_CODE_ALIGN_VALUE)
1069     error_at (loc, "-falign-jumps=%d is not between 0 and %d",
1070 	      opts->x_align_jumps, MAX_CODE_ALIGN_VALUE);
1071 
1072   if (opts->x_align_functions > MAX_CODE_ALIGN_VALUE)
1073     error_at (loc, "-falign-functions=%d is not between 0 and %d",
1074 	      opts->x_align_functions, MAX_CODE_ALIGN_VALUE);
1075 
1076   if (opts->x_align_labels > MAX_CODE_ALIGN_VALUE)
1077     error_at (loc, "-falign-labels=%d is not between 0 and %d",
1078 	      opts->x_align_labels, MAX_CODE_ALIGN_VALUE);
1079 }
1080 
1081 #define LEFT_COLUMN	27
1082 
1083 /* Output ITEM, of length ITEM_WIDTH, in the left column,
1084    followed by word-wrapped HELP in a second column.  */
1085 static void
wrap_help(const char * help,const char * item,unsigned int item_width,unsigned int columns)1086 wrap_help (const char *help,
1087 	   const char *item,
1088 	   unsigned int item_width,
1089 	   unsigned int columns)
1090 {
1091   unsigned int col_width = LEFT_COLUMN;
1092   unsigned int remaining, room, len;
1093 
1094   remaining = strlen (help);
1095 
1096   do
1097     {
1098       room = columns - 3 - MAX (col_width, item_width);
1099       if (room > columns)
1100 	room = 0;
1101       len = remaining;
1102 
1103       if (room < len)
1104 	{
1105 	  unsigned int i;
1106 
1107 	  for (i = 0; help[i]; i++)
1108 	    {
1109 	      if (i >= room && len != remaining)
1110 		break;
1111 	      if (help[i] == ' ')
1112 		len = i;
1113 	      else if ((help[i] == '-' || help[i] == '/')
1114 		       && help[i + 1] != ' '
1115 		       && i > 0 && ISALPHA (help[i - 1]))
1116 		len = i + 1;
1117 	    }
1118 	}
1119 
1120       printf ("  %-*.*s %.*s\n", col_width, item_width, item, len, help);
1121       item_width = 0;
1122       while (help[len] == ' ')
1123 	len++;
1124       help += len;
1125       remaining -= len;
1126     }
1127   while (remaining);
1128 }
1129 
1130 /* Print help for a specific front-end, etc.  */
1131 static void
print_filtered_help(unsigned int include_flags,unsigned int exclude_flags,unsigned int any_flags,unsigned int columns,struct gcc_options * opts,unsigned int lang_mask)1132 print_filtered_help (unsigned int include_flags,
1133 		     unsigned int exclude_flags,
1134 		     unsigned int any_flags,
1135 		     unsigned int columns,
1136 		     struct gcc_options *opts,
1137 		     unsigned int lang_mask)
1138 {
1139   unsigned int i;
1140   const char *help;
1141   bool found = false;
1142   bool displayed = false;
1143   char new_help[256];
1144 
1145   if (include_flags == CL_PARAMS)
1146     {
1147       for (i = 0; i < LAST_PARAM; i++)
1148 	{
1149 	  const char *param = compiler_params[i].option;
1150 
1151 	  help = compiler_params[i].help;
1152 	  if (help == NULL || *help == '\0')
1153 	    {
1154 	      if (exclude_flags & CL_UNDOCUMENTED)
1155 		continue;
1156 	      help = undocumented_msg;
1157 	    }
1158 
1159 	  /* Get the translation.  */
1160 	  help = _(help);
1161 
1162 	  if (!opts->x_quiet_flag)
1163 	    {
1164 	      snprintf (new_help, sizeof (new_help),
1165 			_("default %d minimum %d maximum %d"),
1166 			compiler_params[i].default_value,
1167 			compiler_params[i].min_value,
1168 			compiler_params[i].max_value);
1169 	      help = new_help;
1170 	    }
1171 	  wrap_help (help, param, strlen (param), columns);
1172 	}
1173       putchar ('\n');
1174       return;
1175     }
1176 
1177   if (!opts->x_help_printed)
1178     opts->x_help_printed = XCNEWVAR (char, cl_options_count);
1179 
1180   if (!opts->x_help_enum_printed)
1181     opts->x_help_enum_printed = XCNEWVAR (char, cl_enums_count);
1182 
1183   for (i = 0; i < cl_options_count; i++)
1184     {
1185       const struct cl_option *option = cl_options + i;
1186       unsigned int len;
1187       const char *opt;
1188       const char *tab;
1189 
1190       if (include_flags == 0
1191 	  || ((option->flags & include_flags) != include_flags))
1192 	{
1193 	  if ((option->flags & any_flags) == 0)
1194 	    continue;
1195 	}
1196 
1197       /* Skip unwanted switches.  */
1198       if ((option->flags & exclude_flags) != 0)
1199 	continue;
1200 
1201       /* The driver currently prints its own help text.  */
1202       if ((option->flags & CL_DRIVER) != 0
1203 	  && (option->flags & (((1U << cl_lang_count) - 1)
1204 			       | CL_COMMON | CL_TARGET)) == 0)
1205 	continue;
1206 
1207       found = true;
1208       /* Skip switches that have already been printed.  */
1209       if (opts->x_help_printed[i])
1210 	continue;
1211 
1212       opts->x_help_printed[i] = true;
1213 
1214       help = option->help;
1215       if (help == NULL)
1216 	{
1217 	  if (exclude_flags & CL_UNDOCUMENTED)
1218 	    continue;
1219 
1220 	  help = undocumented_msg;
1221 	}
1222 
1223       if (option->alias_target < N_OPTS
1224 	  && cl_options [option->alias_target].help)
1225 	{
1226 	  if (help == undocumented_msg)
1227 	    {
1228 	      /* For undocumented options that are aliases for other options
1229 		 that are documented, point the reader to the other option in
1230 		 preference of the former.  */
1231 	      snprintf (new_help, sizeof new_help,
1232 			_("Same as %s.  Use the latter option instead."),
1233 			cl_options [option->alias_target].opt_text);
1234 	    }
1235 	  else
1236 	    {
1237 	      /* For documented options with aliases, mention the aliased
1238 		 option's name for reference.  */
1239 	      snprintf (new_help, sizeof new_help,
1240 			_("%s  Same as %s."),
1241 			help, cl_options [option->alias_target].opt_text);
1242 	    }
1243 
1244 	  help = new_help;
1245 	}
1246 
1247       if (option->warn_message)
1248 	{
1249 	  /* Mention that the use of the option will trigger a warning.  */
1250 	  if (help == new_help)
1251 	    snprintf (new_help + strlen (new_help),
1252 		      sizeof new_help - strlen (new_help),
1253 		      "  %s", _(use_diagnosed_msg));
1254 	  else
1255 	    snprintf (new_help, sizeof new_help,
1256 		      "%s  %s", help, _(use_diagnosed_msg));
1257 
1258 	  help = new_help;
1259 	}
1260 
1261       /* Get the translation.  */
1262       help = _(help);
1263 
1264       /* Find the gap between the name of the
1265 	 option and its descriptive text.  */
1266       tab = strchr (help, '\t');
1267       if (tab)
1268 	{
1269 	  len = tab - help;
1270 	  opt = help;
1271 	  help = tab + 1;
1272 	}
1273       else
1274 	{
1275 	  opt = option->opt_text;
1276 	  len = strlen (opt);
1277 	}
1278 
1279       /* With the -Q option enabled we change the descriptive text associated
1280 	 with an option to be an indication of its current setting.  */
1281       if (!opts->x_quiet_flag)
1282 	{
1283 	  void *flag_var = option_flag_var (i, opts);
1284 
1285 	  if (len < (LEFT_COLUMN + 2))
1286 	    strcpy (new_help, "\t\t");
1287 	  else
1288 	    strcpy (new_help, "\t");
1289 
1290 	  if (flag_var != NULL
1291 	      && option->var_type != CLVC_DEFER)
1292 	    {
1293 	      if (option->flags & CL_JOINED)
1294 		{
1295 		  if (option->var_type == CLVC_STRING)
1296 		    {
1297 		      if (* (const char **) flag_var != NULL)
1298 			snprintf (new_help + strlen (new_help),
1299 				  sizeof (new_help) - strlen (new_help),
1300 				  "%s", * (const char **) flag_var);
1301 		    }
1302 		  else if (option->var_type == CLVC_ENUM)
1303 		    {
1304 		      const struct cl_enum *e = &cl_enums[option->var_enum];
1305 		      int value;
1306 		      const char *arg = NULL;
1307 
1308 		      value = e->get (flag_var);
1309 		      enum_value_to_arg (e->values, &arg, value, lang_mask);
1310 		      if (arg == NULL)
1311 			arg = _("[default]");
1312 		      snprintf (new_help + strlen (new_help),
1313 				sizeof (new_help) - strlen (new_help),
1314 				"%s", arg);
1315 		    }
1316 		  else
1317 		    sprintf (new_help + strlen (new_help),
1318 			     "%d", * (int *) flag_var);
1319 		}
1320 	      else
1321 		strcat (new_help, option_enabled (i, opts)
1322 			? _("[enabled]") : _("[disabled]"));
1323 	    }
1324 
1325 	  help = new_help;
1326 	}
1327 
1328       if (option->range_max != -1)
1329 	{
1330 	  char b[128];
1331 	  snprintf (b, sizeof (b), "<%d,%d>", option->range_min,
1332 		    option->range_max);
1333 	  opt = concat (opt, b, NULL);
1334 	  len += strlen (b);
1335 	}
1336 
1337       wrap_help (help, opt, len, columns);
1338       displayed = true;
1339 
1340       if (option->var_type == CLVC_ENUM
1341 	  && opts->x_help_enum_printed[option->var_enum] != 2)
1342 	opts->x_help_enum_printed[option->var_enum] = 1;
1343     }
1344 
1345   if (! found)
1346     {
1347       unsigned int langs = include_flags & CL_LANG_ALL;
1348 
1349       if (langs == 0)
1350 	printf (_(" No options with the desired characteristics were found\n"));
1351       else
1352 	{
1353 	  unsigned int i;
1354 
1355 	  /* PR 31349: Tell the user how to see all of the
1356 	     options supported by a specific front end.  */
1357 	  for (i = 0; (1U << i) < CL_LANG_ALL; i ++)
1358 	    if ((1U << i) & langs)
1359 	      printf (_(" None found.  Use --help=%s to show *all* the options supported by the %s front-end.\n"),
1360 		      lang_names[i], lang_names[i]);
1361 	}
1362 
1363     }
1364   else if (! displayed)
1365     printf (_(" All options with the desired characteristics have already been displayed\n"));
1366 
1367   putchar ('\n');
1368 
1369   /* Print details of enumerated option arguments, if those
1370      enumerations have help text headings provided.  If no help text
1371      is provided, presume that the possible values are listed in the
1372      help text for the relevant options.  */
1373   for (i = 0; i < cl_enums_count; i++)
1374     {
1375       unsigned int j, pos;
1376 
1377       if (opts->x_help_enum_printed[i] != 1)
1378 	continue;
1379       if (cl_enums[i].help == NULL)
1380 	continue;
1381       printf ("  %s\n    ", _(cl_enums[i].help));
1382       pos = 4;
1383       for (j = 0; cl_enums[i].values[j].arg != NULL; j++)
1384 	{
1385 	  unsigned int len = strlen (cl_enums[i].values[j].arg);
1386 
1387 	  if (pos > 4 && pos + 1 + len <= columns)
1388 	    {
1389 	      printf (" %s", cl_enums[i].values[j].arg);
1390 	      pos += 1 + len;
1391 	    }
1392 	  else
1393 	    {
1394 	      if (pos > 4)
1395 		{
1396 		  printf ("\n    ");
1397 		  pos = 4;
1398 		}
1399 	      printf ("%s", cl_enums[i].values[j].arg);
1400 	      pos += len;
1401 	    }
1402 	}
1403       printf ("\n\n");
1404       opts->x_help_enum_printed[i] = 2;
1405     }
1406 }
1407 
1408 /* Display help for a specified type of option.
1409    The options must have ALL of the INCLUDE_FLAGS set
1410    ANY of the flags in the ANY_FLAGS set
1411    and NONE of the EXCLUDE_FLAGS set.  The current option state is in
1412    OPTS; LANG_MASK is used for interpreting enumerated option state.  */
1413 static void
print_specific_help(unsigned int include_flags,unsigned int exclude_flags,unsigned int any_flags,struct gcc_options * opts,unsigned int lang_mask)1414 print_specific_help (unsigned int include_flags,
1415 		     unsigned int exclude_flags,
1416 		     unsigned int any_flags,
1417 		     struct gcc_options *opts,
1418 		     unsigned int lang_mask)
1419 {
1420   unsigned int all_langs_mask = (1U << cl_lang_count) - 1;
1421   const char * description = NULL;
1422   const char * descrip_extra = "";
1423   size_t i;
1424   unsigned int flag;
1425 
1426   /* Sanity check: Make sure that we do not have more
1427      languages than we have bits available to enumerate them.  */
1428   gcc_assert ((1U << cl_lang_count) <= CL_MIN_OPTION_CLASS);
1429 
1430   /* If we have not done so already, obtain
1431      the desired maximum width of the output.  */
1432   if (opts->x_help_columns == 0)
1433     {
1434       opts->x_help_columns = get_terminal_width ();
1435       if (opts->x_help_columns == INT_MAX)
1436 	/* Use a reasonable default.  */
1437 	opts->x_help_columns = 80;
1438     }
1439 
1440   /* Decide upon the title for the options that we are going to display.  */
1441   for (i = 0, flag = 1; flag <= CL_MAX_OPTION_CLASS; flag <<= 1, i ++)
1442     {
1443       switch (flag & include_flags)
1444 	{
1445 	case 0:
1446 	case CL_DRIVER:
1447 	  break;
1448 
1449 	case CL_TARGET:
1450 	  description = _("The following options are target specific");
1451 	  break;
1452 	case CL_WARNING:
1453 	  description = _("The following options control compiler warning messages");
1454 	  break;
1455 	case CL_OPTIMIZATION:
1456 	  description = _("The following options control optimizations");
1457 	  break;
1458 	case CL_COMMON:
1459 	  description = _("The following options are language-independent");
1460 	  break;
1461 	case CL_PARAMS:
1462 	  description = _("The --param option recognizes the following as parameters");
1463 	  break;
1464 	default:
1465 	  if (i >= cl_lang_count)
1466 	    break;
1467 	  if (exclude_flags & all_langs_mask)
1468 	    description = _("The following options are specific to just the language ");
1469 	  else
1470 	    description = _("The following options are supported by the language ");
1471 	  descrip_extra = lang_names [i];
1472 	  break;
1473 	}
1474     }
1475 
1476   if (description == NULL)
1477     {
1478       if (any_flags == 0)
1479 	{
1480 	  if (include_flags & CL_UNDOCUMENTED)
1481 	    description = _("The following options are not documented");
1482 	  else if (include_flags & CL_SEPARATE)
1483 	    description = _("The following options take separate arguments");
1484 	  else if (include_flags & CL_JOINED)
1485 	    description = _("The following options take joined arguments");
1486 	  else
1487 	    {
1488 	      internal_error ("unrecognized include_flags 0x%x passed to print_specific_help",
1489 			      include_flags);
1490 	      return;
1491 	    }
1492 	}
1493       else
1494 	{
1495 	  if (any_flags & all_langs_mask)
1496 	    description = _("The following options are language-related");
1497 	  else
1498 	    description = _("The following options are language-independent");
1499 	}
1500     }
1501 
1502   printf ("%s%s:\n", description, descrip_extra);
1503   print_filtered_help (include_flags, exclude_flags, any_flags,
1504 		       opts->x_help_columns, opts, lang_mask);
1505 }
1506 
1507 /* Enable FDO-related flags.  */
1508 
1509 static void
enable_fdo_optimizations(struct gcc_options * opts,struct gcc_options * opts_set,int value)1510 enable_fdo_optimizations (struct gcc_options *opts,
1511 			  struct gcc_options *opts_set,
1512 			  int value)
1513 {
1514   if (!opts_set->x_flag_branch_probabilities)
1515     opts->x_flag_branch_probabilities = value;
1516   if (!opts_set->x_flag_profile_values)
1517     opts->x_flag_profile_values = value;
1518   if (!opts_set->x_flag_unroll_loops)
1519     opts->x_flag_unroll_loops = value;
1520   if (!opts_set->x_flag_peel_loops)
1521     opts->x_flag_peel_loops = value;
1522   if (!opts_set->x_flag_tracer)
1523     opts->x_flag_tracer = value;
1524   if (!opts_set->x_flag_value_profile_transformations)
1525     opts->x_flag_value_profile_transformations = value;
1526   if (!opts_set->x_flag_inline_functions)
1527     opts->x_flag_inline_functions = value;
1528   if (!opts_set->x_flag_ipa_cp)
1529     opts->x_flag_ipa_cp = value;
1530   if (!opts_set->x_flag_ipa_cp_clone
1531       && value && opts->x_flag_ipa_cp)
1532     opts->x_flag_ipa_cp_clone = value;
1533   if (!opts_set->x_flag_ipa_bit_cp
1534       && value && opts->x_flag_ipa_cp)
1535     opts->x_flag_ipa_bit_cp = value;
1536   if (!opts_set->x_flag_predictive_commoning)
1537     opts->x_flag_predictive_commoning = value;
1538   if (!opts_set->x_flag_split_loops)
1539     opts->x_flag_split_loops = value;
1540   if (!opts_set->x_flag_unswitch_loops)
1541     opts->x_flag_unswitch_loops = value;
1542   if (!opts_set->x_flag_gcse_after_reload)
1543     opts->x_flag_gcse_after_reload = value;
1544   if (!opts_set->x_flag_tree_loop_vectorize)
1545     opts->x_flag_tree_loop_vectorize = value;
1546   if (!opts_set->x_flag_tree_slp_vectorize)
1547     opts->x_flag_tree_slp_vectorize = value;
1548   if (!opts_set->x_flag_vect_cost_model)
1549     opts->x_flag_vect_cost_model = VECT_COST_MODEL_DYNAMIC;
1550   if (!opts_set->x_flag_tree_loop_distribute_patterns)
1551     opts->x_flag_tree_loop_distribute_patterns = value;
1552 }
1553 
1554 /* -f{,no-}sanitize{,-recover}= suboptions.  */
1555 const struct sanitizer_opts_s sanitizer_opts[] =
1556 {
1557 #define SANITIZER_OPT(name, flags, recover) \
1558     { #name, flags, sizeof #name - 1, recover }
1559   SANITIZER_OPT (address, (SANITIZE_ADDRESS | SANITIZE_USER_ADDRESS), true),
1560   SANITIZER_OPT (kernel-address, (SANITIZE_ADDRESS | SANITIZE_KERNEL_ADDRESS),
1561 		 true),
1562   SANITIZER_OPT (pointer-compare, SANITIZE_POINTER_COMPARE, true),
1563   SANITIZER_OPT (pointer-subtract, SANITIZE_POINTER_SUBTRACT, true),
1564   SANITIZER_OPT (thread, SANITIZE_THREAD, false),
1565   SANITIZER_OPT (leak, SANITIZE_LEAK, false),
1566   SANITIZER_OPT (shift, SANITIZE_SHIFT, true),
1567   SANITIZER_OPT (shift-base, SANITIZE_SHIFT_BASE, true),
1568   SANITIZER_OPT (shift-exponent, SANITIZE_SHIFT_EXPONENT, true),
1569   SANITIZER_OPT (integer-divide-by-zero, SANITIZE_DIVIDE, true),
1570   SANITIZER_OPT (undefined, SANITIZE_UNDEFINED, true),
1571   SANITIZER_OPT (unreachable, SANITIZE_UNREACHABLE, false),
1572   SANITIZER_OPT (vla-bound, SANITIZE_VLA, true),
1573   SANITIZER_OPT (return, SANITIZE_RETURN, false),
1574   SANITIZER_OPT (null, SANITIZE_NULL, true),
1575   SANITIZER_OPT (signed-integer-overflow, SANITIZE_SI_OVERFLOW, true),
1576   SANITIZER_OPT (bool, SANITIZE_BOOL, true),
1577   SANITIZER_OPT (enum, SANITIZE_ENUM, true),
1578   SANITIZER_OPT (float-divide-by-zero, SANITIZE_FLOAT_DIVIDE, true),
1579   SANITIZER_OPT (float-cast-overflow, SANITIZE_FLOAT_CAST, true),
1580   SANITIZER_OPT (bounds, SANITIZE_BOUNDS, true),
1581   SANITIZER_OPT (bounds-strict, SANITIZE_BOUNDS | SANITIZE_BOUNDS_STRICT, true),
1582   SANITIZER_OPT (alignment, SANITIZE_ALIGNMENT, true),
1583   SANITIZER_OPT (nonnull-attribute, SANITIZE_NONNULL_ATTRIBUTE, true),
1584   SANITIZER_OPT (returns-nonnull-attribute, SANITIZE_RETURNS_NONNULL_ATTRIBUTE,
1585 		 true),
1586   SANITIZER_OPT (object-size, SANITIZE_OBJECT_SIZE, true),
1587   SANITIZER_OPT (vptr, SANITIZE_VPTR, true),
1588   SANITIZER_OPT (pointer-overflow, SANITIZE_POINTER_OVERFLOW, true),
1589   SANITIZER_OPT (builtin, SANITIZE_BUILTIN, true),
1590   SANITIZER_OPT (all, ~0U, true),
1591 #undef SANITIZER_OPT
1592   { NULL, 0U, 0UL, false }
1593 };
1594 
1595 /* -f{,no-}sanitize-coverage= suboptions.  */
1596 const struct sanitizer_opts_s coverage_sanitizer_opts[] =
1597 {
1598 #define COVERAGE_SANITIZER_OPT(name, flags) \
1599     { #name, flags, sizeof #name - 1, true }
1600   COVERAGE_SANITIZER_OPT (trace-pc, SANITIZE_COV_TRACE_PC),
1601   COVERAGE_SANITIZER_OPT (trace-cmp, SANITIZE_COV_TRACE_CMP),
1602 #undef COVERAGE_SANITIZER_OPT
1603   { NULL, 0U, 0UL, false }
1604 };
1605 
1606 /* A struct for describing a run of chars within a string.  */
1607 
1608 struct string_fragment
1609 {
string_fragmentstring_fragment1610   string_fragment (const char *start, size_t len)
1611   : m_start (start), m_len (len) {}
1612 
1613   const char *m_start;
1614   size_t m_len;
1615 };
1616 
1617 /* Specialization of edit_distance_traits for string_fragment,
1618    for use by get_closest_sanitizer_option.  */
1619 
1620 template <>
1621 struct edit_distance_traits<const string_fragment &>
1622 {
1623   static size_t get_length (const string_fragment &fragment)
1624   {
1625     return fragment.m_len;
1626   }
1627 
1628   static const char *get_string (const string_fragment &fragment)
1629   {
1630     return fragment.m_start;
1631   }
1632 };
1633 
1634 /* Given ARG, an unrecognized sanitizer option, return the best
1635    matching sanitizer option, or NULL if there isn't one.
1636    OPTS is array of candidate sanitizer options.
1637    CODE is OPT_fsanitize_, OPT_fsanitize_recover_ or
1638    OPT_fsanitize_coverage_.
1639    VALUE is non-zero for the regular form of the option, zero
1640    for the "no-" form (e.g. "-fno-sanitize-recover=").  */
1641 
1642 static const char *
1643 get_closest_sanitizer_option (const string_fragment &arg,
1644 			      const struct sanitizer_opts_s *opts,
1645 			      enum opt_code code, int value)
1646 {
1647   best_match <const string_fragment &, const char*> bm (arg);
1648   for (int i = 0; opts[i].name != NULL; ++i)
1649     {
1650       /* -fsanitize=all is not valid, so don't offer it.  */
1651       if (code == OPT_fsanitize_
1652 	  && opts[i].flag == ~0U
1653 	  && value)
1654 	continue;
1655 
1656       /* For -fsanitize-recover= (and not -fno-sanitize-recover=),
1657 	 don't offer the non-recoverable options.  */
1658       if (code == OPT_fsanitize_recover_
1659 	  && !opts[i].can_recover
1660 	  && value)
1661 	continue;
1662 
1663       bm.consider (opts[i].name);
1664     }
1665   return bm.get_best_meaningful_candidate ();
1666 }
1667 
1668 /* Parse comma separated sanitizer suboptions from P for option SCODE,
1669    adjust previous FLAGS and return new ones.  If COMPLAIN is false,
1670    don't issue diagnostics.  */
1671 
1672 unsigned int
1673 parse_sanitizer_options (const char *p, location_t loc, int scode,
1674 			 unsigned int flags, int value, bool complain)
1675 {
1676   enum opt_code code = (enum opt_code) scode;
1677 
1678   const struct sanitizer_opts_s *opts;
1679   if (code == OPT_fsanitize_coverage_)
1680     opts = coverage_sanitizer_opts;
1681   else
1682     opts = sanitizer_opts;
1683 
1684   while (*p != 0)
1685     {
1686       size_t len, i;
1687       bool found = false;
1688       const char *comma = strchr (p, ',');
1689 
1690       if (comma == NULL)
1691 	len = strlen (p);
1692       else
1693 	len = comma - p;
1694       if (len == 0)
1695 	{
1696 	  p = comma + 1;
1697 	  continue;
1698 	}
1699 
1700       /* Check to see if the string matches an option class name.  */
1701       for (i = 0; opts[i].name != NULL; ++i)
1702 	if (len == opts[i].len && memcmp (p, opts[i].name, len) == 0)
1703 	  {
1704 	    /* Handle both -fsanitize and -fno-sanitize cases.  */
1705 	    if (value && opts[i].flag == ~0U)
1706 	      {
1707 		if (code == OPT_fsanitize_)
1708 		  {
1709 		    if (complain)
1710 		      error_at (loc, "%<-fsanitize=all%> option is not valid");
1711 		  }
1712 		else
1713 		  flags |= ~(SANITIZE_THREAD | SANITIZE_LEAK
1714 			     | SANITIZE_UNREACHABLE | SANITIZE_RETURN);
1715 	      }
1716 	    else if (value)
1717 	      {
1718 		/* Do not enable -fsanitize-recover=unreachable and
1719 		   -fsanitize-recover=return if -fsanitize-recover=undefined
1720 		   is selected.  */
1721 		if (code == OPT_fsanitize_recover_
1722 		    && opts[i].flag == SANITIZE_UNDEFINED)
1723 		  flags |= (SANITIZE_UNDEFINED
1724 			    & ~(SANITIZE_UNREACHABLE | SANITIZE_RETURN));
1725 		else
1726 		  flags |= opts[i].flag;
1727 	      }
1728 	    else
1729 	      flags &= ~opts[i].flag;
1730 	    found = true;
1731 	    break;
1732 	  }
1733 
1734       if (! found && complain)
1735 	{
1736 	  const char *hint
1737 	    = get_closest_sanitizer_option (string_fragment (p, len),
1738 					    opts, code, value);
1739 
1740 	  const char *suffix;
1741 	  if (code == OPT_fsanitize_recover_)
1742 	    suffix = "-recover";
1743 	  else if (code == OPT_fsanitize_coverage_)
1744 	    suffix = "-coverage";
1745 	  else
1746 	    suffix = "";
1747 
1748 	  if (hint)
1749 	    error_at (loc,
1750 		      "unrecognized argument to -f%ssanitize%s= option: %q.*s;"
1751 		      " did you mean %qs?",
1752 		      value ? "" : "no-",
1753 		      suffix, (int) len, p, hint);
1754 	  else
1755 	    error_at (loc,
1756 		      "unrecognized argument to -f%ssanitize%s= option: %q.*s",
1757 		      value ? "" : "no-",
1758 		      suffix, (int) len, p);
1759 	}
1760 
1761       if (comma == NULL)
1762 	break;
1763       p = comma + 1;
1764     }
1765   return flags;
1766 }
1767 
1768 /* Parse string values of no_sanitize attribute passed in VALUE.
1769    Values are separated with comma.  */
1770 
1771 unsigned int
1772 parse_no_sanitize_attribute (char *value)
1773 {
1774   unsigned int flags = 0;
1775   unsigned int i;
1776   char *q = strtok (value, ",");
1777 
1778   while (q != NULL)
1779     {
1780       for (i = 0; sanitizer_opts[i].name != NULL; ++i)
1781 	if (strcmp (sanitizer_opts[i].name, q) == 0)
1782 	  {
1783 	    flags |= sanitizer_opts[i].flag;
1784 	    if (sanitizer_opts[i].flag == SANITIZE_UNDEFINED)
1785 	      flags |= SANITIZE_UNDEFINED_NONDEFAULT;
1786 	    break;
1787 	  }
1788 
1789       if (sanitizer_opts[i].name == NULL)
1790 	warning (OPT_Wattributes,
1791 		 "%<%s%> attribute directive ignored", q);
1792 
1793       q = strtok (NULL, ",");
1794     }
1795 
1796   return flags;
1797 }
1798 
1799 /* Handle target- and language-independent options.  Return zero to
1800    generate an "unknown option" message.  Only options that need
1801    extra handling need to be listed here; if you simply want
1802    DECODED->value assigned to a variable, it happens automatically.  */
1803 
1804 bool
1805 common_handle_option (struct gcc_options *opts,
1806 		      struct gcc_options *opts_set,
1807 		      const struct cl_decoded_option *decoded,
1808 		      unsigned int lang_mask, int kind ATTRIBUTE_UNUSED,
1809 		      location_t loc,
1810 		      const struct cl_option_handlers *handlers,
1811 		      diagnostic_context *dc,
1812 		      void (*target_option_override_hook) (void))
1813 {
1814   size_t scode = decoded->opt_index;
1815   const char *arg = decoded->arg;
1816   int value = decoded->value;
1817   enum opt_code code = (enum opt_code) scode;
1818 
1819   gcc_assert (decoded->canonical_option_num_elements <= 2);
1820 
1821   switch (code)
1822     {
1823     case OPT__param:
1824       handle_param (opts, opts_set, loc, arg);
1825       break;
1826 
1827     case OPT__help:
1828       {
1829 	unsigned int all_langs_mask = (1U << cl_lang_count) - 1;
1830 	unsigned int undoc_mask;
1831 	unsigned int i;
1832 
1833 	if (lang_mask == CL_DRIVER)
1834 	  break;
1835 
1836 	undoc_mask = ((opts->x_verbose_flag | opts->x_extra_warnings)
1837 		      ? 0
1838 		      : CL_UNDOCUMENTED);
1839 	target_option_override_hook ();
1840 	/* First display any single language specific options.  */
1841 	for (i = 0; i < cl_lang_count; i++)
1842 	  print_specific_help
1843 	    (1U << i, (all_langs_mask & (~ (1U << i))) | undoc_mask, 0, opts,
1844 	     lang_mask);
1845 	/* Next display any multi language specific options.  */
1846 	print_specific_help (0, undoc_mask, all_langs_mask, opts, lang_mask);
1847 	/* Then display any remaining, non-language options.  */
1848 	for (i = CL_MIN_OPTION_CLASS; i <= CL_MAX_OPTION_CLASS; i <<= 1)
1849 	  if (i != CL_DRIVER)
1850 	    print_specific_help (i, undoc_mask, 0, opts, lang_mask);
1851 	opts->x_exit_after_options = true;
1852 	break;
1853       }
1854 
1855     case OPT__target_help:
1856       if (lang_mask == CL_DRIVER)
1857 	break;
1858 
1859       target_option_override_hook ();
1860       print_specific_help (CL_TARGET, CL_UNDOCUMENTED, 0, opts, lang_mask);
1861       opts->x_exit_after_options = true;
1862       break;
1863 
1864     case OPT__help_:
1865       {
1866 	const char *a = arg;
1867 	unsigned int include_flags = 0;
1868 	/* Note - by default we include undocumented options when listing
1869 	   specific classes.  If you only want to see documented options
1870 	   then add ",^undocumented" to the --help= option.  E.g.:
1871 
1872 	   --help=target,^undocumented  */
1873 	unsigned int exclude_flags = 0;
1874 
1875 	if (lang_mask == CL_DRIVER)
1876 	  break;
1877 
1878 	/* Walk along the argument string, parsing each word in turn.
1879 	   The format is:
1880 	   arg = [^]{word}[,{arg}]
1881 	   word = {optimizers|target|warnings|undocumented|
1882 		   params|common|<language>}  */
1883 	while (*a != 0)
1884 	  {
1885 	    static const struct
1886 	    {
1887 	      const char *string;
1888 	      unsigned int flag;
1889 	    }
1890 	    specifics[] =
1891 	    {
1892 	      { "optimizers", CL_OPTIMIZATION },
1893 	      { "target", CL_TARGET },
1894 	      { "warnings", CL_WARNING },
1895 	      { "undocumented", CL_UNDOCUMENTED },
1896 	      { "params", CL_PARAMS },
1897 	      { "joined", CL_JOINED },
1898 	      { "separate", CL_SEPARATE },
1899 	      { "common", CL_COMMON },
1900 	      { NULL, 0 }
1901 	    };
1902 	    unsigned int *pflags;
1903 	    const char *comma;
1904 	    unsigned int lang_flag, specific_flag;
1905 	    unsigned int len;
1906 	    unsigned int i;
1907 
1908 	    if (*a == '^')
1909 	      {
1910 		++a;
1911 		if (*a == '\0')
1912 		  {
1913 		    error_at (loc, "missing argument to %qs", "--help=^");
1914 		    break;
1915 		  }
1916 		pflags = &exclude_flags;
1917 	      }
1918 	    else
1919 	      pflags = &include_flags;
1920 
1921 	    comma = strchr (a, ',');
1922 	    if (comma == NULL)
1923 	      len = strlen (a);
1924 	    else
1925 	      len = comma - a;
1926 	    if (len == 0)
1927 	      {
1928 		a = comma + 1;
1929 		continue;
1930 	      }
1931 
1932 	    /* Check to see if the string matches an option class name.  */
1933 	    for (i = 0, specific_flag = 0; specifics[i].string != NULL; i++)
1934 	      if (strncasecmp (a, specifics[i].string, len) == 0)
1935 		{
1936 		  specific_flag = specifics[i].flag;
1937 		  break;
1938 		}
1939 
1940 	    /* Check to see if the string matches a language name.
1941 	       Note - we rely upon the alpha-sorted nature of the entries in
1942 	       the lang_names array, specifically that shorter names appear
1943 	       before their longer variants.  (i.e. C before C++).  That way
1944 	       when we are attempting to match --help=c for example we will
1945 	       match with C first and not C++.  */
1946 	    for (i = 0, lang_flag = 0; i < cl_lang_count; i++)
1947 	      if (strncasecmp (a, lang_names[i], len) == 0)
1948 		{
1949 		  lang_flag = 1U << i;
1950 		  break;
1951 		}
1952 
1953 	    if (specific_flag != 0)
1954 	      {
1955 		if (lang_flag == 0)
1956 		  *pflags |= specific_flag;
1957 		else
1958 		  {
1959 		    /* The option's argument matches both the start of a
1960 		       language name and the start of an option class name.
1961 		       We have a special case for when the user has
1962 		       specified "--help=c", but otherwise we have to issue
1963 		       a warning.  */
1964 		    if (strncasecmp (a, "c", len) == 0)
1965 		      *pflags |= lang_flag;
1966 		    else
1967 		      warning_at (loc, 0,
1968 				  "--help argument %q.*s is ambiguous, "
1969 				  "please be more specific",
1970 				  len, a);
1971 		  }
1972 	      }
1973 	    else if (lang_flag != 0)
1974 	      *pflags |= lang_flag;
1975 	    else
1976 	      warning_at (loc, 0,
1977 			  "unrecognized argument to --help= option: %q.*s",
1978 			  len, a);
1979 
1980 	    if (comma == NULL)
1981 	      break;
1982 	    a = comma + 1;
1983 	  }
1984 
1985 	if (include_flags)
1986 	  {
1987 	    target_option_override_hook ();
1988 	    print_specific_help (include_flags, exclude_flags, 0, opts,
1989 				 lang_mask);
1990 	  }
1991 	opts->x_exit_after_options = true;
1992 	break;
1993       }
1994 
1995     case OPT__version:
1996       if (lang_mask == CL_DRIVER)
1997 	break;
1998 
1999       opts->x_exit_after_options = true;
2000       break;
2001 
2002     case OPT_fsanitize_:
2003       opts->x_flag_sanitize
2004 	= parse_sanitizer_options (arg, loc, code,
2005 				   opts->x_flag_sanitize, value, true);
2006 
2007       /* Kernel ASan implies normal ASan but does not yet support
2008 	 all features.  */
2009       if (opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS)
2010 	{
2011 	  maybe_set_param_value (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD,
2012 				 0, opts->x_param_values,
2013 				 opts_set->x_param_values);
2014 	  maybe_set_param_value (PARAM_ASAN_GLOBALS, 0, opts->x_param_values,
2015 				 opts_set->x_param_values);
2016 	  maybe_set_param_value (PARAM_ASAN_STACK, 0, opts->x_param_values,
2017 				 opts_set->x_param_values);
2018 	  maybe_set_param_value (PARAM_ASAN_PROTECT_ALLOCAS, 0,
2019 				 opts->x_param_values,
2020 				 opts_set->x_param_values);
2021 	  maybe_set_param_value (PARAM_ASAN_USE_AFTER_RETURN, 0,
2022 				 opts->x_param_values,
2023 				 opts_set->x_param_values);
2024 	}
2025       break;
2026 
2027     case OPT_fsanitize_recover_:
2028       opts->x_flag_sanitize_recover
2029 	= parse_sanitizer_options (arg, loc, code,
2030 				   opts->x_flag_sanitize_recover, value, true);
2031       break;
2032 
2033     case OPT_fasan_shadow_offset_:
2034       /* Deferred.  */
2035       break;
2036 
2037     case OPT_fsanitize_address_use_after_scope:
2038       opts->x_flag_sanitize_address_use_after_scope = value;
2039       break;
2040 
2041     case OPT_fsanitize_recover:
2042       if (value)
2043 	opts->x_flag_sanitize_recover
2044 	  |= (SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT)
2045 	     & ~(SANITIZE_UNREACHABLE | SANITIZE_RETURN);
2046       else
2047 	opts->x_flag_sanitize_recover
2048 	  &= ~(SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT);
2049       break;
2050 
2051     case OPT_fsanitize_coverage_:
2052       opts->x_flag_sanitize_coverage
2053 	= parse_sanitizer_options (arg, loc, code,
2054 				   opts->x_flag_sanitize_coverage, value, true);
2055       break;
2056 
2057     case OPT_O:
2058     case OPT_Os:
2059     case OPT_Ofast:
2060     case OPT_Og:
2061       /* Currently handled in a prescan.  */
2062       break;
2063 
2064     case OPT_Werror:
2065       dc->warning_as_error_requested = value;
2066       break;
2067 
2068     case OPT_Werror_:
2069       if (lang_mask == CL_DRIVER)
2070 	break;
2071 
2072       enable_warning_as_error (arg, value, lang_mask, handlers,
2073 			       opts, opts_set, loc, dc);
2074       break;
2075 
2076     case OPT_Wlarger_than_:
2077       opts->x_larger_than_size = value;
2078       opts->x_warn_larger_than = value != -1;
2079       break;
2080 
2081     case OPT_Wfatal_errors:
2082       dc->fatal_errors = value;
2083       break;
2084 
2085     case OPT_Wframe_larger_than_:
2086       opts->x_frame_larger_than_size = value;
2087       opts->x_warn_frame_larger_than = value != -1;
2088       break;
2089 
2090     case OPT_Wstack_usage_:
2091       opts->x_warn_stack_usage = value;
2092       opts->x_flag_stack_usage_info = value != -1;
2093       break;
2094 
2095     case OPT_Wstrict_aliasing:
2096       set_Wstrict_aliasing (opts, value);
2097       break;
2098 
2099     case OPT_Wstrict_overflow:
2100       opts->x_warn_strict_overflow = (value
2101 				      ? (int) WARN_STRICT_OVERFLOW_CONDITIONAL
2102 				      : 0);
2103       break;
2104 
2105     case OPT_Wsystem_headers:
2106       dc->dc_warn_system_headers = value;
2107       break;
2108 
2109     case OPT_aux_info:
2110       opts->x_flag_gen_aux_info = 1;
2111       break;
2112 
2113     case OPT_auxbase_strip:
2114       {
2115 	char *tmp = xstrdup (arg);
2116 	strip_off_ending (tmp, strlen (tmp));
2117 	if (tmp[0])
2118 	  opts->x_aux_base_name = tmp;
2119 	else
2120 	  free (tmp);
2121       }
2122       break;
2123 
2124     case OPT_d:
2125       decode_d_option (arg, opts, loc, dc);
2126       break;
2127 
2128     case OPT_fcall_used_:
2129     case OPT_fcall_saved_:
2130       /* Deferred.  */
2131       break;
2132 
2133     case OPT_fdbg_cnt_:
2134       /* Deferred.  */
2135       break;
2136 
2137     case OPT_fdbg_cnt_list:
2138       /* Deferred.  */
2139       opts->x_exit_after_options = true;
2140       break;
2141 
2142     case OPT_fdebug_prefix_map_:
2143     case OPT_ffile_prefix_map_:
2144       /* Deferred.  */
2145       break;
2146 
2147     case OPT_fdiagnostics_show_location_:
2148       diagnostic_prefixing_rule (dc) = (diagnostic_prefixing_rule_t) value;
2149       break;
2150 
2151     case OPT_fdiagnostics_show_caret:
2152       dc->show_caret = value;
2153       break;
2154 
2155     case OPT_fdiagnostics_color_:
2156       diagnostic_color_init (dc, value);
2157       break;
2158 
2159     case OPT_fdiagnostics_parseable_fixits:
2160       dc->parseable_fixits_p = value;
2161       break;
2162 
2163     case OPT_fdiagnostics_show_option:
2164       dc->show_option_requested = value;
2165       break;
2166 
2167     case OPT_fdump_:
2168       /* Deferred.  */
2169       break;
2170 
2171     case OPT_ffast_math:
2172       set_fast_math_flags (opts, value);
2173       break;
2174 
2175     case OPT_funsafe_math_optimizations:
2176       set_unsafe_math_optimizations_flags (opts, value);
2177       break;
2178 
2179     case OPT_ffixed_:
2180       /* Deferred.  */
2181       break;
2182 
2183     case OPT_finline_limit_:
2184       set_param_value ("max-inline-insns-single", value / 2,
2185 		       opts->x_param_values, opts_set->x_param_values);
2186       set_param_value ("max-inline-insns-auto", value / 2,
2187 		       opts->x_param_values, opts_set->x_param_values);
2188       break;
2189 
2190     case OPT_finstrument_functions_exclude_function_list_:
2191       add_comma_separated_to_vector
2192 	(&opts->x_flag_instrument_functions_exclude_functions, arg);
2193       break;
2194 
2195     case OPT_finstrument_functions_exclude_file_list_:
2196       add_comma_separated_to_vector
2197 	(&opts->x_flag_instrument_functions_exclude_files, arg);
2198       break;
2199 
2200     case OPT_fmessage_length_:
2201       pp_set_line_maximum_length (dc->printer, value);
2202       diagnostic_set_caret_max_width (dc, value);
2203       break;
2204 
2205     case OPT_fopt_info:
2206     case OPT_fopt_info_:
2207       /* Deferred.  */
2208       break;
2209 
2210     case OPT_foffload_:
2211       {
2212 	const char *p = arg;
2213 	opts->x_flag_disable_hsa = true;
2214 	while (*p != 0)
2215 	  {
2216 	    const char *comma = strchr (p, ',');
2217 
2218 	    if ((strncmp (p, "disable", 7) == 0)
2219 		&& (p[7] == ',' || p[7] == '\0'))
2220 	      {
2221 		opts->x_flag_disable_hsa = true;
2222 		break;
2223 	      }
2224 
2225 	    if ((strncmp (p, "hsa", 3) == 0)
2226 		&& (p[3] == ',' || p[3] == '\0'))
2227 	      {
2228 #ifdef ENABLE_HSA
2229 		opts->x_flag_disable_hsa = false;
2230 #else
2231 		sorry ("HSA has not been enabled during configuration");
2232 #endif
2233 	      }
2234 	    if (!comma)
2235 	      break;
2236 	    p = comma + 1;
2237 	  }
2238 	break;
2239       }
2240 
2241 #ifndef ACCEL_COMPILER
2242     case OPT_foffload_abi_:
2243       error_at (loc, "%<-foffload-abi%> option can be specified only for "
2244 		"offload compiler");
2245       break;
2246 #endif
2247 
2248     case OPT_fpack_struct_:
2249       if (value <= 0 || (value & (value - 1)) || value > 16)
2250 	error_at (loc,
2251 		  "structure alignment must be a small power of two, not %d",
2252 		  value);
2253       else
2254 	opts->x_initial_max_fld_align = value;
2255       break;
2256 
2257     case OPT_fplugin_:
2258     case OPT_fplugin_arg_:
2259       /* Deferred.  */
2260       break;
2261 
2262     case OPT_fprofile_use_:
2263       opts->x_profile_data_prefix = xstrdup (arg);
2264       opts->x_flag_profile_use = true;
2265       value = true;
2266       /* No break here - do -fprofile-use processing. */
2267       /* FALLTHRU */
2268     case OPT_fprofile_use:
2269       enable_fdo_optimizations (opts, opts_set, value);
2270       if (!opts_set->x_flag_profile_reorder_functions)
2271 	  opts->x_flag_profile_reorder_functions = value;
2272 	/* Indirect call profiling should do all useful transformations
2273 	   speculative devirtualization does.  */
2274       if (!opts_set->x_flag_devirtualize_speculatively
2275 	  && opts->x_flag_value_profile_transformations)
2276 	opts->x_flag_devirtualize_speculatively = false;
2277       break;
2278 
2279     case OPT_fauto_profile_:
2280       opts->x_auto_profile_file = xstrdup (arg);
2281       opts->x_flag_auto_profile = true;
2282       value = true;
2283       /* No break here - do -fauto-profile processing. */
2284       /* FALLTHRU */
2285     case OPT_fauto_profile:
2286       enable_fdo_optimizations (opts, opts_set, value);
2287       if (!opts_set->x_flag_profile_correction)
2288 	opts->x_flag_profile_correction = value;
2289       maybe_set_param_value (
2290 	PARAM_EARLY_INLINER_MAX_ITERATIONS, 10,
2291 	opts->x_param_values, opts_set->x_param_values);
2292       break;
2293 
2294     case OPT_fprofile_generate_:
2295       opts->x_profile_data_prefix = xstrdup (arg);
2296       value = true;
2297       /* No break here - do -fprofile-generate processing. */
2298       /* FALLTHRU */
2299     case OPT_fprofile_generate:
2300       if (!opts_set->x_profile_arc_flag)
2301 	opts->x_profile_arc_flag = value;
2302       if (!opts_set->x_flag_profile_values)
2303 	opts->x_flag_profile_values = value;
2304       if (!opts_set->x_flag_inline_functions)
2305 	opts->x_flag_inline_functions = value;
2306       if (!opts_set->x_flag_ipa_bit_cp)
2307 	opts->x_flag_ipa_bit_cp = value;
2308       /* FIXME: Instrumentation we insert makes ipa-reference bitmaps
2309 	 quadratic.  Disable the pass until better memory representation
2310 	 is done.  */
2311       if (!opts_set->x_flag_ipa_reference)
2312         opts->x_flag_ipa_reference = false;
2313       break;
2314 
2315     case OPT_fpatchable_function_entry_:
2316       {
2317 	char *patch_area_arg = xstrdup (arg);
2318 	char *comma = strchr (patch_area_arg, ',');
2319 	if (comma)
2320 	  {
2321 	    *comma = '\0';
2322 	    function_entry_patch_area_size =
2323 	      integral_argument (patch_area_arg);
2324 	    function_entry_patch_area_start =
2325 	      integral_argument (comma + 1);
2326 	  }
2327 	else
2328 	  {
2329 	    function_entry_patch_area_size =
2330 	      integral_argument (patch_area_arg);
2331 	    function_entry_patch_area_start = 0;
2332 	  }
2333 	if (function_entry_patch_area_size < 0
2334 	    || function_entry_patch_area_start < 0
2335 	    || function_entry_patch_area_size
2336 		< function_entry_patch_area_start)
2337 	  error ("invalid arguments for %<-fpatchable_function_entry%>");
2338 	free (patch_area_arg);
2339       }
2340       break;
2341 
2342     case OPT_ftree_vectorize:
2343       /* Automatically sets -ftree-loop-vectorize and
2344 	 -ftree-slp-vectorize.  Nothing more to do here.  */
2345       break;
2346     case OPT_fshow_column:
2347       dc->show_column = value;
2348       break;
2349 
2350     case OPT_frandom_seed:
2351       /* The real switch is -fno-random-seed.  */
2352       if (value)
2353 	return false;
2354       /* Deferred.  */
2355       break;
2356 
2357     case OPT_frandom_seed_:
2358       /* Deferred.  */
2359       break;
2360 
2361     case OPT_fsched_verbose_:
2362 #ifdef INSN_SCHEDULING
2363       /* Handled with Var in common.opt.  */
2364       break;
2365 #else
2366       return false;
2367 #endif
2368 
2369     case OPT_fsched_stalled_insns_:
2370       opts->x_flag_sched_stalled_insns = value;
2371       if (opts->x_flag_sched_stalled_insns == 0)
2372 	opts->x_flag_sched_stalled_insns = -1;
2373       break;
2374 
2375     case OPT_fsched_stalled_insns_dep_:
2376       opts->x_flag_sched_stalled_insns_dep = value;
2377       break;
2378 
2379     case OPT_fstack_check_:
2380       if (!strcmp (arg, "no"))
2381 	opts->x_flag_stack_check = NO_STACK_CHECK;
2382       else if (!strcmp (arg, "generic"))
2383 	/* This is the old stack checking method.  */
2384 	opts->x_flag_stack_check = STACK_CHECK_BUILTIN
2385 			   ? FULL_BUILTIN_STACK_CHECK
2386 			   : GENERIC_STACK_CHECK;
2387       else if (!strcmp (arg, "specific"))
2388 	/* This is the new stack checking method.  */
2389 	opts->x_flag_stack_check = STACK_CHECK_BUILTIN
2390 			   ? FULL_BUILTIN_STACK_CHECK
2391 			   : STACK_CHECK_STATIC_BUILTIN
2392 			     ? STATIC_BUILTIN_STACK_CHECK
2393 			     : GENERIC_STACK_CHECK;
2394       else
2395 	warning_at (loc, 0, "unknown stack check parameter %qs", arg);
2396       break;
2397 
2398     case OPT_fstack_limit:
2399       /* The real switch is -fno-stack-limit.  */
2400       if (value)
2401 	return false;
2402       /* Deferred.  */
2403       break;
2404 
2405     case OPT_fstack_limit_register_:
2406     case OPT_fstack_limit_symbol_:
2407       /* Deferred.  */
2408       break;
2409 
2410     case OPT_fstack_usage:
2411       opts->x_flag_stack_usage = value;
2412       opts->x_flag_stack_usage_info = value != 0;
2413       break;
2414 
2415     case OPT_g:
2416       set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, arg, opts, opts_set,
2417                        loc);
2418       break;
2419 
2420     case OPT_gdwarf:
2421       if (arg && strlen (arg) != 0)
2422         {
2423           error_at (loc, "%<-gdwarf%s%> is ambiguous; "
2424                     "use %<-gdwarf-%s%> for DWARF version "
2425                     "or %<-gdwarf -g%s%> for debug level", arg, arg, arg);
2426           break;
2427         }
2428       else
2429         value = opts->x_dwarf_version;
2430 
2431       /* FALLTHRU */
2432     case OPT_gdwarf_:
2433       if (value < 2 || value > 5)
2434 	error_at (loc, "dwarf version %d is not supported", value);
2435       else
2436 	opts->x_dwarf_version = value;
2437       set_debug_level (DWARF2_DEBUG, false, "", opts, opts_set, loc);
2438       break;
2439 
2440     case OPT_gsplit_dwarf:
2441       set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, "", opts, opts_set,
2442 		       loc);
2443       break;
2444 
2445     case OPT_ggdb:
2446       set_debug_level (NO_DEBUG, 2, arg, opts, opts_set, loc);
2447       break;
2448 
2449     case OPT_gstabs:
2450     case OPT_gstabs_:
2451       set_debug_level (DBX_DEBUG, code == OPT_gstabs_, arg, opts, opts_set,
2452 		       loc);
2453       break;
2454 
2455     case OPT_gvms:
2456       set_debug_level (VMS_DEBUG, false, arg, opts, opts_set, loc);
2457       break;
2458 
2459     case OPT_gxcoff:
2460     case OPT_gxcoff_:
2461       set_debug_level (XCOFF_DEBUG, code == OPT_gxcoff_, arg, opts, opts_set,
2462 		       loc);
2463       break;
2464 
2465     case OPT_gz:
2466     case OPT_gz_:
2467       /* Handled completely via specs.  */
2468       break;
2469 
2470     case OPT_pedantic_errors:
2471       dc->pedantic_errors = 1;
2472       control_warning_option (OPT_Wpedantic, DK_ERROR, NULL, value,
2473 			      loc, lang_mask,
2474 			      handlers, opts, opts_set,
2475                               dc);
2476       break;
2477 
2478     case OPT_flto:
2479       opts->x_flag_lto = value ? "" : NULL;
2480       break;
2481 
2482     case OPT_w:
2483       dc->dc_inhibit_warnings = true;
2484       break;
2485 
2486     case OPT_fmax_errors_:
2487       dc->max_errors = value;
2488       break;
2489 
2490     case OPT_fuse_ld_bfd:
2491     case OPT_fuse_ld_gold:
2492     case OPT_fuse_ld_lld:
2493     case OPT_fuse_linker_plugin:
2494       /* No-op. Used by the driver and passed to us because it starts with f.*/
2495       break;
2496 
2497     case OPT_fwrapv:
2498       if (value)
2499 	opts->x_flag_trapv = 0;
2500       break;
2501 
2502     case OPT_ftrapv:
2503       if (value)
2504 	opts->x_flag_wrapv = 0;
2505       break;
2506 
2507     case OPT_fstrict_overflow:
2508       opts->x_flag_wrapv = !value;
2509       opts->x_flag_wrapv_pointer = !value;
2510       if (!value)
2511 	opts->x_flag_trapv = 0;
2512       break;
2513 
2514     case OPT_fipa_icf:
2515       opts->x_flag_ipa_icf_functions = value;
2516       opts->x_flag_ipa_icf_variables = value;
2517       break;
2518 
2519     default:
2520       /* If the flag was handled in a standard way, assume the lack of
2521 	 processing here is intentional.  */
2522       gcc_assert (option_flag_var (scode, opts));
2523       break;
2524     }
2525 
2526   common_handle_option_auto (opts, opts_set, decoded, lang_mask, kind,
2527                              loc, handlers, dc);
2528   return true;
2529 }
2530 
2531 /* Handle --param NAME=VALUE.  */
2532 static void
2533 handle_param (struct gcc_options *opts, struct gcc_options *opts_set,
2534 	      location_t loc, const char *carg)
2535 {
2536   char *equal, *arg;
2537   int value;
2538 
2539   arg = xstrdup (carg);
2540   equal = strchr (arg, '=');
2541   if (!equal)
2542     error_at (loc, "%s: --param arguments should be of the form NAME=VALUE",
2543 	      arg);
2544   else
2545     {
2546       *equal = '\0';
2547 
2548       enum compiler_param index;
2549       if (!find_param (arg, &index))
2550 	{
2551 	  const char *suggestion = find_param_fuzzy (arg);
2552 	  if (suggestion)
2553 	    error_at (loc, "invalid --param name %qs; did you mean %qs?",
2554 		      arg, suggestion);
2555 	  else
2556 	    error_at (loc, "invalid --param name %qs", arg);
2557 	}
2558       else
2559 	{
2560 	  if (!param_string_value_p (index, equal + 1, &value))
2561 	    value = integral_argument (equal + 1);
2562 
2563 	  if (value == -1)
2564 	    error_at (loc, "invalid --param value %qs", equal + 1);
2565 	  else
2566 	    set_param_value (arg, value,
2567 			     opts->x_param_values, opts_set->x_param_values);
2568 	}
2569     }
2570 
2571   free (arg);
2572 }
2573 
2574 /* Used to set the level of strict aliasing warnings in OPTS,
2575    when no level is specified (i.e., when -Wstrict-aliasing, and not
2576    -Wstrict-aliasing=level was given).
2577    ONOFF is assumed to take value 1 when -Wstrict-aliasing is specified,
2578    and 0 otherwise.  After calling this function, wstrict_aliasing will be
2579    set to the default value of -Wstrict_aliasing=level, currently 3.  */
2580 static void
2581 set_Wstrict_aliasing (struct gcc_options *opts, int onoff)
2582 {
2583   gcc_assert (onoff == 0 || onoff == 1);
2584   if (onoff != 0)
2585     opts->x_warn_strict_aliasing = 3;
2586   else
2587     opts->x_warn_strict_aliasing = 0;
2588 }
2589 
2590 /* The following routines are useful in setting all the flags that
2591    -ffast-math and -fno-fast-math imply.  */
2592 static void
2593 set_fast_math_flags (struct gcc_options *opts, int set)
2594 {
2595   if (!opts->frontend_set_flag_unsafe_math_optimizations)
2596     {
2597       opts->x_flag_unsafe_math_optimizations = set;
2598       set_unsafe_math_optimizations_flags (opts, set);
2599     }
2600   if (!opts->frontend_set_flag_finite_math_only)
2601     opts->x_flag_finite_math_only = set;
2602   if (!opts->frontend_set_flag_errno_math)
2603     opts->x_flag_errno_math = !set;
2604   if (set)
2605     {
2606       if (opts->frontend_set_flag_excess_precision_cmdline
2607 	  == EXCESS_PRECISION_DEFAULT)
2608 	opts->x_flag_excess_precision_cmdline
2609 	  = set ? EXCESS_PRECISION_FAST : EXCESS_PRECISION_DEFAULT;
2610       if (!opts->frontend_set_flag_signaling_nans)
2611 	opts->x_flag_signaling_nans = 0;
2612       if (!opts->frontend_set_flag_rounding_math)
2613 	opts->x_flag_rounding_math = 0;
2614       if (!opts->frontend_set_flag_cx_limited_range)
2615 	opts->x_flag_cx_limited_range = 1;
2616     }
2617 }
2618 
2619 /* When -funsafe-math-optimizations is set the following
2620    flags are set as well.  */
2621 static void
2622 set_unsafe_math_optimizations_flags (struct gcc_options *opts, int set)
2623 {
2624   if (!opts->frontend_set_flag_trapping_math)
2625     opts->x_flag_trapping_math = !set;
2626   if (!opts->frontend_set_flag_signed_zeros)
2627     opts->x_flag_signed_zeros = !set;
2628   if (!opts->frontend_set_flag_associative_math)
2629     opts->x_flag_associative_math = set;
2630   if (!opts->frontend_set_flag_reciprocal_math)
2631     opts->x_flag_reciprocal_math = set;
2632 }
2633 
2634 /* Return true iff flags in OPTS are set as if -ffast-math.  */
2635 bool
2636 fast_math_flags_set_p (const struct gcc_options *opts)
2637 {
2638   return (!opts->x_flag_trapping_math
2639 	  && opts->x_flag_unsafe_math_optimizations
2640 	  && opts->x_flag_finite_math_only
2641 	  && !opts->x_flag_signed_zeros
2642 	  && !opts->x_flag_errno_math
2643 	  && opts->x_flag_excess_precision_cmdline
2644 	     == EXCESS_PRECISION_FAST);
2645 }
2646 
2647 /* Return true iff flags are set as if -ffast-math but using the flags stored
2648    in the struct cl_optimization structure.  */
2649 bool
2650 fast_math_flags_struct_set_p (struct cl_optimization *opt)
2651 {
2652   return (!opt->x_flag_trapping_math
2653 	  && opt->x_flag_unsafe_math_optimizations
2654 	  && opt->x_flag_finite_math_only
2655 	  && !opt->x_flag_signed_zeros
2656 	  && !opt->x_flag_errno_math);
2657 }
2658 
2659 /* Handle a debug output -g switch for options OPTS
2660    (OPTS_SET->x_write_symbols storing whether a debug type was passed
2661    explicitly), location LOC.  EXTENDED is true or false to support
2662    extended output (2 is special and means "-ggdb" was given).  */
2663 static void
2664 set_debug_level (enum debug_info_type type, int extended, const char *arg,
2665 		 struct gcc_options *opts, struct gcc_options *opts_set,
2666 		 location_t loc)
2667 {
2668   opts->x_use_gnu_debug_info_extensions = extended;
2669 
2670   if (type == NO_DEBUG)
2671     {
2672       if (opts->x_write_symbols == NO_DEBUG)
2673 	{
2674 	  opts->x_write_symbols = PREFERRED_DEBUGGING_TYPE;
2675 
2676 	  if (extended == 2)
2677 	    {
2678 #if defined DWARF2_DEBUGGING_INFO || defined DWARF2_LINENO_DEBUGGING_INFO
2679 	      opts->x_write_symbols = DWARF2_DEBUG;
2680 #elif defined DBX_DEBUGGING_INFO
2681 	      opts->x_write_symbols = DBX_DEBUG;
2682 #endif
2683 	    }
2684 
2685 	  if (opts->x_write_symbols == NO_DEBUG)
2686 	    warning_at (loc, 0, "target system does not support debug output");
2687 	}
2688     }
2689   else
2690     {
2691       /* Does it conflict with an already selected type?  */
2692       if (opts_set->x_write_symbols != NO_DEBUG
2693 	  && opts->x_write_symbols != NO_DEBUG
2694 	  && type != opts->x_write_symbols)
2695 	error_at (loc, "debug format %qs conflicts with prior selection",
2696 		  debug_type_names[type]);
2697       opts->x_write_symbols = type;
2698       opts_set->x_write_symbols = type;
2699     }
2700 
2701   /* A debug flag without a level defaults to level 2.
2702      If off or at level 1, set it to level 2, but if already
2703      at level 3, don't lower it.  */
2704   if (*arg == '\0')
2705     {
2706       if (opts->x_debug_info_level < DINFO_LEVEL_NORMAL)
2707 	opts->x_debug_info_level = DINFO_LEVEL_NORMAL;
2708     }
2709   else
2710     {
2711       int argval = integral_argument (arg);
2712       if (argval == -1)
2713 	error_at (loc, "unrecognized debug output level %qs", arg);
2714       else if (argval > 3)
2715 	error_at (loc, "debug output level %qs is too high", arg);
2716       else
2717 	opts->x_debug_info_level = (enum debug_info_levels) argval;
2718     }
2719 }
2720 
2721 /* Arrange to dump core on error for diagnostic context DC.  (The
2722    regular error message is still printed first, except in the case of
2723    abort ().)  */
2724 
2725 static void
2726 setup_core_dumping (diagnostic_context *dc)
2727 {
2728 #ifdef SIGABRT
2729   signal (SIGABRT, SIG_DFL);
2730 #endif
2731 #if defined(HAVE_SETRLIMIT)
2732   {
2733     struct rlimit rlim;
2734     if (getrlimit (RLIMIT_CORE, &rlim) != 0)
2735       fatal_error (input_location, "getting core file size maximum limit: %m");
2736     rlim.rlim_cur = rlim.rlim_max;
2737     if (setrlimit (RLIMIT_CORE, &rlim) != 0)
2738       fatal_error (input_location,
2739 		   "setting core file size limit to maximum: %m");
2740   }
2741 #endif
2742   diagnostic_abort_on_error (dc);
2743 }
2744 
2745 /* Parse a -d<ARG> command line switch for OPTS, location LOC,
2746    diagnostic context DC.  */
2747 
2748 static void
2749 decode_d_option (const char *arg, struct gcc_options *opts,
2750 		 location_t loc, diagnostic_context *dc)
2751 {
2752   int c;
2753 
2754   while (*arg)
2755     switch (c = *arg++)
2756       {
2757       case 'A':
2758 	opts->x_flag_debug_asm = 1;
2759 	break;
2760       case 'p':
2761 	opts->x_flag_print_asm_name = 1;
2762 	break;
2763       case 'P':
2764 	opts->x_flag_dump_rtl_in_asm = 1;
2765 	opts->x_flag_print_asm_name = 1;
2766 	break;
2767       case 'x':
2768 	opts->x_rtl_dump_and_exit = 1;
2769 	break;
2770       case 'D':	/* These are handled by the preprocessor.  */
2771       case 'I':
2772       case 'M':
2773       case 'N':
2774       case 'U':
2775 	break;
2776       case 'H':
2777 	setup_core_dumping (dc);
2778 	break;
2779       case 'a':
2780 	opts->x_flag_dump_all_passed = true;
2781 	break;
2782 
2783       default:
2784 	  warning_at (loc, 0, "unrecognized gcc debugging option: %c", c);
2785 	break;
2786       }
2787 }
2788 
2789 /* Enable (or disable if VALUE is 0) a warning option ARG (language
2790    mask LANG_MASK, option handlers HANDLERS) as an error for option
2791    structures OPTS and OPTS_SET, diagnostic context DC (possibly
2792    NULL), location LOC.  This is used by -Werror=.  */
2793 
2794 static void
2795 enable_warning_as_error (const char *arg, int value, unsigned int lang_mask,
2796 			 const struct cl_option_handlers *handlers,
2797 			 struct gcc_options *opts,
2798 			 struct gcc_options *opts_set,
2799 			 location_t loc, diagnostic_context *dc)
2800 {
2801   char *new_option;
2802   int option_index;
2803 
2804   new_option = XNEWVEC (char, strlen (arg) + 2);
2805   new_option[0] = 'W';
2806   strcpy (new_option + 1, arg);
2807   option_index = find_opt (new_option, lang_mask);
2808   if (option_index == OPT_SPECIAL_unknown)
2809     error_at (loc, "-Werror=%s: no option -%s", arg, new_option);
2810   else if (!(cl_options[option_index].flags & CL_WARNING))
2811     error_at (loc, "-Werror=%s: -%s is not an option that controls warnings",
2812 	      arg, new_option);
2813   else
2814     {
2815       const diagnostic_t kind = value ? DK_ERROR : DK_WARNING;
2816       const char *arg = NULL;
2817 
2818       if (cl_options[option_index].flags & CL_JOINED)
2819 	arg = new_option + cl_options[option_index].opt_len;
2820       control_warning_option (option_index, (int) kind, arg, value,
2821 			      loc, lang_mask,
2822 			      handlers, opts, opts_set, dc);
2823     }
2824   free (new_option);
2825 }
2826 
2827 /* Return malloced memory for the name of the option OPTION_INDEX
2828    which enabled a diagnostic (context CONTEXT), originally of type
2829    ORIG_DIAG_KIND but possibly converted to DIAG_KIND by options such
2830    as -Werror.  */
2831 
2832 char *
2833 option_name (diagnostic_context *context, int option_index,
2834 	     diagnostic_t orig_diag_kind, diagnostic_t diag_kind)
2835 {
2836   if (option_index)
2837     {
2838       /* A warning classified as an error.  */
2839       if ((orig_diag_kind == DK_WARNING || orig_diag_kind == DK_PEDWARN)
2840 	  && diag_kind == DK_ERROR)
2841 	return concat (cl_options[OPT_Werror_].opt_text,
2842 		       /* Skip over "-W".  */
2843 		       cl_options[option_index].opt_text + 2,
2844 		       NULL);
2845       /* A warning with option.  */
2846       else
2847 	return xstrdup (cl_options[option_index].opt_text);
2848     }
2849   /* A warning without option classified as an error.  */
2850   else if ((orig_diag_kind == DK_WARNING || orig_diag_kind == DK_PEDWARN
2851 	    || diag_kind == DK_WARNING)
2852 	   && context->warning_as_error_requested)
2853     return xstrdup (cl_options[OPT_Werror].opt_text);
2854   else
2855     return NULL;
2856 }
2857