1 /* Command line option handling.
2    Copyright (C) 2002-2021 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 "diagnostic.h"
29 #include "opts-diagnostic.h"
30 #include "insn-attr-common.h"
31 #include "common/common-target.h"
32 #include "spellcheck.h"
33 #include "opt-suggestions.h"
34 #include "diagnostic-color.h"
35 #include "version.h"
36 #include "selftest.h"
37 
38 static void set_Wstrict_aliasing (struct gcc_options *opts, int onoff);
39 
40 /* Indexed by enum debug_info_type.  */
41 const char *const debug_type_names[] =
42 {
43   "none", "stabs", "dwarf-2", "xcoff", "vms"
44 };
45 
46 /* Parse the -femit-struct-debug-detailed option value
47    and set the flag variables. */
48 
49 #define MATCH( prefix, string ) \
50   ((strncmp (prefix, string, sizeof prefix - 1) == 0) \
51    ? ((string += sizeof prefix - 1), 1) : 0)
52 
53 void
set_struct_debug_option(struct gcc_options * opts,location_t loc,const char * spec)54 set_struct_debug_option (struct gcc_options *opts, location_t loc,
55 			 const char *spec)
56 {
57   /* various labels for comparison */
58   static const char dfn_lbl[] = "dfn:", dir_lbl[] = "dir:", ind_lbl[] = "ind:";
59   static const char ord_lbl[] = "ord:", gen_lbl[] = "gen:";
60   static const char none_lbl[] = "none", any_lbl[] = "any";
61   static const char base_lbl[] = "base", sys_lbl[] = "sys";
62 
63   enum debug_struct_file files = DINFO_STRUCT_FILE_ANY;
64   /* Default is to apply to as much as possible. */
65   enum debug_info_usage usage = DINFO_USAGE_NUM_ENUMS;
66   int ord = 1, gen = 1;
67 
68   /* What usage? */
69   if (MATCH (dfn_lbl, spec))
70     usage = DINFO_USAGE_DFN;
71   else if (MATCH (dir_lbl, spec))
72     usage = DINFO_USAGE_DIR_USE;
73   else if (MATCH (ind_lbl, spec))
74     usage = DINFO_USAGE_IND_USE;
75 
76   /* Generics or not? */
77   if (MATCH (ord_lbl, spec))
78     gen = 0;
79   else if (MATCH (gen_lbl, spec))
80     ord = 0;
81 
82   /* What allowable environment? */
83   if (MATCH (none_lbl, spec))
84     files = DINFO_STRUCT_FILE_NONE;
85   else if (MATCH (any_lbl, spec))
86     files = DINFO_STRUCT_FILE_ANY;
87   else if (MATCH (sys_lbl, spec))
88     files = DINFO_STRUCT_FILE_SYS;
89   else if (MATCH (base_lbl, spec))
90     files = DINFO_STRUCT_FILE_BASE;
91   else
92     error_at (loc,
93 	      "argument %qs to %<-femit-struct-debug-detailed%> "
94 	      "not recognized",
95 	      spec);
96 
97   /* Effect the specification. */
98   if (usage == DINFO_USAGE_NUM_ENUMS)
99     {
100       if (ord)
101         {
102           opts->x_debug_struct_ordinary[DINFO_USAGE_DFN] = files;
103           opts->x_debug_struct_ordinary[DINFO_USAGE_DIR_USE] = files;
104           opts->x_debug_struct_ordinary[DINFO_USAGE_IND_USE] = files;
105         }
106       if (gen)
107         {
108           opts->x_debug_struct_generic[DINFO_USAGE_DFN] = files;
109           opts->x_debug_struct_generic[DINFO_USAGE_DIR_USE] = files;
110           opts->x_debug_struct_generic[DINFO_USAGE_IND_USE] = files;
111         }
112     }
113   else
114     {
115       if (ord)
116         opts->x_debug_struct_ordinary[usage] = files;
117       if (gen)
118         opts->x_debug_struct_generic[usage] = files;
119     }
120 
121   if (*spec == ',')
122     set_struct_debug_option (opts, loc, spec+1);
123   else
124     {
125       /* No more -femit-struct-debug-detailed specifications.
126          Do final checks. */
127       if (*spec != '\0')
128 	error_at (loc,
129 		  "argument %qs to %<-femit-struct-debug-detailed%> unknown",
130 		  spec);
131       if (opts->x_debug_struct_ordinary[DINFO_USAGE_DIR_USE]
132 		< opts->x_debug_struct_ordinary[DINFO_USAGE_IND_USE]
133 	  || opts->x_debug_struct_generic[DINFO_USAGE_DIR_USE]
134 		< opts->x_debug_struct_generic[DINFO_USAGE_IND_USE])
135 	error_at (loc,
136 		  "%<-femit-struct-debug-detailed=dir:...%> must allow "
137 		  "at least as much as "
138 		  "%<-femit-struct-debug-detailed=ind:...%>");
139     }
140 }
141 
142 /* Strip off a legitimate source ending from the input string NAME of
143    length LEN.  Rather than having to know the names used by all of
144    our front ends, we strip off an ending of a period followed by
145    up to fource characters.  (C++ uses ".cpp".)  */
146 
147 void
strip_off_ending(char * name,int len)148 strip_off_ending (char *name, int len)
149 {
150   int i;
151   for (i = 2; i < 5 && len > i; i++)
152     {
153       if (name[len - i] == '.')
154 	{
155 	  name[len - i] = '\0';
156 	  break;
157 	}
158     }
159 }
160 
161 /* Find the base name of a path, stripping off both directories and
162    a single final extension. */
163 int
base_of_path(const char * path,const char ** base_out)164 base_of_path (const char *path, const char **base_out)
165 {
166   const char *base = path;
167   const char *dot = 0;
168   const char *p = path;
169   char c = *p;
170   while (c)
171     {
172       if (IS_DIR_SEPARATOR (c))
173         {
174           base = p + 1;
175           dot = 0;
176         }
177       else if (c == '.')
178         dot = p;
179       c = *++p;
180     }
181   if (!dot)
182     dot = p;
183   *base_out = base;
184   return dot - base;
185 }
186 
187 /* What to print when a switch has no documentation.  */
188 static const char undocumented_msg[] = N_("This option lacks documentation.");
189 static const char use_diagnosed_msg[] = N_("Uses of this option are diagnosed.");
190 
191 typedef char *char_p; /* For DEF_VEC_P.  */
192 
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 
265   *w = '\0';
266   if (*token_start != '\0')
267     v->safe_push (token_start);
268 
269   *pvec = v;
270 }
271 
272 /* Initialize opts_obstack.  */
273 
274 void
init_opts_obstack(void)275 init_opts_obstack (void)
276 {
277   gcc_obstack_init (&opts_obstack);
278 }
279 
280 /* Initialize OPTS and OPTS_SET before using them in parsing options.  */
281 
282 void
init_options_struct(struct gcc_options * opts,struct gcc_options * opts_set)283 init_options_struct (struct gcc_options *opts, struct gcc_options *opts_set)
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   /* Initialize whether `char' is signed.  */
295   opts->x_flag_signed_char = DEFAULT_SIGNED_CHAR;
296   /* Set this to a special "uninitialized" value.  The actual default
297      is set after target options have been processed.  */
298   opts->x_flag_short_enums = 2;
299 
300   /* Initialize target_flags before default_options_optimization
301      so the latter can modify it.  */
302   opts->x_target_flags = targetm_common.default_target_flags;
303 
304   /* Some targets have ABI-specified unwind tables.  */
305   opts->x_flag_unwind_tables = targetm_common.unwind_tables_default;
306 
307   /* Some targets have other target-specific initialization.  */
308   targetm_common.option_init_struct (opts);
309 }
310 
311 /* If indicated by the optimization level LEVEL (-Os if SIZE is set,
312    -Ofast if FAST is set, -Og if DEBUG is set), apply the option DEFAULT_OPT
313    to OPTS and OPTS_SET, diagnostic context DC, location LOC, with language
314    mask LANG_MASK and option handlers HANDLERS.  */
315 
316 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)317 maybe_default_option (struct gcc_options *opts,
318 		      struct gcc_options *opts_set,
319 		      const struct default_options *default_opt,
320 		      int level, bool size, bool fast, bool debug,
321 		      unsigned int lang_mask,
322 		      const struct cl_option_handlers *handlers,
323 		      location_t loc,
324 		      diagnostic_context *dc)
325 {
326   const struct cl_option *option = &cl_options[default_opt->opt_index];
327   bool enabled;
328 
329   if (size)
330     gcc_assert (level == 2);
331   if (fast)
332     gcc_assert (level == 3);
333   if (debug)
334     gcc_assert (level == 1);
335 
336   switch (default_opt->levels)
337     {
338     case OPT_LEVELS_ALL:
339       enabled = true;
340       break;
341 
342     case OPT_LEVELS_0_ONLY:
343       enabled = (level == 0);
344       break;
345 
346     case OPT_LEVELS_1_PLUS:
347       enabled = (level >= 1);
348       break;
349 
350     case OPT_LEVELS_1_PLUS_SPEED_ONLY:
351       enabled = (level >= 1 && !size && !debug);
352       break;
353 
354     case OPT_LEVELS_1_PLUS_NOT_DEBUG:
355       enabled = (level >= 1 && !debug);
356       break;
357 
358     case OPT_LEVELS_2_PLUS:
359       enabled = (level >= 2);
360       break;
361 
362     case OPT_LEVELS_2_PLUS_SPEED_ONLY:
363       enabled = (level >= 2 && !size && !debug);
364       break;
365 
366     case OPT_LEVELS_3_PLUS:
367       enabled = (level >= 3);
368       break;
369 
370     case OPT_LEVELS_3_PLUS_AND_SIZE:
371       enabled = (level >= 3 || size);
372       break;
373 
374     case OPT_LEVELS_SIZE:
375       enabled = size;
376       break;
377 
378     case OPT_LEVELS_FAST:
379       enabled = fast;
380       break;
381 
382     case OPT_LEVELS_NONE:
383     default:
384       gcc_unreachable ();
385     }
386 
387   if (enabled)
388     handle_generated_option (opts, opts_set, default_opt->opt_index,
389 			     default_opt->arg, default_opt->value,
390 			     lang_mask, DK_UNSPECIFIED, loc,
391 			     handlers, true, dc);
392   else if (default_opt->arg == NULL
393 	   && !option->cl_reject_negative
394 	   && !(option->flags & CL_PARAMS))
395     handle_generated_option (opts, opts_set, default_opt->opt_index,
396 			     default_opt->arg, !default_opt->value,
397 			     lang_mask, DK_UNSPECIFIED, loc,
398 			     handlers, true, dc);
399 }
400 
401 /* As indicated by the optimization level LEVEL (-Os if SIZE is set,
402    -Ofast if FAST is set), apply the options in array DEFAULT_OPTS to
403    OPTS and OPTS_SET, diagnostic context DC, location LOC, with
404    language mask LANG_MASK and option handlers HANDLERS.  */
405 
406 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)407 maybe_default_options (struct gcc_options *opts,
408 		       struct gcc_options *opts_set,
409 		       const struct default_options *default_opts,
410 		       int level, bool size, bool fast, bool debug,
411 		       unsigned int lang_mask,
412 		       const struct cl_option_handlers *handlers,
413 		       location_t loc,
414 		       diagnostic_context *dc)
415 {
416   size_t i;
417 
418   for (i = 0; default_opts[i].levels != OPT_LEVELS_NONE; i++)
419     maybe_default_option (opts, opts_set, &default_opts[i],
420 			  level, size, fast, debug,
421 			  lang_mask, handlers, loc, dc);
422 }
423 
424 /* Table of options enabled by default at different levels.
425    Please keep this list sorted by level and alphabetized within
426    each level; this makes it easier to keep the documentation
427    in sync.  */
428 
429 static const struct default_options default_options_table[] =
430   {
431     /* -O1 and -Og optimizations.  */
432     { OPT_LEVELS_1_PLUS, OPT_fcombine_stack_adjustments, NULL, 1 },
433     { OPT_LEVELS_1_PLUS, OPT_fcompare_elim, NULL, 1 },
434     { OPT_LEVELS_1_PLUS, OPT_fcprop_registers, NULL, 1 },
435     { OPT_LEVELS_1_PLUS, OPT_fdefer_pop, NULL, 1 },
436     { OPT_LEVELS_1_PLUS, OPT_fforward_propagate, NULL, 1 },
437     { OPT_LEVELS_1_PLUS, OPT_fguess_branch_probability, NULL, 1 },
438     { OPT_LEVELS_1_PLUS, OPT_fipa_profile, NULL, 1 },
439     { OPT_LEVELS_1_PLUS, OPT_fipa_pure_const, NULL, 1 },
440     { OPT_LEVELS_1_PLUS, OPT_fipa_reference, NULL, 1 },
441     { OPT_LEVELS_1_PLUS, OPT_fipa_reference_addressable, NULL, 1 },
442     { OPT_LEVELS_1_PLUS, OPT_fmerge_constants, NULL, 1 },
443     { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
444     { OPT_LEVELS_1_PLUS, OPT_freorder_blocks, NULL, 1 },
445     { OPT_LEVELS_1_PLUS, OPT_fshrink_wrap, NULL, 1 },
446     { OPT_LEVELS_1_PLUS, OPT_fsplit_wide_types, NULL, 1 },
447     { OPT_LEVELS_1_PLUS, OPT_ftree_builtin_call_dce, NULL, 1 },
448     { OPT_LEVELS_1_PLUS, OPT_ftree_ccp, NULL, 1 },
449     { OPT_LEVELS_1_PLUS, OPT_ftree_ch, NULL, 1 },
450     { OPT_LEVELS_1_PLUS, OPT_ftree_coalesce_vars, NULL, 1 },
451     { OPT_LEVELS_1_PLUS, OPT_ftree_copy_prop, NULL, 1 },
452     { OPT_LEVELS_1_PLUS, OPT_ftree_dce, NULL, 1 },
453     { OPT_LEVELS_1_PLUS, OPT_ftree_dominator_opts, NULL, 1 },
454     { OPT_LEVELS_1_PLUS, OPT_ftree_fre, NULL, 1 },
455     { OPT_LEVELS_1_PLUS, OPT_ftree_sink, NULL, 1 },
456     { OPT_LEVELS_1_PLUS, OPT_ftree_slsr, NULL, 1 },
457     { OPT_LEVELS_1_PLUS, OPT_ftree_ter, NULL, 1 },
458 
459     /* -O1 (and not -Og) optimizations.  */
460     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fbranch_count_reg, NULL, 1 },
461 #if DELAY_SLOTS
462     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fdelayed_branch, NULL, 1 },
463 #endif
464     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fdse, NULL, 1 },
465     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fif_conversion, NULL, 1 },
466     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fif_conversion2, NULL, 1 },
467     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_finline_functions_called_once, NULL, 1 },
468     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fmove_loop_invariants, NULL, 1 },
469     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fssa_phiopt, NULL, 1 },
470     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fipa_modref, NULL, 1 },
471     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_bit_ccp, NULL, 1 },
472     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_dse, NULL, 1 },
473     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_pta, NULL, 1 },
474     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_sra, NULL, 1 },
475 
476     /* -O2 and -Os optimizations.  */
477     { OPT_LEVELS_2_PLUS, OPT_fcaller_saves, NULL, 1 },
478     { OPT_LEVELS_2_PLUS, OPT_fcode_hoisting, NULL, 1 },
479     { OPT_LEVELS_2_PLUS, OPT_fcrossjumping, NULL, 1 },
480     { OPT_LEVELS_2_PLUS, OPT_fcse_follow_jumps, NULL, 1 },
481     { OPT_LEVELS_2_PLUS, OPT_fdevirtualize, NULL, 1 },
482     { OPT_LEVELS_2_PLUS, OPT_fdevirtualize_speculatively, NULL, 1 },
483     { OPT_LEVELS_2_PLUS, OPT_fexpensive_optimizations, NULL, 1 },
484     { OPT_LEVELS_2_PLUS, OPT_fgcse, NULL, 1 },
485     { OPT_LEVELS_2_PLUS, OPT_fhoist_adjacent_loads, NULL, 1 },
486     { OPT_LEVELS_2_PLUS, OPT_findirect_inlining, NULL, 1 },
487     { OPT_LEVELS_2_PLUS, OPT_finline_small_functions, NULL, 1 },
488     { OPT_LEVELS_2_PLUS, OPT_fipa_bit_cp, NULL, 1 },
489     { OPT_LEVELS_2_PLUS, OPT_fipa_cp, NULL, 1 },
490     { OPT_LEVELS_2_PLUS, OPT_fipa_icf, NULL, 1 },
491     { OPT_LEVELS_2_PLUS, OPT_fipa_ra, NULL, 1 },
492     { OPT_LEVELS_2_PLUS, OPT_fipa_sra, NULL, 1 },
493     { OPT_LEVELS_2_PLUS, OPT_fipa_vrp, NULL, 1 },
494     { OPT_LEVELS_2_PLUS, OPT_fisolate_erroneous_paths_dereference, NULL, 1 },
495     { OPT_LEVELS_2_PLUS, OPT_flra_remat, NULL, 1 },
496     { OPT_LEVELS_2_PLUS, OPT_foptimize_sibling_calls, NULL, 1 },
497     { OPT_LEVELS_2_PLUS, OPT_fpartial_inlining, NULL, 1 },
498     { OPT_LEVELS_2_PLUS, OPT_fpeephole2, NULL, 1 },
499     { OPT_LEVELS_2_PLUS, OPT_freorder_functions, NULL, 1 },
500     { OPT_LEVELS_2_PLUS, OPT_frerun_cse_after_loop, NULL, 1 },
501 #ifdef INSN_SCHEDULING
502     { OPT_LEVELS_2_PLUS, OPT_fschedule_insns2, NULL, 1 },
503 #endif
504     { OPT_LEVELS_2_PLUS, OPT_fstrict_aliasing, NULL, 1 },
505     { OPT_LEVELS_2_PLUS, OPT_fstore_merging, NULL, 1 },
506     { OPT_LEVELS_2_PLUS, OPT_fthread_jumps, NULL, 1 },
507     { OPT_LEVELS_2_PLUS, OPT_ftree_pre, NULL, 1 },
508     { OPT_LEVELS_2_PLUS, OPT_ftree_switch_conversion, NULL, 1 },
509     { OPT_LEVELS_2_PLUS, OPT_ftree_tail_merge, NULL, 1 },
510     { OPT_LEVELS_2_PLUS, OPT_ftree_vrp, NULL, 1 },
511     { OPT_LEVELS_2_PLUS, OPT_fvect_cost_model_, NULL, VECT_COST_MODEL_CHEAP },
512     { OPT_LEVELS_2_PLUS, OPT_finline_functions, NULL, 1 },
513     { OPT_LEVELS_2_PLUS, OPT_ftree_loop_distribute_patterns, NULL, 1 },
514 
515     /* -O2 and above optimizations, but not -Os or -Og.  */
516     { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_falign_functions, NULL, 1 },
517     { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_falign_jumps, NULL, 1 },
518     { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_falign_labels, NULL, 1 },
519     { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_falign_loops, NULL, 1 },
520     { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_foptimize_strlen, NULL, 1 },
521     { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_freorder_blocks_algorithm_, NULL,
522       REORDER_BLOCKS_ALGORITHM_STC },
523 #ifdef INSN_SCHEDULING
524   /* Only run the pre-regalloc scheduling pass if optimizing for speed.  */
525     { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_fschedule_insns, NULL, 1 },
526 #endif
527 
528     /* -O3 and -Os optimizations.  */
529 
530     /* -O3 optimizations.  */
531     { OPT_LEVELS_3_PLUS, OPT_fgcse_after_reload, NULL, 1 },
532     { OPT_LEVELS_3_PLUS, OPT_fipa_cp_clone, NULL, 1 },
533     { OPT_LEVELS_3_PLUS, OPT_floop_interchange, NULL, 1 },
534     { OPT_LEVELS_3_PLUS, OPT_floop_unroll_and_jam, NULL, 1 },
535     { OPT_LEVELS_3_PLUS, OPT_fpeel_loops, NULL, 1 },
536     { OPT_LEVELS_3_PLUS, OPT_fpredictive_commoning, NULL, 1 },
537     { OPT_LEVELS_3_PLUS, OPT_fsplit_loops, NULL, 1 },
538     { OPT_LEVELS_3_PLUS, OPT_fsplit_paths, NULL, 1 },
539     { OPT_LEVELS_3_PLUS, OPT_ftree_loop_distribution, NULL, 1 },
540     { OPT_LEVELS_3_PLUS, OPT_ftree_loop_vectorize, NULL, 1 },
541     { OPT_LEVELS_3_PLUS, OPT_ftree_partial_pre, NULL, 1 },
542     { OPT_LEVELS_3_PLUS, OPT_ftree_slp_vectorize, NULL, 1 },
543     { OPT_LEVELS_3_PLUS, OPT_funswitch_loops, NULL, 1 },
544     { OPT_LEVELS_3_PLUS, OPT_fvect_cost_model_, NULL, VECT_COST_MODEL_DYNAMIC },
545     { OPT_LEVELS_3_PLUS, OPT_fversion_loops_for_strides, NULL, 1 },
546 
547     /* -O3 parameters.  */
548     { OPT_LEVELS_3_PLUS, OPT__param_max_inline_insns_auto_, NULL, 30 },
549     { OPT_LEVELS_3_PLUS, OPT__param_early_inlining_insns_, NULL, 14 },
550     { OPT_LEVELS_3_PLUS, OPT__param_inline_heuristics_hint_percent_, NULL, 600 },
551     { OPT_LEVELS_3_PLUS, OPT__param_inline_min_speedup_, NULL, 15 },
552     { OPT_LEVELS_3_PLUS, OPT__param_max_inline_insns_single_, NULL, 200 },
553 
554     /* -Ofast adds optimizations to -O3.  */
555     { OPT_LEVELS_FAST, OPT_ffast_math, NULL, 1 },
556     { OPT_LEVELS_FAST, OPT_fallow_store_data_races, NULL, 1 },
557 
558     { OPT_LEVELS_NONE, 0, NULL, 0 }
559   };
560 
561 /* Default the options in OPTS and OPTS_SET based on the optimization
562    settings in DECODED_OPTIONS and DECODED_OPTIONS_COUNT.  */
563 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)564 default_options_optimization (struct gcc_options *opts,
565 			      struct gcc_options *opts_set,
566 			      struct cl_decoded_option *decoded_options,
567 			      unsigned int decoded_options_count,
568 			      location_t loc,
569 			      unsigned int lang_mask,
570 			      const struct cl_option_handlers *handlers,
571 			      diagnostic_context *dc)
572 {
573   unsigned int i;
574   int opt2;
575   bool openacc_mode = false;
576 
577   /* Scan to see what optimization level has been specified.  That will
578      determine the default value of many flags.  */
579   for (i = 1; i < decoded_options_count; i++)
580     {
581       struct cl_decoded_option *opt = &decoded_options[i];
582       switch (opt->opt_index)
583 	{
584 	case OPT_O:
585 	  if (*opt->arg == '\0')
586 	    {
587 	      opts->x_optimize = 1;
588 	      opts->x_optimize_size = 0;
589 	      opts->x_optimize_fast = 0;
590 	      opts->x_optimize_debug = 0;
591 	    }
592 	  else
593 	    {
594 	      const int optimize_val = integral_argument (opt->arg);
595 	      if (optimize_val == -1)
596 		error_at (loc, "argument to %<-O%> should be a non-negative "
597 			       "integer, %<g%>, %<s%> or %<fast%>");
598 	      else
599 		{
600 		  opts->x_optimize = optimize_val;
601 		  if ((unsigned int) opts->x_optimize > 255)
602 		    opts->x_optimize = 255;
603 		  opts->x_optimize_size = 0;
604 		  opts->x_optimize_fast = 0;
605 		  opts->x_optimize_debug = 0;
606 		}
607 	    }
608 	  break;
609 
610 	case OPT_Os:
611 	  opts->x_optimize_size = 1;
612 
613 	  /* Optimizing for size forces optimize to be 2.  */
614 	  opts->x_optimize = 2;
615 	  opts->x_optimize_fast = 0;
616 	  opts->x_optimize_debug = 0;
617 	  break;
618 
619 	case OPT_Ofast:
620 	  /* -Ofast only adds flags to -O3.  */
621 	  opts->x_optimize_size = 0;
622 	  opts->x_optimize = 3;
623 	  opts->x_optimize_fast = 1;
624 	  opts->x_optimize_debug = 0;
625 	  break;
626 
627 	case OPT_Og:
628 	  /* -Og selects optimization level 1.  */
629 	  opts->x_optimize_size = 0;
630 	  opts->x_optimize = 1;
631 	  opts->x_optimize_fast = 0;
632 	  opts->x_optimize_debug = 1;
633 	  break;
634 
635 	case OPT_fopenacc:
636 	  if (opt->value)
637 	    openacc_mode = true;
638 	  break;
639 
640 	default:
641 	  /* Ignore other options in this prescan.  */
642 	  break;
643 	}
644     }
645 
646   maybe_default_options (opts, opts_set, default_options_table,
647 			 opts->x_optimize, opts->x_optimize_size,
648 			 opts->x_optimize_fast, opts->x_optimize_debug,
649 			 lang_mask, handlers, loc, dc);
650 
651   /* -O2 param settings.  */
652   opt2 = (opts->x_optimize >= 2);
653 
654   if (openacc_mode)
655     SET_OPTION_IF_UNSET (opts, opts_set, flag_ipa_pta, true);
656 
657   /* Track fields in field-sensitive alias analysis.  */
658   if (opt2)
659     SET_OPTION_IF_UNSET (opts, opts_set, param_max_fields_for_field_sensitive,
660 			 100);
661 
662   if (opts->x_optimize_size)
663     /* We want to crossjump as much as possible.  */
664     SET_OPTION_IF_UNSET (opts, opts_set, param_min_crossjump_insns, 1);
665 
666   /* Restrict the amount of work combine does at -Og while retaining
667      most of its useful transforms.  */
668   if (opts->x_optimize_debug)
669     SET_OPTION_IF_UNSET (opts, opts_set, param_max_combine_insns, 2);
670 
671   /* Allow default optimizations to be specified on a per-machine basis.  */
672   maybe_default_options (opts, opts_set,
673 			 targetm_common.option_optimization_table,
674 			 opts->x_optimize, opts->x_optimize_size,
675 			 opts->x_optimize_fast, opts->x_optimize_debug,
676 			 lang_mask, handlers, loc, dc);
677 }
678 
679 /* Control IPA optimizations based on different live patching LEVEL.  */
680 static void
control_options_for_live_patching(struct gcc_options * opts,struct gcc_options * opts_set,enum live_patching_level level,location_t loc)681 control_options_for_live_patching (struct gcc_options *opts,
682 				   struct gcc_options *opts_set,
683 				   enum live_patching_level level,
684 				   location_t loc)
685 {
686   gcc_assert (level > LIVE_PATCHING_NONE);
687 
688   switch (level)
689     {
690     case LIVE_PATCHING_INLINE_ONLY_STATIC:
691       if (opts_set->x_flag_ipa_cp_clone && opts->x_flag_ipa_cp_clone)
692 	error_at (loc, "%qs is incompatible with %qs",
693 		  "-fipa-cp-clone", "-flive-patching=inline-only-static");
694       else
695 	opts->x_flag_ipa_cp_clone = 0;
696 
697       if (opts_set->x_flag_ipa_sra && opts->x_flag_ipa_sra)
698 	error_at (loc, "%qs is incompatible with %qs",
699 		  "-fipa-sra", "-flive-patching=inline-only-static");
700       else
701 	opts->x_flag_ipa_sra = 0;
702 
703       if (opts_set->x_flag_partial_inlining && opts->x_flag_partial_inlining)
704 	error_at (loc, "%qs is incompatible with %qs",
705 		  "-fpartial-inlining", "-flive-patching=inline-only-static");
706       else
707 	opts->x_flag_partial_inlining = 0;
708 
709       if (opts_set->x_flag_ipa_cp && opts->x_flag_ipa_cp)
710 	error_at (loc, "%qs is incompatible with %qs",
711 		  "-fipa-cp", "-flive-patching=inline-only-static");
712       else
713 	opts->x_flag_ipa_cp = 0;
714 
715       /* FALLTHROUGH.  */
716     case LIVE_PATCHING_INLINE_CLONE:
717       /* live patching should disable whole-program optimization.  */
718       if (opts_set->x_flag_whole_program && opts->x_flag_whole_program)
719 	error_at (loc, "%qs is incompatible with %qs",
720 		  "-fwhole-program",
721 		  "-flive-patching=inline-only-static|inline-clone");
722       else
723 	opts->x_flag_whole_program = 0;
724 
725       /* visibility change should be excluded by !flag_whole_program
726 	 && !in_lto_p && !flag_ipa_cp_clone && !flag_ipa_sra
727 	 && !flag_partial_inlining.  */
728 
729       if (opts_set->x_flag_ipa_pta && opts->x_flag_ipa_pta)
730 	error_at (loc, "%qs is incompatible with %qs",
731 		  "-fipa-pta",
732 		  "-flive-patching=inline-only-static|inline-clone");
733       else
734 	opts->x_flag_ipa_pta = 0;
735 
736       if (opts_set->x_flag_ipa_reference && opts->x_flag_ipa_reference)
737 	error_at (loc, "%qs is incompatible with %qs",
738 		  "-fipa-reference",
739 		  "-flive-patching=inline-only-static|inline-clone");
740       else
741 	opts->x_flag_ipa_reference = 0;
742 
743       if (opts_set->x_flag_ipa_ra && opts->x_flag_ipa_ra)
744 	error_at (loc, "%qs is incompatible with %qs",
745 		  "-fipa-ra",
746 		  "-flive-patching=inline-only-static|inline-clone");
747       else
748 	opts->x_flag_ipa_ra = 0;
749 
750       if (opts_set->x_flag_ipa_icf && opts->x_flag_ipa_icf)
751 	error_at (loc, "%qs is incompatible with %qs",
752 		  "-fipa-icf",
753 		  "-flive-patching=inline-only-static|inline-clone");
754       else
755 	opts->x_flag_ipa_icf = 0;
756 
757       if (opts_set->x_flag_ipa_icf_functions && opts->x_flag_ipa_icf_functions)
758 	error_at (loc, "%qs is incompatible with %qs",
759 		  "-fipa-icf-functions",
760 		  "-flive-patching=inline-only-static|inline-clone");
761       else
762 	opts->x_flag_ipa_icf_functions = 0;
763 
764       if (opts_set->x_flag_ipa_icf_variables && opts->x_flag_ipa_icf_variables)
765 	error_at (loc, "%qs is incompatible with %qs",
766 		  "-fipa-icf-variables",
767 		  "-flive-patching=inline-only-static|inline-clone");
768       else
769 	opts->x_flag_ipa_icf_variables = 0;
770 
771       if (opts_set->x_flag_ipa_bit_cp && opts->x_flag_ipa_bit_cp)
772 	error_at (loc, "%qs is incompatible with %qs",
773 		  "-fipa-bit-cp",
774 		  "-flive-patching=inline-only-static|inline-clone");
775       else
776 	opts->x_flag_ipa_bit_cp = 0;
777 
778       if (opts_set->x_flag_ipa_vrp && opts->x_flag_ipa_vrp)
779 	error_at (loc, "%qs is incompatible with %qs",
780 		  "-fipa-vrp",
781 		  "-flive-patching=inline-only-static|inline-clone");
782       else
783 	opts->x_flag_ipa_vrp = 0;
784 
785       if (opts_set->x_flag_ipa_pure_const && opts->x_flag_ipa_pure_const)
786 	error_at (loc, "%qs is incompatible with %qs",
787 		  "-fipa-pure-const",
788 		  "-flive-patching=inline-only-static|inline-clone");
789       else
790 	opts->x_flag_ipa_pure_const = 0;
791 
792       if (opts_set->x_flag_ipa_modref && opts->x_flag_ipa_modref)
793 	error_at (loc,
794 		  "%<-fipa-modref%> is incompatible with "
795 		  "%<-flive-patching=inline-only-static|inline-clone%>");
796       else
797 	opts->x_flag_ipa_modref = 0;
798 
799       /* FIXME: disable unreachable code removal.  */
800 
801       /* discovery of functions/variables with no address taken.  */
802       if (opts_set->x_flag_ipa_reference_addressable
803 	  && opts->x_flag_ipa_reference_addressable)
804 	error_at (loc, "%qs is incompatible with %qs",
805 		  "-fipa-reference-addressable",
806 		  "-flive-patching=inline-only-static|inline-clone");
807       else
808 	opts->x_flag_ipa_reference_addressable = 0;
809 
810       /* ipa stack alignment propagation.  */
811       if (opts_set->x_flag_ipa_stack_alignment
812 	  && opts->x_flag_ipa_stack_alignment)
813 	error_at (loc, "%qs is incompatible with %qs",
814 		  "-fipa-stack-alignment",
815 		  "-flive-patching=inline-only-static|inline-clone");
816       else
817 	opts->x_flag_ipa_stack_alignment = 0;
818       break;
819     default:
820       gcc_unreachable ();
821     }
822 }
823 
824 /* --help option argument if set.  */
825 vec<const char *> help_option_arguments;
826 
827 /* Return the string name describing a sanitizer argument which has been
828    provided on the command line and has set this particular flag.  */
829 const char *
find_sanitizer_argument(struct gcc_options * opts,unsigned int flags)830 find_sanitizer_argument (struct gcc_options *opts, unsigned int flags)
831 {
832   for (int i = 0; sanitizer_opts[i].name != NULL; ++i)
833     {
834       /* Need to find the sanitizer_opts element which:
835 	 a) Could have set the flags requested.
836 	 b) Has been set on the command line.
837 
838 	 Can have (a) without (b) if the flag requested is e.g.
839 	 SANITIZE_ADDRESS, since both -fsanitize=address and
840 	 -fsanitize=kernel-address set this flag.
841 
842 	 Can have (b) without (a) by requesting more than one sanitizer on the
843 	 command line.  */
844       if ((sanitizer_opts[i].flag & opts->x_flag_sanitize)
845 	  != sanitizer_opts[i].flag)
846 	continue;
847       if ((sanitizer_opts[i].flag & flags) != flags)
848 	continue;
849       return sanitizer_opts[i].name;
850     }
851   return NULL;
852 }
853 
854 
855 /* Report an error to the user about sanitizer options they have requested
856    which have set conflicting flags.
857 
858    LEFT and RIGHT indicate sanitizer flags which conflict with each other, this
859    function reports an error if both have been set in OPTS->x_flag_sanitize and
860    ensures the error identifies the requested command line options that have
861    set these flags.  */
862 static void
report_conflicting_sanitizer_options(struct gcc_options * opts,location_t loc,unsigned int left,unsigned int right)863 report_conflicting_sanitizer_options (struct gcc_options *opts, location_t loc,
864 				      unsigned int left, unsigned int right)
865 {
866   unsigned int left_seen = (opts->x_flag_sanitize & left);
867   unsigned int right_seen = (opts->x_flag_sanitize & right);
868   if (left_seen && right_seen)
869     {
870       const char* left_arg = find_sanitizer_argument (opts, left_seen);
871       const char* right_arg = find_sanitizer_argument (opts, right_seen);
872       gcc_assert (left_arg && right_arg);
873       error_at (loc,
874 		"%<-fsanitize=%s%> is incompatible with %<-fsanitize=%s%>",
875 		left_arg, right_arg);
876     }
877 }
878 
879 /* After all options at LOC have been read into OPTS and OPTS_SET,
880    finalize settings of those options and diagnose incompatible
881    combinations.  */
882 void
finish_options(struct gcc_options * opts,struct gcc_options * opts_set,location_t loc)883 finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
884 		location_t loc)
885 {
886   enum unwind_info_type ui_except;
887 
888   if (opts->x_dump_base_name
889       && ! opts->x_dump_base_name_prefixed)
890     {
891       const char *sep = opts->x_dump_base_name;
892 
893       for (; *sep; sep++)
894 	if (IS_DIR_SEPARATOR (*sep))
895 	  break;
896 
897       if (*sep)
898 	/* If dump_base_path contains subdirectories, don't prepend
899 	   anything.  */;
900       else if (opts->x_dump_dir_name)
901 	/* We have a DUMP_DIR_NAME, prepend that.  */
902 	opts->x_dump_base_name = opts_concat (opts->x_dump_dir_name,
903 					      opts->x_dump_base_name, NULL);
904 
905       /* It is definitely prefixed now.  */
906       opts->x_dump_base_name_prefixed = true;
907     }
908 
909   /* Handle related options for unit-at-a-time, toplevel-reorder, and
910      section-anchors.  */
911   if (!opts->x_flag_unit_at_a_time)
912     {
913       if (opts->x_flag_section_anchors && opts_set->x_flag_section_anchors)
914 	error_at (loc, "section anchors must be disabled when unit-at-a-time "
915 		  "is disabled");
916       opts->x_flag_section_anchors = 0;
917       if (opts->x_flag_toplevel_reorder == 1)
918 	error_at (loc, "toplevel reorder must be disabled when unit-at-a-time "
919 		  "is disabled");
920       opts->x_flag_toplevel_reorder = 0;
921     }
922 
923   /* -fself-test depends on the state of the compiler prior to
924      compiling anything.  Ideally it should be run on an empty source
925      file.  However, in case we get run with actual source, assume
926      -fsyntax-only which will inhibit any compiler initialization
927      which may confuse the self tests.  */
928   if (opts->x_flag_self_test)
929     opts->x_flag_syntax_only = 1;
930 
931   if (opts->x_flag_tm && opts->x_flag_non_call_exceptions)
932     sorry ("transactional memory is not supported with non-call exceptions");
933 
934   /* Unless the user has asked for section anchors, we disable toplevel
935      reordering at -O0 to disable transformations that might be surprising
936      to end users and to get -fno-toplevel-reorder tested.  */
937   if (!opts->x_optimize
938       && opts->x_flag_toplevel_reorder == 2
939       && !(opts->x_flag_section_anchors && opts_set->x_flag_section_anchors))
940     {
941       opts->x_flag_toplevel_reorder = 0;
942       opts->x_flag_section_anchors = 0;
943     }
944   if (!opts->x_flag_toplevel_reorder)
945     {
946       if (opts->x_flag_section_anchors && opts_set->x_flag_section_anchors)
947 	error_at (loc, "section anchors must be disabled when toplevel reorder"
948 		  " is disabled");
949       opts->x_flag_section_anchors = 0;
950     }
951 
952   if (!opts->x_flag_opts_finished)
953     {
954       /* We initialize opts->x_flag_pie to -1 so that targets can set a
955 	 default value.  */
956       if (opts->x_flag_pie == -1)
957 	{
958 	  /* We initialize opts->x_flag_pic to -1 so that we can tell if
959 	     -fpic, -fPIC, -fno-pic or -fno-PIC is used.  */
960 	  if (opts->x_flag_pic == -1)
961 	    opts->x_flag_pie = DEFAULT_FLAG_PIE;
962 	  else
963 	    opts->x_flag_pie = 0;
964 	}
965       /* If -fPIE or -fpie is used, turn on PIC.  */
966       if (opts->x_flag_pie)
967 	opts->x_flag_pic = opts->x_flag_pie;
968       else if (opts->x_flag_pic == -1)
969 	opts->x_flag_pic = 0;
970       if (opts->x_flag_pic && !opts->x_flag_pie)
971 	opts->x_flag_shlib = 1;
972       opts->x_flag_opts_finished = true;
973     }
974 
975   /* We initialize opts->x_flag_stack_protect to -1 so that targets
976      can set a default value.  */
977   if (opts->x_flag_stack_protect == -1)
978     opts->x_flag_stack_protect = DEFAULT_FLAG_SSP;
979 
980   if (opts->x_optimize == 0)
981     {
982       /* Inlining does not work if not optimizing,
983 	 so force it not to be done.  */
984       opts->x_warn_inline = 0;
985       opts->x_flag_no_inline = 1;
986     }
987 
988   /* The optimization to partition hot and cold basic blocks into separate
989      sections of the .o and executable files does not work (currently)
990      with exception handling.  This is because there is no support for
991      generating unwind info.  If opts->x_flag_exceptions is turned on
992      we need to turn off the partitioning optimization.  */
993 
994   ui_except = targetm_common.except_unwind_info (opts);
995 
996   if (opts->x_flag_exceptions
997       && opts->x_flag_reorder_blocks_and_partition
998       && (ui_except == UI_SJLJ || ui_except >= UI_TARGET))
999     {
1000       if (opts_set->x_flag_reorder_blocks_and_partition)
1001         inform (loc,
1002 		"%<-freorder-blocks-and-partition%> does not work "
1003 		"with exceptions on this architecture");
1004       opts->x_flag_reorder_blocks_and_partition = 0;
1005       opts->x_flag_reorder_blocks = 1;
1006     }
1007 
1008   /* If user requested unwind info, then turn off the partitioning
1009      optimization.  */
1010 
1011   if (opts->x_flag_unwind_tables
1012       && !targetm_common.unwind_tables_default
1013       && opts->x_flag_reorder_blocks_and_partition
1014       && (ui_except == UI_SJLJ || ui_except >= UI_TARGET))
1015     {
1016       if (opts_set->x_flag_reorder_blocks_and_partition)
1017         inform (loc,
1018 		"%<-freorder-blocks-and-partition%> does not support "
1019 		"unwind info on this architecture");
1020       opts->x_flag_reorder_blocks_and_partition = 0;
1021       opts->x_flag_reorder_blocks = 1;
1022     }
1023 
1024   /* If the target requested unwind info, then turn off the partitioning
1025      optimization with a different message.  Likewise, if the target does not
1026      support named sections.  */
1027 
1028   if (opts->x_flag_reorder_blocks_and_partition
1029       && (!targetm_common.have_named_sections
1030 	  || (opts->x_flag_unwind_tables
1031 	      && targetm_common.unwind_tables_default
1032 	      && (ui_except == UI_SJLJ || ui_except >= UI_TARGET))))
1033     {
1034       if (opts_set->x_flag_reorder_blocks_and_partition)
1035         inform (loc,
1036 		"%<-freorder-blocks-and-partition%> does not work "
1037 		"on this architecture");
1038       opts->x_flag_reorder_blocks_and_partition = 0;
1039       opts->x_flag_reorder_blocks = 1;
1040     }
1041 
1042 
1043   /* Pipelining of outer loops is only possible when general pipelining
1044      capabilities are requested.  */
1045   if (!opts->x_flag_sel_sched_pipelining)
1046     opts->x_flag_sel_sched_pipelining_outer_loops = 0;
1047 
1048   if (opts->x_flag_conserve_stack)
1049     {
1050       SET_OPTION_IF_UNSET (opts, opts_set, param_large_stack_frame, 100);
1051       SET_OPTION_IF_UNSET (opts, opts_set, param_stack_frame_growth, 40);
1052     }
1053 
1054   if (opts->x_flag_lto)
1055     {
1056 #ifdef ENABLE_LTO
1057       opts->x_flag_generate_lto = 1;
1058 
1059       /* When generating IL, do not operate in whole-program mode.
1060 	 Otherwise, symbols will be privatized too early, causing link
1061 	 errors later.  */
1062       opts->x_flag_whole_program = 0;
1063 #else
1064       error_at (loc, "LTO support has not been enabled in this configuration");
1065 #endif
1066       if (!opts->x_flag_fat_lto_objects
1067 	  && (!HAVE_LTO_PLUGIN
1068 	      || (opts_set->x_flag_use_linker_plugin
1069 		  && !opts->x_flag_use_linker_plugin)))
1070 	{
1071 	  if (opts_set->x_flag_fat_lto_objects)
1072 	    error_at (loc, "%<-fno-fat-lto-objects%> are supported only with "
1073 		      "linker plugin");
1074 	  opts->x_flag_fat_lto_objects = 1;
1075 	}
1076 
1077       /* -gsplit-dwarf isn't compatible with LTO, see PR88389.  */
1078       if (opts->x_dwarf_split_debug_info)
1079 	{
1080 	  inform (loc, "%<-gsplit-dwarf%> is not supported with LTO,"
1081 		  " disabling");
1082 	  opts->x_dwarf_split_debug_info = 0;
1083 	}
1084     }
1085 
1086   /* We initialize opts->x_flag_split_stack to -1 so that targets can set a
1087      default value if they choose based on other options.  */
1088   if (opts->x_flag_split_stack == -1)
1089     opts->x_flag_split_stack = 0;
1090   else if (opts->x_flag_split_stack)
1091     {
1092       if (!targetm_common.supports_split_stack (true, opts))
1093 	{
1094 	  error_at (loc, "%<-fsplit-stack%> is not supported by "
1095 		    "this compiler configuration");
1096 	  opts->x_flag_split_stack = 0;
1097 	}
1098     }
1099 
1100   /* If stack splitting is turned on, and the user did not explicitly
1101      request function partitioning, turn off partitioning, as it
1102      confuses the linker when trying to handle partitioned split-stack
1103      code that calls a non-split-stack functions.  But if partitioning
1104      was turned on explicitly just hope for the best.  */
1105   if (opts->x_flag_split_stack
1106       && opts->x_flag_reorder_blocks_and_partition)
1107     SET_OPTION_IF_UNSET (opts, opts_set, flag_reorder_blocks_and_partition, 0);
1108 
1109   if (opts->x_flag_reorder_blocks_and_partition)
1110     SET_OPTION_IF_UNSET (opts, opts_set, flag_reorder_functions, 1);
1111 
1112   /* The -gsplit-dwarf option requires -ggnu-pubnames.  */
1113   if (opts->x_dwarf_split_debug_info)
1114     opts->x_debug_generate_pub_sections = 2;
1115 
1116   if ((opts->x_flag_sanitize
1117        & (SANITIZE_USER_ADDRESS | SANITIZE_KERNEL_ADDRESS)) == 0)
1118     {
1119       if (opts->x_flag_sanitize & SANITIZE_POINTER_COMPARE)
1120 	error_at (loc,
1121 		  "%<-fsanitize=pointer-compare%> must be combined with "
1122 		  "%<-fsanitize=address%> or %<-fsanitize=kernel-address%>");
1123       if (opts->x_flag_sanitize & SANITIZE_POINTER_SUBTRACT)
1124 	error_at (loc,
1125 		  "%<-fsanitize=pointer-subtract%> must be combined with "
1126 		  "%<-fsanitize=address%> or %<-fsanitize=kernel-address%>");
1127     }
1128 
1129   /* Address sanitizers conflict with the thread sanitizer.  */
1130   report_conflicting_sanitizer_options (opts, loc, SANITIZE_THREAD,
1131 					SANITIZE_ADDRESS | SANITIZE_HWADDRESS);
1132   /* The leak sanitizer conflicts with the thread sanitizer.  */
1133   report_conflicting_sanitizer_options (opts, loc, SANITIZE_LEAK,
1134 					SANITIZE_THREAD);
1135 
1136   /* No combination of HWASAN and ASAN work together.  */
1137   report_conflicting_sanitizer_options (opts, loc,
1138 					SANITIZE_HWADDRESS, SANITIZE_ADDRESS);
1139 
1140   /* The userspace and kernel address sanitizers conflict with each other.  */
1141   report_conflicting_sanitizer_options (opts, loc, SANITIZE_USER_HWADDRESS,
1142 					SANITIZE_KERNEL_HWADDRESS);
1143   report_conflicting_sanitizer_options (opts, loc, SANITIZE_USER_ADDRESS,
1144 					SANITIZE_KERNEL_ADDRESS);
1145 
1146   /* Check error recovery for -fsanitize-recover option.  */
1147   for (int i = 0; sanitizer_opts[i].name != NULL; ++i)
1148     if ((opts->x_flag_sanitize_recover & sanitizer_opts[i].flag)
1149 	&& !sanitizer_opts[i].can_recover)
1150       error_at (loc, "%<-fsanitize-recover=%s%> is not supported",
1151 		sanitizer_opts[i].name);
1152 
1153   /* When instrumenting the pointers, we don't want to remove
1154      the null pointer checks.  */
1155   if (opts->x_flag_sanitize & (SANITIZE_NULL | SANITIZE_NONNULL_ATTRIBUTE
1156 				| SANITIZE_RETURNS_NONNULL_ATTRIBUTE))
1157     opts->x_flag_delete_null_pointer_checks = 0;
1158 
1159   /* Aggressive compiler optimizations may cause false negatives.  */
1160   if (opts->x_flag_sanitize & ~(SANITIZE_LEAK | SANITIZE_UNREACHABLE))
1161     opts->x_flag_aggressive_loop_optimizations = 0;
1162 
1163   /* Enable -fsanitize-address-use-after-scope if either address sanitizer is
1164      enabled.  */
1165   if (opts->x_flag_sanitize
1166       & (SANITIZE_USER_ADDRESS | SANITIZE_USER_HWADDRESS))
1167     SET_OPTION_IF_UNSET (opts, opts_set, flag_sanitize_address_use_after_scope,
1168 			 true);
1169 
1170   /* Force -fstack-reuse=none in case -fsanitize-address-use-after-scope
1171      is enabled.  */
1172   if (opts->x_flag_sanitize_address_use_after_scope)
1173     {
1174       if (opts->x_flag_stack_reuse != SR_NONE
1175 	  && opts_set->x_flag_stack_reuse != SR_NONE)
1176 	error_at (loc,
1177 		  "%<-fsanitize-address-use-after-scope%> requires "
1178 		  "%<-fstack-reuse=none%> option");
1179 
1180       opts->x_flag_stack_reuse = SR_NONE;
1181     }
1182 
1183   if ((opts->x_flag_sanitize & SANITIZE_USER_ADDRESS) && opts->x_flag_tm)
1184     sorry ("transactional memory is not supported with %<-fsanitize=address%>");
1185 
1186   if ((opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS) && opts->x_flag_tm)
1187     sorry ("transactional memory is not supported with "
1188 	   "%<-fsanitize=kernel-address%>");
1189 
1190   /* Currently live patching is not support for LTO.  */
1191   if (opts->x_flag_live_patching && opts->x_flag_lto)
1192     sorry ("live patching is not supported with LTO");
1193 
1194   /* Currently vtable verification is not supported for LTO */
1195   if (opts->x_flag_vtable_verify && opts->x_flag_lto)
1196     sorry ("vtable verification is not supported with LTO");
1197 
1198   /* Control IPA optimizations based on different -flive-patching level.  */
1199   if (opts->x_flag_live_patching)
1200     control_options_for_live_patching (opts, opts_set,
1201 				       opts->x_flag_live_patching,
1202 				       loc);
1203 
1204   /* Unrolling all loops implies that standard loop unrolling must also
1205      be done.  */
1206   if (opts->x_flag_unroll_all_loops)
1207     opts->x_flag_unroll_loops = 1;
1208 
1209   /* Allow cunroll to grow size accordingly.  */
1210   if (!opts_set->x_flag_cunroll_grow_size)
1211     opts->x_flag_cunroll_grow_size
1212       = (opts->x_flag_unroll_loops
1213          || opts->x_flag_peel_loops
1214          || opts->x_optimize >= 3);
1215 }
1216 
1217 #define LEFT_COLUMN	27
1218 
1219 /* Output ITEM, of length ITEM_WIDTH, in the left column,
1220    followed by word-wrapped HELP in a second column.  */
1221 static void
wrap_help(const char * help,const char * item,unsigned int item_width,unsigned int columns)1222 wrap_help (const char *help,
1223 	   const char *item,
1224 	   unsigned int item_width,
1225 	   unsigned int columns)
1226 {
1227   unsigned int col_width = LEFT_COLUMN;
1228   unsigned int remaining, room, len;
1229 
1230   remaining = strlen (help);
1231 
1232   do
1233     {
1234       room = columns - 3 - MAX (col_width, item_width);
1235       if (room > columns)
1236 	room = 0;
1237       len = remaining;
1238 
1239       if (room < len)
1240 	{
1241 	  unsigned int i;
1242 
1243 	  for (i = 0; help[i]; i++)
1244 	    {
1245 	      if (i >= room && len != remaining)
1246 		break;
1247 	      if (help[i] == ' ')
1248 		len = i;
1249 	      else if ((help[i] == '-' || help[i] == '/')
1250 		       && help[i + 1] != ' '
1251 		       && i > 0 && ISALPHA (help[i - 1]))
1252 		len = i + 1;
1253 	    }
1254 	}
1255 
1256       printf ("  %-*.*s %.*s\n", col_width, item_width, item, len, help);
1257       item_width = 0;
1258       while (help[len] == ' ')
1259 	len++;
1260       help += len;
1261       remaining -= len;
1262     }
1263   while (remaining);
1264 }
1265 
1266 /* Data structure used to print list of valid option values.  */
1267 
1268 class option_help_tuple
1269 {
1270 public:
option_help_tuple(int code,vec<const char * > values)1271   option_help_tuple (int code, vec<const char *> values):
1272     m_code (code), m_values (values)
1273   {}
1274 
1275   /* Code of an option.  */
1276   int m_code;
1277 
1278   /* List of possible values.  */
1279   vec<const char *> m_values;
1280 };
1281 
1282 /* Print help for a specific front-end, etc.  */
1283 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)1284 print_filtered_help (unsigned int include_flags,
1285 		     unsigned int exclude_flags,
1286 		     unsigned int any_flags,
1287 		     unsigned int columns,
1288 		     struct gcc_options *opts,
1289 		     unsigned int lang_mask)
1290 {
1291   unsigned int i;
1292   const char *help;
1293   bool found = false;
1294   bool displayed = false;
1295   char new_help[256];
1296 
1297   if (!opts->x_help_printed)
1298     opts->x_help_printed = XCNEWVAR (char, cl_options_count);
1299 
1300   if (!opts->x_help_enum_printed)
1301     opts->x_help_enum_printed = XCNEWVAR (char, cl_enums_count);
1302 
1303   auto_vec<option_help_tuple> help_tuples;
1304 
1305   for (i = 0; i < cl_options_count; i++)
1306     {
1307       const struct cl_option *option = cl_options + i;
1308       unsigned int len;
1309       const char *opt;
1310       const char *tab;
1311 
1312       if (include_flags == 0
1313 	  || ((option->flags & include_flags) != include_flags))
1314 	{
1315 	  if ((option->flags & any_flags) == 0)
1316 	    continue;
1317 	}
1318 
1319       /* Skip unwanted switches.  */
1320       if ((option->flags & exclude_flags) != 0)
1321 	continue;
1322 
1323       /* The driver currently prints its own help text.  */
1324       if ((option->flags & CL_DRIVER) != 0
1325 	  && (option->flags & (((1U << cl_lang_count) - 1)
1326 			       | CL_COMMON | CL_TARGET)) == 0)
1327 	continue;
1328 
1329       /* If an option contains a language specification,
1330 	 exclude it from common unless all languages are present.  */
1331       if ((include_flags & CL_COMMON)
1332 	  && !(option->flags & CL_DRIVER)
1333 	  && (option->flags & CL_LANG_ALL)
1334 	  && (option->flags & CL_LANG_ALL) != CL_LANG_ALL)
1335 	continue;
1336 
1337       found = true;
1338       /* Skip switches that have already been printed.  */
1339       if (opts->x_help_printed[i])
1340 	continue;
1341 
1342       opts->x_help_printed[i] = true;
1343 
1344       help = option->help;
1345       if (help == NULL)
1346 	{
1347 	  if (exclude_flags & CL_UNDOCUMENTED)
1348 	    continue;
1349 
1350 	  help = undocumented_msg;
1351 	}
1352 
1353       /* Get the translation.  */
1354       help = _(help);
1355 
1356       if (option->alias_target < N_OPTS
1357 	  && cl_options [option->alias_target].help)
1358 	{
1359 	  const struct cl_option *target = cl_options + option->alias_target;
1360 	  if (option->help == NULL)
1361 	    {
1362 	      /* The option is undocumented but is an alias for an option that
1363 		 is documented.  If the option has alias arguments, then its
1364 		 purpose is to provide certain arguments to the other option, so
1365 		 inform the reader of this.  Otherwise, point the reader to the
1366 		 other option in preference to the former.  */
1367 
1368 	      if (option->alias_arg)
1369 		{
1370 		  if (option->neg_alias_arg)
1371 		    snprintf (new_help, sizeof new_help,
1372 			      _("Same as %s%s (or, in negated form, %s%s)."),
1373 			      target->opt_text, option->alias_arg,
1374 			      target->opt_text, option->neg_alias_arg);
1375 		  else
1376 		    snprintf (new_help, sizeof new_help,
1377 			      _("Same as %s%s."),
1378 			      target->opt_text, option->alias_arg);
1379 		}
1380 	      else
1381 		snprintf (new_help, sizeof new_help,
1382 			  _("Same as %s."),
1383 			  target->opt_text);
1384 	    }
1385 	  else
1386 	    {
1387 	      /* For documented options with aliases, mention the aliased
1388 		 option's name for reference.  */
1389 	      snprintf (new_help, sizeof new_help,
1390 			_("%s  Same as %s."),
1391 			help, cl_options [option->alias_target].opt_text);
1392 	    }
1393 
1394 	  help = new_help;
1395 	}
1396 
1397       if (option->warn_message)
1398 	{
1399 	  /* Mention that the use of the option will trigger a warning.  */
1400 	  if (help == new_help)
1401 	    snprintf (new_help + strlen (new_help),
1402 		      sizeof new_help - strlen (new_help),
1403 		      "  %s", _(use_diagnosed_msg));
1404 	  else
1405 	    snprintf (new_help, sizeof new_help,
1406 		      "%s  %s", help, _(use_diagnosed_msg));
1407 
1408 	  help = new_help;
1409 	}
1410 
1411       /* Find the gap between the name of the
1412 	 option and its descriptive text.  */
1413       tab = strchr (help, '\t');
1414       if (tab)
1415 	{
1416 	  len = tab - help;
1417 	  opt = help;
1418 	  help = tab + 1;
1419 	}
1420       else
1421 	{
1422 	  opt = option->opt_text;
1423 	  len = strlen (opt);
1424 	}
1425 
1426       /* With the -Q option enabled we change the descriptive text associated
1427 	 with an option to be an indication of its current setting.  */
1428       if (!opts->x_quiet_flag)
1429 	{
1430 	  void *flag_var = option_flag_var (i, opts);
1431 
1432 	  if (len < (LEFT_COLUMN + 2))
1433 	    strcpy (new_help, "\t\t");
1434 	  else
1435 	    strcpy (new_help, "\t");
1436 
1437 	  /* Set to print whether the option is enabled or disabled,
1438 	     or, if it's an alias for another option, the name of
1439 	     the aliased option.  */
1440 	  bool print_state = false;
1441 
1442 	  if (flag_var != NULL
1443 	      && option->var_type != CLVC_DEFER)
1444 	    {
1445 	      /* If OPTION is only available for a specific subset
1446 		 of languages other than this one, mention them.  */
1447 	      bool avail_for_lang = true;
1448 	      if (unsigned langset = option->flags & CL_LANG_ALL)
1449 		{
1450 		  if (!(langset & lang_mask))
1451 		    {
1452 		      avail_for_lang = false;
1453 		      strcat (new_help, _("[available in "));
1454 		      for (unsigned i = 0, n = 0; (1U << i) < CL_LANG_ALL; ++i)
1455 			if (langset & (1U << i))
1456 			  {
1457 			    if (n++)
1458 			      strcat (new_help, ", ");
1459 			    strcat (new_help, lang_names[i]);
1460 			  }
1461 		      strcat (new_help, "]");
1462 		    }
1463 		}
1464 	      if (!avail_for_lang)
1465 		; /* Print nothing else if the option is not available
1466 		     in the current language.  */
1467 	      else if (option->flags & CL_JOINED)
1468 		{
1469 		  if (option->var_type == CLVC_STRING)
1470 		    {
1471 		      if (* (const char **) flag_var != NULL)
1472 			snprintf (new_help + strlen (new_help),
1473 				  sizeof (new_help) - strlen (new_help),
1474 				  "%s", * (const char **) flag_var);
1475 		    }
1476 		  else if (option->var_type == CLVC_ENUM)
1477 		    {
1478 		      const struct cl_enum *e = &cl_enums[option->var_enum];
1479 		      int value;
1480 		      const char *arg = NULL;
1481 
1482 		      value = e->get (flag_var);
1483 		      enum_value_to_arg (e->values, &arg, value, lang_mask);
1484 		      if (arg == NULL)
1485 			arg = _("[default]");
1486 		      snprintf (new_help + strlen (new_help),
1487 				sizeof (new_help) - strlen (new_help),
1488 				"%s", arg);
1489 		    }
1490 		  else
1491 		    {
1492 		      if (option->cl_host_wide_int)
1493 			sprintf (new_help + strlen (new_help),
1494 				 _("%llu bytes"), (unsigned long long)
1495 				 *(unsigned HOST_WIDE_INT *) flag_var);
1496 		      else
1497 			sprintf (new_help + strlen (new_help),
1498 				 "%i", * (int *) flag_var);
1499 		    }
1500 		}
1501 	      else
1502 		print_state = true;
1503 	    }
1504 	  else
1505 	    /* When there is no argument, print the option state only
1506 	       if the option takes no argument.  */
1507 	    print_state = !(option->flags & CL_JOINED);
1508 
1509 	  if (print_state)
1510 	    {
1511 	      if (option->alias_target < N_OPTS
1512 		  && option->alias_target != OPT_SPECIAL_warn_removed
1513 		  && option->alias_target != OPT_SPECIAL_ignore
1514 		  && option->alias_target != OPT_SPECIAL_input_file
1515 		  && option->alias_target != OPT_SPECIAL_program_name
1516 		  && option->alias_target != OPT_SPECIAL_unknown)
1517 		{
1518 		  const struct cl_option *target
1519 		    = &cl_options[option->alias_target];
1520 		  sprintf (new_help + strlen (new_help), "%s%s",
1521 			   target->opt_text,
1522 			   option->alias_arg ? option->alias_arg : "");
1523 		}
1524 	      else if (option->alias_target == OPT_SPECIAL_ignore)
1525 		strcat (new_help, ("[ignored]"));
1526 	      else
1527 		{
1528 		  /* Print the state for an on/off option.  */
1529 		  int ena = option_enabled (i, lang_mask, opts);
1530 		  if (ena > 0)
1531 		    strcat (new_help, _("[enabled]"));
1532 		  else if (ena == 0)
1533 		    strcat (new_help, _("[disabled]"));
1534 		}
1535 	    }
1536 
1537 	  help = new_help;
1538 	}
1539 
1540       if (option->range_max != -1)
1541 	{
1542 	  char b[128];
1543 	  snprintf (b, sizeof (b), "<%d,%d>", option->range_min,
1544 		    option->range_max);
1545 	  opt = concat (opt, b, NULL);
1546 	  len += strlen (b);
1547 	}
1548 
1549       wrap_help (help, opt, len, columns);
1550       displayed = true;
1551 
1552       if (option->var_type == CLVC_ENUM
1553 	  && opts->x_help_enum_printed[option->var_enum] != 2)
1554 	opts->x_help_enum_printed[option->var_enum] = 1;
1555       else
1556 	{
1557 	  vec<const char *> option_values
1558 	    = targetm_common.get_valid_option_values (i, NULL);
1559 	  if (!option_values.is_empty ())
1560 	    help_tuples.safe_push (option_help_tuple (i, option_values));
1561 	}
1562     }
1563 
1564   if (! found)
1565     {
1566       unsigned int langs = include_flags & CL_LANG_ALL;
1567 
1568       if (langs == 0)
1569 	printf (_(" No options with the desired characteristics were found\n"));
1570       else
1571 	{
1572 	  unsigned int i;
1573 
1574 	  /* PR 31349: Tell the user how to see all of the
1575 	     options supported by a specific front end.  */
1576 	  for (i = 0; (1U << i) < CL_LANG_ALL; i ++)
1577 	    if ((1U << i) & langs)
1578 	      printf (_(" None found.  Use --help=%s to show *all* the options supported by the %s front-end.\n"),
1579 		      lang_names[i], lang_names[i]);
1580 	}
1581 
1582     }
1583   else if (! displayed)
1584     printf (_(" All options with the desired characteristics have already been displayed\n"));
1585 
1586   putchar ('\n');
1587 
1588   /* Print details of enumerated option arguments, if those
1589      enumerations have help text headings provided.  If no help text
1590      is provided, presume that the possible values are listed in the
1591      help text for the relevant options.  */
1592   for (i = 0; i < cl_enums_count; i++)
1593     {
1594       unsigned int j, pos;
1595 
1596       if (opts->x_help_enum_printed[i] != 1)
1597 	continue;
1598       if (cl_enums[i].help == NULL)
1599 	continue;
1600       printf ("  %s\n    ", _(cl_enums[i].help));
1601       pos = 4;
1602       for (j = 0; cl_enums[i].values[j].arg != NULL; j++)
1603 	{
1604 	  unsigned int len = strlen (cl_enums[i].values[j].arg);
1605 
1606 	  if (pos > 4 && pos + 1 + len <= columns)
1607 	    {
1608 	      printf (" %s", cl_enums[i].values[j].arg);
1609 	      pos += 1 + len;
1610 	    }
1611 	  else
1612 	    {
1613 	      if (pos > 4)
1614 		{
1615 		  printf ("\n    ");
1616 		  pos = 4;
1617 		}
1618 	      printf ("%s", cl_enums[i].values[j].arg);
1619 	      pos += len;
1620 	    }
1621 	}
1622       printf ("\n\n");
1623       opts->x_help_enum_printed[i] = 2;
1624     }
1625 
1626   for (unsigned i = 0; i < help_tuples.length (); i++)
1627     {
1628       const struct cl_option *option = cl_options + help_tuples[i].m_code;
1629       printf (_("  Known valid arguments for %s option:\n   "),
1630 	      option->opt_text);
1631       for (unsigned j = 0; j < help_tuples[i].m_values.length (); j++)
1632 	printf (" %s", help_tuples[i].m_values[j]);
1633       printf ("\n\n");
1634     }
1635 }
1636 
1637 /* Display help for a specified type of option.
1638    The options must have ALL of the INCLUDE_FLAGS set
1639    ANY of the flags in the ANY_FLAGS set
1640    and NONE of the EXCLUDE_FLAGS set.  The current option state is in
1641    OPTS; LANG_MASK is used for interpreting enumerated option state.  */
1642 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)1643 print_specific_help (unsigned int include_flags,
1644 		     unsigned int exclude_flags,
1645 		     unsigned int any_flags,
1646 		     struct gcc_options *opts,
1647 		     unsigned int lang_mask)
1648 {
1649   unsigned int all_langs_mask = (1U << cl_lang_count) - 1;
1650   const char * description = NULL;
1651   const char * descrip_extra = "";
1652   size_t i;
1653   unsigned int flag;
1654 
1655   /* Sanity check: Make sure that we do not have more
1656      languages than we have bits available to enumerate them.  */
1657   gcc_assert ((1U << cl_lang_count) <= CL_MIN_OPTION_CLASS);
1658 
1659   /* If we have not done so already, obtain
1660      the desired maximum width of the output.  */
1661   if (opts->x_help_columns == 0)
1662     {
1663       opts->x_help_columns = get_terminal_width ();
1664       if (opts->x_help_columns == INT_MAX)
1665 	/* Use a reasonable default.  */
1666 	opts->x_help_columns = 80;
1667     }
1668 
1669   /* Decide upon the title for the options that we are going to display.  */
1670   for (i = 0, flag = 1; flag <= CL_MAX_OPTION_CLASS; flag <<= 1, i ++)
1671     {
1672       switch (flag & include_flags)
1673 	{
1674 	case 0:
1675 	case CL_DRIVER:
1676 	  break;
1677 
1678 	case CL_TARGET:
1679 	  description = _("The following options are target specific");
1680 	  break;
1681 	case CL_WARNING:
1682 	  description = _("The following options control compiler warning messages");
1683 	  break;
1684 	case CL_OPTIMIZATION:
1685 	  description = _("The following options control optimizations");
1686 	  break;
1687 	case CL_COMMON:
1688 	  description = _("The following options are language-independent");
1689 	  break;
1690 	case CL_PARAMS:
1691 	  description = _("The following options control parameters");
1692 	  break;
1693 	default:
1694 	  if (i >= cl_lang_count)
1695 	    break;
1696 	  if (exclude_flags & all_langs_mask)
1697 	    description = _("The following options are specific to just the language ");
1698 	  else
1699 	    description = _("The following options are supported by the language ");
1700 	  descrip_extra = lang_names [i];
1701 	  break;
1702 	}
1703     }
1704 
1705   if (description == NULL)
1706     {
1707       if (any_flags == 0)
1708 	{
1709 	  if (include_flags & CL_UNDOCUMENTED)
1710 	    description = _("The following options are not documented");
1711 	  else if (include_flags & CL_SEPARATE)
1712 	    description = _("The following options take separate arguments");
1713 	  else if (include_flags & CL_JOINED)
1714 	    description = _("The following options take joined arguments");
1715 	  else
1716 	    {
1717 	      internal_error ("unrecognized %<include_flags 0x%x%> passed "
1718 			      "to %<print_specific_help%>",
1719 			      include_flags);
1720 	      return;
1721 	    }
1722 	}
1723       else
1724 	{
1725 	  if (any_flags & all_langs_mask)
1726 	    description = _("The following options are language-related");
1727 	  else
1728 	    description = _("The following options are language-independent");
1729 	}
1730     }
1731 
1732   printf ("%s%s:\n", description, descrip_extra);
1733   print_filtered_help (include_flags, exclude_flags, any_flags,
1734 		       opts->x_help_columns, opts, lang_mask);
1735 }
1736 
1737 /* Enable FDO-related flags.  */
1738 
1739 static void
enable_fdo_optimizations(struct gcc_options * opts,struct gcc_options * opts_set,int value)1740 enable_fdo_optimizations (struct gcc_options *opts,
1741 			  struct gcc_options *opts_set,
1742 			  int value)
1743 {
1744   SET_OPTION_IF_UNSET (opts, opts_set, flag_branch_probabilities, value);
1745   SET_OPTION_IF_UNSET (opts, opts_set, flag_profile_values, value);
1746   SET_OPTION_IF_UNSET (opts, opts_set, flag_unroll_loops, value);
1747   SET_OPTION_IF_UNSET (opts, opts_set, flag_peel_loops, value);
1748   SET_OPTION_IF_UNSET (opts, opts_set, flag_tracer, value);
1749   SET_OPTION_IF_UNSET (opts, opts_set, flag_value_profile_transformations,
1750 		       value);
1751   SET_OPTION_IF_UNSET (opts, opts_set, flag_inline_functions, value);
1752   SET_OPTION_IF_UNSET (opts, opts_set, flag_ipa_cp, value);
1753   if (value)
1754     {
1755       SET_OPTION_IF_UNSET (opts, opts_set, flag_ipa_cp_clone, 1);
1756       SET_OPTION_IF_UNSET (opts, opts_set, flag_ipa_bit_cp, 1);
1757     }
1758   SET_OPTION_IF_UNSET (opts, opts_set, flag_predictive_commoning, value);
1759   SET_OPTION_IF_UNSET (opts, opts_set, flag_split_loops, value);
1760   SET_OPTION_IF_UNSET (opts, opts_set, flag_unswitch_loops, value);
1761   SET_OPTION_IF_UNSET (opts, opts_set, flag_gcse_after_reload, value);
1762   SET_OPTION_IF_UNSET (opts, opts_set, flag_tree_loop_vectorize, value);
1763   SET_OPTION_IF_UNSET (opts, opts_set, flag_tree_slp_vectorize, value);
1764   SET_OPTION_IF_UNSET (opts, opts_set, flag_version_loops_for_strides, value);
1765   SET_OPTION_IF_UNSET (opts, opts_set, flag_vect_cost_model,
1766 		       VECT_COST_MODEL_DYNAMIC);
1767   SET_OPTION_IF_UNSET (opts, opts_set, flag_tree_loop_distribute_patterns,
1768 		       value);
1769   SET_OPTION_IF_UNSET (opts, opts_set, flag_loop_interchange, value);
1770   SET_OPTION_IF_UNSET (opts, opts_set, flag_unroll_jam, value);
1771   SET_OPTION_IF_UNSET (opts, opts_set, flag_tree_loop_distribution, value);
1772 }
1773 
1774 /* -f{,no-}sanitize{,-recover}= suboptions.  */
1775 const struct sanitizer_opts_s sanitizer_opts[] =
1776 {
1777 #define SANITIZER_OPT(name, flags, recover) \
1778     { #name, flags, sizeof #name - 1, recover }
1779   SANITIZER_OPT (address, (SANITIZE_ADDRESS | SANITIZE_USER_ADDRESS), true),
1780   SANITIZER_OPT (hwaddress, (SANITIZE_HWADDRESS | SANITIZE_USER_HWADDRESS),
1781 		 true),
1782   SANITIZER_OPT (kernel-address, (SANITIZE_ADDRESS | SANITIZE_KERNEL_ADDRESS),
1783 		 true),
1784   SANITIZER_OPT (kernel-hwaddress,
1785 		 (SANITIZE_HWADDRESS | SANITIZE_KERNEL_HWADDRESS),
1786 		 true),
1787   SANITIZER_OPT (pointer-compare, SANITIZE_POINTER_COMPARE, true),
1788   SANITIZER_OPT (pointer-subtract, SANITIZE_POINTER_SUBTRACT, true),
1789   SANITIZER_OPT (thread, SANITIZE_THREAD, false),
1790   SANITIZER_OPT (leak, SANITIZE_LEAK, false),
1791   SANITIZER_OPT (shift, SANITIZE_SHIFT, true),
1792   SANITIZER_OPT (shift-base, SANITIZE_SHIFT_BASE, true),
1793   SANITIZER_OPT (shift-exponent, SANITIZE_SHIFT_EXPONENT, true),
1794   SANITIZER_OPT (integer-divide-by-zero, SANITIZE_DIVIDE, true),
1795   SANITIZER_OPT (undefined, SANITIZE_UNDEFINED, true),
1796   SANITIZER_OPT (unreachable, SANITIZE_UNREACHABLE, false),
1797   SANITIZER_OPT (vla-bound, SANITIZE_VLA, true),
1798   SANITIZER_OPT (return, SANITIZE_RETURN, false),
1799   SANITIZER_OPT (null, SANITIZE_NULL, true),
1800   SANITIZER_OPT (signed-integer-overflow, SANITIZE_SI_OVERFLOW, true),
1801   SANITIZER_OPT (bool, SANITIZE_BOOL, true),
1802   SANITIZER_OPT (enum, SANITIZE_ENUM, true),
1803   SANITIZER_OPT (float-divide-by-zero, SANITIZE_FLOAT_DIVIDE, true),
1804   SANITIZER_OPT (float-cast-overflow, SANITIZE_FLOAT_CAST, true),
1805   SANITIZER_OPT (bounds, SANITIZE_BOUNDS, true),
1806   SANITIZER_OPT (bounds-strict, SANITIZE_BOUNDS | SANITIZE_BOUNDS_STRICT, true),
1807   SANITIZER_OPT (alignment, SANITIZE_ALIGNMENT, true),
1808   SANITIZER_OPT (nonnull-attribute, SANITIZE_NONNULL_ATTRIBUTE, true),
1809   SANITIZER_OPT (returns-nonnull-attribute, SANITIZE_RETURNS_NONNULL_ATTRIBUTE,
1810 		 true),
1811   SANITIZER_OPT (object-size, SANITIZE_OBJECT_SIZE, true),
1812   SANITIZER_OPT (vptr, SANITIZE_VPTR, true),
1813   SANITIZER_OPT (pointer-overflow, SANITIZE_POINTER_OVERFLOW, true),
1814   SANITIZER_OPT (builtin, SANITIZE_BUILTIN, true),
1815   SANITIZER_OPT (all, ~0U, true),
1816 #undef SANITIZER_OPT
1817   { NULL, 0U, 0UL, false }
1818 };
1819 
1820 /* -f{,no-}sanitize-coverage= suboptions.  */
1821 const struct sanitizer_opts_s coverage_sanitizer_opts[] =
1822 {
1823 #define COVERAGE_SANITIZER_OPT(name, flags) \
1824     { #name, flags, sizeof #name - 1, true }
1825   COVERAGE_SANITIZER_OPT (trace-pc, SANITIZE_COV_TRACE_PC),
1826   COVERAGE_SANITIZER_OPT (trace-cmp, SANITIZE_COV_TRACE_CMP),
1827 #undef COVERAGE_SANITIZER_OPT
1828   { NULL, 0U, 0UL, false }
1829 };
1830 
1831 /* -fzero-call-used-regs= suboptions.  */
1832 const struct zero_call_used_regs_opts_s zero_call_used_regs_opts[] =
1833 {
1834 #define ZERO_CALL_USED_REGS_OPT(name, flags) \
1835     { #name, flags }
1836   ZERO_CALL_USED_REGS_OPT (skip, zero_regs_flags::SKIP),
1837   ZERO_CALL_USED_REGS_OPT (used-gpr-arg, zero_regs_flags::USED_GPR_ARG),
1838   ZERO_CALL_USED_REGS_OPT (used-gpr, zero_regs_flags::USED_GPR),
1839   ZERO_CALL_USED_REGS_OPT (used-arg, zero_regs_flags::USED_ARG),
1840   ZERO_CALL_USED_REGS_OPT (used, zero_regs_flags::USED),
1841   ZERO_CALL_USED_REGS_OPT (all-gpr-arg, zero_regs_flags::ALL_GPR_ARG),
1842   ZERO_CALL_USED_REGS_OPT (all-gpr, zero_regs_flags::ALL_GPR),
1843   ZERO_CALL_USED_REGS_OPT (all-arg, zero_regs_flags::ALL_ARG),
1844   ZERO_CALL_USED_REGS_OPT (all, zero_regs_flags::ALL),
1845 #undef ZERO_CALL_USED_REGS_OPT
1846   {NULL, 0U}
1847 };
1848 
1849 /* A struct for describing a run of chars within a string.  */
1850 
1851 class string_fragment
1852 {
1853 public:
string_fragment(const char * start,size_t len)1854   string_fragment (const char *start, size_t len)
1855   : m_start (start), m_len (len) {}
1856 
1857   const char *m_start;
1858   size_t m_len;
1859 };
1860 
1861 /* Specialization of edit_distance_traits for string_fragment,
1862    for use by get_closest_sanitizer_option.  */
1863 
1864 template <>
1865 struct edit_distance_traits<const string_fragment &>
1866 {
1867   static size_t get_length (const string_fragment &fragment)
1868   {
1869     return fragment.m_len;
1870   }
1871 
1872   static const char *get_string (const string_fragment &fragment)
1873   {
1874     return fragment.m_start;
1875   }
1876 };
1877 
1878 /* Given ARG, an unrecognized sanitizer option, return the best
1879    matching sanitizer option, or NULL if there isn't one.
1880    OPTS is array of candidate sanitizer options.
1881    CODE is OPT_fsanitize_, OPT_fsanitize_recover_ or
1882    OPT_fsanitize_coverage_.
1883    VALUE is non-zero for the regular form of the option, zero
1884    for the "no-" form (e.g. "-fno-sanitize-recover=").  */
1885 
1886 static const char *
1887 get_closest_sanitizer_option (const string_fragment &arg,
1888 			      const struct sanitizer_opts_s *opts,
1889 			      enum opt_code code, int value)
1890 {
1891   best_match <const string_fragment &, const char*> bm (arg);
1892   for (int i = 0; opts[i].name != NULL; ++i)
1893     {
1894       /* -fsanitize=all is not valid, so don't offer it.  */
1895       if (code == OPT_fsanitize_
1896 	  && opts[i].flag == ~0U
1897 	  && value)
1898 	continue;
1899 
1900       /* For -fsanitize-recover= (and not -fno-sanitize-recover=),
1901 	 don't offer the non-recoverable options.  */
1902       if (code == OPT_fsanitize_recover_
1903 	  && !opts[i].can_recover
1904 	  && value)
1905 	continue;
1906 
1907       bm.consider (opts[i].name);
1908     }
1909   return bm.get_best_meaningful_candidate ();
1910 }
1911 
1912 /* Parse comma separated sanitizer suboptions from P for option SCODE,
1913    adjust previous FLAGS and return new ones.  If COMPLAIN is false,
1914    don't issue diagnostics.  */
1915 
1916 unsigned int
1917 parse_sanitizer_options (const char *p, location_t loc, int scode,
1918 			 unsigned int flags, int value, bool complain)
1919 {
1920   enum opt_code code = (enum opt_code) scode;
1921 
1922   const struct sanitizer_opts_s *opts;
1923   if (code == OPT_fsanitize_coverage_)
1924     opts = coverage_sanitizer_opts;
1925   else
1926     opts = sanitizer_opts;
1927 
1928   while (*p != 0)
1929     {
1930       size_t len, i;
1931       bool found = false;
1932       const char *comma = strchr (p, ',');
1933 
1934       if (comma == NULL)
1935 	len = strlen (p);
1936       else
1937 	len = comma - p;
1938       if (len == 0)
1939 	{
1940 	  p = comma + 1;
1941 	  continue;
1942 	}
1943 
1944       /* Check to see if the string matches an option class name.  */
1945       for (i = 0; opts[i].name != NULL; ++i)
1946 	if (len == opts[i].len && memcmp (p, opts[i].name, len) == 0)
1947 	  {
1948 	    /* Handle both -fsanitize and -fno-sanitize cases.  */
1949 	    if (value && opts[i].flag == ~0U)
1950 	      {
1951 		if (code == OPT_fsanitize_)
1952 		  {
1953 		    if (complain)
1954 		      error_at (loc, "%<-fsanitize=all%> option is not valid");
1955 		  }
1956 		else
1957 		  flags |= ~(SANITIZE_THREAD | SANITIZE_LEAK
1958 			     | SANITIZE_UNREACHABLE | SANITIZE_RETURN);
1959 	      }
1960 	    else if (value)
1961 	      {
1962 		/* Do not enable -fsanitize-recover=unreachable and
1963 		   -fsanitize-recover=return if -fsanitize-recover=undefined
1964 		   is selected.  */
1965 		if (code == OPT_fsanitize_recover_
1966 		    && opts[i].flag == SANITIZE_UNDEFINED)
1967 		  flags |= (SANITIZE_UNDEFINED
1968 			    & ~(SANITIZE_UNREACHABLE | SANITIZE_RETURN));
1969 		else
1970 		  flags |= opts[i].flag;
1971 	      }
1972 	    else
1973 	      flags &= ~opts[i].flag;
1974 	    found = true;
1975 	    break;
1976 	  }
1977 
1978       if (! found && complain)
1979 	{
1980 	  const char *hint
1981 	    = get_closest_sanitizer_option (string_fragment (p, len),
1982 					    opts, code, value);
1983 
1984 	  const char *suffix;
1985 	  if (code == OPT_fsanitize_recover_)
1986 	    suffix = "-recover";
1987 	  else if (code == OPT_fsanitize_coverage_)
1988 	    suffix = "-coverage";
1989 	  else
1990 	    suffix = "";
1991 
1992 	  if (hint)
1993 	    error_at (loc,
1994 		      "unrecognized argument to %<-f%ssanitize%s=%> "
1995 		      "option: %q.*s; did you mean %qs?",
1996 		      value ? "" : "no-",
1997 		      suffix, (int) len, p, hint);
1998 	  else
1999 	    error_at (loc,
2000 		      "unrecognized argument to %<-f%ssanitize%s=%> option: "
2001 		      "%q.*s", value ? "" : "no-",
2002 		      suffix, (int) len, p);
2003 	}
2004 
2005       if (comma == NULL)
2006 	break;
2007       p = comma + 1;
2008     }
2009   return flags;
2010 }
2011 
2012 /* Parse string values of no_sanitize attribute passed in VALUE.
2013    Values are separated with comma.  */
2014 
2015 unsigned int
2016 parse_no_sanitize_attribute (char *value)
2017 {
2018   unsigned int flags = 0;
2019   unsigned int i;
2020   char *q = strtok (value, ",");
2021 
2022   while (q != NULL)
2023     {
2024       for (i = 0; sanitizer_opts[i].name != NULL; ++i)
2025 	if (strcmp (sanitizer_opts[i].name, q) == 0)
2026 	  {
2027 	    flags |= sanitizer_opts[i].flag;
2028 	    if (sanitizer_opts[i].flag == SANITIZE_UNDEFINED)
2029 	      flags |= SANITIZE_UNDEFINED_NONDEFAULT;
2030 	    break;
2031 	  }
2032 
2033       if (sanitizer_opts[i].name == NULL)
2034 	warning (OPT_Wattributes,
2035 		 "%qs attribute directive ignored", q);
2036 
2037       q = strtok (NULL, ",");
2038     }
2039 
2040   return flags;
2041 }
2042 
2043 /* Parse -fzero-call-used-regs suboptions from ARG, return the FLAGS.  */
2044 
2045 unsigned int
2046 parse_zero_call_used_regs_options (const char *arg)
2047 {
2048   unsigned int flags = 0;
2049 
2050   /* Check to see if the string matches a sub-option name.  */
2051   for (unsigned int i = 0; zero_call_used_regs_opts[i].name != NULL; ++i)
2052     if (strcmp (arg, zero_call_used_regs_opts[i].name) == 0)
2053       {
2054 	flags = zero_call_used_regs_opts[i].flag;
2055 	break;
2056       }
2057 
2058   if (!flags)
2059     error ("unrecognized argument to %<-fzero-call-used-regs=%>: %qs", arg);
2060 
2061   return flags;
2062 }
2063 
2064 /* Parse -falign-NAME format for a FLAG value.  Return individual
2065    parsed integer values into RESULT_VALUES array.  If REPORT_ERROR is
2066    set, print error message at LOC location.  */
2067 
2068 bool
2069 parse_and_check_align_values (const char *flag,
2070 			      const char *name,
2071 			      auto_vec<unsigned> &result_values,
2072 			      bool report_error,
2073 			      location_t loc)
2074 {
2075   char *str = xstrdup (flag);
2076   for (char *p = strtok (str, ":"); p; p = strtok (NULL, ":"))
2077     {
2078       char *end;
2079       int v = strtol (p, &end, 10);
2080       if (*end != '\0' || v < 0)
2081 	{
2082 	  if (report_error)
2083 	    error_at (loc, "invalid arguments for %<-falign-%s%> option: %qs",
2084 		      name, flag);
2085 
2086 	  return false;
2087 	}
2088 
2089       result_values.safe_push ((unsigned)v);
2090     }
2091 
2092   free (str);
2093 
2094   /* Check that we have a correct number of values.  */
2095   if (result_values.is_empty () || result_values.length () > 4)
2096     {
2097       if (report_error)
2098 	error_at (loc, "invalid number of arguments for %<-falign-%s%> "
2099 		  "option: %qs", name, flag);
2100       return false;
2101     }
2102 
2103   for (unsigned i = 0; i < result_values.length (); i++)
2104     if (result_values[i] > MAX_CODE_ALIGN_VALUE)
2105       {
2106 	if (report_error)
2107 	  error_at (loc, "%<-falign-%s%> is not between 0 and %d",
2108 		    name, MAX_CODE_ALIGN_VALUE);
2109 	return false;
2110       }
2111 
2112   return true;
2113 }
2114 
2115 /* Check that alignment value FLAG for -falign-NAME is valid at a given
2116    location LOC. OPT_STR points to the stored -falign-NAME=argument and
2117    OPT_FLAG points to the associated -falign-NAME on/off flag.  */
2118 
2119 static void
2120 check_alignment_argument (location_t loc, const char *flag, const char *name,
2121 			  int *opt_flag, const char **opt_str)
2122 {
2123   auto_vec<unsigned> align_result;
2124   parse_and_check_align_values (flag, name, align_result, true, loc);
2125 
2126   if (align_result.length() >= 1 && align_result[0] == 0)
2127     {
2128       *opt_flag = 1;
2129       *opt_str = NULL;
2130     }
2131 }
2132 
2133 /* Parse argument of -fpatchable-function-entry option ARG and store
2134    corresponding values to PATCH_AREA_SIZE and PATCH_AREA_START.
2135    If REPORT_ERROR is set to true, generate error for a problematic
2136    option arguments.  */
2137 
2138 void
2139 parse_and_check_patch_area (const char *arg, bool report_error,
2140 			    HOST_WIDE_INT *patch_area_size,
2141 			    HOST_WIDE_INT *patch_area_start)
2142 {
2143   *patch_area_size = 0;
2144   *patch_area_start = 0;
2145 
2146   if (arg == NULL)
2147     return;
2148 
2149   char *patch_area_arg = xstrdup (arg);
2150   char *comma = strchr (patch_area_arg, ',');
2151   if (comma)
2152     {
2153       *comma = '\0';
2154       *patch_area_size = integral_argument (patch_area_arg);
2155       *patch_area_start = integral_argument (comma + 1);
2156     }
2157   else
2158     *patch_area_size = integral_argument (patch_area_arg);
2159 
2160   if (*patch_area_size < 0
2161       || *patch_area_size > USHRT_MAX
2162       || *patch_area_start < 0
2163       || *patch_area_start > USHRT_MAX
2164       || *patch_area_size < *patch_area_start)
2165     if (report_error)
2166       error ("invalid arguments for %<-fpatchable-function-entry%>");
2167 
2168   free (patch_area_arg);
2169 }
2170 
2171 /* Print help when OPT__help_ is set.  */
2172 
2173 void
2174 print_help (struct gcc_options *opts, unsigned int lang_mask,
2175 	    const char *help_option_argument)
2176 {
2177   const char *a = help_option_argument;
2178   unsigned int include_flags = 0;
2179   /* Note - by default we include undocumented options when listing
2180      specific classes.  If you only want to see documented options
2181      then add ",^undocumented" to the --help= option.  E.g.:
2182 
2183      --help=target,^undocumented  */
2184   unsigned int exclude_flags = 0;
2185 
2186   if (lang_mask == CL_DRIVER)
2187     return;
2188 
2189   /* Walk along the argument string, parsing each word in turn.
2190      The format is:
2191      arg = [^]{word}[,{arg}]
2192      word = {optimizers|target|warnings|undocumented|
2193      params|common|<language>}  */
2194   while (*a != 0)
2195     {
2196       static const struct
2197 	{
2198 	  const char *string;
2199 	  unsigned int flag;
2200 	}
2201       specifics[] =
2202 	{
2203 	    { "optimizers", CL_OPTIMIZATION },
2204 	    { "target", CL_TARGET },
2205 	    { "warnings", CL_WARNING },
2206 	    { "undocumented", CL_UNDOCUMENTED },
2207 	    { "params", CL_PARAMS },
2208 	    { "joined", CL_JOINED },
2209 	    { "separate", CL_SEPARATE },
2210 	    { "common", CL_COMMON },
2211 	    { NULL, 0 }
2212 	};
2213       unsigned int *pflags;
2214       const char *comma;
2215       unsigned int lang_flag, specific_flag;
2216       unsigned int len;
2217       unsigned int i;
2218 
2219       if (*a == '^')
2220 	{
2221 	  ++a;
2222 	  if (*a == '\0')
2223 	    {
2224 	      error ("missing argument to %qs", "--help=^");
2225 	      break;
2226 	    }
2227 	  pflags = &exclude_flags;
2228 	}
2229       else
2230 	pflags = &include_flags;
2231 
2232       comma = strchr (a, ',');
2233       if (comma == NULL)
2234 	len = strlen (a);
2235       else
2236 	len = comma - a;
2237       if (len == 0)
2238 	{
2239 	  a = comma + 1;
2240 	  continue;
2241 	}
2242 
2243       /* Check to see if the string matches an option class name.  */
2244       for (i = 0, specific_flag = 0; specifics[i].string != NULL; i++)
2245 	if (strncasecmp (a, specifics[i].string, len) == 0)
2246 	  {
2247 	    specific_flag = specifics[i].flag;
2248 	    break;
2249 	  }
2250 
2251       /* Check to see if the string matches a language name.
2252 	 Note - we rely upon the alpha-sorted nature of the entries in
2253 	 the lang_names array, specifically that shorter names appear
2254 	 before their longer variants.  (i.e. C before C++).  That way
2255 	 when we are attempting to match --help=c for example we will
2256 	 match with C first and not C++.  */
2257       for (i = 0, lang_flag = 0; i < cl_lang_count; i++)
2258 	if (strncasecmp (a, lang_names[i], len) == 0)
2259 	  {
2260 	    lang_flag = 1U << i;
2261 	    break;
2262 	  }
2263 
2264       if (specific_flag != 0)
2265 	{
2266 	  if (lang_flag == 0)
2267 	    *pflags |= specific_flag;
2268 	  else
2269 	    {
2270 	      /* The option's argument matches both the start of a
2271 		 language name and the start of an option class name.
2272 		 We have a special case for when the user has
2273 		 specified "--help=c", but otherwise we have to issue
2274 		 a warning.  */
2275 	      if (strncasecmp (a, "c", len) == 0)
2276 		*pflags |= lang_flag;
2277 	      else
2278 		warning (0,
2279 			 "%<--help%> argument %q.*s is ambiguous, "
2280 			 "please be more specific",
2281 			 len, a);
2282 	    }
2283 	}
2284       else if (lang_flag != 0)
2285 	*pflags |= lang_flag;
2286       else
2287 	warning (0,
2288 		 "unrecognized argument to %<--help=%> option: %q.*s",
2289 		 len, a);
2290 
2291       if (comma == NULL)
2292 	break;
2293       a = comma + 1;
2294     }
2295 
2296   /* We started using PerFunction/Optimization for parameters and
2297      a warning.  We should exclude these from optimization options.  */
2298   if (include_flags & CL_OPTIMIZATION)
2299     exclude_flags |= CL_WARNING;
2300   if (!(include_flags & CL_PARAMS))
2301     exclude_flags |= CL_PARAMS;
2302 
2303   if (include_flags)
2304     print_specific_help (include_flags, exclude_flags, 0, opts,
2305 			 lang_mask);
2306 }
2307 
2308 /* Handle target- and language-independent options.  Return zero to
2309    generate an "unknown option" message.  Only options that need
2310    extra handling need to be listed here; if you simply want
2311    DECODED->value assigned to a variable, it happens automatically.  */
2312 
2313 bool
2314 common_handle_option (struct gcc_options *opts,
2315 		      struct gcc_options *opts_set,
2316 		      const struct cl_decoded_option *decoded,
2317 		      unsigned int lang_mask, int kind ATTRIBUTE_UNUSED,
2318 		      location_t loc,
2319 		      const struct cl_option_handlers *handlers,
2320 		      diagnostic_context *dc,
2321 		      void (*target_option_override_hook) (void))
2322 {
2323   size_t scode = decoded->opt_index;
2324   const char *arg = decoded->arg;
2325   HOST_WIDE_INT value = decoded->value;
2326   enum opt_code code = (enum opt_code) scode;
2327 
2328   gcc_assert (decoded->canonical_option_num_elements <= 2);
2329 
2330   switch (code)
2331     {
2332     case OPT__help:
2333       {
2334 	unsigned int all_langs_mask = (1U << cl_lang_count) - 1;
2335 	unsigned int undoc_mask;
2336 	unsigned int i;
2337 
2338 	if (lang_mask == CL_DRIVER)
2339 	  break;
2340 
2341 	undoc_mask = ((opts->x_verbose_flag | opts->x_extra_warnings)
2342 		      ? 0
2343 		      : CL_UNDOCUMENTED);
2344 	target_option_override_hook ();
2345 	/* First display any single language specific options.  */
2346 	for (i = 0; i < cl_lang_count; i++)
2347 	  print_specific_help
2348 	    (1U << i, (all_langs_mask & (~ (1U << i))) | undoc_mask, 0, opts,
2349 	     lang_mask);
2350 	/* Next display any multi language specific options.  */
2351 	print_specific_help (0, undoc_mask, all_langs_mask, opts, lang_mask);
2352 	/* Then display any remaining, non-language options.  */
2353 	for (i = CL_MIN_OPTION_CLASS; i <= CL_MAX_OPTION_CLASS; i <<= 1)
2354 	  if (i != CL_DRIVER)
2355 	    print_specific_help (i, undoc_mask, 0, opts, lang_mask);
2356 	opts->x_exit_after_options = true;
2357 	break;
2358       }
2359 
2360     case OPT__target_help:
2361       if (lang_mask == CL_DRIVER)
2362 	break;
2363 
2364       target_option_override_hook ();
2365       print_specific_help (CL_TARGET, CL_UNDOCUMENTED, 0, opts, lang_mask);
2366       opts->x_exit_after_options = true;
2367       break;
2368 
2369     case OPT__help_:
2370       {
2371 	help_option_arguments.safe_push (arg);
2372 	opts->x_exit_after_options = true;
2373 	break;
2374       }
2375 
2376     case OPT__version:
2377       if (lang_mask == CL_DRIVER)
2378 	break;
2379 
2380       opts->x_exit_after_options = true;
2381       break;
2382 
2383     case OPT__completion_:
2384       break;
2385 
2386     case OPT_fsanitize_:
2387       opts->x_flag_sanitize
2388 	= parse_sanitizer_options (arg, loc, code,
2389 				   opts->x_flag_sanitize, value, true);
2390 
2391       /* Kernel ASan implies normal ASan but does not yet support
2392 	 all features.  */
2393       if (opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS)
2394 	{
2395 	  SET_OPTION_IF_UNSET (opts, opts_set,
2396 			       param_asan_instrumentation_with_call_threshold,
2397 			       0);
2398 	  SET_OPTION_IF_UNSET (opts, opts_set, param_asan_globals, 0);
2399 	  SET_OPTION_IF_UNSET (opts, opts_set, param_asan_stack, 0);
2400 	  SET_OPTION_IF_UNSET (opts, opts_set, param_asan_protect_allocas, 0);
2401 	  SET_OPTION_IF_UNSET (opts, opts_set, param_asan_use_after_return, 0);
2402 	}
2403       if (opts->x_flag_sanitize & SANITIZE_KERNEL_HWADDRESS)
2404 	{
2405 	  SET_OPTION_IF_UNSET (opts, opts_set,
2406 			       param_hwasan_instrument_stack, 0);
2407 	  SET_OPTION_IF_UNSET (opts, opts_set,
2408 			       param_hwasan_random_frame_tag, 0);
2409 	  SET_OPTION_IF_UNSET (opts, opts_set,
2410 			       param_hwasan_instrument_allocas, 0);
2411 	}
2412       break;
2413 
2414     case OPT_fsanitize_recover_:
2415       opts->x_flag_sanitize_recover
2416 	= parse_sanitizer_options (arg, loc, code,
2417 				   opts->x_flag_sanitize_recover, value, true);
2418       break;
2419 
2420     case OPT_fasan_shadow_offset_:
2421       /* Deferred.  */
2422       break;
2423 
2424     case OPT_fsanitize_address_use_after_scope:
2425       opts->x_flag_sanitize_address_use_after_scope = value;
2426       break;
2427 
2428     case OPT_fsanitize_recover:
2429       if (value)
2430 	opts->x_flag_sanitize_recover
2431 	  |= (SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT)
2432 	     & ~(SANITIZE_UNREACHABLE | SANITIZE_RETURN);
2433       else
2434 	opts->x_flag_sanitize_recover
2435 	  &= ~(SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT);
2436       break;
2437 
2438     case OPT_fsanitize_coverage_:
2439       opts->x_flag_sanitize_coverage
2440 	= parse_sanitizer_options (arg, loc, code,
2441 				   opts->x_flag_sanitize_coverage, value, true);
2442       break;
2443 
2444     case OPT_O:
2445     case OPT_Os:
2446     case OPT_Ofast:
2447     case OPT_Og:
2448       /* Currently handled in a prescan.  */
2449       break;
2450 
2451     case OPT_Werror:
2452       dc->warning_as_error_requested = value;
2453       break;
2454 
2455     case OPT_Werror_:
2456       if (lang_mask == CL_DRIVER)
2457 	break;
2458 
2459       enable_warning_as_error (arg, value, lang_mask, handlers,
2460 			       opts, opts_set, loc, dc);
2461       break;
2462 
2463     case OPT_Wfatal_errors:
2464       dc->fatal_errors = value;
2465       break;
2466 
2467     case OPT_Wstack_usage_:
2468       opts->x_flag_stack_usage_info = value != -1;
2469       break;
2470 
2471     case OPT_Wstrict_aliasing:
2472       set_Wstrict_aliasing (opts, value);
2473       break;
2474 
2475     case OPT_Wstrict_overflow:
2476       opts->x_warn_strict_overflow = (value
2477 				      ? (int) WARN_STRICT_OVERFLOW_CONDITIONAL
2478 				      : 0);
2479       break;
2480 
2481     case OPT_Wsystem_headers:
2482       dc->dc_warn_system_headers = value;
2483       break;
2484 
2485     case OPT_aux_info:
2486       opts->x_flag_gen_aux_info = 1;
2487       break;
2488 
2489     case OPT_d:
2490       decode_d_option (arg, opts, loc, dc);
2491       break;
2492 
2493     case OPT_fcall_used_:
2494     case OPT_fcall_saved_:
2495       /* Deferred.  */
2496       break;
2497 
2498     case OPT_fdbg_cnt_:
2499       /* Deferred.  */
2500       break;
2501 
2502     case OPT_fdebug_prefix_map_:
2503     case OPT_ffile_prefix_map_:
2504       /* Deferred.  */
2505       break;
2506 
2507     case OPT_fcallgraph_info:
2508       opts->x_flag_callgraph_info = CALLGRAPH_INFO_NAKED;
2509       break;
2510 
2511     case OPT_fcallgraph_info_:
2512       {
2513 	char *my_arg, *p;
2514 	my_arg = xstrdup (arg);
2515 	p = strtok (my_arg, ",");
2516 	while (p)
2517 	  {
2518 	    if (strcmp (p, "su") == 0)
2519 	      {
2520 		opts->x_flag_callgraph_info |= CALLGRAPH_INFO_STACK_USAGE;
2521 		opts->x_flag_stack_usage_info = true;
2522 	      }
2523 	    else if (strcmp (p, "da") == 0)
2524 	      opts->x_flag_callgraph_info |= CALLGRAPH_INFO_DYNAMIC_ALLOC;
2525 	    else
2526 	      return 0;
2527 	    p = strtok (NULL, ",");
2528 	  }
2529 	free (my_arg);
2530       }
2531       break;
2532 
2533     case OPT_fdiagnostics_show_location_:
2534       diagnostic_prefixing_rule (dc) = (diagnostic_prefixing_rule_t) value;
2535       break;
2536 
2537     case OPT_fdiagnostics_show_caret:
2538       dc->show_caret = value;
2539       break;
2540 
2541     case OPT_fdiagnostics_show_labels:
2542       dc->show_labels_p = value;
2543       break;
2544 
2545     case OPT_fdiagnostics_show_line_numbers:
2546       dc->show_line_numbers_p = value;
2547       break;
2548 
2549     case OPT_fdiagnostics_color_:
2550       diagnostic_color_init (dc, value);
2551       break;
2552 
2553     case OPT_fdiagnostics_urls_:
2554       diagnostic_urls_init (dc, value);
2555       break;
2556 
2557     case OPT_fdiagnostics_format_:
2558       diagnostic_output_format_init (dc,
2559 				     (enum diagnostics_output_format)value);
2560       break;
2561 
2562     case OPT_fdiagnostics_parseable_fixits:
2563       dc->extra_output_kind = (value
2564 			       ? EXTRA_DIAGNOSTIC_OUTPUT_fixits_v1
2565 			       : EXTRA_DIAGNOSTIC_OUTPUT_none);
2566       break;
2567 
2568     case OPT_fdiagnostics_column_unit_:
2569       dc->column_unit = (enum diagnostics_column_unit)value;
2570       break;
2571 
2572     case OPT_fdiagnostics_column_origin_:
2573       dc->column_origin = value;
2574       break;
2575 
2576     case OPT_fdiagnostics_show_cwe:
2577       dc->show_cwe = value;
2578       break;
2579 
2580     case OPT_fdiagnostics_path_format_:
2581       dc->path_format = (enum diagnostic_path_format)value;
2582       break;
2583 
2584     case OPT_fdiagnostics_show_path_depths:
2585       dc->show_path_depths = value;
2586       break;
2587 
2588     case OPT_fdiagnostics_show_option:
2589       dc->show_option_requested = value;
2590       break;
2591 
2592     case OPT_fdiagnostics_minimum_margin_width_:
2593       dc->min_margin_width = value;
2594       break;
2595 
2596     case OPT_fdump_:
2597       /* Deferred.  */
2598       break;
2599 
2600     case OPT_ffast_math:
2601       set_fast_math_flags (opts, value);
2602       break;
2603 
2604     case OPT_funsafe_math_optimizations:
2605       set_unsafe_math_optimizations_flags (opts, value);
2606       break;
2607 
2608     case OPT_ffixed_:
2609       /* Deferred.  */
2610       break;
2611 
2612     case OPT_finline_limit_:
2613       SET_OPTION_IF_UNSET (opts, opts_set, param_max_inline_insns_single,
2614 			   value / 2);
2615       SET_OPTION_IF_UNSET (opts, opts_set, param_max_inline_insns_auto,
2616 			   value / 2);
2617       break;
2618 
2619     case OPT_finstrument_functions_exclude_function_list_:
2620       add_comma_separated_to_vector
2621 	(&opts->x_flag_instrument_functions_exclude_functions, arg);
2622       break;
2623 
2624     case OPT_finstrument_functions_exclude_file_list_:
2625       add_comma_separated_to_vector
2626 	(&opts->x_flag_instrument_functions_exclude_files, arg);
2627       break;
2628 
2629     case OPT_fmessage_length_:
2630       pp_set_line_maximum_length (dc->printer, value);
2631       diagnostic_set_caret_max_width (dc, value);
2632       break;
2633 
2634     case OPT_fopt_info:
2635     case OPT_fopt_info_:
2636       /* Deferred.  */
2637       break;
2638 
2639     case OPT_foffload_:
2640       /* Deferred.  */
2641       break;
2642 
2643 #ifndef ACCEL_COMPILER
2644     case OPT_foffload_abi_:
2645       error_at (loc, "%<-foffload-abi%> option can be specified only for "
2646 		"offload compiler");
2647       break;
2648 #endif
2649 
2650     case OPT_fpack_struct_:
2651       if (value <= 0 || (value & (value - 1)) || value > 16)
2652 	error_at (loc,
2653 		  "structure alignment must be a small power of two, not %wu",
2654 		  value);
2655       else
2656 	opts->x_initial_max_fld_align = value;
2657       break;
2658 
2659     case OPT_fplugin_:
2660     case OPT_fplugin_arg_:
2661       /* Deferred.  */
2662       break;
2663 
2664     case OPT_fprofile_use_:
2665       opts->x_profile_data_prefix = xstrdup (arg);
2666       opts->x_flag_profile_use = true;
2667       value = true;
2668       /* No break here - do -fprofile-use processing. */
2669       /* FALLTHRU */
2670     case OPT_fprofile_use:
2671       enable_fdo_optimizations (opts, opts_set, value);
2672       SET_OPTION_IF_UNSET (opts, opts_set, flag_profile_reorder_functions,
2673 			   value);
2674 	/* Indirect call profiling should do all useful transformations
2675 	   speculative devirtualization does.  */
2676       if (opts->x_flag_value_profile_transformations)
2677 	SET_OPTION_IF_UNSET (opts, opts_set, flag_devirtualize_speculatively,
2678 			     false);
2679       break;
2680 
2681     case OPT_fauto_profile_:
2682       opts->x_auto_profile_file = xstrdup (arg);
2683       opts->x_flag_auto_profile = true;
2684       value = true;
2685       /* No break here - do -fauto-profile processing. */
2686       /* FALLTHRU */
2687     case OPT_fauto_profile:
2688       enable_fdo_optimizations (opts, opts_set, value);
2689       SET_OPTION_IF_UNSET (opts, opts_set, flag_profile_correction, value);
2690       SET_OPTION_IF_UNSET (opts, opts_set,
2691 			   param_early_inliner_max_iterations, 10);
2692       break;
2693 
2694     case OPT_fprofile_generate_:
2695       opts->x_profile_data_prefix = xstrdup (arg);
2696       value = true;
2697       /* No break here - do -fprofile-generate processing. */
2698       /* FALLTHRU */
2699     case OPT_fprofile_generate:
2700       SET_OPTION_IF_UNSET (opts, opts_set, profile_arc_flag, value);
2701       SET_OPTION_IF_UNSET (opts, opts_set, flag_profile_values, value);
2702       SET_OPTION_IF_UNSET (opts, opts_set, flag_inline_functions, value);
2703       SET_OPTION_IF_UNSET (opts, opts_set, flag_ipa_bit_cp, value);
2704       break;
2705 
2706     case OPT_fprofile_info_section:
2707       opts->x_profile_info_section = ".gcov_info";
2708       break;
2709 
2710     case OPT_fpatchable_function_entry_:
2711       {
2712 	HOST_WIDE_INT patch_area_size, patch_area_start;
2713 	parse_and_check_patch_area (arg, true, &patch_area_size,
2714 				    &patch_area_start);
2715       }
2716       break;
2717 
2718     case OPT_ftree_vectorize:
2719       /* Automatically sets -ftree-loop-vectorize and
2720 	 -ftree-slp-vectorize.  Nothing more to do here.  */
2721       break;
2722     case OPT_fzero_call_used_regs_:
2723       opts->x_flag_zero_call_used_regs
2724 	= parse_zero_call_used_regs_options (arg);
2725       break;
2726 
2727     case OPT_fshow_column:
2728       dc->show_column = value;
2729       break;
2730 
2731     case OPT_frandom_seed:
2732       /* The real switch is -fno-random-seed.  */
2733       if (value)
2734 	return false;
2735       /* Deferred.  */
2736       break;
2737 
2738     case OPT_frandom_seed_:
2739       /* Deferred.  */
2740       break;
2741 
2742     case OPT_fsched_verbose_:
2743 #ifdef INSN_SCHEDULING
2744       /* Handled with Var in common.opt.  */
2745       break;
2746 #else
2747       return false;
2748 #endif
2749 
2750     case OPT_fsched_stalled_insns_:
2751       opts->x_flag_sched_stalled_insns = value;
2752       if (opts->x_flag_sched_stalled_insns == 0)
2753 	opts->x_flag_sched_stalled_insns = -1;
2754       break;
2755 
2756     case OPT_fsched_stalled_insns_dep_:
2757       opts->x_flag_sched_stalled_insns_dep = value;
2758       break;
2759 
2760     case OPT_fstack_check_:
2761       if (!strcmp (arg, "no"))
2762 	opts->x_flag_stack_check = NO_STACK_CHECK;
2763       else if (!strcmp (arg, "generic"))
2764 	/* This is the old stack checking method.  */
2765 	opts->x_flag_stack_check = STACK_CHECK_BUILTIN
2766 			   ? FULL_BUILTIN_STACK_CHECK
2767 			   : GENERIC_STACK_CHECK;
2768       else if (!strcmp (arg, "specific"))
2769 	/* This is the new stack checking method.  */
2770 	opts->x_flag_stack_check = STACK_CHECK_BUILTIN
2771 			   ? FULL_BUILTIN_STACK_CHECK
2772 			   : STACK_CHECK_STATIC_BUILTIN
2773 			     ? STATIC_BUILTIN_STACK_CHECK
2774 			     : GENERIC_STACK_CHECK;
2775       else
2776 	warning_at (loc, 0, "unknown stack check parameter %qs", arg);
2777       break;
2778 
2779     case OPT_fstack_limit:
2780       /* The real switch is -fno-stack-limit.  */
2781       if (value)
2782 	return false;
2783       /* Deferred.  */
2784       break;
2785 
2786     case OPT_fstack_limit_register_:
2787     case OPT_fstack_limit_symbol_:
2788       /* Deferred.  */
2789       break;
2790 
2791     case OPT_fstack_usage:
2792       opts->x_flag_stack_usage = value;
2793       opts->x_flag_stack_usage_info = value != 0;
2794       break;
2795 
2796     case OPT_g:
2797       set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, arg, opts, opts_set,
2798                        loc);
2799       break;
2800 
2801     case OPT_gdwarf:
2802       if (arg && strlen (arg) != 0)
2803         {
2804 	  error_at (loc, "%<-gdwarf%s%> is ambiguous; "
2805 		    "use %<-gdwarf-%s%> for DWARF version "
2806 		    "or %<-gdwarf%> %<-g%s%> for debug level", arg, arg, arg);
2807           break;
2808         }
2809       else
2810         value = opts->x_dwarf_version;
2811 
2812       /* FALLTHRU */
2813     case OPT_gdwarf_:
2814       if (value < 2 || value > 5)
2815 	error_at (loc, "dwarf version %wu is not supported", value);
2816       else
2817 	opts->x_dwarf_version = value;
2818       set_debug_level (DWARF2_DEBUG, false, "", opts, opts_set, loc);
2819       break;
2820 
2821     case OPT_ggdb:
2822       set_debug_level (NO_DEBUG, 2, arg, opts, opts_set, loc);
2823       break;
2824 
2825     case OPT_gstabs:
2826     case OPT_gstabs_:
2827       set_debug_level (DBX_DEBUG, code == OPT_gstabs_, arg, opts, opts_set,
2828 		       loc);
2829       break;
2830 
2831     case OPT_gvms:
2832       set_debug_level (VMS_DEBUG, false, arg, opts, opts_set, loc);
2833       break;
2834 
2835     case OPT_gxcoff:
2836     case OPT_gxcoff_:
2837       set_debug_level (XCOFF_DEBUG, code == OPT_gxcoff_, arg, opts, opts_set,
2838 		       loc);
2839       break;
2840 
2841     case OPT_gz:
2842     case OPT_gz_:
2843       /* Handled completely via specs.  */
2844       break;
2845 
2846     case OPT_pedantic_errors:
2847       dc->pedantic_errors = 1;
2848       control_warning_option (OPT_Wpedantic, DK_ERROR, NULL, value,
2849 			      loc, lang_mask,
2850 			      handlers, opts, opts_set,
2851                               dc);
2852       break;
2853 
2854     case OPT_flto:
2855       opts->x_flag_lto = value ? "" : NULL;
2856       break;
2857 
2858     case OPT_flto_:
2859       if (strcmp (arg, "none") != 0
2860 	  && strcmp (arg, "jobserver") != 0
2861 	  && strcmp (arg, "auto") != 0
2862 	  && atoi (arg) == 0)
2863 	error_at (loc,
2864 		  "unrecognized argument to %<-flto=%> option: %qs", arg);
2865       break;
2866 
2867     case OPT_w:
2868       dc->dc_inhibit_warnings = true;
2869       break;
2870 
2871     case OPT_fmax_errors_:
2872       dc->max_errors = value;
2873       break;
2874 
2875     case OPT_fuse_ld_bfd:
2876     case OPT_fuse_ld_gold:
2877     case OPT_fuse_ld_lld:
2878     case OPT_fuse_linker_plugin:
2879       /* No-op. Used by the driver and passed to us because it starts with f.*/
2880       break;
2881 
2882     case OPT_fwrapv:
2883       if (value)
2884 	opts->x_flag_trapv = 0;
2885       break;
2886 
2887     case OPT_ftrapv:
2888       if (value)
2889 	opts->x_flag_wrapv = 0;
2890       break;
2891 
2892     case OPT_fstrict_overflow:
2893       opts->x_flag_wrapv = !value;
2894       opts->x_flag_wrapv_pointer = !value;
2895       if (!value)
2896 	opts->x_flag_trapv = 0;
2897       break;
2898 
2899     case OPT_fipa_icf:
2900       opts->x_flag_ipa_icf_functions = value;
2901       opts->x_flag_ipa_icf_variables = value;
2902       break;
2903 
2904     case OPT_falign_loops_:
2905       check_alignment_argument (loc, arg, "loops",
2906 				&opts->x_flag_align_loops,
2907 				&opts->x_str_align_loops);
2908       break;
2909 
2910     case OPT_falign_jumps_:
2911       check_alignment_argument (loc, arg, "jumps",
2912 				&opts->x_flag_align_jumps,
2913 				&opts->x_str_align_jumps);
2914       break;
2915 
2916     case OPT_falign_labels_:
2917       check_alignment_argument (loc, arg, "labels",
2918 				&opts->x_flag_align_labels,
2919 				&opts->x_str_align_labels);
2920       break;
2921 
2922     case OPT_falign_functions_:
2923       check_alignment_argument (loc, arg, "functions",
2924 				&opts->x_flag_align_functions,
2925 				&opts->x_str_align_functions);
2926       break;
2927 
2928     case OPT_ftabstop_:
2929       /* It is documented that we silently ignore silly values.  */
2930       if (value >= 1 && value <= 100)
2931 	dc->tabstop = value;
2932       break;
2933 
2934     default:
2935       /* If the flag was handled in a standard way, assume the lack of
2936 	 processing here is intentional.  */
2937       gcc_assert (option_flag_var (scode, opts));
2938       break;
2939     }
2940 
2941   common_handle_option_auto (opts, opts_set, decoded, lang_mask, kind,
2942                              loc, handlers, dc);
2943   return true;
2944 }
2945 
2946 /* Used to set the level of strict aliasing warnings in OPTS,
2947    when no level is specified (i.e., when -Wstrict-aliasing, and not
2948    -Wstrict-aliasing=level was given).
2949    ONOFF is assumed to take value 1 when -Wstrict-aliasing is specified,
2950    and 0 otherwise.  After calling this function, wstrict_aliasing will be
2951    set to the default value of -Wstrict_aliasing=level, currently 3.  */
2952 static void
2953 set_Wstrict_aliasing (struct gcc_options *opts, int onoff)
2954 {
2955   gcc_assert (onoff == 0 || onoff == 1);
2956   if (onoff != 0)
2957     opts->x_warn_strict_aliasing = 3;
2958   else
2959     opts->x_warn_strict_aliasing = 0;
2960 }
2961 
2962 /* The following routines are useful in setting all the flags that
2963    -ffast-math and -fno-fast-math imply.  */
2964 static void
2965 set_fast_math_flags (struct gcc_options *opts, int set)
2966 {
2967   if (!opts->frontend_set_flag_unsafe_math_optimizations)
2968     {
2969       opts->x_flag_unsafe_math_optimizations = set;
2970       set_unsafe_math_optimizations_flags (opts, set);
2971     }
2972   if (!opts->frontend_set_flag_finite_math_only)
2973     opts->x_flag_finite_math_only = set;
2974   if (!opts->frontend_set_flag_errno_math)
2975     opts->x_flag_errno_math = !set;
2976   if (set)
2977     {
2978       if (opts->frontend_set_flag_excess_precision == EXCESS_PRECISION_DEFAULT)
2979 	opts->x_flag_excess_precision
2980 	  = set ? EXCESS_PRECISION_FAST : EXCESS_PRECISION_DEFAULT;
2981       if (!opts->frontend_set_flag_signaling_nans)
2982 	opts->x_flag_signaling_nans = 0;
2983       if (!opts->frontend_set_flag_rounding_math)
2984 	opts->x_flag_rounding_math = 0;
2985       if (!opts->frontend_set_flag_cx_limited_range)
2986 	opts->x_flag_cx_limited_range = 1;
2987     }
2988 }
2989 
2990 /* When -funsafe-math-optimizations is set the following
2991    flags are set as well.  */
2992 static void
2993 set_unsafe_math_optimizations_flags (struct gcc_options *opts, int set)
2994 {
2995   if (!opts->frontend_set_flag_trapping_math)
2996     opts->x_flag_trapping_math = !set;
2997   if (!opts->frontend_set_flag_signed_zeros)
2998     opts->x_flag_signed_zeros = !set;
2999   if (!opts->frontend_set_flag_associative_math)
3000     opts->x_flag_associative_math = set;
3001   if (!opts->frontend_set_flag_reciprocal_math)
3002     opts->x_flag_reciprocal_math = set;
3003 }
3004 
3005 /* Return true iff flags in OPTS are set as if -ffast-math.  */
3006 bool
3007 fast_math_flags_set_p (const struct gcc_options *opts)
3008 {
3009   return (!opts->x_flag_trapping_math
3010 	  && opts->x_flag_unsafe_math_optimizations
3011 	  && opts->x_flag_finite_math_only
3012 	  && !opts->x_flag_signed_zeros
3013 	  && !opts->x_flag_errno_math
3014 	  && opts->x_flag_excess_precision == EXCESS_PRECISION_FAST);
3015 }
3016 
3017 /* Return true iff flags are set as if -ffast-math but using the flags stored
3018    in the struct cl_optimization structure.  */
3019 bool
3020 fast_math_flags_struct_set_p (struct cl_optimization *opt)
3021 {
3022   return (!opt->x_flag_trapping_math
3023 	  && opt->x_flag_unsafe_math_optimizations
3024 	  && opt->x_flag_finite_math_only
3025 	  && !opt->x_flag_signed_zeros
3026 	  && !opt->x_flag_errno_math);
3027 }
3028 
3029 /* Handle a debug output -g switch for options OPTS
3030    (OPTS_SET->x_write_symbols storing whether a debug type was passed
3031    explicitly), location LOC.  EXTENDED is true or false to support
3032    extended output (2 is special and means "-ggdb" was given).  */
3033 static void
3034 set_debug_level (enum debug_info_type type, int extended, const char *arg,
3035 		 struct gcc_options *opts, struct gcc_options *opts_set,
3036 		 location_t loc)
3037 {
3038   opts->x_use_gnu_debug_info_extensions = extended;
3039 
3040   if (type == NO_DEBUG)
3041     {
3042       if (opts->x_write_symbols == NO_DEBUG)
3043 	{
3044 	  opts->x_write_symbols = PREFERRED_DEBUGGING_TYPE;
3045 
3046 	  if (extended == 2)
3047 	    {
3048 #if defined DWARF2_DEBUGGING_INFO || defined DWARF2_LINENO_DEBUGGING_INFO
3049 	      opts->x_write_symbols = DWARF2_DEBUG;
3050 #elif defined DBX_DEBUGGING_INFO
3051 	      opts->x_write_symbols = DBX_DEBUG;
3052 #endif
3053 	    }
3054 
3055 	  if (opts->x_write_symbols == NO_DEBUG)
3056 	    warning_at (loc, 0, "target system does not support debug output");
3057 	}
3058     }
3059   else
3060     {
3061       /* Does it conflict with an already selected type?  */
3062       if (opts_set->x_write_symbols != NO_DEBUG
3063 	  && opts->x_write_symbols != NO_DEBUG
3064 	  && type != opts->x_write_symbols)
3065 	error_at (loc, "debug format %qs conflicts with prior selection",
3066 		  debug_type_names[type]);
3067       opts->x_write_symbols = type;
3068       opts_set->x_write_symbols = type;
3069     }
3070 
3071   /* A debug flag without a level defaults to level 2.
3072      If off or at level 1, set it to level 2, but if already
3073      at level 3, don't lower it.  */
3074   if (*arg == '\0')
3075     {
3076       if (opts->x_debug_info_level < DINFO_LEVEL_NORMAL)
3077 	opts->x_debug_info_level = DINFO_LEVEL_NORMAL;
3078     }
3079   else
3080     {
3081       int argval = integral_argument (arg);
3082       if (argval == -1)
3083 	error_at (loc, "unrecognized debug output level %qs", arg);
3084       else if (argval > 3)
3085 	error_at (loc, "debug output level %qs is too high", arg);
3086       else
3087 	opts->x_debug_info_level = (enum debug_info_levels) argval;
3088     }
3089 }
3090 
3091 /* Arrange to dump core on error for diagnostic context DC.  (The
3092    regular error message is still printed first, except in the case of
3093    abort ().)  */
3094 
3095 static void
3096 setup_core_dumping (diagnostic_context *dc)
3097 {
3098 #ifdef SIGABRT
3099   signal (SIGABRT, SIG_DFL);
3100 #endif
3101 #if defined(HAVE_SETRLIMIT)
3102   {
3103     struct rlimit rlim;
3104     if (getrlimit (RLIMIT_CORE, &rlim) != 0)
3105       fatal_error (input_location, "getting core file size maximum limit: %m");
3106     rlim.rlim_cur = rlim.rlim_max;
3107     if (setrlimit (RLIMIT_CORE, &rlim) != 0)
3108       fatal_error (input_location,
3109 		   "setting core file size limit to maximum: %m");
3110   }
3111 #endif
3112   diagnostic_abort_on_error (dc);
3113 }
3114 
3115 /* Parse a -d<ARG> command line switch for OPTS, location LOC,
3116    diagnostic context DC.  */
3117 
3118 static void
3119 decode_d_option (const char *arg, struct gcc_options *opts,
3120 		 location_t loc, diagnostic_context *dc)
3121 {
3122   int c;
3123 
3124   while (*arg)
3125     switch (c = *arg++)
3126       {
3127       case 'A':
3128 	opts->x_flag_debug_asm = 1;
3129 	break;
3130       case 'p':
3131 	opts->x_flag_print_asm_name = 1;
3132 	break;
3133       case 'P':
3134 	opts->x_flag_dump_rtl_in_asm = 1;
3135 	opts->x_flag_print_asm_name = 1;
3136 	break;
3137       case 'x':
3138 	opts->x_rtl_dump_and_exit = 1;
3139 	break;
3140       case 'D':	/* These are handled by the preprocessor.  */
3141       case 'I':
3142       case 'M':
3143       case 'N':
3144       case 'U':
3145 	break;
3146       case 'H':
3147 	setup_core_dumping (dc);
3148 	break;
3149       case 'a':
3150 	opts->x_flag_dump_all_passed = true;
3151 	break;
3152 
3153       default:
3154 	  warning_at (loc, 0, "unrecognized gcc debugging option: %c", c);
3155 	break;
3156       }
3157 }
3158 
3159 /* Enable (or disable if VALUE is 0) a warning option ARG (language
3160    mask LANG_MASK, option handlers HANDLERS) as an error for option
3161    structures OPTS and OPTS_SET, diagnostic context DC (possibly
3162    NULL), location LOC.  This is used by -Werror=.  */
3163 
3164 static void
3165 enable_warning_as_error (const char *arg, int value, unsigned int lang_mask,
3166 			 const struct cl_option_handlers *handlers,
3167 			 struct gcc_options *opts,
3168 			 struct gcc_options *opts_set,
3169 			 location_t loc, diagnostic_context *dc)
3170 {
3171   char *new_option;
3172   int option_index;
3173 
3174   new_option = XNEWVEC (char, strlen (arg) + 2);
3175   new_option[0] = 'W';
3176   strcpy (new_option + 1, arg);
3177   option_index = find_opt (new_option, lang_mask);
3178   if (option_index == OPT_SPECIAL_unknown)
3179     {
3180       option_proposer op;
3181       const char *hint = op.suggest_option (new_option);
3182       if (hint)
3183 	error_at (loc, "%<-W%serror=%s%>: no option %<-%s%>;"
3184 		  " did you mean %<-%s%>?", value ? "" : "no-",
3185 		  arg, new_option, hint);
3186       else
3187 	error_at (loc, "%<-W%serror=%s%>: no option %<-%s%>",
3188 		  value ? "" : "no-", arg, new_option);
3189     }
3190   else if (!(cl_options[option_index].flags & CL_WARNING))
3191     error_at (loc, "%<-Werror=%s%>: %<-%s%> is not an option that "
3192 	      "controls warnings", arg, new_option);
3193   else
3194     {
3195       const diagnostic_t kind = value ? DK_ERROR : DK_WARNING;
3196       const char *arg = NULL;
3197 
3198       if (cl_options[option_index].flags & CL_JOINED)
3199 	arg = new_option + cl_options[option_index].opt_len;
3200       control_warning_option (option_index, (int) kind, arg, value,
3201 			      loc, lang_mask,
3202 			      handlers, opts, opts_set, dc);
3203     }
3204   free (new_option);
3205 }
3206 
3207 /* Return malloced memory for the name of the option OPTION_INDEX
3208    which enabled a diagnostic (context CONTEXT), originally of type
3209    ORIG_DIAG_KIND but possibly converted to DIAG_KIND by options such
3210    as -Werror.  */
3211 
3212 char *
3213 option_name (diagnostic_context *context, int option_index,
3214 	     diagnostic_t orig_diag_kind, diagnostic_t diag_kind)
3215 {
3216   if (option_index)
3217     {
3218       /* A warning classified as an error.  */
3219       if ((orig_diag_kind == DK_WARNING || orig_diag_kind == DK_PEDWARN)
3220 	  && diag_kind == DK_ERROR)
3221 	return concat (cl_options[OPT_Werror_].opt_text,
3222 		       /* Skip over "-W".  */
3223 		       cl_options[option_index].opt_text + 2,
3224 		       NULL);
3225       /* A warning with option.  */
3226       else
3227 	return xstrdup (cl_options[option_index].opt_text);
3228     }
3229   /* A warning without option classified as an error.  */
3230   else if ((orig_diag_kind == DK_WARNING || orig_diag_kind == DK_PEDWARN
3231 	    || diag_kind == DK_WARNING)
3232 	   && context->warning_as_error_requested)
3233     return xstrdup (cl_options[OPT_Werror].opt_text);
3234   else
3235     return NULL;
3236 }
3237 
3238 /* Get the page within the documentation for this option.  */
3239 
3240 static const char *
3241 get_option_html_page (int option_index)
3242 {
3243   const cl_option *cl_opt = &cl_options[option_index];
3244 
3245   /* Analyzer options are on their own page.  */
3246   if (strstr(cl_opt->opt_text, "analyzer-"))
3247     return "gcc/Static-Analyzer-Options.html";
3248 
3249 #ifdef CL_Fortran
3250   if ((cl_opt->flags & CL_Fortran) != 0
3251       /* If it is option common to both C/C++ and Fortran, it is documented
3252 	 in gcc/ rather than gfortran/ docs.  */
3253       && (cl_opt->flags & CL_C) == 0
3254 #ifdef CL_CXX
3255       && (cl_opt->flags & CL_CXX) == 0
3256 #endif
3257      )
3258     return "gfortran/Error-and-Warning-Options.html";
3259 #endif
3260 
3261   return "gcc/Warning-Options.html";
3262 }
3263 
3264 /* Return malloced memory for a URL describing the option OPTION_INDEX
3265    which enabled a diagnostic (context CONTEXT).  */
3266 
3267 char *
3268 get_option_url (diagnostic_context *, int option_index)
3269 {
3270   if (option_index)
3271     return concat (/* DOCUMENTATION_ROOT_URL should be supplied via -D by
3272 		      the Makefile (see --with-documentation-root-url), and
3273 		      should have a trailing slash.  */
3274 		   DOCUMENTATION_ROOT_URL,
3275 
3276 		   /* get_option_html_page will return something like
3277 		      "gcc/Warning-Options.html".  */
3278 		   get_option_html_page (option_index),
3279 
3280 		   /* Expect an anchor of the form "index-Wfoo" e.g.
3281 		      <a name="index-Wformat"></a>, and thus an id within
3282 		      the URL of "#index-Wformat".  */
3283 		   "#index", cl_options[option_index].opt_text,
3284 		   NULL);
3285   else
3286     return NULL;
3287 }
3288 
3289 /* Return a heap allocated producer with command line options.  */
3290 
3291 char *
3292 gen_command_line_string (cl_decoded_option *options,
3293 			 unsigned int options_count)
3294 {
3295   auto_vec<const char *> switches;
3296   char *options_string, *tail;
3297   const char *p;
3298   size_t len = 0;
3299 
3300   for (unsigned i = 0; i < options_count; i++)
3301     switch (options[i].opt_index)
3302       {
3303       case OPT_o:
3304       case OPT_d:
3305       case OPT_dumpbase:
3306       case OPT_dumpbase_ext:
3307       case OPT_dumpdir:
3308       case OPT_quiet:
3309       case OPT_version:
3310       case OPT_v:
3311       case OPT_w:
3312       case OPT_L:
3313       case OPT_D:
3314       case OPT_I:
3315       case OPT_U:
3316       case OPT_SPECIAL_unknown:
3317       case OPT_SPECIAL_ignore:
3318       case OPT_SPECIAL_warn_removed:
3319       case OPT_SPECIAL_program_name:
3320       case OPT_SPECIAL_input_file:
3321       case OPT_grecord_gcc_switches:
3322       case OPT_frecord_gcc_switches:
3323       case OPT__output_pch_:
3324       case OPT_fdiagnostics_show_location_:
3325       case OPT_fdiagnostics_show_option:
3326       case OPT_fdiagnostics_show_caret:
3327       case OPT_fdiagnostics_show_labels:
3328       case OPT_fdiagnostics_show_line_numbers:
3329       case OPT_fdiagnostics_color_:
3330       case OPT_fdiagnostics_format_:
3331       case OPT_fverbose_asm:
3332       case OPT____:
3333       case OPT__sysroot_:
3334       case OPT_nostdinc:
3335       case OPT_nostdinc__:
3336       case OPT_fpreprocessed:
3337       case OPT_fltrans_output_list_:
3338       case OPT_fresolution_:
3339       case OPT_fdebug_prefix_map_:
3340       case OPT_fmacro_prefix_map_:
3341       case OPT_ffile_prefix_map_:
3342       case OPT_fcompare_debug:
3343       case OPT_fchecking:
3344       case OPT_fchecking_:
3345 	/* Ignore these.  */
3346 	continue;
3347       case OPT_flto_:
3348 	{
3349 	  const char *lto_canonical = "-flto";
3350 	  switches.safe_push (lto_canonical);
3351 	  len += strlen (lto_canonical) + 1;
3352 	  break;
3353 	}
3354       default:
3355 	if (cl_options[options[i].opt_index].flags
3356 	    & CL_NO_DWARF_RECORD)
3357 	  continue;
3358 	gcc_checking_assert (options[i].canonical_option[0][0] == '-');
3359 	switch (options[i].canonical_option[0][1])
3360 	  {
3361 	  case 'M':
3362 	  case 'i':
3363 	  case 'W':
3364 	    continue;
3365 	  case 'f':
3366 	    if (strncmp (options[i].canonical_option[0] + 2,
3367 			 "dump", 4) == 0)
3368 	      continue;
3369 	    break;
3370 	  default:
3371 	    break;
3372 	  }
3373 	switches.safe_push (options[i].orig_option_with_args_text);
3374 	len += strlen (options[i].orig_option_with_args_text) + 1;
3375 	break;
3376       }
3377 
3378   options_string = XNEWVEC (char, len + 1);
3379   tail = options_string;
3380 
3381   unsigned i;
3382   FOR_EACH_VEC_ELT (switches, i, p)
3383     {
3384       len = strlen (p);
3385       memcpy (tail, p, len);
3386       tail += len;
3387       if (i != switches.length () - 1)
3388 	{
3389 	  *tail = ' ';
3390 	  ++tail;
3391 	}
3392     }
3393 
3394   *tail = '\0';
3395   return options_string;
3396 }
3397 
3398 /* Return a heap allocated producer string including command line options.  */
3399 
3400 char *
3401 gen_producer_string (const char *language_string, cl_decoded_option *options,
3402 		     unsigned int options_count)
3403 {
3404   char *cmdline = gen_command_line_string (options, options_count);
3405   char *combined = concat (language_string, " ", version_string, " ",
3406 			   cmdline, NULL);
3407   free (cmdline);
3408   return combined;
3409 }
3410 
3411 #if CHECKING_P
3412 
3413 namespace selftest {
3414 
3415 /* Verify that get_option_html_page works as expected.  */
3416 
3417 static void
3418 test_get_option_html_page ()
3419 {
3420   ASSERT_STREQ (get_option_html_page (OPT_Wcpp), "gcc/Warning-Options.html");
3421   ASSERT_STREQ (get_option_html_page (OPT_Wanalyzer_double_free),
3422 	     "gcc/Static-Analyzer-Options.html");
3423 #ifdef CL_Fortran
3424   ASSERT_STREQ (get_option_html_page (OPT_Wline_truncation),
3425 		"gfortran/Error-and-Warning-Options.html");
3426 #endif
3427 }
3428 
3429 /* Run all of the selftests within this file.  */
3430 
3431 void
3432 opts_c_tests ()
3433 {
3434   test_get_option_html_page ();
3435 }
3436 
3437 } // namespace selftest
3438 
3439 #endif /* #if CHECKING_P */
3440