analyzer: fix feasibility false +ve on jumps through function ptrs [PR107582]
[platform/upstream/gcc.git] / gcc / opts.cc
1 /* Command line option handling.
2    Copyright (C) 2002-2022 Free Software Foundation, Inc.
3    Contributed by Neil Booth.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.  */
20
21 #include "config.h"
22 #include "system.h"
23 #include "intl.h"
24 #include "coretypes.h"
25 #include "opts.h"
26 #include "tm.h"
27 #include "flags.h"
28 #include "diagnostic.h"
29 #include "opts-diagnostic.h"
30 #include "insn-attr-common.h"
31 #include "common/common-target.h"
32 #include "spellcheck.h"
33 #include "opt-suggestions.h"
34 #include "diagnostic-color.h"
35 #include "version.h"
36 #include "selftest.h"
37
38 /* In this file all option sets are explicit.  */
39 #undef OPTION_SET_P
40
41 static 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
46 const 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
54 static uint32_t debug_type_masks[] =
55 {
56   NO_DEBUG, DWARF2_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
63 static 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
68 enum debug_info_type
69 debug_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
87 unsigned int
88 debug_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
101 const char *
102 debug_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
135 bool
136 btf_debuginfo_p ()
137 {
138   return (write_symbols & BTF_DEBUG);
139 }
140
141 /* Return TRUE iff BTF with CO-RE debug info is enabled.  */
142
143 bool
144 btf_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
151 bool
152 ctf_debuginfo_p ()
153 {
154   return (write_symbols & CTF_DEBUG);
155 }
156
157 /* Return TRUE iff dwarf2 debug info is enabled.  */
158
159 bool
160 dwarf_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
168 bool 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
186 void
187 set_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
280 void
281 strip_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. */
296 int
297 base_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.  */
321 static const char undocumented_msg[] = N_("This option lacks documentation.");
322 static const char use_diagnosed_msg[] = N_("Uses of this option are diagnosed.");
323
324 typedef char *char_p; /* For DEF_VEC_P.  */
325
326 static 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);
330 static void set_fast_math_flags (struct gcc_options *opts, int set);
331 static void decode_d_option (const char *arg, struct gcc_options *opts,
332                              location_t loc, diagnostic_context *dc);
333 static void set_unsafe_math_optimizations_flags (struct gcc_options *opts,
334                                                  int set);
335 static 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
346 bool
347 target_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
362 static void
363 add_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
407 void
408 init_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
415 void
416 init_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
449 static void
450 maybe_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
539 static void
540 maybe_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
562 static 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.  */
700 void
701 default_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.  */
826 static void
827 control_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.  */
964 vec<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.  */
968 const char *
969 find_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.  */
1001 static void
1002 report_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.  */
1021 void
1022 finish_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   /* At -O0 or -Og, turn __builtin_unreachable into a trap.  */
1126   if (!opts->x_optimize || opts->x_optimize_debug)
1127     SET_OPTION_IF_UNSET (opts, opts_set, flag_unreachable_traps, true);
1128
1129   /* Pipelining of outer loops is only possible when general pipelining
1130      capabilities are requested.  */
1131   if (!opts->x_flag_sel_sched_pipelining)
1132     opts->x_flag_sel_sched_pipelining_outer_loops = 0;
1133
1134   if (opts->x_flag_conserve_stack)
1135     {
1136       SET_OPTION_IF_UNSET (opts, opts_set, param_large_stack_frame, 100);
1137       SET_OPTION_IF_UNSET (opts, opts_set, param_stack_frame_growth, 40);
1138     }
1139
1140   if (opts->x_flag_lto)
1141     {
1142 #ifdef ENABLE_LTO
1143       opts->x_flag_generate_lto = 1;
1144
1145       /* When generating IL, do not operate in whole-program mode.
1146          Otherwise, symbols will be privatized too early, causing link
1147          errors later.  */
1148       opts->x_flag_whole_program = 0;
1149 #else
1150       error_at (loc, "LTO support has not been enabled in this configuration");
1151 #endif
1152       if (!opts->x_flag_fat_lto_objects
1153           && (!HAVE_LTO_PLUGIN
1154               || (opts_set->x_flag_use_linker_plugin
1155                   && !opts->x_flag_use_linker_plugin)))
1156         {
1157           if (opts_set->x_flag_fat_lto_objects)
1158             error_at (loc, "%<-fno-fat-lto-objects%> are supported only with "
1159                       "linker plugin");
1160           opts->x_flag_fat_lto_objects = 1;
1161         }
1162
1163       /* -gsplit-dwarf isn't compatible with LTO, see PR88389.  */
1164       if (opts->x_dwarf_split_debug_info)
1165         {
1166           inform (loc, "%<-gsplit-dwarf%> is not supported with LTO,"
1167                   " disabling");
1168           opts->x_dwarf_split_debug_info = 0;
1169         }
1170     }
1171
1172   /* We initialize opts->x_flag_split_stack to -1 so that targets can set a
1173      default value if they choose based on other options.  */
1174   if (opts->x_flag_split_stack == -1)
1175     opts->x_flag_split_stack = 0;
1176   else if (opts->x_flag_split_stack)
1177     {
1178       if (!targetm_common.supports_split_stack (true, opts))
1179         {
1180           error_at (loc, "%<-fsplit-stack%> is not supported by "
1181                     "this compiler configuration");
1182           opts->x_flag_split_stack = 0;
1183         }
1184     }
1185
1186   /* If stack splitting is turned on, and the user did not explicitly
1187      request function partitioning, turn off partitioning, as it
1188      confuses the linker when trying to handle partitioned split-stack
1189      code that calls a non-split-stack functions.  But if partitioning
1190      was turned on explicitly just hope for the best.  */
1191   if (opts->x_flag_split_stack
1192       && opts->x_flag_reorder_blocks_and_partition)
1193     SET_OPTION_IF_UNSET (opts, opts_set, flag_reorder_blocks_and_partition, 0);
1194
1195   if (opts->x_flag_reorder_blocks_and_partition)
1196     SET_OPTION_IF_UNSET (opts, opts_set, flag_reorder_functions, 1);
1197
1198   /* The -gsplit-dwarf option requires -ggnu-pubnames.  */
1199   if (opts->x_dwarf_split_debug_info)
1200     opts->x_debug_generate_pub_sections = 2;
1201
1202   if ((opts->x_flag_sanitize
1203        & (SANITIZE_USER_ADDRESS | SANITIZE_KERNEL_ADDRESS)) == 0)
1204     {
1205       if (opts->x_flag_sanitize & SANITIZE_POINTER_COMPARE)
1206         error_at (loc,
1207                   "%<-fsanitize=pointer-compare%> must be combined with "
1208                   "%<-fsanitize=address%> or %<-fsanitize=kernel-address%>");
1209       if (opts->x_flag_sanitize & SANITIZE_POINTER_SUBTRACT)
1210         error_at (loc,
1211                   "%<-fsanitize=pointer-subtract%> must be combined with "
1212                   "%<-fsanitize=address%> or %<-fsanitize=kernel-address%>");
1213     }
1214
1215   /* Address sanitizers conflict with the thread sanitizer.  */
1216   report_conflicting_sanitizer_options (opts, loc, SANITIZE_THREAD,
1217                                         SANITIZE_ADDRESS);
1218   report_conflicting_sanitizer_options (opts, loc, SANITIZE_THREAD,
1219                                         SANITIZE_HWADDRESS);
1220   /* The leak sanitizer conflicts with the thread sanitizer.  */
1221   report_conflicting_sanitizer_options (opts, loc, SANITIZE_LEAK,
1222                                         SANITIZE_THREAD);
1223
1224   /* No combination of HWASAN and ASAN work together.  */
1225   report_conflicting_sanitizer_options (opts, loc,
1226                                         SANITIZE_HWADDRESS, SANITIZE_ADDRESS);
1227
1228   /* The userspace and kernel address sanitizers conflict with each other.  */
1229   report_conflicting_sanitizer_options (opts, loc, SANITIZE_USER_HWADDRESS,
1230                                         SANITIZE_KERNEL_HWADDRESS);
1231   report_conflicting_sanitizer_options (opts, loc, SANITIZE_USER_ADDRESS,
1232                                         SANITIZE_KERNEL_ADDRESS);
1233
1234   /* Check error recovery for -fsanitize-recover option.  */
1235   for (int i = 0; sanitizer_opts[i].name != NULL; ++i)
1236     if ((opts->x_flag_sanitize_recover & sanitizer_opts[i].flag)
1237         && !sanitizer_opts[i].can_recover)
1238       error_at (loc, "%<-fsanitize-recover=%s%> is not supported",
1239                 sanitizer_opts[i].name);
1240
1241   /* Check -fsanitize-trap option.  */
1242   for (int i = 0; sanitizer_opts[i].name != NULL; ++i)
1243     if ((opts->x_flag_sanitize_trap & sanitizer_opts[i].flag)
1244         && !sanitizer_opts[i].can_trap
1245         /* Allow -fsanitize-trap=all or -fsanitize-trap=undefined
1246            to set flag_sanitize_trap & SANITIZE_VPTR bit which will
1247            effectively disable -fsanitize=vptr, just disallow
1248            explicit -fsanitize-trap=vptr.  */
1249         && sanitizer_opts[i].flag != SANITIZE_VPTR)
1250       error_at (loc, "%<-fsanitize-trap=%s%> is not supported",
1251                 sanitizer_opts[i].name);
1252
1253   /* When instrumenting the pointers, we don't want to remove
1254      the null pointer checks.  */
1255   if (opts->x_flag_sanitize & (SANITIZE_NULL | SANITIZE_NONNULL_ATTRIBUTE
1256                                 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE))
1257     opts->x_flag_delete_null_pointer_checks = 0;
1258
1259   /* Aggressive compiler optimizations may cause false negatives.  */
1260   if (opts->x_flag_sanitize & ~(SANITIZE_LEAK | SANITIZE_UNREACHABLE))
1261     opts->x_flag_aggressive_loop_optimizations = 0;
1262
1263   /* Enable -fsanitize-address-use-after-scope if either address sanitizer is
1264      enabled.  */
1265   if (opts->x_flag_sanitize
1266       & (SANITIZE_USER_ADDRESS | SANITIZE_USER_HWADDRESS))
1267     SET_OPTION_IF_UNSET (opts, opts_set, flag_sanitize_address_use_after_scope,
1268                          true);
1269
1270   /* Force -fstack-reuse=none in case -fsanitize-address-use-after-scope
1271      is enabled.  */
1272   if (opts->x_flag_sanitize_address_use_after_scope)
1273     {
1274       if (opts->x_flag_stack_reuse != SR_NONE
1275           && opts_set->x_flag_stack_reuse != SR_NONE)
1276         error_at (loc,
1277                   "%<-fsanitize-address-use-after-scope%> requires "
1278                   "%<-fstack-reuse=none%> option");
1279
1280       opts->x_flag_stack_reuse = SR_NONE;
1281     }
1282
1283   if ((opts->x_flag_sanitize & SANITIZE_USER_ADDRESS) && opts->x_flag_tm)
1284     sorry ("transactional memory is not supported with %<-fsanitize=address%>");
1285
1286   if ((opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS) && opts->x_flag_tm)
1287     sorry ("transactional memory is not supported with "
1288            "%<-fsanitize=kernel-address%>");
1289
1290   /* Currently live patching is not support for LTO.  */
1291   if (opts->x_flag_live_patching == LIVE_PATCHING_INLINE_ONLY_STATIC && opts->x_flag_lto)
1292     sorry ("live patching (with %qs) is not supported with LTO",
1293            "inline-only-static");
1294
1295   /* Currently vtable verification is not supported for LTO */
1296   if (opts->x_flag_vtable_verify && opts->x_flag_lto)
1297     sorry ("vtable verification is not supported with LTO");
1298
1299   /* Control IPA optimizations based on different -flive-patching level.  */
1300   if (opts->x_flag_live_patching)
1301     control_options_for_live_patching (opts, opts_set,
1302                                        opts->x_flag_live_patching,
1303                                        loc);
1304
1305   /* Allow cunroll to grow size accordingly.  */
1306   if (!opts_set->x_flag_cunroll_grow_size)
1307     opts->x_flag_cunroll_grow_size
1308       = (opts->x_flag_unroll_loops
1309          || opts->x_flag_peel_loops
1310          || opts->x_optimize >= 3);
1311
1312   /* With -fcx-limited-range, we do cheap and quick complex arithmetic.  */
1313   if (opts->x_flag_cx_limited_range)
1314     opts->x_flag_complex_method = 0;
1315   else if (opts_set->x_flag_cx_limited_range)
1316     opts->x_flag_complex_method = opts->x_flag_default_complex_method;
1317
1318   /* With -fcx-fortran-rules, we do something in-between cheap and C99.  */
1319   if (opts->x_flag_cx_fortran_rules)
1320     opts->x_flag_complex_method = 1;
1321   else if (opts_set->x_flag_cx_fortran_rules)
1322     opts->x_flag_complex_method = opts->x_flag_default_complex_method;
1323
1324   /* Use -fvect-cost-model=cheap instead of -fvect-cost-mode=very-cheap
1325      by default with explicit -ftree-{loop,slp}-vectorize.  */
1326   if (opts->x_optimize == 2
1327       && (opts_set->x_flag_tree_loop_vectorize
1328           || opts_set->x_flag_tree_vectorize))
1329     SET_OPTION_IF_UNSET (opts, opts_set, flag_vect_cost_model,
1330                          VECT_COST_MODEL_CHEAP);
1331
1332   if (opts->x_flag_gtoggle)
1333     {
1334       /* Make sure to process -gtoggle only once.  */
1335       opts->x_flag_gtoggle = false;
1336       if (opts->x_debug_info_level == DINFO_LEVEL_NONE)
1337         {
1338           opts->x_debug_info_level = DINFO_LEVEL_NORMAL;
1339
1340           if (opts->x_write_symbols == NO_DEBUG)
1341             opts->x_write_symbols = PREFERRED_DEBUGGING_TYPE;
1342         }
1343       else
1344         opts->x_debug_info_level = DINFO_LEVEL_NONE;
1345     }
1346
1347   if (!opts_set->x_debug_nonbind_markers_p)
1348     opts->x_debug_nonbind_markers_p
1349       = (opts->x_optimize
1350          && opts->x_debug_info_level >= DINFO_LEVEL_NORMAL
1351          && dwarf_debuginfo_p (opts)
1352          && !(opts->x_flag_selective_scheduling
1353               || opts->x_flag_selective_scheduling2));
1354
1355   /* We know which debug output will be used so we can set flag_var_tracking
1356      and flag_var_tracking_uninit if the user has not specified them.  */
1357   if (opts->x_debug_info_level < DINFO_LEVEL_NORMAL
1358       || !dwarf_debuginfo_p (opts)
1359       /* We have not yet initialized debug hooks so match that to check
1360          whether we're only doing DWARF2_LINENO_DEBUGGING_INFO.  */
1361 #ifndef DWARF2_DEBUGGING_INFO
1362       || true
1363 #endif
1364      )
1365     {
1366       if ((opts_set->x_flag_var_tracking && opts->x_flag_var_tracking == 1)
1367           || (opts_set->x_flag_var_tracking_uninit
1368               && opts->x_flag_var_tracking_uninit == 1))
1369         {
1370           if (opts->x_debug_info_level < DINFO_LEVEL_NORMAL)
1371             warning_at (UNKNOWN_LOCATION, 0,
1372                         "variable tracking requested, but useless unless "
1373                         "producing debug info");
1374           else
1375             warning_at (UNKNOWN_LOCATION, 0,
1376                         "variable tracking requested, but not supported "
1377                         "by this debug format");
1378         }
1379       opts->x_flag_var_tracking = 0;
1380       opts->x_flag_var_tracking_uninit = 0;
1381     }
1382
1383   /* One could use EnabledBy, but it would lead to a circular dependency.  */
1384   if (!opts_set->x_flag_var_tracking_uninit)
1385     opts->x_flag_var_tracking_uninit = opts->x_flag_var_tracking;
1386
1387   if (!opts_set->x_flag_var_tracking_assignments)
1388     opts->x_flag_var_tracking_assignments
1389       = (opts->x_flag_var_tracking
1390          && !(opts->x_flag_selective_scheduling
1391               || opts->x_flag_selective_scheduling2));
1392
1393   if (opts->x_flag_var_tracking_assignments_toggle)
1394     opts->x_flag_var_tracking_assignments
1395       = !opts->x_flag_var_tracking_assignments;
1396
1397   if (opts->x_flag_var_tracking_assignments && !opts->x_flag_var_tracking)
1398     opts->x_flag_var_tracking = opts->x_flag_var_tracking_assignments = -1;
1399
1400   if (opts->x_flag_var_tracking_assignments
1401       && (opts->x_flag_selective_scheduling
1402           || opts->x_flag_selective_scheduling2))
1403     warning_at (loc, 0,
1404                 "var-tracking-assignments changes selective scheduling");
1405
1406   if (opts->x_flag_syntax_only)
1407     {
1408       opts->x_write_symbols = NO_DEBUG;
1409       opts->x_profile_flag = 0;
1410     }
1411
1412
1413   diagnose_options (opts, opts_set, loc);
1414 }
1415
1416 /* The function diagnoses incompatible combinations for provided options
1417    (OPTS and OPTS_SET) at a given LOCation.  The function is called both
1418    when command line is parsed (after the target optimization hook) and
1419    when an optimize/target attribute (or pragma) is used.  */
1420
1421 void diagnose_options (gcc_options *opts, gcc_options *opts_set,
1422                        location_t loc)
1423 {
1424   /* The optimization to partition hot and cold basic blocks into separate
1425      sections of the .o and executable files does not work (currently)
1426      with exception handling.  This is because there is no support for
1427      generating unwind info.  If opts->x_flag_exceptions is turned on
1428      we need to turn off the partitioning optimization.  */
1429
1430   enum unwind_info_type ui_except
1431     = targetm_common.except_unwind_info (opts);
1432
1433   if (opts->x_flag_exceptions
1434       && opts->x_flag_reorder_blocks_and_partition
1435       && (ui_except == UI_SJLJ || ui_except >= UI_TARGET))
1436     {
1437       if (opts_set->x_flag_reorder_blocks_and_partition)
1438         inform (loc,
1439                 "%<-freorder-blocks-and-partition%> does not work "
1440                 "with exceptions on this architecture");
1441       opts->x_flag_reorder_blocks_and_partition = 0;
1442       opts->x_flag_reorder_blocks = 1;
1443     }
1444
1445   /* If user requested unwind info, then turn off the partitioning
1446      optimization.  */
1447
1448   if (opts->x_flag_unwind_tables
1449       && !targetm_common.unwind_tables_default
1450       && opts->x_flag_reorder_blocks_and_partition
1451       && (ui_except == UI_SJLJ || ui_except >= UI_TARGET))
1452     {
1453       if (opts_set->x_flag_reorder_blocks_and_partition)
1454         inform (loc,
1455                 "%<-freorder-blocks-and-partition%> does not support "
1456                 "unwind info on this architecture");
1457       opts->x_flag_reorder_blocks_and_partition = 0;
1458       opts->x_flag_reorder_blocks = 1;
1459     }
1460
1461   /* If the target requested unwind info, then turn off the partitioning
1462      optimization with a different message.  Likewise, if the target does not
1463      support named sections.  */
1464
1465   if (opts->x_flag_reorder_blocks_and_partition
1466       && (!targetm_common.have_named_sections
1467           || (opts->x_flag_unwind_tables
1468               && targetm_common.unwind_tables_default
1469               && (ui_except == UI_SJLJ || ui_except >= UI_TARGET))))
1470     {
1471       if (opts_set->x_flag_reorder_blocks_and_partition)
1472         inform (loc,
1473                 "%<-freorder-blocks-and-partition%> does not work "
1474                 "on this architecture");
1475       opts->x_flag_reorder_blocks_and_partition = 0;
1476       opts->x_flag_reorder_blocks = 1;
1477     }
1478
1479
1480 }
1481
1482 #define LEFT_COLUMN     27
1483
1484 /* Output ITEM, of length ITEM_WIDTH, in the left column,
1485    followed by word-wrapped HELP in a second column.  */
1486 static void
1487 wrap_help (const char *help,
1488            const char *item,
1489            unsigned int item_width,
1490            unsigned int columns)
1491 {
1492   unsigned int col_width = LEFT_COLUMN;
1493   unsigned int remaining, room, len;
1494
1495   remaining = strlen (help);
1496
1497   do
1498     {
1499       room = columns - 3 - MAX (col_width, item_width);
1500       if (room > columns)
1501         room = 0;
1502       len = remaining;
1503
1504       if (room < len)
1505         {
1506           unsigned int i;
1507
1508           for (i = 0; help[i]; i++)
1509             {
1510               if (i >= room && len != remaining)
1511                 break;
1512               if (help[i] == ' ')
1513                 len = i;
1514               else if ((help[i] == '-' || help[i] == '/')
1515                        && help[i + 1] != ' '
1516                        && i > 0 && ISALPHA (help[i - 1]))
1517                 len = i + 1;
1518             }
1519         }
1520
1521       printf ("  %-*.*s %.*s\n", col_width, item_width, item, len, help);
1522       item_width = 0;
1523       while (help[len] == ' ')
1524         len++;
1525       help += len;
1526       remaining -= len;
1527     }
1528   while (remaining);
1529 }
1530
1531 /* Data structure used to print list of valid option values.  */
1532
1533 class option_help_tuple
1534 {
1535 public:
1536   option_help_tuple (int code, vec<const char *> values):
1537     m_code (code), m_values (values)
1538   {}
1539
1540   /* Code of an option.  */
1541   int m_code;
1542
1543   /* List of possible values.  */
1544   vec<const char *> m_values;
1545 };
1546
1547 /* Print help for a specific front-end, etc.  */
1548 static void
1549 print_filtered_help (unsigned int include_flags,
1550                      unsigned int exclude_flags,
1551                      unsigned int any_flags,
1552                      unsigned int columns,
1553                      struct gcc_options *opts,
1554                      unsigned int lang_mask)
1555 {
1556   unsigned int i;
1557   const char *help;
1558   bool found = false;
1559   bool displayed = false;
1560   char new_help[256];
1561
1562   if (!opts->x_help_printed)
1563     opts->x_help_printed = XCNEWVAR (char, cl_options_count);
1564
1565   if (!opts->x_help_enum_printed)
1566     opts->x_help_enum_printed = XCNEWVAR (char, cl_enums_count);
1567
1568   auto_vec<option_help_tuple> help_tuples;
1569
1570   for (i = 0; i < cl_options_count; i++)
1571     {
1572       const struct cl_option *option = cl_options + i;
1573       unsigned int len;
1574       const char *opt;
1575       const char *tab;
1576
1577       if (include_flags == 0
1578           || ((option->flags & include_flags) != include_flags))
1579         {
1580           if ((option->flags & any_flags) == 0)
1581             continue;
1582         }
1583
1584       /* Skip unwanted switches.  */
1585       if ((option->flags & exclude_flags) != 0)
1586         continue;
1587
1588       /* The driver currently prints its own help text.  */
1589       if ((option->flags & CL_DRIVER) != 0
1590           && (option->flags & (((1U << cl_lang_count) - 1)
1591                                | CL_COMMON | CL_TARGET)) == 0)
1592         continue;
1593
1594       /* If an option contains a language specification,
1595          exclude it from common unless all languages are present.  */
1596       if ((include_flags & CL_COMMON)
1597           && !(option->flags & CL_DRIVER)
1598           && (option->flags & CL_LANG_ALL)
1599           && (option->flags & CL_LANG_ALL) != CL_LANG_ALL)
1600         continue;
1601
1602       found = true;
1603       /* Skip switches that have already been printed.  */
1604       if (opts->x_help_printed[i])
1605         continue;
1606
1607       opts->x_help_printed[i] = true;
1608
1609       help = option->help;
1610       if (help == NULL)
1611         {
1612           if (exclude_flags & CL_UNDOCUMENTED)
1613             continue;
1614
1615           help = undocumented_msg;
1616         }
1617
1618       /* Get the translation.  */
1619       help = _(help);
1620
1621       if (option->alias_target < N_OPTS
1622           && cl_options [option->alias_target].help)
1623         {
1624           const struct cl_option *target = cl_options + option->alias_target;
1625           if (option->help == NULL)
1626             {
1627               /* The option is undocumented but is an alias for an option that
1628                  is documented.  If the option has alias arguments, then its
1629                  purpose is to provide certain arguments to the other option, so
1630                  inform the reader of this.  Otherwise, point the reader to the
1631                  other option in preference to the former.  */
1632
1633               if (option->alias_arg)
1634                 {
1635                   if (option->neg_alias_arg)
1636                     snprintf (new_help, sizeof new_help,
1637                               _("Same as %s%s (or, in negated form, %s%s)."),
1638                               target->opt_text, option->alias_arg,
1639                               target->opt_text, option->neg_alias_arg);
1640                   else
1641                     snprintf (new_help, sizeof new_help,
1642                               _("Same as %s%s."),
1643                               target->opt_text, option->alias_arg);
1644                 }
1645               else
1646                 snprintf (new_help, sizeof new_help,
1647                           _("Same as %s."),
1648                           target->opt_text);
1649             }
1650           else
1651             {
1652               /* For documented options with aliases, mention the aliased
1653                  option's name for reference.  */
1654               snprintf (new_help, sizeof new_help,
1655                         _("%s  Same as %s."),
1656                         help, cl_options [option->alias_target].opt_text);
1657             }
1658
1659           help = new_help;
1660         }
1661
1662       if (option->warn_message)
1663         {
1664           /* Mention that the use of the option will trigger a warning.  */
1665           if (help == new_help)
1666             snprintf (new_help + strlen (new_help),
1667                       sizeof new_help - strlen (new_help),
1668                       "  %s", _(use_diagnosed_msg));
1669           else
1670             snprintf (new_help, sizeof new_help,
1671                       "%s  %s", help, _(use_diagnosed_msg));
1672
1673           help = new_help;
1674         }
1675
1676       /* Find the gap between the name of the
1677          option and its descriptive text.  */
1678       tab = strchr (help, '\t');
1679       if (tab)
1680         {
1681           len = tab - help;
1682           opt = help;
1683           help = tab + 1;
1684         }
1685       else
1686         {
1687           opt = option->opt_text;
1688           len = strlen (opt);
1689         }
1690
1691       /* With the -Q option enabled we change the descriptive text associated
1692          with an option to be an indication of its current setting.  */
1693       if (!opts->x_quiet_flag)
1694         {
1695           void *flag_var = option_flag_var (i, opts);
1696
1697           if (len < (LEFT_COLUMN + 2))
1698             strcpy (new_help, "\t\t");
1699           else
1700             strcpy (new_help, "\t");
1701
1702           /* Set to print whether the option is enabled or disabled,
1703              or, if it's an alias for another option, the name of
1704              the aliased option.  */
1705           bool print_state = false;
1706
1707           if (flag_var != NULL
1708               && option->var_type != CLVC_DEFER)
1709             {
1710               /* If OPTION is only available for a specific subset
1711                  of languages other than this one, mention them.  */
1712               bool avail_for_lang = true;
1713               if (unsigned langset = option->flags & CL_LANG_ALL)
1714                 {
1715                   if (!(langset & lang_mask))
1716                     {
1717                       avail_for_lang = false;
1718                       strcat (new_help, _("[available in "));
1719                       for (unsigned i = 0, n = 0; (1U << i) < CL_LANG_ALL; ++i)
1720                         if (langset & (1U << i))
1721                           {
1722                             if (n++)
1723                               strcat (new_help, ", ");
1724                             strcat (new_help, lang_names[i]);
1725                           }
1726                       strcat (new_help, "]");
1727                     }
1728                 }
1729               if (!avail_for_lang)
1730                 ; /* Print nothing else if the option is not available
1731                      in the current language.  */
1732               else if (option->flags & CL_JOINED)
1733                 {
1734                   if (option->var_type == CLVC_STRING)
1735                     {
1736                       if (* (const char **) flag_var != NULL)
1737                         snprintf (new_help + strlen (new_help),
1738                                   sizeof (new_help) - strlen (new_help),
1739                                   "%s", * (const char **) flag_var);
1740                     }
1741                   else if (option->var_type == CLVC_ENUM)
1742                     {
1743                       const struct cl_enum *e = &cl_enums[option->var_enum];
1744                       int value;
1745                       const char *arg = NULL;
1746
1747                       value = e->get (flag_var);
1748                       enum_value_to_arg (e->values, &arg, value, lang_mask);
1749                       if (arg == NULL)
1750                         arg = _("[default]");
1751                       snprintf (new_help + strlen (new_help),
1752                                 sizeof (new_help) - strlen (new_help),
1753                                 "%s", arg);
1754                     }
1755                   else
1756                     {
1757                       if (option->cl_host_wide_int)
1758                         sprintf (new_help + strlen (new_help),
1759                                  _("%llu bytes"), (unsigned long long)
1760                                  *(unsigned HOST_WIDE_INT *) flag_var);
1761                       else
1762                         sprintf (new_help + strlen (new_help),
1763                                  "%i", * (int *) flag_var);
1764                     }
1765                 }
1766               else
1767                 print_state = true;
1768             }
1769           else
1770             /* When there is no argument, print the option state only
1771                if the option takes no argument.  */
1772             print_state = !(option->flags & CL_JOINED);
1773
1774           if (print_state)
1775             {
1776               if (option->alias_target < N_OPTS
1777                   && option->alias_target != OPT_SPECIAL_warn_removed
1778                   && option->alias_target != OPT_SPECIAL_ignore
1779                   && option->alias_target != OPT_SPECIAL_input_file
1780                   && option->alias_target != OPT_SPECIAL_program_name
1781                   && option->alias_target != OPT_SPECIAL_unknown)
1782                 {
1783                   const struct cl_option *target
1784                     = &cl_options[option->alias_target];
1785                   sprintf (new_help + strlen (new_help), "%s%s",
1786                            target->opt_text,
1787                            option->alias_arg ? option->alias_arg : "");
1788                 }
1789               else if (option->alias_target == OPT_SPECIAL_ignore)
1790                 strcat (new_help, ("[ignored]"));
1791               else
1792                 {
1793                   /* Print the state for an on/off option.  */
1794                   int ena = option_enabled (i, lang_mask, opts);
1795                   if (ena > 0)
1796                     strcat (new_help, _("[enabled]"));
1797                   else if (ena == 0)
1798                     strcat (new_help, _("[disabled]"));
1799                 }
1800             }
1801
1802           help = new_help;
1803         }
1804
1805       if (option->range_max != -1 && tab == NULL)
1806         {
1807           char b[128];
1808           snprintf (b, sizeof (b), "<%d,%d>", option->range_min,
1809                     option->range_max);
1810           opt = concat (opt, b, NULL);
1811           len += strlen (b);
1812         }
1813
1814       wrap_help (help, opt, len, columns);
1815       displayed = true;
1816
1817       if (option->var_type == CLVC_ENUM
1818           && opts->x_help_enum_printed[option->var_enum] != 2)
1819         opts->x_help_enum_printed[option->var_enum] = 1;
1820       else
1821         {
1822           vec<const char *> option_values
1823             = targetm_common.get_valid_option_values (i, NULL);
1824           if (!option_values.is_empty ())
1825             help_tuples.safe_push (option_help_tuple (i, option_values));
1826         }
1827     }
1828
1829   if (! found)
1830     {
1831       unsigned int langs = include_flags & CL_LANG_ALL;
1832
1833       if (langs == 0)
1834         printf (_(" No options with the desired characteristics were found\n"));
1835       else
1836         {
1837           unsigned int i;
1838
1839           /* PR 31349: Tell the user how to see all of the
1840              options supported by a specific front end.  */
1841           for (i = 0; (1U << i) < CL_LANG_ALL; i ++)
1842             if ((1U << i) & langs)
1843               printf (_(" None found.  Use --help=%s to show *all* the options supported by the %s front-end.\n"),
1844                       lang_names[i], lang_names[i]);
1845         }
1846
1847     }
1848   else if (! displayed)
1849     printf (_(" All options with the desired characteristics have already been displayed\n"));
1850
1851   putchar ('\n');
1852
1853   /* Print details of enumerated option arguments, if those
1854      enumerations have help text headings provided.  If no help text
1855      is provided, presume that the possible values are listed in the
1856      help text for the relevant options.  */
1857   for (i = 0; i < cl_enums_count; i++)
1858     {
1859       unsigned int j, pos;
1860
1861       if (opts->x_help_enum_printed[i] != 1)
1862         continue;
1863       if (cl_enums[i].help == NULL)
1864         continue;
1865       printf ("  %s\n    ", _(cl_enums[i].help));
1866       pos = 4;
1867       for (j = 0; cl_enums[i].values[j].arg != NULL; j++)
1868         {
1869           unsigned int len = strlen (cl_enums[i].values[j].arg);
1870
1871           if (pos > 4 && pos + 1 + len <= columns)
1872             {
1873               printf (" %s", cl_enums[i].values[j].arg);
1874               pos += 1 + len;
1875             }
1876           else
1877             {
1878               if (pos > 4)
1879                 {
1880                   printf ("\n    ");
1881                   pos = 4;
1882                 }
1883               printf ("%s", cl_enums[i].values[j].arg);
1884               pos += len;
1885             }
1886         }
1887       printf ("\n\n");
1888       opts->x_help_enum_printed[i] = 2;
1889     }
1890
1891   for (unsigned i = 0; i < help_tuples.length (); i++)
1892     {
1893       const struct cl_option *option = cl_options + help_tuples[i].m_code;
1894       printf (_("  Known valid arguments for %s option:\n   "),
1895               option->opt_text);
1896       for (unsigned j = 0; j < help_tuples[i].m_values.length (); j++)
1897         printf (" %s", help_tuples[i].m_values[j]);
1898       printf ("\n\n");
1899     }
1900 }
1901
1902 /* Display help for a specified type of option.
1903    The options must have ALL of the INCLUDE_FLAGS set
1904    ANY of the flags in the ANY_FLAGS set
1905    and NONE of the EXCLUDE_FLAGS set.  The current option state is in
1906    OPTS; LANG_MASK is used for interpreting enumerated option state.  */
1907 static void
1908 print_specific_help (unsigned int include_flags,
1909                      unsigned int exclude_flags,
1910                      unsigned int any_flags,
1911                      struct gcc_options *opts,
1912                      unsigned int lang_mask)
1913 {
1914   unsigned int all_langs_mask = (1U << cl_lang_count) - 1;
1915   const char * description = NULL;
1916   const char * descrip_extra = "";
1917   size_t i;
1918   unsigned int flag;
1919
1920   /* Sanity check: Make sure that we do not have more
1921      languages than we have bits available to enumerate them.  */
1922   gcc_assert ((1U << cl_lang_count) <= CL_MIN_OPTION_CLASS);
1923
1924   /* If we have not done so already, obtain
1925      the desired maximum width of the output.  */
1926   if (opts->x_help_columns == 0)
1927     {
1928       opts->x_help_columns = get_terminal_width ();
1929       if (opts->x_help_columns == INT_MAX)
1930         /* Use a reasonable default.  */
1931         opts->x_help_columns = 80;
1932     }
1933
1934   /* Decide upon the title for the options that we are going to display.  */
1935   for (i = 0, flag = 1; flag <= CL_MAX_OPTION_CLASS; flag <<= 1, i ++)
1936     {
1937       switch (flag & include_flags)
1938         {
1939         case 0:
1940         case CL_DRIVER:
1941           break;
1942
1943         case CL_TARGET:
1944           description = _("The following options are target specific");
1945           break;
1946         case CL_WARNING:
1947           description = _("The following options control compiler warning messages");
1948           break;
1949         case CL_OPTIMIZATION:
1950           description = _("The following options control optimizations");
1951           break;
1952         case CL_COMMON:
1953           description = _("The following options are language-independent");
1954           break;
1955         case CL_PARAMS:
1956           description = _("The following options control parameters");
1957           break;
1958         default:
1959           if (i >= cl_lang_count)
1960             break;
1961           if (exclude_flags & all_langs_mask)
1962             description = _("The following options are specific to just the language ");
1963           else
1964             description = _("The following options are supported by the language ");
1965           descrip_extra = lang_names [i];
1966           break;
1967         }
1968     }
1969
1970   if (description == NULL)
1971     {
1972       if (any_flags == 0)
1973         {
1974           if (include_flags & CL_UNDOCUMENTED)
1975             description = _("The following options are not documented");
1976           else if (include_flags & CL_SEPARATE)
1977             description = _("The following options take separate arguments");
1978           else if (include_flags & CL_JOINED)
1979             description = _("The following options take joined arguments");
1980           else
1981             {
1982               internal_error ("unrecognized %<include_flags 0x%x%> passed "
1983                               "to %<print_specific_help%>",
1984                               include_flags);
1985               return;
1986             }
1987         }
1988       else
1989         {
1990           if (any_flags & all_langs_mask)
1991             description = _("The following options are language-related");
1992           else
1993             description = _("The following options are language-independent");
1994         }
1995     }
1996
1997   printf ("%s%s:\n", description, descrip_extra);
1998   print_filtered_help (include_flags, exclude_flags, any_flags,
1999                        opts->x_help_columns, opts, lang_mask);
2000 }
2001
2002 /* Enable FDO-related flags.  */
2003
2004 static void
2005 enable_fdo_optimizations (struct gcc_options *opts,
2006                           struct gcc_options *opts_set,
2007                           int value)
2008 {
2009   SET_OPTION_IF_UNSET (opts, opts_set, flag_branch_probabilities, value);
2010   SET_OPTION_IF_UNSET (opts, opts_set, flag_profile_values, value);
2011   SET_OPTION_IF_UNSET (opts, opts_set, flag_unroll_loops, value);
2012   SET_OPTION_IF_UNSET (opts, opts_set, flag_peel_loops, value);
2013   SET_OPTION_IF_UNSET (opts, opts_set, flag_tracer, value);
2014   SET_OPTION_IF_UNSET (opts, opts_set, flag_value_profile_transformations,
2015                        value);
2016   SET_OPTION_IF_UNSET (opts, opts_set, flag_inline_functions, value);
2017   SET_OPTION_IF_UNSET (opts, opts_set, flag_ipa_cp, value);
2018   if (value)
2019     {
2020       SET_OPTION_IF_UNSET (opts, opts_set, flag_ipa_cp_clone, 1);
2021       SET_OPTION_IF_UNSET (opts, opts_set, flag_ipa_bit_cp, 1);
2022     }
2023   SET_OPTION_IF_UNSET (opts, opts_set, flag_predictive_commoning, value);
2024   SET_OPTION_IF_UNSET (opts, opts_set, flag_split_loops, value);
2025   SET_OPTION_IF_UNSET (opts, opts_set, flag_unswitch_loops, value);
2026   SET_OPTION_IF_UNSET (opts, opts_set, flag_gcse_after_reload, value);
2027   SET_OPTION_IF_UNSET (opts, opts_set, flag_tree_loop_vectorize, value);
2028   SET_OPTION_IF_UNSET (opts, opts_set, flag_tree_slp_vectorize, value);
2029   SET_OPTION_IF_UNSET (opts, opts_set, flag_version_loops_for_strides, value);
2030   SET_OPTION_IF_UNSET (opts, opts_set, flag_vect_cost_model,
2031                        VECT_COST_MODEL_DYNAMIC);
2032   SET_OPTION_IF_UNSET (opts, opts_set, flag_tree_loop_distribute_patterns,
2033                        value);
2034   SET_OPTION_IF_UNSET (opts, opts_set, flag_loop_interchange, value);
2035   SET_OPTION_IF_UNSET (opts, opts_set, flag_unroll_jam, value);
2036   SET_OPTION_IF_UNSET (opts, opts_set, flag_tree_loop_distribution, value);
2037 }
2038
2039 /* -f{,no-}sanitize{,-recover}= suboptions.  */
2040 const struct sanitizer_opts_s sanitizer_opts[] =
2041 {
2042 #define SANITIZER_OPT(name, flags, recover, trap) \
2043     { #name, flags, sizeof #name - 1, recover, trap }
2044   SANITIZER_OPT (address, (SANITIZE_ADDRESS | SANITIZE_USER_ADDRESS), true,
2045                  false),
2046   SANITIZER_OPT (hwaddress, (SANITIZE_HWADDRESS | SANITIZE_USER_HWADDRESS),
2047                  true, false),
2048   SANITIZER_OPT (kernel-address, (SANITIZE_ADDRESS | SANITIZE_KERNEL_ADDRESS),
2049                  true, false),
2050   SANITIZER_OPT (kernel-hwaddress,
2051                  (SANITIZE_HWADDRESS | SANITIZE_KERNEL_HWADDRESS),
2052                  true, false),
2053   SANITIZER_OPT (pointer-compare, SANITIZE_POINTER_COMPARE, true, false),
2054   SANITIZER_OPT (pointer-subtract, SANITIZE_POINTER_SUBTRACT, true, false),
2055   SANITIZER_OPT (thread, SANITIZE_THREAD, false, false),
2056   SANITIZER_OPT (leak, SANITIZE_LEAK, false, false),
2057   SANITIZER_OPT (shift, SANITIZE_SHIFT, true, true),
2058   SANITIZER_OPT (shift-base, SANITIZE_SHIFT_BASE, true, true),
2059   SANITIZER_OPT (shift-exponent, SANITIZE_SHIFT_EXPONENT, true, true),
2060   SANITIZER_OPT (integer-divide-by-zero, SANITIZE_DIVIDE, true, true),
2061   SANITIZER_OPT (undefined, SANITIZE_UNDEFINED, true, true),
2062   SANITIZER_OPT (unreachable, SANITIZE_UNREACHABLE, false, true),
2063   SANITIZER_OPT (vla-bound, SANITIZE_VLA, true, true),
2064   SANITIZER_OPT (return, SANITIZE_RETURN, false, true),
2065   SANITIZER_OPT (null, SANITIZE_NULL, true, true),
2066   SANITIZER_OPT (signed-integer-overflow, SANITIZE_SI_OVERFLOW, true, true),
2067   SANITIZER_OPT (bool, SANITIZE_BOOL, true, true),
2068   SANITIZER_OPT (enum, SANITIZE_ENUM, true, true),
2069   SANITIZER_OPT (float-divide-by-zero, SANITIZE_FLOAT_DIVIDE, true, true),
2070   SANITIZER_OPT (float-cast-overflow, SANITIZE_FLOAT_CAST, true, true),
2071   SANITIZER_OPT (bounds, SANITIZE_BOUNDS, true, true),
2072   SANITIZER_OPT (bounds-strict, SANITIZE_BOUNDS | SANITIZE_BOUNDS_STRICT, true,
2073                  true),
2074   SANITIZER_OPT (alignment, SANITIZE_ALIGNMENT, true, true),
2075   SANITIZER_OPT (nonnull-attribute, SANITIZE_NONNULL_ATTRIBUTE, true, true),
2076   SANITIZER_OPT (returns-nonnull-attribute, SANITIZE_RETURNS_NONNULL_ATTRIBUTE,
2077                  true, true),
2078   SANITIZER_OPT (object-size, SANITIZE_OBJECT_SIZE, true, true),
2079   SANITIZER_OPT (vptr, SANITIZE_VPTR, true, false),
2080   SANITIZER_OPT (pointer-overflow, SANITIZE_POINTER_OVERFLOW, true, true),
2081   SANITIZER_OPT (builtin, SANITIZE_BUILTIN, true, true),
2082   SANITIZER_OPT (shadow-call-stack, SANITIZE_SHADOW_CALL_STACK, false, false),
2083   SANITIZER_OPT (all, ~0U, true, true),
2084 #undef SANITIZER_OPT
2085   { NULL, 0U, 0UL, false, false }
2086 };
2087
2088 /* -fzero-call-used-regs= suboptions.  */
2089 const struct zero_call_used_regs_opts_s zero_call_used_regs_opts[] =
2090 {
2091 #define ZERO_CALL_USED_REGS_OPT(name, flags) \
2092     { #name, flags }
2093   ZERO_CALL_USED_REGS_OPT (skip, zero_regs_flags::SKIP),
2094   ZERO_CALL_USED_REGS_OPT (used-gpr-arg, zero_regs_flags::USED_GPR_ARG),
2095   ZERO_CALL_USED_REGS_OPT (used-gpr, zero_regs_flags::USED_GPR),
2096   ZERO_CALL_USED_REGS_OPT (used-arg, zero_regs_flags::USED_ARG),
2097   ZERO_CALL_USED_REGS_OPT (used, zero_regs_flags::USED),
2098   ZERO_CALL_USED_REGS_OPT (all-gpr-arg, zero_regs_flags::ALL_GPR_ARG),
2099   ZERO_CALL_USED_REGS_OPT (all-gpr, zero_regs_flags::ALL_GPR),
2100   ZERO_CALL_USED_REGS_OPT (all-arg, zero_regs_flags::ALL_ARG),
2101   ZERO_CALL_USED_REGS_OPT (all, zero_regs_flags::ALL),
2102 #undef ZERO_CALL_USED_REGS_OPT
2103   {NULL, 0U}
2104 };
2105
2106 /* A struct for describing a run of chars within a string.  */
2107
2108 class string_fragment
2109 {
2110 public:
2111   string_fragment (const char *start, size_t len)
2112   : m_start (start), m_len (len) {}
2113
2114   const char *m_start;
2115   size_t m_len;
2116 };
2117
2118 /* Specialization of edit_distance_traits for string_fragment,
2119    for use by get_closest_sanitizer_option.  */
2120
2121 template <>
2122 struct edit_distance_traits<const string_fragment &>
2123 {
2124   static size_t get_length (const string_fragment &fragment)
2125   {
2126     return fragment.m_len;
2127   }
2128
2129   static const char *get_string (const string_fragment &fragment)
2130   {
2131     return fragment.m_start;
2132   }
2133 };
2134
2135 /* Given ARG, an unrecognized sanitizer option, return the best
2136    matching sanitizer option, or NULL if there isn't one.
2137    OPTS is array of candidate sanitizer options.
2138    CODE is OPT_fsanitize_, OPT_fsanitize_recover_ or OPT_fsanitize_trap_.
2139    VALUE is non-zero for the regular form of the option, zero
2140    for the "no-" form (e.g. "-fno-sanitize-recover=").  */
2141
2142 static const char *
2143 get_closest_sanitizer_option (const string_fragment &arg,
2144                               const struct sanitizer_opts_s *opts,
2145                               enum opt_code code, int value)
2146 {
2147   best_match <const string_fragment &, const char*> bm (arg);
2148   for (int i = 0; opts[i].name != NULL; ++i)
2149     {
2150       /* -fsanitize=all is not valid, so don't offer it.  */
2151       if (code == OPT_fsanitize_
2152           && opts[i].flag == ~0U
2153           && value)
2154         continue;
2155
2156       /* For -fsanitize-recover= (and not -fno-sanitize-recover=),
2157          don't offer the non-recoverable options.  */
2158       if (code == OPT_fsanitize_recover_
2159           && !opts[i].can_recover
2160           && value)
2161         continue;
2162
2163       /* For -fsanitize-trap= (and not -fno-sanitize-trap=),
2164          don't offer the non-trapping options.  */
2165       if (code == OPT_fsanitize_trap_
2166           && !opts[i].can_trap
2167           && value)
2168         continue;
2169
2170       bm.consider (opts[i].name);
2171     }
2172   return bm.get_best_meaningful_candidate ();
2173 }
2174
2175 /* Parse comma separated sanitizer suboptions from P for option SCODE,
2176    adjust previous FLAGS and return new ones.  If COMPLAIN is false,
2177    don't issue diagnostics.  */
2178
2179 unsigned int
2180 parse_sanitizer_options (const char *p, location_t loc, int scode,
2181                          unsigned int flags, int value, bool complain)
2182 {
2183   enum opt_code code = (enum opt_code) scode;
2184
2185   while (*p != 0)
2186     {
2187       size_t len, i;
2188       bool found = false;
2189       const char *comma = strchr (p, ',');
2190
2191       if (comma == NULL)
2192         len = strlen (p);
2193       else
2194         len = comma - p;
2195       if (len == 0)
2196         {
2197           p = comma + 1;
2198           continue;
2199         }
2200
2201       /* Check to see if the string matches an option class name.  */
2202       for (i = 0; sanitizer_opts[i].name != NULL; ++i)
2203         if (len == sanitizer_opts[i].len
2204             && memcmp (p, sanitizer_opts[i].name, len) == 0)
2205           {
2206             /* Handle both -fsanitize and -fno-sanitize cases.  */
2207             if (value && sanitizer_opts[i].flag == ~0U)
2208               {
2209                 if (code == OPT_fsanitize_)
2210                   {
2211                     if (complain)
2212                       error_at (loc, "%<-fsanitize=all%> option is not valid");
2213                   }
2214                 else if (code == OPT_fsanitize_recover_)
2215                   flags |= ~(SANITIZE_THREAD | SANITIZE_LEAK
2216                              | SANITIZE_UNREACHABLE | SANITIZE_RETURN
2217                              | SANITIZE_SHADOW_CALL_STACK);
2218                 else /* if (code == OPT_fsanitize_trap_) */
2219                   flags |= (SANITIZE_UNDEFINED
2220                             | SANITIZE_UNDEFINED_NONDEFAULT);
2221               }
2222             else if (value)
2223               {
2224                 /* Do not enable -fsanitize-recover=unreachable and
2225                    -fsanitize-recover=return if -fsanitize-recover=undefined
2226                    is selected.  */
2227                 if (code == OPT_fsanitize_recover_
2228                     && sanitizer_opts[i].flag == SANITIZE_UNDEFINED)
2229                   flags |= (SANITIZE_UNDEFINED
2230                             & ~(SANITIZE_UNREACHABLE | SANITIZE_RETURN));
2231                 else if (code == OPT_fsanitize_trap_
2232                          && sanitizer_opts[i].flag == SANITIZE_VPTR)
2233                   error_at (loc, "%<-fsanitize-trap=%s%> is not supported",
2234                             sanitizer_opts[i].name);
2235                 else
2236                   flags |= sanitizer_opts[i].flag;
2237               }
2238             else
2239               flags &= ~sanitizer_opts[i].flag;
2240             found = true;
2241             break;
2242           }
2243
2244       if (! found && complain)
2245         {
2246           const char *hint
2247             = get_closest_sanitizer_option (string_fragment (p, len),
2248                                             sanitizer_opts, code, value);
2249
2250           const char *suffix;
2251           if (code == OPT_fsanitize_recover_)
2252             suffix = "-recover";
2253           else if (code == OPT_fsanitize_trap_)
2254             suffix = "-trap";
2255           else
2256             suffix = "";
2257
2258           if (hint)
2259             error_at (loc,
2260                       "unrecognized argument to %<-f%ssanitize%s=%> "
2261                       "option: %q.*s; did you mean %qs?",
2262                       value ? "" : "no-",
2263                       suffix, (int) len, p, hint);
2264           else
2265             error_at (loc,
2266                       "unrecognized argument to %<-f%ssanitize%s=%> option: "
2267                       "%q.*s", value ? "" : "no-",
2268                       suffix, (int) len, p);
2269         }
2270
2271       if (comma == NULL)
2272         break;
2273       p = comma + 1;
2274     }
2275   return flags;
2276 }
2277
2278 /* Parse string values of no_sanitize attribute passed in VALUE.
2279    Values are separated with comma.  */
2280
2281 unsigned int
2282 parse_no_sanitize_attribute (char *value)
2283 {
2284   unsigned int flags = 0;
2285   unsigned int i;
2286   char *q = strtok (value, ",");
2287
2288   while (q != NULL)
2289     {
2290       for (i = 0; sanitizer_opts[i].name != NULL; ++i)
2291         if (strcmp (sanitizer_opts[i].name, q) == 0)
2292           {
2293             flags |= sanitizer_opts[i].flag;
2294             if (sanitizer_opts[i].flag == SANITIZE_UNDEFINED)
2295               flags |= SANITIZE_UNDEFINED_NONDEFAULT;
2296             break;
2297           }
2298
2299       if (sanitizer_opts[i].name == NULL)
2300         warning (OPT_Wattributes,
2301                  "%qs attribute directive ignored", q);
2302
2303       q = strtok (NULL, ",");
2304     }
2305
2306   return flags;
2307 }
2308
2309 /* Parse -fzero-call-used-regs suboptions from ARG, return the FLAGS.  */
2310
2311 unsigned int
2312 parse_zero_call_used_regs_options (const char *arg)
2313 {
2314   unsigned int flags = 0;
2315
2316   /* Check to see if the string matches a sub-option name.  */
2317   for (unsigned int i = 0; zero_call_used_regs_opts[i].name != NULL; ++i)
2318     if (strcmp (arg, zero_call_used_regs_opts[i].name) == 0)
2319       {
2320         flags = zero_call_used_regs_opts[i].flag;
2321         break;
2322       }
2323
2324   if (!flags)
2325     error ("unrecognized argument to %<-fzero-call-used-regs=%>: %qs", arg);
2326
2327   return flags;
2328 }
2329
2330 /* Parse -falign-NAME format for a FLAG value.  Return individual
2331    parsed integer values into RESULT_VALUES array.  If REPORT_ERROR is
2332    set, print error message at LOC location.  */
2333
2334 bool
2335 parse_and_check_align_values (const char *flag,
2336                               const char *name,
2337                               auto_vec<unsigned> &result_values,
2338                               bool report_error,
2339                               location_t loc)
2340 {
2341   char *str = xstrdup (flag);
2342   for (char *p = strtok (str, ":"); p; p = strtok (NULL, ":"))
2343     {
2344       char *end;
2345       int v = strtol (p, &end, 10);
2346       if (*end != '\0' || v < 0)
2347         {
2348           if (report_error)
2349             error_at (loc, "invalid arguments for %<-falign-%s%> option: %qs",
2350                       name, flag);
2351
2352           return false;
2353         }
2354
2355       result_values.safe_push ((unsigned)v);
2356     }
2357
2358   free (str);
2359
2360   /* Check that we have a correct number of values.  */
2361   if (result_values.is_empty () || result_values.length () > 4)
2362     {
2363       if (report_error)
2364         error_at (loc, "invalid number of arguments for %<-falign-%s%> "
2365                   "option: %qs", name, flag);
2366       return false;
2367     }
2368
2369   for (unsigned i = 0; i < result_values.length (); i++)
2370     if (result_values[i] > MAX_CODE_ALIGN_VALUE)
2371       {
2372         if (report_error)
2373           error_at (loc, "%<-falign-%s%> is not between 0 and %d",
2374                     name, MAX_CODE_ALIGN_VALUE);
2375         return false;
2376       }
2377
2378   return true;
2379 }
2380
2381 /* Check that alignment value FLAG for -falign-NAME is valid at a given
2382    location LOC. OPT_STR points to the stored -falign-NAME=argument and
2383    OPT_FLAG points to the associated -falign-NAME on/off flag.  */
2384
2385 static void
2386 check_alignment_argument (location_t loc, const char *flag, const char *name,
2387                           int *opt_flag, const char **opt_str)
2388 {
2389   auto_vec<unsigned> align_result;
2390   parse_and_check_align_values (flag, name, align_result, true, loc);
2391
2392   if (align_result.length() >= 1 && align_result[0] == 0)
2393     {
2394       *opt_flag = 1;
2395       *opt_str = NULL;
2396     }
2397 }
2398
2399 /* Parse argument of -fpatchable-function-entry option ARG and store
2400    corresponding values to PATCH_AREA_SIZE and PATCH_AREA_START.
2401    If REPORT_ERROR is set to true, generate error for a problematic
2402    option arguments.  */
2403
2404 void
2405 parse_and_check_patch_area (const char *arg, bool report_error,
2406                             HOST_WIDE_INT *patch_area_size,
2407                             HOST_WIDE_INT *patch_area_start)
2408 {
2409   *patch_area_size = 0;
2410   *patch_area_start = 0;
2411
2412   if (arg == NULL)
2413     return;
2414
2415   char *patch_area_arg = xstrdup (arg);
2416   char *comma = strchr (patch_area_arg, ',');
2417   if (comma)
2418     {
2419       *comma = '\0';
2420       *patch_area_size = integral_argument (patch_area_arg);
2421       *patch_area_start = integral_argument (comma + 1);
2422     }
2423   else
2424     *patch_area_size = integral_argument (patch_area_arg);
2425
2426   if (*patch_area_size < 0
2427       || *patch_area_size > USHRT_MAX
2428       || *patch_area_start < 0
2429       || *patch_area_start > USHRT_MAX
2430       || *patch_area_size < *patch_area_start)
2431     if (report_error)
2432       error ("invalid arguments for %<-fpatchable-function-entry%>");
2433
2434   free (patch_area_arg);
2435 }
2436
2437 /* Print help when OPT__help_ is set.  */
2438
2439 void
2440 print_help (struct gcc_options *opts, unsigned int lang_mask,
2441             const char *help_option_argument)
2442 {
2443   const char *a = help_option_argument;
2444   unsigned int include_flags = 0;
2445   /* Note - by default we include undocumented options when listing
2446      specific classes.  If you only want to see documented options
2447      then add ",^undocumented" to the --help= option.  E.g.:
2448
2449      --help=target,^undocumented  */
2450   unsigned int exclude_flags = 0;
2451
2452   if (lang_mask == CL_DRIVER)
2453     return;
2454
2455   /* Walk along the argument string, parsing each word in turn.
2456      The format is:
2457      arg = [^]{word}[,{arg}]
2458      word = {optimizers|target|warnings|undocumented|
2459      params|common|<language>}  */
2460   while (*a != 0)
2461     {
2462       static const struct
2463         {
2464           const char *string;
2465           unsigned int flag;
2466         }
2467       specifics[] =
2468         {
2469             { "optimizers", CL_OPTIMIZATION },
2470             { "target", CL_TARGET },
2471             { "warnings", CL_WARNING },
2472             { "undocumented", CL_UNDOCUMENTED },
2473             { "params", CL_PARAMS },
2474             { "joined", CL_JOINED },
2475             { "separate", CL_SEPARATE },
2476             { "common", CL_COMMON },
2477             { NULL, 0 }
2478         };
2479       unsigned int *pflags;
2480       const char *comma;
2481       unsigned int lang_flag, specific_flag;
2482       unsigned int len;
2483       unsigned int i;
2484
2485       if (*a == '^')
2486         {
2487           ++a;
2488           if (*a == '\0')
2489             {
2490               error ("missing argument to %qs", "--help=^");
2491               break;
2492             }
2493           pflags = &exclude_flags;
2494         }
2495       else
2496         pflags = &include_flags;
2497
2498       comma = strchr (a, ',');
2499       if (comma == NULL)
2500         len = strlen (a);
2501       else
2502         len = comma - a;
2503       if (len == 0)
2504         {
2505           a = comma + 1;
2506           continue;
2507         }
2508
2509       /* Check to see if the string matches an option class name.  */
2510       for (i = 0, specific_flag = 0; specifics[i].string != NULL; i++)
2511         if (strncasecmp (a, specifics[i].string, len) == 0)
2512           {
2513             specific_flag = specifics[i].flag;
2514             break;
2515           }
2516
2517       /* Check to see if the string matches a language name.
2518          Note - we rely upon the alpha-sorted nature of the entries in
2519          the lang_names array, specifically that shorter names appear
2520          before their longer variants.  (i.e. C before C++).  That way
2521          when we are attempting to match --help=c for example we will
2522          match with C first and not C++.  */
2523       for (i = 0, lang_flag = 0; i < cl_lang_count; i++)
2524         if (strncasecmp (a, lang_names[i], len) == 0)
2525           {
2526             lang_flag = 1U << i;
2527             break;
2528           }
2529
2530       if (specific_flag != 0)
2531         {
2532           if (lang_flag == 0)
2533             *pflags |= specific_flag;
2534           else
2535             {
2536               /* The option's argument matches both the start of a
2537                  language name and the start of an option class name.
2538                  We have a special case for when the user has
2539                  specified "--help=c", but otherwise we have to issue
2540                  a warning.  */
2541               if (strncasecmp (a, "c", len) == 0)
2542                 *pflags |= lang_flag;
2543               else
2544                 warning (0,
2545                          "%<--help%> argument %q.*s is ambiguous, "
2546                          "please be more specific",
2547                          len, a);
2548             }
2549         }
2550       else if (lang_flag != 0)
2551         *pflags |= lang_flag;
2552       else
2553         warning (0,
2554                  "unrecognized argument to %<--help=%> option: %q.*s",
2555                  len, a);
2556
2557       if (comma == NULL)
2558         break;
2559       a = comma + 1;
2560     }
2561
2562   /* We started using PerFunction/Optimization for parameters and
2563      a warning.  We should exclude these from optimization options.  */
2564   if (include_flags & CL_OPTIMIZATION)
2565     exclude_flags |= CL_WARNING;
2566   if (!(include_flags & CL_PARAMS))
2567     exclude_flags |= CL_PARAMS;
2568
2569   if (include_flags)
2570     print_specific_help (include_flags, exclude_flags, 0, opts,
2571                          lang_mask);
2572 }
2573
2574 /* Handle target- and language-independent options.  Return zero to
2575    generate an "unknown option" message.  Only options that need
2576    extra handling need to be listed here; if you simply want
2577    DECODED->value assigned to a variable, it happens automatically.  */
2578
2579 bool
2580 common_handle_option (struct gcc_options *opts,
2581                       struct gcc_options *opts_set,
2582                       const struct cl_decoded_option *decoded,
2583                       unsigned int lang_mask, int kind ATTRIBUTE_UNUSED,
2584                       location_t loc,
2585                       const struct cl_option_handlers *handlers,
2586                       diagnostic_context *dc,
2587                       void (*target_option_override_hook) (void))
2588 {
2589   size_t scode = decoded->opt_index;
2590   const char *arg = decoded->arg;
2591   HOST_WIDE_INT value = decoded->value;
2592   enum opt_code code = (enum opt_code) scode;
2593
2594   gcc_assert (decoded->canonical_option_num_elements <= 2);
2595
2596   switch (code)
2597     {
2598     case OPT__help:
2599       {
2600         unsigned int all_langs_mask = (1U << cl_lang_count) - 1;
2601         unsigned int undoc_mask;
2602         unsigned int i;
2603
2604         if (lang_mask == CL_DRIVER)
2605           break;
2606
2607         undoc_mask = ((opts->x_verbose_flag | opts->x_extra_warnings)
2608                       ? 0
2609                       : CL_UNDOCUMENTED);
2610         target_option_override_hook ();
2611         /* First display any single language specific options.  */
2612         for (i = 0; i < cl_lang_count; i++)
2613           print_specific_help
2614             (1U << i, (all_langs_mask & (~ (1U << i))) | undoc_mask, 0, opts,
2615              lang_mask);
2616         /* Next display any multi language specific options.  */
2617         print_specific_help (0, undoc_mask, all_langs_mask, opts, lang_mask);
2618         /* Then display any remaining, non-language options.  */
2619         for (i = CL_MIN_OPTION_CLASS; i <= CL_MAX_OPTION_CLASS; i <<= 1)
2620           if (i != CL_DRIVER)
2621             print_specific_help (i, undoc_mask, 0, opts, lang_mask);
2622         opts->x_exit_after_options = true;
2623         break;
2624       }
2625
2626     case OPT__target_help:
2627       if (lang_mask == CL_DRIVER)
2628         break;
2629
2630       target_option_override_hook ();
2631       print_specific_help (CL_TARGET, 0, 0, opts, lang_mask);
2632       opts->x_exit_after_options = true;
2633       break;
2634
2635     case OPT__help_:
2636       {
2637         help_option_arguments.safe_push (arg);
2638         opts->x_exit_after_options = true;
2639         break;
2640       }
2641
2642     case OPT__version:
2643       if (lang_mask == CL_DRIVER)
2644         break;
2645
2646       opts->x_exit_after_options = true;
2647       break;
2648
2649     case OPT__completion_:
2650       break;
2651
2652     case OPT_fsanitize_:
2653       opts_set->x_flag_sanitize = true;
2654       opts->x_flag_sanitize
2655         = parse_sanitizer_options (arg, loc, code,
2656                                    opts->x_flag_sanitize, value, true);
2657
2658       /* Kernel ASan implies normal ASan but does not yet support
2659          all features.  */
2660       if (opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS)
2661         {
2662           SET_OPTION_IF_UNSET (opts, opts_set,
2663                                param_asan_instrumentation_with_call_threshold,
2664                                0);
2665           SET_OPTION_IF_UNSET (opts, opts_set, param_asan_globals, 0);
2666           SET_OPTION_IF_UNSET (opts, opts_set, param_asan_stack, 0);
2667           SET_OPTION_IF_UNSET (opts, opts_set, param_asan_protect_allocas, 0);
2668           SET_OPTION_IF_UNSET (opts, opts_set, param_asan_use_after_return, 0);
2669         }
2670       if (opts->x_flag_sanitize & SANITIZE_KERNEL_HWADDRESS)
2671         {
2672           SET_OPTION_IF_UNSET (opts, opts_set,
2673                                param_hwasan_instrument_stack, 0);
2674           SET_OPTION_IF_UNSET (opts, opts_set,
2675                                param_hwasan_random_frame_tag, 0);
2676           SET_OPTION_IF_UNSET (opts, opts_set,
2677                                param_hwasan_instrument_allocas, 0);
2678         }
2679       break;
2680
2681     case OPT_fsanitize_recover_:
2682       opts->x_flag_sanitize_recover
2683         = parse_sanitizer_options (arg, loc, code,
2684                                    opts->x_flag_sanitize_recover, value, true);
2685       break;
2686
2687     case OPT_fsanitize_trap_:
2688       opts->x_flag_sanitize_trap
2689         = parse_sanitizer_options (arg, loc, code,
2690                                    opts->x_flag_sanitize_trap, value, true);
2691       break;
2692
2693     case OPT_fasan_shadow_offset_:
2694       /* Deferred.  */
2695       break;
2696
2697     case OPT_fsanitize_address_use_after_scope:
2698       opts->x_flag_sanitize_address_use_after_scope = value;
2699       break;
2700
2701     case OPT_fsanitize_recover:
2702       if (value)
2703         opts->x_flag_sanitize_recover
2704           |= (SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT)
2705              & ~(SANITIZE_UNREACHABLE | SANITIZE_RETURN);
2706       else
2707         opts->x_flag_sanitize_recover
2708           &= ~(SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT);
2709       break;
2710
2711     case OPT_fsanitize_trap:
2712       if (value)
2713         opts->x_flag_sanitize_trap
2714           |= (SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT);
2715       else
2716         opts->x_flag_sanitize_trap
2717           &= ~(SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT);
2718       break;
2719
2720     case OPT_O:
2721     case OPT_Os:
2722     case OPT_Ofast:
2723     case OPT_Og:
2724     case OPT_Oz:
2725       /* Currently handled in a prescan.  */
2726       break;
2727
2728     case OPT_Wattributes_:
2729       if (lang_mask == CL_DRIVER)
2730         break;
2731
2732       if (value)
2733         {
2734           error_at (loc, "arguments ignored for %<-Wattributes=%>; use "
2735                     "%<-Wno-attributes=%> instead");
2736           break;
2737         }
2738       else if (arg[strlen (arg) - 1] == ',')
2739         {
2740           error_at (loc, "trailing %<,%> in arguments for "
2741                     "%<-Wno-attributes=%>");
2742           break;
2743         }
2744
2745       add_comma_separated_to_vector (&opts->x_flag_ignored_attributes, arg);
2746       break;
2747
2748     case OPT_Werror:
2749       dc->warning_as_error_requested = value;
2750       break;
2751
2752     case OPT_Werror_:
2753       if (lang_mask == CL_DRIVER)
2754         break;
2755
2756       enable_warning_as_error (arg, value, lang_mask, handlers,
2757                                opts, opts_set, loc, dc);
2758       break;
2759
2760     case OPT_Wfatal_errors:
2761       dc->fatal_errors = value;
2762       break;
2763
2764     case OPT_Wstack_usage_:
2765       opts->x_flag_stack_usage_info = value != -1;
2766       break;
2767
2768     case OPT_Wstrict_aliasing:
2769       set_Wstrict_aliasing (opts, value);
2770       break;
2771
2772     case OPT_Wstrict_overflow:
2773       opts->x_warn_strict_overflow = (value
2774                                       ? (int) WARN_STRICT_OVERFLOW_CONDITIONAL
2775                                       : 0);
2776       break;
2777
2778     case OPT_Wsystem_headers:
2779       dc->dc_warn_system_headers = value;
2780       break;
2781
2782     case OPT_aux_info:
2783       opts->x_flag_gen_aux_info = 1;
2784       break;
2785
2786     case OPT_d:
2787       decode_d_option (arg, opts, loc, dc);
2788       break;
2789
2790     case OPT_fcall_used_:
2791     case OPT_fcall_saved_:
2792       /* Deferred.  */
2793       break;
2794
2795     case OPT_fdbg_cnt_:
2796       /* Deferred.  */
2797       break;
2798
2799     case OPT_fdebug_prefix_map_:
2800     case OPT_ffile_prefix_map_:
2801     case OPT_fprofile_prefix_map_:
2802       /* Deferred.  */
2803       break;
2804
2805     case OPT_fcallgraph_info:
2806       opts->x_flag_callgraph_info = CALLGRAPH_INFO_NAKED;
2807       break;
2808
2809     case OPT_fcallgraph_info_:
2810       {
2811         char *my_arg, *p;
2812         my_arg = xstrdup (arg);
2813         p = strtok (my_arg, ",");
2814         while (p)
2815           {
2816             if (strcmp (p, "su") == 0)
2817               {
2818                 opts->x_flag_callgraph_info |= CALLGRAPH_INFO_STACK_USAGE;
2819                 opts->x_flag_stack_usage_info = true;
2820               }
2821             else if (strcmp (p, "da") == 0)
2822               opts->x_flag_callgraph_info |= CALLGRAPH_INFO_DYNAMIC_ALLOC;
2823             else
2824               return 0;
2825             p = strtok (NULL, ",");
2826           }
2827         free (my_arg);
2828       }
2829       break;
2830
2831     case OPT_fdiagnostics_show_location_:
2832       diagnostic_prefixing_rule (dc) = (diagnostic_prefixing_rule_t) value;
2833       break;
2834  
2835     case OPT_fdiagnostics_show_caret:
2836       dc->show_caret = value;
2837       break;
2838
2839     case OPT_fdiagnostics_show_labels:
2840       dc->show_labels_p = value;
2841       break;
2842
2843     case OPT_fdiagnostics_show_line_numbers:
2844       dc->show_line_numbers_p = value;
2845       break;
2846
2847     case OPT_fdiagnostics_color_:
2848       diagnostic_color_init (dc, value);
2849       break;
2850
2851     case OPT_fdiagnostics_urls_:
2852       diagnostic_urls_init (dc, value);
2853       break;
2854
2855     case OPT_fdiagnostics_format_:
2856       diagnostic_output_format_init (dc, opts->x_dump_base_name,
2857                                      (enum diagnostics_output_format)value);
2858       break;
2859
2860     case OPT_fdiagnostics_parseable_fixits:
2861       dc->extra_output_kind = (value
2862                                ? EXTRA_DIAGNOSTIC_OUTPUT_fixits_v1
2863                                : EXTRA_DIAGNOSTIC_OUTPUT_none);
2864       break;
2865
2866     case OPT_fdiagnostics_column_unit_:
2867       dc->column_unit = (enum diagnostics_column_unit)value;
2868       break;
2869
2870     case OPT_fdiagnostics_column_origin_:
2871       dc->column_origin = value;
2872       break;
2873
2874     case OPT_fdiagnostics_escape_format_:
2875       dc->escape_format = (enum diagnostics_escape_format)value;
2876       break;
2877
2878     case OPT_fdiagnostics_show_cwe:
2879       dc->show_cwe = value;
2880       break;
2881
2882     case OPT_fdiagnostics_show_rules:
2883       dc->show_rules = value;
2884       break;
2885
2886     case OPT_fdiagnostics_path_format_:
2887       dc->path_format = (enum diagnostic_path_format)value;
2888       break;
2889
2890     case OPT_fdiagnostics_show_path_depths:
2891       dc->show_path_depths = value;
2892       break;
2893
2894     case OPT_fdiagnostics_show_option:
2895       dc->show_option_requested = value;
2896       break;
2897
2898     case OPT_fdiagnostics_minimum_margin_width_:
2899       dc->min_margin_width = value;
2900       break;
2901
2902     case OPT_fdump_:
2903       /* Deferred.  */
2904       break;
2905
2906     case OPT_ffast_math:
2907       set_fast_math_flags (opts, value);
2908       break;
2909
2910     case OPT_funsafe_math_optimizations:
2911       set_unsafe_math_optimizations_flags (opts, value);
2912       break;
2913
2914     case OPT_ffixed_:
2915       /* Deferred.  */
2916       break;
2917
2918     case OPT_finline_limit_:
2919       SET_OPTION_IF_UNSET (opts, opts_set, param_max_inline_insns_single,
2920                            value / 2);
2921       SET_OPTION_IF_UNSET (opts, opts_set, param_max_inline_insns_auto,
2922                            value / 2);
2923       break;
2924
2925     case OPT_finstrument_functions_exclude_function_list_:
2926       add_comma_separated_to_vector
2927         (&opts->x_flag_instrument_functions_exclude_functions, arg);
2928       break;
2929
2930     case OPT_finstrument_functions_exclude_file_list_:
2931       add_comma_separated_to_vector
2932         (&opts->x_flag_instrument_functions_exclude_files, arg);
2933       break;
2934
2935     case OPT_fmessage_length_:
2936       pp_set_line_maximum_length (dc->printer, value);
2937       diagnostic_set_caret_max_width (dc, value);
2938       break;
2939
2940     case OPT_fopt_info:
2941     case OPT_fopt_info_:
2942       /* Deferred.  */
2943       break;
2944
2945     case OPT_foffload_options_:
2946       /* Deferred.  */
2947       break;
2948
2949     case OPT_foffload_abi_:
2950 #ifdef ACCEL_COMPILER
2951       /* Handled in the 'mkoffload's.  */
2952 #else
2953       error_at (loc, "%<-foffload-abi%> option can be specified only for "
2954                 "offload compiler");
2955 #endif
2956       break;
2957
2958     case OPT_fpack_struct_:
2959       if (value <= 0 || (value & (value - 1)) || value > 16)
2960         error_at (loc,
2961                   "structure alignment must be a small power of two, not %wu",
2962                   value);
2963       else
2964         opts->x_initial_max_fld_align = value;
2965       break;
2966
2967     case OPT_fplugin_:
2968     case OPT_fplugin_arg_:
2969       /* Deferred.  */
2970       break;
2971
2972     case OPT_fprofile_use_:
2973       opts->x_profile_data_prefix = xstrdup (arg);
2974       opts->x_flag_profile_use = true;
2975       value = true;
2976       /* No break here - do -fprofile-use processing. */
2977       /* FALLTHRU */
2978     case OPT_fprofile_use:
2979       enable_fdo_optimizations (opts, opts_set, value);
2980       SET_OPTION_IF_UNSET (opts, opts_set, flag_profile_reorder_functions,
2981                            value);
2982         /* Indirect call profiling should do all useful transformations
2983            speculative devirtualization does.  */
2984       if (opts->x_flag_value_profile_transformations)
2985         SET_OPTION_IF_UNSET (opts, opts_set, flag_devirtualize_speculatively,
2986                              false);
2987       break;
2988
2989     case OPT_fauto_profile_:
2990       opts->x_auto_profile_file = xstrdup (arg);
2991       opts->x_flag_auto_profile = true;
2992       value = true;
2993       /* No break here - do -fauto-profile processing. */
2994       /* FALLTHRU */
2995     case OPT_fauto_profile:
2996       enable_fdo_optimizations (opts, opts_set, value);
2997       SET_OPTION_IF_UNSET (opts, opts_set, flag_profile_correction, value);
2998       break;
2999
3000     case OPT_fprofile_generate_:
3001       opts->x_profile_data_prefix = xstrdup (arg);
3002       value = true;
3003       /* No break here - do -fprofile-generate processing. */
3004       /* FALLTHRU */
3005     case OPT_fprofile_generate:
3006       SET_OPTION_IF_UNSET (opts, opts_set, profile_arc_flag, value);
3007       SET_OPTION_IF_UNSET (opts, opts_set, flag_profile_values, value);
3008       SET_OPTION_IF_UNSET (opts, opts_set, flag_inline_functions, value);
3009       SET_OPTION_IF_UNSET (opts, opts_set, flag_ipa_bit_cp, value);
3010       break;
3011
3012     case OPT_fprofile_info_section:
3013       opts->x_profile_info_section = ".gcov_info";
3014       break;
3015
3016     case OPT_fpatchable_function_entry_:
3017       {
3018         HOST_WIDE_INT patch_area_size, patch_area_start;
3019         parse_and_check_patch_area (arg, true, &patch_area_size,
3020                                     &patch_area_start);
3021       }
3022       break;
3023
3024     case OPT_ftree_vectorize:
3025       /* Automatically sets -ftree-loop-vectorize and
3026          -ftree-slp-vectorize.  Nothing more to do here.  */
3027       break;
3028     case OPT_fzero_call_used_regs_:
3029       opts->x_flag_zero_call_used_regs
3030         = parse_zero_call_used_regs_options (arg);
3031       break;
3032
3033     case OPT_fshow_column:
3034       dc->show_column = value;
3035       break;
3036
3037     case OPT_frandom_seed:
3038       /* The real switch is -fno-random-seed.  */
3039       if (value)
3040         return false;
3041       /* Deferred.  */
3042       break;
3043
3044     case OPT_frandom_seed_:
3045       /* Deferred.  */
3046       break;
3047
3048     case OPT_fsched_verbose_:
3049 #ifdef INSN_SCHEDULING
3050       /* Handled with Var in common.opt.  */
3051       break;
3052 #else
3053       return false;
3054 #endif
3055
3056     case OPT_fsched_stalled_insns_:
3057       opts->x_flag_sched_stalled_insns = value;
3058       if (opts->x_flag_sched_stalled_insns == 0)
3059         opts->x_flag_sched_stalled_insns = -1;
3060       break;
3061
3062     case OPT_fsched_stalled_insns_dep_:
3063       opts->x_flag_sched_stalled_insns_dep = value;
3064       break;
3065
3066     case OPT_fstack_check_:
3067       if (!strcmp (arg, "no"))
3068         opts->x_flag_stack_check = NO_STACK_CHECK;
3069       else if (!strcmp (arg, "generic"))
3070         /* This is the old stack checking method.  */
3071         opts->x_flag_stack_check = STACK_CHECK_BUILTIN
3072                            ? FULL_BUILTIN_STACK_CHECK
3073                            : GENERIC_STACK_CHECK;
3074       else if (!strcmp (arg, "specific"))
3075         /* This is the new stack checking method.  */
3076         opts->x_flag_stack_check = STACK_CHECK_BUILTIN
3077                            ? FULL_BUILTIN_STACK_CHECK
3078                            : STACK_CHECK_STATIC_BUILTIN
3079                              ? STATIC_BUILTIN_STACK_CHECK
3080                              : GENERIC_STACK_CHECK;
3081       else
3082         warning_at (loc, 0, "unknown stack check parameter %qs", arg);
3083       break;
3084
3085     case OPT_fstack_limit:
3086       /* The real switch is -fno-stack-limit.  */
3087       if (value)
3088         return false;
3089       /* Deferred.  */
3090       break;
3091
3092     case OPT_fstack_limit_register_:
3093     case OPT_fstack_limit_symbol_:
3094       /* Deferred.  */
3095       break;
3096
3097     case OPT_fstack_usage:
3098       opts->x_flag_stack_usage = value;
3099       opts->x_flag_stack_usage_info = value != 0;
3100       break;
3101
3102     case OPT_g:
3103       set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, arg, opts, opts_set,
3104                        loc);
3105       break;
3106
3107     case OPT_gbtf:
3108       set_debug_level (BTF_DEBUG, false, arg, opts, opts_set, loc);
3109       /* set the debug level to level 2, but if already at level 3,
3110          don't lower it.  */
3111       if (opts->x_debug_info_level < DINFO_LEVEL_NORMAL)
3112         opts->x_debug_info_level = DINFO_LEVEL_NORMAL;
3113       break;
3114
3115     case OPT_gctf:
3116       set_debug_level (CTF_DEBUG, false, arg, opts, opts_set, loc);
3117       /* CTF generation feeds off DWARF dies.  For optimal CTF, switch debug
3118          info level to 2.  If off or at level 1, set it to level 2, but if
3119          already at level 3, don't lower it.  */
3120       if (opts->x_debug_info_level < DINFO_LEVEL_NORMAL
3121           && opts->x_ctf_debug_info_level > CTFINFO_LEVEL_NONE)
3122         opts->x_debug_info_level = DINFO_LEVEL_NORMAL;
3123       break;
3124
3125     case OPT_gdwarf:
3126       if (arg && strlen (arg) != 0)
3127         {
3128           error_at (loc, "%<-gdwarf%s%> is ambiguous; "
3129                     "use %<-gdwarf-%s%> for DWARF version "
3130                     "or %<-gdwarf%> %<-g%s%> for debug level", arg, arg, arg);
3131           break;
3132         }
3133       else
3134         value = opts->x_dwarf_version;
3135       
3136       /* FALLTHRU */
3137     case OPT_gdwarf_:
3138       if (value < 2 || value > 5)
3139         error_at (loc, "dwarf version %wu is not supported", value);
3140       else
3141         opts->x_dwarf_version = value;
3142       set_debug_level (DWARF2_DEBUG, false, "", opts, opts_set, loc);
3143       break;
3144
3145     case OPT_ggdb:
3146       set_debug_level (NO_DEBUG, 2, arg, opts, opts_set, loc);
3147       break;
3148
3149     case OPT_gvms:
3150       set_debug_level (VMS_DEBUG, false, arg, opts, opts_set, loc);
3151       break;
3152
3153     case OPT_gz:
3154     case OPT_gz_:
3155       /* Handled completely via specs.  */
3156       break;
3157
3158     case OPT_pedantic_errors:
3159       dc->pedantic_errors = 1;
3160       control_warning_option (OPT_Wpedantic, DK_ERROR, NULL, value,
3161                               loc, lang_mask,
3162                               handlers, opts, opts_set,
3163                               dc);
3164       break;
3165
3166     case OPT_flto:
3167       opts->x_flag_lto = value ? "" : NULL;
3168       break;
3169
3170     case OPT_flto_:
3171       if (strcmp (arg, "none") != 0
3172           && strcmp (arg, "jobserver") != 0
3173           && strcmp (arg, "auto") != 0
3174           && atoi (arg) == 0)
3175         error_at (loc,
3176                   "unrecognized argument to %<-flto=%> option: %qs", arg);
3177       break;
3178
3179     case OPT_w:
3180       dc->dc_inhibit_warnings = true;
3181       break;
3182
3183     case OPT_fmax_errors_:
3184       dc->max_errors = value;
3185       break;
3186
3187     case OPT_fuse_ld_bfd:
3188     case OPT_fuse_ld_gold:
3189     case OPT_fuse_ld_lld:
3190     case OPT_fuse_ld_mold:
3191     case OPT_fuse_linker_plugin:
3192       /* No-op. Used by the driver and passed to us because it starts with f.*/
3193       break;
3194
3195     case OPT_fwrapv:
3196       if (value)
3197         opts->x_flag_trapv = 0;
3198       break;
3199
3200     case OPT_ftrapv:
3201       if (value)
3202         opts->x_flag_wrapv = 0;
3203       break;
3204
3205     case OPT_fstrict_overflow:
3206       opts->x_flag_wrapv = !value;
3207       opts->x_flag_wrapv_pointer = !value;
3208       if (!value)
3209         opts->x_flag_trapv = 0;
3210       break;
3211
3212     case OPT_fipa_icf:
3213       opts->x_flag_ipa_icf_functions = value;
3214       opts->x_flag_ipa_icf_variables = value;
3215       break;
3216
3217     case OPT_falign_loops_:
3218       check_alignment_argument (loc, arg, "loops",
3219                                 &opts->x_flag_align_loops,
3220                                 &opts->x_str_align_loops);
3221       break;
3222
3223     case OPT_falign_jumps_:
3224       check_alignment_argument (loc, arg, "jumps",
3225                                 &opts->x_flag_align_jumps,
3226                                 &opts->x_str_align_jumps);
3227       break;
3228
3229     case OPT_falign_labels_:
3230       check_alignment_argument (loc, arg, "labels",
3231                                 &opts->x_flag_align_labels,
3232                                 &opts->x_str_align_labels);
3233       break;
3234
3235     case OPT_falign_functions_:
3236       check_alignment_argument (loc, arg, "functions",
3237                                 &opts->x_flag_align_functions,
3238                                 &opts->x_str_align_functions);
3239       break;
3240
3241     case OPT_ftabstop_:
3242       /* It is documented that we silently ignore silly values.  */
3243       if (value >= 1 && value <= 100)
3244         dc->tabstop = value;
3245       break;
3246
3247     case OPT_freport_bug:
3248       dc->report_bug = value;
3249       break;
3250
3251     case OPT_fmultiflags:
3252       gcc_checking_assert (lang_mask == CL_DRIVER);
3253       break;
3254
3255     default:
3256       /* If the flag was handled in a standard way, assume the lack of
3257          processing here is intentional.  */
3258       gcc_assert (option_flag_var (scode, opts));
3259       break;
3260     }
3261
3262   common_handle_option_auto (opts, opts_set, decoded, lang_mask, kind,
3263                              loc, handlers, dc);
3264   return true;
3265 }
3266
3267 /* Used to set the level of strict aliasing warnings in OPTS,
3268    when no level is specified (i.e., when -Wstrict-aliasing, and not
3269    -Wstrict-aliasing=level was given).
3270    ONOFF is assumed to take value 1 when -Wstrict-aliasing is specified,
3271    and 0 otherwise.  After calling this function, wstrict_aliasing will be
3272    set to the default value of -Wstrict_aliasing=level, currently 3.  */
3273 static void
3274 set_Wstrict_aliasing (struct gcc_options *opts, int onoff)
3275 {
3276   gcc_assert (onoff == 0 || onoff == 1);
3277   if (onoff != 0)
3278     opts->x_warn_strict_aliasing = 3;
3279   else
3280     opts->x_warn_strict_aliasing = 0;
3281 }
3282
3283 /* The following routines are useful in setting all the flags that
3284    -ffast-math and -fno-fast-math imply.  */
3285 static void
3286 set_fast_math_flags (struct gcc_options *opts, int set)
3287 {
3288   if (!opts->frontend_set_flag_unsafe_math_optimizations)
3289     {
3290       opts->x_flag_unsafe_math_optimizations = set;
3291       set_unsafe_math_optimizations_flags (opts, set);
3292     }
3293   if (!opts->frontend_set_flag_finite_math_only)
3294     opts->x_flag_finite_math_only = set;
3295   if (!opts->frontend_set_flag_errno_math)
3296     opts->x_flag_errno_math = !set;
3297   if (set)
3298     {
3299       if (opts->frontend_set_flag_excess_precision == EXCESS_PRECISION_DEFAULT)
3300         opts->x_flag_excess_precision
3301           = set ? EXCESS_PRECISION_FAST : EXCESS_PRECISION_DEFAULT;
3302       if (!opts->frontend_set_flag_signaling_nans)
3303         opts->x_flag_signaling_nans = 0;
3304       if (!opts->frontend_set_flag_rounding_math)
3305         opts->x_flag_rounding_math = 0;
3306       if (!opts->frontend_set_flag_cx_limited_range)
3307         opts->x_flag_cx_limited_range = 1;
3308     }
3309 }
3310
3311 /* When -funsafe-math-optimizations is set the following
3312    flags are set as well.  */
3313 static void
3314 set_unsafe_math_optimizations_flags (struct gcc_options *opts, int set)
3315 {
3316   if (!opts->frontend_set_flag_trapping_math)
3317     opts->x_flag_trapping_math = !set;
3318   if (!opts->frontend_set_flag_signed_zeros)
3319     opts->x_flag_signed_zeros = !set;
3320   if (!opts->frontend_set_flag_associative_math)
3321     opts->x_flag_associative_math = set;
3322   if (!opts->frontend_set_flag_reciprocal_math)
3323     opts->x_flag_reciprocal_math = set;
3324 }
3325
3326 /* Return true iff flags in OPTS are set as if -ffast-math.  */
3327 bool
3328 fast_math_flags_set_p (const struct gcc_options *opts)
3329 {
3330   return (!opts->x_flag_trapping_math
3331           && opts->x_flag_unsafe_math_optimizations
3332           && opts->x_flag_finite_math_only
3333           && !opts->x_flag_signed_zeros
3334           && !opts->x_flag_errno_math
3335           && opts->x_flag_excess_precision == EXCESS_PRECISION_FAST);
3336 }
3337
3338 /* Return true iff flags are set as if -ffast-math but using the flags stored
3339    in the struct cl_optimization structure.  */
3340 bool
3341 fast_math_flags_struct_set_p (struct cl_optimization *opt)
3342 {
3343   return (!opt->x_flag_trapping_math
3344           && opt->x_flag_unsafe_math_optimizations
3345           && opt->x_flag_finite_math_only
3346           && !opt->x_flag_signed_zeros
3347           && !opt->x_flag_errno_math);
3348 }
3349
3350 /* Handle a debug output -g switch for options OPTS
3351    (OPTS_SET->x_write_symbols storing whether a debug format was passed
3352    explicitly), location LOC.  EXTENDED is true or false to support
3353    extended output (2 is special and means "-ggdb" was given).  */
3354 static void
3355 set_debug_level (uint32_t dinfo, int extended, const char *arg,
3356                  struct gcc_options *opts, struct gcc_options *opts_set,
3357                  location_t loc)
3358 {
3359   if (dinfo == NO_DEBUG)
3360     {
3361       if (opts->x_write_symbols == NO_DEBUG)
3362         {
3363           opts->x_write_symbols = PREFERRED_DEBUGGING_TYPE;
3364
3365           if (extended == 2)
3366             {
3367 #if defined DWARF2_DEBUGGING_INFO || defined DWARF2_LINENO_DEBUGGING_INFO
3368               if (opts->x_write_symbols & CTF_DEBUG)
3369                 opts->x_write_symbols |= DWARF2_DEBUG;
3370               else
3371                 opts->x_write_symbols = DWARF2_DEBUG;
3372 #endif
3373             }
3374
3375           if (opts->x_write_symbols == NO_DEBUG)
3376             warning_at (loc, 0, "target system does not support debug output");
3377         }
3378       else if ((opts->x_write_symbols & CTF_DEBUG)
3379                || (opts->x_write_symbols & BTF_DEBUG))
3380         {
3381           opts->x_write_symbols |= DWARF2_DEBUG;
3382           opts_set->x_write_symbols |= DWARF2_DEBUG;
3383         }
3384     }
3385   else
3386     {
3387       /* Make and retain the choice if both CTF and DWARF debug info are to
3388          be generated.  */
3389       if (((dinfo == DWARF2_DEBUG) || (dinfo == CTF_DEBUG))
3390           && ((opts->x_write_symbols == (DWARF2_DEBUG|CTF_DEBUG))
3391               || (opts->x_write_symbols == DWARF2_DEBUG)
3392               || (opts->x_write_symbols == CTF_DEBUG)))
3393         {
3394           opts->x_write_symbols |= dinfo;
3395           opts_set->x_write_symbols |= dinfo;
3396         }
3397       /* However, CTF and BTF are not allowed together at this time.  */
3398       else if (((dinfo == DWARF2_DEBUG) || (dinfo == BTF_DEBUG))
3399                && ((opts->x_write_symbols == (DWARF2_DEBUG|BTF_DEBUG))
3400                    || (opts->x_write_symbols == DWARF2_DEBUG)
3401                    || (opts->x_write_symbols == BTF_DEBUG)))
3402         {
3403           opts->x_write_symbols |= dinfo;
3404           opts_set->x_write_symbols |= dinfo;
3405         }
3406       else
3407         {
3408           /* Does it conflict with an already selected debug format?  */
3409           if (opts_set->x_write_symbols != NO_DEBUG
3410               && opts->x_write_symbols != NO_DEBUG
3411               && dinfo != opts->x_write_symbols)
3412             {
3413               gcc_assert (debug_set_count (dinfo) <= 1);
3414               error_at (loc, "debug format %qs conflicts with prior selection",
3415                         debug_type_names[debug_set_to_format (dinfo)]);
3416             }
3417           opts->x_write_symbols = dinfo;
3418           opts_set->x_write_symbols = dinfo;
3419         }
3420     }
3421
3422   if (dinfo != BTF_DEBUG)
3423     {
3424       /* A debug flag without a level defaults to level 2.
3425          If off or at level 1, set it to level 2, but if already
3426          at level 3, don't lower it.  */
3427       if (*arg == '\0')
3428         {
3429           if (dinfo == CTF_DEBUG)
3430             opts->x_ctf_debug_info_level = CTFINFO_LEVEL_NORMAL;
3431           else if (opts->x_debug_info_level < DINFO_LEVEL_NORMAL)
3432             opts->x_debug_info_level = DINFO_LEVEL_NORMAL;
3433         }
3434       else
3435         {
3436           int argval = integral_argument (arg);
3437           if (argval == -1)
3438             error_at (loc, "unrecognized debug output level %qs", arg);
3439           else if (argval > 3)
3440             error_at (loc, "debug output level %qs is too high", arg);
3441           else
3442             {
3443               if (dinfo == CTF_DEBUG)
3444                 opts->x_ctf_debug_info_level
3445                   = (enum ctf_debug_info_levels) argval;
3446               else
3447                 opts->x_debug_info_level = (enum debug_info_levels) argval;
3448             }
3449         }
3450     }
3451   else if (*arg != '\0')
3452     error_at (loc, "unrecognized btf debug output level %qs", arg);
3453 }
3454
3455 /* Arrange to dump core on error for diagnostic context DC.  (The
3456    regular error message is still printed first, except in the case of
3457    abort ().)  */
3458
3459 static void
3460 setup_core_dumping (diagnostic_context *dc)
3461 {
3462 #ifdef SIGABRT
3463   signal (SIGABRT, SIG_DFL);
3464 #endif
3465 #if defined(HAVE_SETRLIMIT)
3466   {
3467     struct rlimit rlim;
3468     if (getrlimit (RLIMIT_CORE, &rlim) != 0)
3469       fatal_error (input_location, "getting core file size maximum limit: %m");
3470     rlim.rlim_cur = rlim.rlim_max;
3471     if (setrlimit (RLIMIT_CORE, &rlim) != 0)
3472       fatal_error (input_location,
3473                    "setting core file size limit to maximum: %m");
3474   }
3475 #endif
3476   diagnostic_abort_on_error (dc);
3477 }
3478
3479 /* Parse a -d<ARG> command line switch for OPTS, location LOC,
3480    diagnostic context DC.  */
3481
3482 static void
3483 decode_d_option (const char *arg, struct gcc_options *opts,
3484                  location_t loc, diagnostic_context *dc)
3485 {
3486   int c;
3487
3488   while (*arg)
3489     switch (c = *arg++)
3490       {
3491       case 'A':
3492         opts->x_flag_debug_asm = 1;
3493         break;
3494       case 'p':
3495         opts->x_flag_print_asm_name = 1;
3496         break;
3497       case 'P':
3498         opts->x_flag_dump_rtl_in_asm = 1;
3499         opts->x_flag_print_asm_name = 1;
3500         break;
3501       case 'x':
3502         opts->x_rtl_dump_and_exit = 1;
3503         break;
3504       case 'D': /* These are handled by the preprocessor.  */
3505       case 'I':
3506       case 'M':
3507       case 'N':
3508       case 'U':
3509         break;
3510       case 'H':
3511         setup_core_dumping (dc);
3512         break;
3513       case 'a':
3514         opts->x_flag_dump_all_passed = true;
3515         break;
3516
3517       default:
3518           warning_at (loc, 0, "unrecognized gcc debugging option: %c", c);
3519         break;
3520       }
3521 }
3522
3523 /* Enable (or disable if VALUE is 0) a warning option ARG (language
3524    mask LANG_MASK, option handlers HANDLERS) as an error for option
3525    structures OPTS and OPTS_SET, diagnostic context DC (possibly
3526    NULL), location LOC.  This is used by -Werror=.  */
3527
3528 static void
3529 enable_warning_as_error (const char *arg, int value, unsigned int lang_mask,
3530                          const struct cl_option_handlers *handlers,
3531                          struct gcc_options *opts,
3532                          struct gcc_options *opts_set,
3533                          location_t loc, diagnostic_context *dc)
3534 {
3535   char *new_option;
3536   int option_index;
3537
3538   new_option = XNEWVEC (char, strlen (arg) + 2);
3539   new_option[0] = 'W';
3540   strcpy (new_option + 1, arg);
3541   option_index = find_opt (new_option, lang_mask);
3542   if (option_index == OPT_SPECIAL_unknown)
3543     {
3544       option_proposer op;
3545       const char *hint = op.suggest_option (new_option);
3546       if (hint)
3547         error_at (loc, "%<-W%serror=%s%>: no option %<-%s%>;"
3548                   " did you mean %<-%s%>?", value ? "" : "no-",
3549                   arg, new_option, hint);
3550       else
3551         error_at (loc, "%<-W%serror=%s%>: no option %<-%s%>",
3552                   value ? "" : "no-", arg, new_option);
3553     }
3554   else if (!(cl_options[option_index].flags & CL_WARNING))
3555     error_at (loc, "%<-Werror=%s%>: %<-%s%> is not an option that "
3556               "controls warnings", arg, new_option);
3557   else
3558     {
3559       const diagnostic_t kind = value ? DK_ERROR : DK_WARNING;
3560       const char *arg = NULL;
3561
3562       if (cl_options[option_index].flags & CL_JOINED)
3563         arg = new_option + cl_options[option_index].opt_len;
3564       control_warning_option (option_index, (int) kind, arg, value,
3565                               loc, lang_mask,
3566                               handlers, opts, opts_set, dc);
3567     }
3568   free (new_option);
3569 }
3570
3571 /* Return malloced memory for the name of the option OPTION_INDEX
3572    which enabled a diagnostic (context CONTEXT), originally of type
3573    ORIG_DIAG_KIND but possibly converted to DIAG_KIND by options such
3574    as -Werror.  */
3575
3576 char *
3577 option_name (diagnostic_context *context, int option_index,
3578              diagnostic_t orig_diag_kind, diagnostic_t diag_kind)
3579 {
3580   if (option_index)
3581     {
3582       /* A warning classified as an error.  */
3583       if ((orig_diag_kind == DK_WARNING || orig_diag_kind == DK_PEDWARN)
3584           && diag_kind == DK_ERROR)
3585         return concat (cl_options[OPT_Werror_].opt_text,
3586                        /* Skip over "-W".  */
3587                        cl_options[option_index].opt_text + 2,
3588                        NULL);
3589       /* A warning with option.  */
3590       else
3591         return xstrdup (cl_options[option_index].opt_text);
3592     }
3593   /* A warning without option classified as an error.  */
3594   else if ((orig_diag_kind == DK_WARNING || orig_diag_kind == DK_PEDWARN
3595             || diag_kind == DK_WARNING)
3596            && context->warning_as_error_requested)
3597     return xstrdup (cl_options[OPT_Werror].opt_text);
3598   else
3599     return NULL;
3600 }
3601
3602 /* Get the page within the documentation for this option.  */
3603
3604 static const char *
3605 get_option_html_page (int option_index)
3606 {
3607   const cl_option *cl_opt = &cl_options[option_index];
3608
3609   /* Analyzer options are on their own page.  */
3610   if (strstr (cl_opt->opt_text, "analyzer-"))
3611     return "gcc/Static-Analyzer-Options.html";
3612
3613   /* Handle -flto= option.  */
3614   if (strstr (cl_opt->opt_text, "flto"))
3615     return "gcc/Optimize-Options.html";
3616
3617 #ifdef CL_Fortran
3618   if ((cl_opt->flags & CL_Fortran) != 0
3619       /* If it is option common to both C/C++ and Fortran, it is documented
3620          in gcc/ rather than gfortran/ docs.  */
3621       && (cl_opt->flags & CL_C) == 0
3622 #ifdef CL_CXX
3623       && (cl_opt->flags & CL_CXX) == 0
3624 #endif
3625      )
3626     return "gfortran/Error-and-Warning-Options.html";
3627 #endif
3628
3629   return "gcc/Warning-Options.html";
3630 }
3631
3632 /* Return malloced memory for a URL describing the option OPTION_INDEX
3633    which enabled a diagnostic (context CONTEXT).  */
3634
3635 char *
3636 get_option_url (diagnostic_context *, int option_index)
3637 {
3638   if (option_index)
3639     return concat (/* DOCUMENTATION_ROOT_URL should be supplied via -D by
3640                       the Makefile (see --with-documentation-root-url), and
3641                       should have a trailing slash.  */
3642                    DOCUMENTATION_ROOT_URL,
3643
3644                    /* get_option_html_page will return something like
3645                       "gcc/Warning-Options.html".  */
3646                    get_option_html_page (option_index),
3647
3648                    /* Expect an anchor of the form "index-Wfoo" e.g.
3649                       <a name="index-Wformat"></a>, and thus an id within
3650                       the URL of "#index-Wformat".  */
3651                    "#index", cl_options[option_index].opt_text,
3652                    NULL);
3653   else
3654     return NULL;
3655 }
3656
3657 /* Return a heap allocated producer with command line options.  */
3658
3659 char *
3660 gen_command_line_string (cl_decoded_option *options,
3661                          unsigned int options_count)
3662 {
3663   auto_vec<const char *> switches;
3664   char *options_string, *tail;
3665   const char *p;
3666   size_t len = 0;
3667
3668   for (unsigned i = 0; i < options_count; i++)
3669     switch (options[i].opt_index)
3670       {
3671       case OPT_o:
3672       case OPT_d:
3673       case OPT_dumpbase:
3674       case OPT_dumpbase_ext:
3675       case OPT_dumpdir:
3676       case OPT_quiet:
3677       case OPT_version:
3678       case OPT_v:
3679       case OPT_w:
3680       case OPT_L:
3681       case OPT_D:
3682       case OPT_I:
3683       case OPT_U:
3684       case OPT_SPECIAL_unknown:
3685       case OPT_SPECIAL_ignore:
3686       case OPT_SPECIAL_warn_removed:
3687       case OPT_SPECIAL_program_name:
3688       case OPT_SPECIAL_input_file:
3689       case OPT_grecord_gcc_switches:
3690       case OPT_frecord_gcc_switches:
3691       case OPT__output_pch:
3692       case OPT_fdiagnostics_show_location_:
3693       case OPT_fdiagnostics_show_option:
3694       case OPT_fdiagnostics_show_caret:
3695       case OPT_fdiagnostics_show_labels:
3696       case OPT_fdiagnostics_show_line_numbers:
3697       case OPT_fdiagnostics_color_:
3698       case OPT_fdiagnostics_format_:
3699       case OPT_fverbose_asm:
3700       case OPT____:
3701       case OPT__sysroot_:
3702       case OPT_nostdinc:
3703       case OPT_nostdinc__:
3704       case OPT_fpreprocessed:
3705       case OPT_fltrans_output_list_:
3706       case OPT_fresolution_:
3707       case OPT_fdebug_prefix_map_:
3708       case OPT_fmacro_prefix_map_:
3709       case OPT_ffile_prefix_map_:
3710       case OPT_fprofile_prefix_map_:
3711       case OPT_fcompare_debug:
3712       case OPT_fchecking:
3713       case OPT_fchecking_:
3714         /* Ignore these.  */
3715         continue;
3716       case OPT_flto_:
3717         {
3718           const char *lto_canonical = "-flto";
3719           switches.safe_push (lto_canonical);
3720           len += strlen (lto_canonical) + 1;
3721           break;
3722         }
3723       default:
3724         if (cl_options[options[i].opt_index].flags
3725             & CL_NO_DWARF_RECORD)
3726           continue;
3727         gcc_checking_assert (options[i].canonical_option[0][0] == '-');
3728         switch (options[i].canonical_option[0][1])
3729           {
3730           case 'M':
3731           case 'i':
3732           case 'W':
3733             continue;
3734           case 'f':
3735             if (strncmp (options[i].canonical_option[0] + 2,
3736                          "dump", 4) == 0)
3737               continue;
3738             break;
3739           default:
3740             break;
3741           }
3742         switches.safe_push (options[i].orig_option_with_args_text);
3743         len += strlen (options[i].orig_option_with_args_text) + 1;
3744         break;
3745       }
3746
3747   options_string = XNEWVEC (char, len + 1);
3748   tail = options_string;
3749
3750   unsigned i;
3751   FOR_EACH_VEC_ELT (switches, i, p)
3752     {
3753       len = strlen (p);
3754       memcpy (tail, p, len);
3755       tail += len;
3756       if (i != switches.length () - 1)
3757         {
3758           *tail = ' ';
3759           ++tail;
3760         }
3761     }
3762
3763   *tail = '\0';
3764   return options_string;
3765 }
3766
3767 /* Return a heap allocated producer string including command line options.  */
3768
3769 char *
3770 gen_producer_string (const char *language_string, cl_decoded_option *options,
3771                      unsigned int options_count)
3772 {
3773   char *cmdline = gen_command_line_string (options, options_count);
3774   char *combined = concat (language_string, " ", version_string, " ",
3775                            cmdline, NULL);
3776   free (cmdline);
3777   return combined;
3778 }
3779
3780 #if CHECKING_P
3781
3782 namespace selftest {
3783
3784 /* Verify that get_option_html_page works as expected.  */
3785
3786 static void
3787 test_get_option_html_page ()
3788 {
3789   ASSERT_STREQ (get_option_html_page (OPT_Wcpp), "gcc/Warning-Options.html");
3790   ASSERT_STREQ (get_option_html_page (OPT_Wanalyzer_double_free),
3791              "gcc/Static-Analyzer-Options.html");
3792 #ifdef CL_Fortran
3793   ASSERT_STREQ (get_option_html_page (OPT_Wline_truncation),
3794                 "gfortran/Error-and-Warning-Options.html");
3795 #endif
3796 }
3797
3798 /* Verify EnumSet and EnumBitSet requirements.  */
3799
3800 static void
3801 test_enum_sets ()
3802 {
3803   for (unsigned i = 0; i < cl_options_count; ++i)
3804     if (cl_options[i].var_type == CLVC_ENUM
3805         && cl_options[i].var_value != CLEV_NORMAL)
3806       {
3807         const struct cl_enum *e = &cl_enums[cl_options[i].var_enum];
3808         unsigned HOST_WIDE_INT used_sets = 0;
3809         unsigned HOST_WIDE_INT mask = 0;
3810         unsigned highest_set = 0;
3811         for (unsigned j = 0; e->values[j].arg; ++j)
3812           {
3813             unsigned set = e->values[j].flags >> CL_ENUM_SET_SHIFT;
3814             if (cl_options[i].var_value == CLEV_BITSET)
3815               {
3816                 /* For EnumBitSet Set shouldn't be used and Value should
3817                    be a power of two.  */
3818                 ASSERT_TRUE (set == 0);
3819                 ASSERT_TRUE (pow2p_hwi (e->values[j].value));
3820                 continue;
3821               }
3822             /* Test that enumerators referenced in EnumSet have all
3823                Set(n) on them within the valid range.  */
3824             ASSERT_TRUE (set >= 1 && set <= HOST_BITS_PER_WIDE_INT);
3825             highest_set = MAX (set, highest_set);
3826             used_sets |= HOST_WIDE_INT_1U << (set - 1);
3827           }
3828         if (cl_options[i].var_value == CLEV_BITSET)
3829           continue;
3830         /* If there is just one set, no point to using EnumSet.  */
3831         ASSERT_TRUE (highest_set >= 2);
3832         /* Test that there are no gaps in between the sets.  */
3833         if (highest_set == HOST_BITS_PER_WIDE_INT)
3834           ASSERT_TRUE (used_sets == HOST_WIDE_INT_M1U);
3835         else
3836           ASSERT_TRUE (used_sets == (HOST_WIDE_INT_1U << highest_set) - 1);
3837         for (unsigned int j = 1; j <= highest_set; ++j)
3838           {
3839             unsigned HOST_WIDE_INT this_mask = 0;
3840             for (unsigned k = 0; e->values[k].arg; ++k)
3841               {
3842                 unsigned set = e->values[j].flags >> CL_ENUM_SET_SHIFT;
3843                 if (set == j)
3844                   this_mask |= e->values[j].value;
3845               }
3846             ASSERT_TRUE ((mask & this_mask) == 0);
3847             mask |= this_mask;
3848           }
3849       }
3850 }
3851
3852 /* Run all of the selftests within this file.  */
3853
3854 void
3855 opts_cc_tests ()
3856 {
3857   test_get_option_html_page ();
3858   test_enum_sets ();
3859 }
3860
3861 } // namespace selftest
3862
3863 #endif /* #if CHECKING_P */