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