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