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