xref: /dragonfly/contrib/gcc-8.0/gcc/opts.c (revision 95059079af47f9a66a175f374f2da1a5020e3255)
1 /* Command line option handling.
2    Copyright (C) 2002-2018 Free Software Foundation, Inc.
3    Contributed by Neil Booth.
4 
5 This file is part of GCC.
6 
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
11 
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.  */
20 
21 #include "config.h"
22 #include "system.h"
23 #include "intl.h"
24 #include "coretypes.h"
25 #include "opts.h"
26 #include "tm.h"
27 #include "flags.h"
28 #include "params.h"
29 #include "diagnostic.h"
30 #include "opts-diagnostic.h"
31 #include "insn-attr-common.h"
32 #include "common/common-target.h"
33 #include "spellcheck.h"
34 
35 static void set_Wstrict_aliasing (struct gcc_options *opts, int onoff);
36 
37 /* Indexed by enum debug_info_type.  */
38 const char *const debug_type_names[] =
39 {
40   "none", "stabs", "dwarf-2", "xcoff", "vms"
41 };
42 
43 /* Parse the -femit-struct-debug-detailed option value
44    and set the flag variables. */
45 
46 #define MATCH( prefix, string ) \
47   ((strncmp (prefix, string, sizeof prefix - 1) == 0) \
48    ? ((string += sizeof prefix - 1), 1) : 0)
49 
50 void
set_struct_debug_option(struct gcc_options * opts,location_t loc,const char * spec)51 set_struct_debug_option (struct gcc_options *opts, location_t loc,
52                                const char *spec)
53 {
54   /* various labels for comparison */
55   static const char dfn_lbl[] = "dfn:", dir_lbl[] = "dir:", ind_lbl[] = "ind:";
56   static const char ord_lbl[] = "ord:", gen_lbl[] = "gen:";
57   static const char none_lbl[] = "none", any_lbl[] = "any";
58   static const char base_lbl[] = "base", sys_lbl[] = "sys";
59 
60   enum debug_struct_file files = DINFO_STRUCT_FILE_ANY;
61   /* Default is to apply to as much as possible. */
62   enum debug_info_usage usage = DINFO_USAGE_NUM_ENUMS;
63   int ord = 1, gen = 1;
64 
65   /* What usage? */
66   if (MATCH (dfn_lbl, spec))
67     usage = DINFO_USAGE_DFN;
68   else if (MATCH (dir_lbl, spec))
69     usage = DINFO_USAGE_DIR_USE;
70   else if (MATCH (ind_lbl, spec))
71     usage = DINFO_USAGE_IND_USE;
72 
73   /* Generics or not? */
74   if (MATCH (ord_lbl, spec))
75     gen = 0;
76   else if (MATCH (gen_lbl, spec))
77     ord = 0;
78 
79   /* What allowable environment? */
80   if (MATCH (none_lbl, spec))
81     files = DINFO_STRUCT_FILE_NONE;
82   else if (MATCH (any_lbl, spec))
83     files = DINFO_STRUCT_FILE_ANY;
84   else if (MATCH (sys_lbl, spec))
85     files = DINFO_STRUCT_FILE_SYS;
86   else if (MATCH (base_lbl, spec))
87     files = DINFO_STRUCT_FILE_BASE;
88   else
89     error_at (loc,
90                 "argument %qs to %<-femit-struct-debug-detailed%> "
91                 "not recognized",
92                 spec);
93 
94   /* Effect the specification. */
95   if (usage == DINFO_USAGE_NUM_ENUMS)
96     {
97       if (ord)
98         {
99           opts->x_debug_struct_ordinary[DINFO_USAGE_DFN] = files;
100           opts->x_debug_struct_ordinary[DINFO_USAGE_DIR_USE] = files;
101           opts->x_debug_struct_ordinary[DINFO_USAGE_IND_USE] = files;
102         }
103       if (gen)
104         {
105           opts->x_debug_struct_generic[DINFO_USAGE_DFN] = files;
106           opts->x_debug_struct_generic[DINFO_USAGE_DIR_USE] = files;
107           opts->x_debug_struct_generic[DINFO_USAGE_IND_USE] = files;
108         }
109     }
110   else
111     {
112       if (ord)
113         opts->x_debug_struct_ordinary[usage] = files;
114       if (gen)
115         opts->x_debug_struct_generic[usage] = files;
116     }
117 
118   if (*spec == ',')
119     set_struct_debug_option (opts, loc, spec+1);
120   else
121     {
122       /* No more -femit-struct-debug-detailed specifications.
123          Do final checks. */
124       if (*spec != '\0')
125           error_at (loc,
126                       "argument %qs to %<-femit-struct-debug-detailed%> unknown",
127                       spec);
128       if (opts->x_debug_struct_ordinary[DINFO_USAGE_DIR_USE]
129                     < opts->x_debug_struct_ordinary[DINFO_USAGE_IND_USE]
130             || opts->x_debug_struct_generic[DINFO_USAGE_DIR_USE]
131                     < opts->x_debug_struct_generic[DINFO_USAGE_IND_USE])
132           error_at (loc,
133                       "%<-femit-struct-debug-detailed=dir:...%> must allow "
134                       "at least as much as "
135                       "%<-femit-struct-debug-detailed=ind:...%>");
136     }
137 }
138 
139 /* Strip off a legitimate source ending from the input string NAME of
140    length LEN.  Rather than having to know the names used by all of
141    our front ends, we strip off an ending of a period followed by
142    up to fource characters.  (C++ uses ".cpp".)  */
143 
144 void
strip_off_ending(char * name,int len)145 strip_off_ending (char *name, int len)
146 {
147   int i;
148   for (i = 2; i < 5 && len > i; i++)
149     {
150       if (name[len - i] == '.')
151           {
152             name[len - i] = '\0';
153             break;
154           }
155     }
156 }
157 
158 /* Find the base name of a path, stripping off both directories and
159    a single final extension. */
160 int
base_of_path(const char * path,const char ** base_out)161 base_of_path (const char *path, const char **base_out)
162 {
163   const char *base = path;
164   const char *dot = 0;
165   const char *p = path;
166   char c = *p;
167   while (c)
168     {
169       if (IS_DIR_SEPARATOR (c))
170         {
171           base = p + 1;
172           dot = 0;
173         }
174       else if (c == '.')
175         dot = p;
176       c = *++p;
177     }
178   if (!dot)
179     dot = p;
180   *base_out = base;
181   return dot - base;
182 }
183 
184 /* What to print when a switch has no documentation.  */
185 static const char undocumented_msg[] = N_("This option lacks documentation.");
186 static const char use_diagnosed_msg[] = N_("Uses of this option are diagnosed.");
187 
188 typedef char *char_p; /* For DEF_VEC_P.  */
189 
190 static void handle_param (struct gcc_options *opts,
191                                 struct gcc_options *opts_set, location_t loc,
192                                 const char *carg);
193 static void set_debug_level (enum debug_info_type type, int extended,
194                                    const char *arg, struct gcc_options *opts,
195                                    struct gcc_options *opts_set,
196                                    location_t loc);
197 static void set_fast_math_flags (struct gcc_options *opts, int set);
198 static void decode_d_option (const char *arg, struct gcc_options *opts,
199                                    location_t loc, diagnostic_context *dc);
200 static void set_unsafe_math_optimizations_flags (struct gcc_options *opts,
201                                                              int set);
202 static void enable_warning_as_error (const char *arg, int value,
203                                              unsigned int lang_mask,
204                                              const struct cl_option_handlers *handlers,
205                                              struct gcc_options *opts,
206                                              struct gcc_options *opts_set,
207                                              location_t loc,
208                                              diagnostic_context *dc);
209 
210 /* Handle a back-end option; arguments and return value as for
211    handle_option.  */
212 
213 bool
target_handle_option(struct gcc_options * opts,struct gcc_options * opts_set,const struct cl_decoded_option * decoded,unsigned int lang_mask ATTRIBUTE_UNUSED,int kind,location_t loc,const struct cl_option_handlers * handlers ATTRIBUTE_UNUSED,diagnostic_context * dc,void (*)(void))214 target_handle_option (struct gcc_options *opts,
215                           struct gcc_options *opts_set,
216                           const struct cl_decoded_option *decoded,
217                           unsigned int lang_mask ATTRIBUTE_UNUSED, int kind,
218                           location_t loc,
219                           const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED,
220                           diagnostic_context *dc, void (*) (void))
221 {
222   gcc_assert (dc == global_dc);
223   gcc_assert (kind == DK_UNSPECIFIED);
224   return targetm_common.handle_option (opts, opts_set, decoded, loc);
225 }
226 
227 /* Add comma-separated strings to a char_p vector.  */
228 
229 static void
add_comma_separated_to_vector(void ** pvec,const char * arg)230 add_comma_separated_to_vector (void **pvec, const char *arg)
231 {
232   char *tmp;
233   char *r;
234   char *w;
235   char *token_start;
236   vec<char_p> *v = (vec<char_p> *) *pvec;
237 
238   vec_check_alloc (v, 1);
239 
240   /* We never free this string.  */
241   tmp = xstrdup (arg);
242 
243   r = tmp;
244   w = tmp;
245   token_start = tmp;
246 
247   while (*r != '\0')
248     {
249       if (*r == ',')
250           {
251             *w++ = '\0';
252             ++r;
253             v->safe_push (token_start);
254             token_start = w;
255           }
256       if (*r == '\\' && r[1] == ',')
257           {
258             *w++ = ',';
259             r += 2;
260           }
261       else
262           *w++ = *r++;
263     }
264   if (*token_start != '\0')
265     v->safe_push (token_start);
266 
267   *pvec = v;
268 }
269 
270 /* Initialize opts_obstack.  */
271 
272 void
init_opts_obstack(void)273 init_opts_obstack (void)
274 {
275   gcc_obstack_init (&opts_obstack);
276 }
277 
278 /* Initialize OPTS and OPTS_SET before using them in parsing options.  */
279 
280 void
init_options_struct(struct gcc_options * opts,struct gcc_options * opts_set)281 init_options_struct (struct gcc_options *opts, struct gcc_options *opts_set)
282 {
283   size_t num_params = get_num_compiler_params ();
284 
285   /* Ensure that opts_obstack has already been initialized by the time
286      that we initialize any gcc_options instances (PR jit/68446).  */
287   gcc_assert (opts_obstack.chunk_size > 0);
288 
289   *opts = global_options_init;
290 
291   if (opts_set)
292     memset (opts_set, 0, sizeof (*opts_set));
293 
294   opts->x_param_values = XNEWVEC (int, num_params);
295 
296   if (opts_set)
297     opts_set->x_param_values = XCNEWVEC (int, num_params);
298 
299   init_param_values (opts->x_param_values);
300 
301   /* Initialize whether `char' is signed.  */
302   opts->x_flag_signed_char = DEFAULT_SIGNED_CHAR;
303   /* Set this to a special "uninitialized" value.  The actual default
304      is set after target options have been processed.  */
305   opts->x_flag_short_enums = 2;
306 
307   /* Initialize target_flags before default_options_optimization
308      so the latter can modify it.  */
309   opts->x_target_flags = targetm_common.default_target_flags;
310 
311   /* Some targets have ABI-specified unwind tables.  */
312   opts->x_flag_unwind_tables = targetm_common.unwind_tables_default;
313 
314   /* Some targets have other target-specific initialization.  */
315   targetm_common.option_init_struct (opts);
316 }
317 
318 /* Release any allocations owned by OPTS.  */
319 
320 void
finalize_options_struct(struct gcc_options * opts)321 finalize_options_struct (struct gcc_options *opts)
322 {
323   XDELETEVEC (opts->x_param_values);
324 }
325 
326 /* If indicated by the optimization level LEVEL (-Os if SIZE is set,
327    -Ofast if FAST is set, -Og if DEBUG is set), apply the option DEFAULT_OPT
328    to OPTS and OPTS_SET, diagnostic context DC, location LOC, with language
329    mask LANG_MASK and option handlers HANDLERS.  */
330 
331 static void
maybe_default_option(struct gcc_options * opts,struct gcc_options * opts_set,const struct default_options * default_opt,int level,bool size,bool fast,bool debug,unsigned int lang_mask,const struct cl_option_handlers * handlers,location_t loc,diagnostic_context * dc)332 maybe_default_option (struct gcc_options *opts,
333                           struct gcc_options *opts_set,
334                           const struct default_options *default_opt,
335                           int level, bool size, bool fast, bool debug,
336                           unsigned int lang_mask,
337                           const struct cl_option_handlers *handlers,
338                           location_t loc,
339                           diagnostic_context *dc)
340 {
341   const struct cl_option *option = &cl_options[default_opt->opt_index];
342   bool enabled;
343 
344   if (size)
345     gcc_assert (level == 2);
346   if (fast)
347     gcc_assert (level == 3);
348   if (debug)
349     gcc_assert (level == 1);
350 
351   switch (default_opt->levels)
352     {
353     case OPT_LEVELS_ALL:
354       enabled = true;
355       break;
356 
357     case OPT_LEVELS_0_ONLY:
358       enabled = (level == 0);
359       break;
360 
361     case OPT_LEVELS_1_PLUS:
362       enabled = (level >= 1);
363       break;
364 
365     case OPT_LEVELS_1_PLUS_SPEED_ONLY:
366       enabled = (level >= 1 && !size && !debug);
367       break;
368 
369     case OPT_LEVELS_1_PLUS_NOT_DEBUG:
370       enabled = (level >= 1 && !debug);
371       break;
372 
373     case OPT_LEVELS_2_PLUS:
374       enabled = (level >= 2);
375       break;
376 
377     case OPT_LEVELS_2_PLUS_SPEED_ONLY:
378       enabled = (level >= 2 && !size && !debug);
379       break;
380 
381     case OPT_LEVELS_3_PLUS:
382       enabled = (level >= 3);
383       break;
384 
385     case OPT_LEVELS_3_PLUS_AND_SIZE:
386       enabled = (level >= 3 || size);
387       break;
388 
389     case OPT_LEVELS_SIZE:
390       enabled = size;
391       break;
392 
393     case OPT_LEVELS_FAST:
394       enabled = fast;
395       break;
396 
397     case OPT_LEVELS_NONE:
398     default:
399       gcc_unreachable ();
400     }
401 
402   if (enabled)
403     handle_generated_option (opts, opts_set, default_opt->opt_index,
404                                    default_opt->arg, default_opt->value,
405                                    lang_mask, DK_UNSPECIFIED, loc,
406                                    handlers, true, dc);
407   else if (default_opt->arg == NULL
408              && !option->cl_reject_negative)
409     handle_generated_option (opts, opts_set, default_opt->opt_index,
410                                    default_opt->arg, !default_opt->value,
411                                    lang_mask, DK_UNSPECIFIED, loc,
412                                    handlers, true, dc);
413 }
414 
415 /* As indicated by the optimization level LEVEL (-Os if SIZE is set,
416    -Ofast if FAST is set), apply the options in array DEFAULT_OPTS to
417    OPTS and OPTS_SET, diagnostic context DC, location LOC, with
418    language mask LANG_MASK and option handlers HANDLERS.  */
419 
420 static void
maybe_default_options(struct gcc_options * opts,struct gcc_options * opts_set,const struct default_options * default_opts,int level,bool size,bool fast,bool debug,unsigned int lang_mask,const struct cl_option_handlers * handlers,location_t loc,diagnostic_context * dc)421 maybe_default_options (struct gcc_options *opts,
422                            struct gcc_options *opts_set,
423                            const struct default_options *default_opts,
424                            int level, bool size, bool fast, bool debug,
425                            unsigned int lang_mask,
426                            const struct cl_option_handlers *handlers,
427                            location_t loc,
428                            diagnostic_context *dc)
429 {
430   size_t i;
431 
432   for (i = 0; default_opts[i].levels != OPT_LEVELS_NONE; i++)
433     maybe_default_option (opts, opts_set, &default_opts[i],
434                                 level, size, fast, debug,
435                                 lang_mask, handlers, loc, dc);
436 }
437 
438 /* Table of options enabled by default at different levels.  */
439 
440 static const struct default_options default_options_table[] =
441   {
442     /* -O1 optimizations.  */
443     { OPT_LEVELS_1_PLUS, OPT_fdefer_pop, NULL, 1 },
444 #if DELAY_SLOTS
445     { OPT_LEVELS_1_PLUS, OPT_fdelayed_branch, NULL, 1 },
446 #endif
447     { OPT_LEVELS_1_PLUS, OPT_fguess_branch_probability, NULL, 1 },
448     { OPT_LEVELS_1_PLUS, OPT_fcprop_registers, NULL, 1 },
449     { OPT_LEVELS_1_PLUS, OPT_fforward_propagate, NULL, 1 },
450     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fif_conversion, NULL, 1 },
451     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fif_conversion2, NULL, 1 },
452     { OPT_LEVELS_1_PLUS, OPT_fipa_pure_const, NULL, 1 },
453     { OPT_LEVELS_1_PLUS, OPT_fipa_reference, NULL, 1 },
454     { OPT_LEVELS_1_PLUS, OPT_fipa_profile, NULL, 1 },
455     { OPT_LEVELS_1_PLUS, OPT_fmerge_constants, NULL, 1 },
456     { OPT_LEVELS_1_PLUS, OPT_freorder_blocks, NULL, 1 },
457     { OPT_LEVELS_1_PLUS, OPT_fshrink_wrap, NULL, 1 },
458     { OPT_LEVELS_1_PLUS, OPT_fsplit_wide_types, NULL, 1 },
459     { OPT_LEVELS_1_PLUS, OPT_ftree_ccp, NULL, 1 },
460     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_bit_ccp, NULL, 1 },
461     { OPT_LEVELS_1_PLUS, OPT_ftree_coalesce_vars, NULL, 1 },
462     { OPT_LEVELS_1_PLUS, OPT_ftree_dce, NULL, 1 },
463     { OPT_LEVELS_1_PLUS, OPT_ftree_dominator_opts, NULL, 1 },
464     { OPT_LEVELS_1_PLUS, OPT_ftree_dse, NULL, 1 },
465     { OPT_LEVELS_1_PLUS, OPT_ftree_ter, NULL, 1 },
466     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_sra, NULL, 1 },
467     { OPT_LEVELS_1_PLUS, OPT_ftree_fre, NULL, 1 },
468     { OPT_LEVELS_1_PLUS, OPT_ftree_copy_prop, NULL, 1 },
469     { OPT_LEVELS_1_PLUS, OPT_ftree_sink, NULL, 1 },
470     { OPT_LEVELS_1_PLUS, OPT_ftree_ch, NULL, 1 },
471     { OPT_LEVELS_1_PLUS, OPT_fcombine_stack_adjustments, NULL, 1 },
472     { OPT_LEVELS_1_PLUS, OPT_fcompare_elim, NULL, 1 },
473     { OPT_LEVELS_1_PLUS, OPT_ftree_slsr, NULL, 1 },
474     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fbranch_count_reg, NULL, 1 },
475     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fmove_loop_invariants, NULL, 1 },
476     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_pta, NULL, 1 },
477     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fssa_phiopt, NULL, 1 },
478     { OPT_LEVELS_1_PLUS, OPT_ftree_builtin_call_dce, NULL, 1 },
479     { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
480 
481     /* -O2 optimizations.  */
482     { OPT_LEVELS_2_PLUS, OPT_finline_small_functions, NULL, 1 },
483     { OPT_LEVELS_2_PLUS, OPT_findirect_inlining, NULL, 1 },
484     { OPT_LEVELS_2_PLUS, OPT_fpartial_inlining, NULL, 1 },
485     { OPT_LEVELS_2_PLUS, OPT_fthread_jumps, NULL, 1 },
486     { OPT_LEVELS_2_PLUS, OPT_fcrossjumping, NULL, 1 },
487     { OPT_LEVELS_2_PLUS, OPT_foptimize_sibling_calls, NULL, 1 },
488     { OPT_LEVELS_2_PLUS, OPT_fcse_follow_jumps, NULL, 1 },
489     { OPT_LEVELS_2_PLUS, OPT_fgcse, NULL, 1 },
490     { OPT_LEVELS_2_PLUS, OPT_fexpensive_optimizations, NULL, 1 },
491     { OPT_LEVELS_2_PLUS, OPT_frerun_cse_after_loop, NULL, 1 },
492     { OPT_LEVELS_2_PLUS, OPT_fcaller_saves, NULL, 1 },
493     { OPT_LEVELS_2_PLUS, OPT_fpeephole2, NULL, 1 },
494 #ifdef INSN_SCHEDULING
495   /* Only run the pre-regalloc scheduling pass if optimizing for speed.  */
496     { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_fschedule_insns, NULL, 1 },
497     { OPT_LEVELS_2_PLUS, OPT_fschedule_insns2, NULL, 1 },
498 #endif
499     { OPT_LEVELS_2_PLUS, OPT_fstrict_aliasing, NULL, 1 },
500     { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_freorder_blocks_algorithm_, NULL,
501       REORDER_BLOCKS_ALGORITHM_STC },
502     { OPT_LEVELS_2_PLUS, OPT_freorder_functions, NULL, 1 },
503     { OPT_LEVELS_2_PLUS, OPT_ftree_vrp, NULL, 1 },
504     { OPT_LEVELS_2_PLUS, OPT_fcode_hoisting, NULL, 1 },
505     { OPT_LEVELS_2_PLUS, OPT_ftree_pre, NULL, 1 },
506     { OPT_LEVELS_2_PLUS, OPT_ftree_switch_conversion, NULL, 1 },
507     { OPT_LEVELS_2_PLUS, OPT_fipa_cp, NULL, 1 },
508     { OPT_LEVELS_2_PLUS, OPT_fipa_bit_cp, NULL, 1 },
509     { OPT_LEVELS_2_PLUS, OPT_fipa_vrp, NULL, 1 },
510     { OPT_LEVELS_2_PLUS, OPT_fdevirtualize, NULL, 1 },
511     { OPT_LEVELS_2_PLUS, OPT_fdevirtualize_speculatively, NULL, 1 },
512     { OPT_LEVELS_2_PLUS, OPT_fipa_sra, NULL, 1 },
513     { OPT_LEVELS_2_PLUS, OPT_falign_loops, NULL, 1 },
514     { OPT_LEVELS_2_PLUS, OPT_falign_jumps, NULL, 1 },
515     { OPT_LEVELS_2_PLUS, OPT_falign_labels, NULL, 1 },
516     { OPT_LEVELS_2_PLUS, OPT_falign_functions, NULL, 1 },
517     { OPT_LEVELS_2_PLUS, OPT_ftree_tail_merge, NULL, 1 },
518     { OPT_LEVELS_2_PLUS, OPT_fvect_cost_model_, NULL, VECT_COST_MODEL_CHEAP },
519     { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_foptimize_strlen, NULL, 1 },
520     { OPT_LEVELS_2_PLUS, OPT_fhoist_adjacent_loads, NULL, 1 },
521     { OPT_LEVELS_2_PLUS, OPT_fipa_icf, NULL, 1 },
522     { OPT_LEVELS_2_PLUS, OPT_fisolate_erroneous_paths_dereference, NULL, 1 },
523     { OPT_LEVELS_2_PLUS, OPT_fipa_ra, NULL, 1 },
524     { OPT_LEVELS_2_PLUS, OPT_flra_remat, NULL, 1 },
525     { OPT_LEVELS_2_PLUS, OPT_fstore_merging, NULL, 1 },
526 
527     /* -O3 optimizations.  */
528     { OPT_LEVELS_3_PLUS, OPT_ftree_loop_distribute_patterns, NULL, 1 },
529     { OPT_LEVELS_3_PLUS, OPT_ftree_loop_distribution, NULL, 1 },
530     { OPT_LEVELS_3_PLUS, OPT_floop_interchange, NULL, 1 },
531     { OPT_LEVELS_3_PLUS, OPT_fpredictive_commoning, NULL, 1 },
532     { OPT_LEVELS_3_PLUS, OPT_fsplit_paths, NULL, 1 },
533     /* Inlining of functions reducing size is a good idea with -Os
534        regardless of them being declared inline.  */
535     { OPT_LEVELS_3_PLUS_AND_SIZE, OPT_finline_functions, NULL, 1 },
536     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_finline_functions_called_once, NULL, 1 },
537     { OPT_LEVELS_3_PLUS, OPT_fsplit_loops, NULL, 1 },
538     { OPT_LEVELS_3_PLUS, OPT_funswitch_loops, NULL, 1 },
539     { OPT_LEVELS_3_PLUS, OPT_floop_unroll_and_jam, NULL, 1 },
540     { OPT_LEVELS_3_PLUS, OPT_fgcse_after_reload, NULL, 1 },
541     { OPT_LEVELS_3_PLUS, OPT_ftree_loop_vectorize, NULL, 1 },
542     { OPT_LEVELS_3_PLUS, OPT_ftree_slp_vectorize, NULL, 1 },
543     { OPT_LEVELS_3_PLUS, OPT_fvect_cost_model_, NULL, VECT_COST_MODEL_DYNAMIC },
544     { OPT_LEVELS_3_PLUS, OPT_fipa_cp_clone, NULL, 1 },
545     { OPT_LEVELS_3_PLUS, OPT_ftree_partial_pre, NULL, 1 },
546     { OPT_LEVELS_3_PLUS, OPT_fpeel_loops, NULL, 1 },
547 
548     /* -Ofast adds optimizations to -O3.  */
549     { OPT_LEVELS_FAST, OPT_ffast_math, NULL, 1 },
550 
551     { OPT_LEVELS_NONE, 0, NULL, 0 }
552   };
553 
554 /* Default the options in OPTS and OPTS_SET based on the optimization
555    settings in DECODED_OPTIONS and DECODED_OPTIONS_COUNT.  */
556 void
default_options_optimization(struct gcc_options * opts,struct gcc_options * opts_set,struct cl_decoded_option * decoded_options,unsigned int decoded_options_count,location_t loc,unsigned int lang_mask,const struct cl_option_handlers * handlers,diagnostic_context * dc)557 default_options_optimization (struct gcc_options *opts,
558                                     struct gcc_options *opts_set,
559                                     struct cl_decoded_option *decoded_options,
560                                     unsigned int decoded_options_count,
561                                     location_t loc,
562                                     unsigned int lang_mask,
563                                     const struct cl_option_handlers *handlers,
564                                     diagnostic_context *dc)
565 {
566   unsigned int i;
567   int opt2;
568   bool openacc_mode = false;
569 
570   /* Scan to see what optimization level has been specified.  That will
571      determine the default value of many flags.  */
572   for (i = 1; i < decoded_options_count; i++)
573     {
574       struct cl_decoded_option *opt = &decoded_options[i];
575       switch (opt->opt_index)
576           {
577           case OPT_O:
578             if (*opt->arg == '\0')
579               {
580                 opts->x_optimize = 1;
581                 opts->x_optimize_size = 0;
582                 opts->x_optimize_fast = 0;
583                 opts->x_optimize_debug = 0;
584               }
585             else
586               {
587                 const int optimize_val = integral_argument (opt->arg);
588                 if (optimize_val == -1)
589                     error_at (loc, "argument to %<-O%> should be a non-negative "
590                                      "integer, %<g%>, %<s%> or %<fast%>");
591                 else
592                     {
593                       opts->x_optimize = optimize_val;
594                       if ((unsigned int) opts->x_optimize > 255)
595                         opts->x_optimize = 255;
596                       opts->x_optimize_size = 0;
597                       opts->x_optimize_fast = 0;
598                       opts->x_optimize_debug = 0;
599                     }
600               }
601             break;
602 
603           case OPT_Os:
604             opts->x_optimize_size = 1;
605 
606             /* Optimizing for size forces optimize to be 2.  */
607             opts->x_optimize = 2;
608             opts->x_optimize_fast = 0;
609             opts->x_optimize_debug = 0;
610             break;
611 
612           case OPT_Ofast:
613             /* -Ofast only adds flags to -O3.  */
614             opts->x_optimize_size = 0;
615             opts->x_optimize = 3;
616             opts->x_optimize_fast = 1;
617             opts->x_optimize_debug = 0;
618             break;
619 
620           case OPT_Og:
621             /* -Og selects optimization level 1.  */
622             opts->x_optimize_size = 0;
623             opts->x_optimize = 1;
624             opts->x_optimize_fast = 0;
625             opts->x_optimize_debug = 1;
626             break;
627 
628           case OPT_fopenacc:
629             if (opt->value)
630               openacc_mode = true;
631             break;
632 
633           default:
634             /* Ignore other options in this prescan.  */
635             break;
636           }
637     }
638 
639   maybe_default_options (opts, opts_set, default_options_table,
640                                opts->x_optimize, opts->x_optimize_size,
641                                opts->x_optimize_fast, opts->x_optimize_debug,
642                                lang_mask, handlers, loc, dc);
643 
644   /* -O2 param settings.  */
645   opt2 = (opts->x_optimize >= 2);
646 
647   if (openacc_mode
648       && !opts_set->x_flag_ipa_pta)
649     opts->x_flag_ipa_pta = true;
650 
651   /* Track fields in field-sensitive alias analysis.  */
652   maybe_set_param_value
653     (PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE,
654      opt2 ? 100 : default_param_value (PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE),
655      opts->x_param_values, opts_set->x_param_values);
656 
657   /* For -O1 only do loop invariant motion for very small loops.  */
658   maybe_set_param_value
659     (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP,
660      opt2 ? default_param_value (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP)
661      : default_param_value (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP) / 10,
662      opts->x_param_values, opts_set->x_param_values);
663 
664   /* For -O1 reduce the maximum number of active local stores for RTL DSE
665      since this can consume huge amounts of memory (PR89115).  */
666   maybe_set_param_value
667     (PARAM_MAX_DSE_ACTIVE_LOCAL_STORES,
668      opt2 ? default_param_value (PARAM_MAX_DSE_ACTIVE_LOCAL_STORES)
669      : default_param_value (PARAM_MAX_DSE_ACTIVE_LOCAL_STORES) / 10,
670      opts->x_param_values, opts_set->x_param_values);
671 
672   /* At -Ofast, allow store motion to introduce potential race conditions.  */
673   maybe_set_param_value
674     (PARAM_ALLOW_STORE_DATA_RACES,
675      opts->x_optimize_fast ? 1
676      : default_param_value (PARAM_ALLOW_STORE_DATA_RACES),
677      opts->x_param_values, opts_set->x_param_values);
678 
679   if (opts->x_optimize_size)
680     /* We want to crossjump as much as possible.  */
681     maybe_set_param_value (PARAM_MIN_CROSSJUMP_INSNS, 1,
682                                  opts->x_param_values, opts_set->x_param_values);
683   else
684     maybe_set_param_value (PARAM_MIN_CROSSJUMP_INSNS,
685                                  default_param_value (PARAM_MIN_CROSSJUMP_INSNS),
686                                  opts->x_param_values, opts_set->x_param_values);
687 
688   /* Restrict the amount of work combine does at -Og while retaining
689      most of its useful transforms.  */
690   if (opts->x_optimize_debug)
691     maybe_set_param_value (PARAM_MAX_COMBINE_INSNS, 2,
692                                  opts->x_param_values, opts_set->x_param_values);
693 
694   /* Allow default optimizations to be specified on a per-machine basis.  */
695   maybe_default_options (opts, opts_set,
696                                targetm_common.option_optimization_table,
697                                opts->x_optimize, opts->x_optimize_size,
698                                opts->x_optimize_fast, opts->x_optimize_debug,
699                                lang_mask, handlers, loc, dc);
700 }
701 
702 /* After all options at LOC have been read into OPTS and OPTS_SET,
703    finalize settings of those options and diagnose incompatible
704    combinations.  */
705 void
finish_options(struct gcc_options * opts,struct gcc_options * opts_set,location_t loc)706 finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
707                     location_t loc)
708 {
709   enum unwind_info_type ui_except;
710 
711   if (opts->x_dump_base_name
712       && ! opts->x_dump_base_name_prefixed)
713     {
714       const char *sep = opts->x_dump_base_name;
715 
716       for (; *sep; sep++)
717           if (IS_DIR_SEPARATOR (*sep))
718             break;
719 
720       if (*sep)
721           /* If dump_base_path contains subdirectories, don't prepend
722              anything.  */;
723       else if (opts->x_dump_dir_name)
724           /* We have a DUMP_DIR_NAME, prepend that.  */
725           opts->x_dump_base_name = opts_concat (opts->x_dump_dir_name,
726                                                         opts->x_dump_base_name, NULL);
727       else if (opts->x_aux_base_name
728                  && strcmp (opts->x_aux_base_name, HOST_BIT_BUCKET) != 0)
729           /* AUX_BASE_NAME is set and is not the bit bucket.  If it
730              contains a directory component, prepend those directories.
731              Typically this places things in the same directory as the
732              object file.  */
733           {
734             const char *aux_base;
735 
736             base_of_path (opts->x_aux_base_name, &aux_base);
737             if (opts->x_aux_base_name != aux_base)
738               {
739                 int dir_len = aux_base - opts->x_aux_base_name;
740                 char *new_dump_base_name
741                     = XOBNEWVEC (&opts_obstack, char,
742                                    strlen (opts->x_dump_base_name) + dir_len + 1);
743 
744                 /* Copy directory component from OPTS->X_AUX_BASE_NAME.  */
745                 memcpy (new_dump_base_name, opts->x_aux_base_name, dir_len);
746                 /* Append existing OPTS->X_DUMP_BASE_NAME.  */
747                 strcpy (new_dump_base_name + dir_len, opts->x_dump_base_name);
748                 opts->x_dump_base_name = new_dump_base_name;
749               }
750           }
751 
752       /* It is definitely prefixed now.  */
753       opts->x_dump_base_name_prefixed = true;
754     }
755 
756   /* Handle related options for unit-at-a-time, toplevel-reorder, and
757      section-anchors.  */
758   if (!opts->x_flag_unit_at_a_time)
759     {
760       if (opts->x_flag_section_anchors && opts_set->x_flag_section_anchors)
761           error_at (loc, "section anchors must be disabled when unit-at-a-time "
762                       "is disabled");
763       opts->x_flag_section_anchors = 0;
764       if (opts->x_flag_toplevel_reorder == 1)
765           error_at (loc, "toplevel reorder must be disabled when unit-at-a-time "
766                       "is disabled");
767       opts->x_flag_toplevel_reorder = 0;
768     }
769 
770   /* -fself-test depends on the state of the compiler prior to
771      compiling anything.  Ideally it should be run on an empty source
772      file.  However, in case we get run with actual source, assume
773      -fsyntax-only which will inhibit any compiler initialization
774      which may confuse the self tests.  */
775   if (opts->x_flag_self_test)
776     opts->x_flag_syntax_only = 1;
777 
778   if (opts->x_flag_tm && opts->x_flag_non_call_exceptions)
779     sorry ("transactional memory is not supported with non-call exceptions");
780 
781   /* Unless the user has asked for section anchors, we disable toplevel
782      reordering at -O0 to disable transformations that might be surprising
783      to end users and to get -fno-toplevel-reorder tested.  */
784   if (!opts->x_optimize
785       && opts->x_flag_toplevel_reorder == 2
786       && !(opts->x_flag_section_anchors && opts_set->x_flag_section_anchors))
787     {
788       opts->x_flag_toplevel_reorder = 0;
789       opts->x_flag_section_anchors = 0;
790     }
791   if (!opts->x_flag_toplevel_reorder)
792     {
793       if (opts->x_flag_section_anchors && opts_set->x_flag_section_anchors)
794           error_at (loc, "section anchors must be disabled when toplevel reorder"
795                       " is disabled");
796       opts->x_flag_section_anchors = 0;
797     }
798 
799   if (!opts->x_flag_opts_finished)
800     {
801       /* We initialize opts->x_flag_pie to -1 so that targets can set a
802            default value.  */
803       if (opts->x_flag_pie == -1)
804           {
805             /* We initialize opts->x_flag_pic to -1 so that we can tell if
806                -fpic, -fPIC, -fno-pic or -fno-PIC is used.  */
807             if (opts->x_flag_pic == -1)
808               opts->x_flag_pie = DEFAULT_FLAG_PIE;
809             else
810               opts->x_flag_pie = 0;
811           }
812       /* If -fPIE or -fpie is used, turn on PIC.  */
813       if (opts->x_flag_pie)
814           opts->x_flag_pic = opts->x_flag_pie;
815       else if (opts->x_flag_pic == -1)
816           opts->x_flag_pic = 0;
817       if (opts->x_flag_pic && !opts->x_flag_pie)
818           opts->x_flag_shlib = 1;
819       opts->x_flag_opts_finished = true;
820     }
821 
822   /* We initialize opts->x_flag_stack_protect to -1 so that targets
823      can set a default value.  */
824   if (opts->x_flag_stack_protect == -1)
825     opts->x_flag_stack_protect = DEFAULT_FLAG_SSP;
826 
827   if (opts->x_optimize == 0)
828     {
829       /* Inlining does not work if not optimizing,
830            so force it not to be done.  */
831       opts->x_warn_inline = 0;
832       opts->x_flag_no_inline = 1;
833     }
834 
835   /* The optimization to partition hot and cold basic blocks into separate
836      sections of the .o and executable files does not work (currently)
837      with exception handling.  This is because there is no support for
838      generating unwind info.  If opts->x_flag_exceptions is turned on
839      we need to turn off the partitioning optimization.  */
840 
841   ui_except = targetm_common.except_unwind_info (opts);
842 
843   if (opts->x_flag_exceptions
844       && opts->x_flag_reorder_blocks_and_partition
845       && (ui_except == UI_SJLJ || ui_except >= UI_TARGET))
846     {
847       if (opts_set->x_flag_reorder_blocks_and_partition)
848         inform (loc,
849                     "%<-freorder-blocks-and-partition%> does not work "
850                     "with exceptions on this architecture");
851       opts->x_flag_reorder_blocks_and_partition = 0;
852       opts->x_flag_reorder_blocks = 1;
853     }
854 
855   /* If user requested unwind info, then turn off the partitioning
856      optimization.  */
857 
858   if (opts->x_flag_unwind_tables
859       && !targetm_common.unwind_tables_default
860       && opts->x_flag_reorder_blocks_and_partition
861       && (ui_except == UI_SJLJ || ui_except >= UI_TARGET))
862     {
863       if (opts_set->x_flag_reorder_blocks_and_partition)
864         inform (loc,
865                     "%<-freorder-blocks-and-partition%> does not support "
866                     "unwind info on this architecture");
867       opts->x_flag_reorder_blocks_and_partition = 0;
868       opts->x_flag_reorder_blocks = 1;
869     }
870 
871   /* If the target requested unwind info, then turn off the partitioning
872      optimization with a different message.  Likewise, if the target does not
873      support named sections.  */
874 
875   if (opts->x_flag_reorder_blocks_and_partition
876       && (!targetm_common.have_named_sections
877             || (opts->x_flag_unwind_tables
878                 && targetm_common.unwind_tables_default
879                 && (ui_except == UI_SJLJ || ui_except >= UI_TARGET))))
880     {
881       if (opts_set->x_flag_reorder_blocks_and_partition)
882         inform (loc,
883                     "%<-freorder-blocks-and-partition%> does not work "
884                     "on this architecture");
885       opts->x_flag_reorder_blocks_and_partition = 0;
886       opts->x_flag_reorder_blocks = 1;
887     }
888 
889 
890   /* Pipelining of outer loops is only possible when general pipelining
891      capabilities are requested.  */
892   if (!opts->x_flag_sel_sched_pipelining)
893     opts->x_flag_sel_sched_pipelining_outer_loops = 0;
894 
895   if (opts->x_flag_conserve_stack)
896     {
897       maybe_set_param_value (PARAM_LARGE_STACK_FRAME, 100,
898                                    opts->x_param_values, opts_set->x_param_values);
899       maybe_set_param_value (PARAM_STACK_FRAME_GROWTH, 40,
900                                    opts->x_param_values, opts_set->x_param_values);
901     }
902 
903   if (opts->x_flag_lto)
904     {
905 #ifdef ENABLE_LTO
906       opts->x_flag_generate_lto = 1;
907 
908       /* When generating IL, do not operate in whole-program mode.
909            Otherwise, symbols will be privatized too early, causing link
910            errors later.  */
911       opts->x_flag_whole_program = 0;
912 #else
913       error_at (loc, "LTO support has not been enabled in this configuration");
914 #endif
915       if (!opts->x_flag_fat_lto_objects
916             && (!HAVE_LTO_PLUGIN
917                 || (opts_set->x_flag_use_linker_plugin
918                       && !opts->x_flag_use_linker_plugin)))
919           {
920             if (opts_set->x_flag_fat_lto_objects)
921               error_at (loc, "%<-fno-fat-lto-objects%> are supported only with "
922                           "linker plugin");
923             opts->x_flag_fat_lto_objects = 1;
924           }
925 
926       /* -gsplit-dwarf isn't compatible with LTO, see PR88389.  */
927       if (opts->x_dwarf_split_debug_info)
928           {
929             inform (loc, "%<-gsplit-dwarf%> is not supported with LTO,"
930                       " disabling");
931             opts->x_dwarf_split_debug_info = 0;
932           }
933     }
934 
935   /* We initialize opts->x_flag_split_stack to -1 so that targets can set a
936      default value if they choose based on other options.  */
937   if (opts->x_flag_split_stack == -1)
938     opts->x_flag_split_stack = 0;
939   else if (opts->x_flag_split_stack)
940     {
941       if (!targetm_common.supports_split_stack (true, opts))
942           {
943             error_at (loc, "%<-fsplit-stack%> is not supported by "
944                         "this compiler configuration");
945             opts->x_flag_split_stack = 0;
946           }
947     }
948 
949   /* If stack splitting is turned on, and the user did not explicitly
950      request function partitioning, turn off partitioning, as it
951      confuses the linker when trying to handle partitioned split-stack
952      code that calls a non-split-stack functions.  But if partitioning
953      was turned on explicitly just hope for the best.  */
954   if (opts->x_flag_split_stack
955       && opts->x_flag_reorder_blocks_and_partition
956       && !opts_set->x_flag_reorder_blocks_and_partition)
957     opts->x_flag_reorder_blocks_and_partition = 0;
958 
959   if (opts->x_flag_reorder_blocks_and_partition
960       && !opts_set->x_flag_reorder_functions)
961     opts->x_flag_reorder_functions = 1;
962 
963   /* Tune vectorization related parametees according to cost model.  */
964   if (opts->x_flag_vect_cost_model == VECT_COST_MODEL_CHEAP)
965     {
966       maybe_set_param_value (PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS,
967             6, opts->x_param_values, opts_set->x_param_values);
968       maybe_set_param_value (PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS,
969             0, opts->x_param_values, opts_set->x_param_values);
970       maybe_set_param_value (PARAM_VECT_MAX_PEELING_FOR_ALIGNMENT,
971             0, opts->x_param_values, opts_set->x_param_values);
972     }
973 
974   /* Set PARAM_MAX_STORES_TO_SINK to 0 if either vectorization or if-conversion
975      is disabled.  */
976   if ((!opts->x_flag_tree_loop_vectorize && !opts->x_flag_tree_slp_vectorize)
977        || !opts->x_flag_tree_loop_if_convert)
978     maybe_set_param_value (PARAM_MAX_STORES_TO_SINK, 0,
979                            opts->x_param_values, opts_set->x_param_values);
980 
981   /* The -gsplit-dwarf option requires -ggnu-pubnames.  */
982   if (opts->x_dwarf_split_debug_info)
983     opts->x_debug_generate_pub_sections = 2;
984 
985   if ((opts->x_flag_sanitize
986        & (SANITIZE_USER_ADDRESS | SANITIZE_KERNEL_ADDRESS)) == 0)
987     {
988       if (opts->x_flag_sanitize & SANITIZE_POINTER_COMPARE)
989           error_at (loc,
990                       "%<-fsanitize=pointer-compare%> must be combined with "
991                       "%<-fsanitize=address%> or %<-fsanitize=kernel-address%>");
992       if (opts->x_flag_sanitize & SANITIZE_POINTER_SUBTRACT)
993           error_at (loc,
994                       "%<-fsanitize=pointer-subtract%> must be combined with "
995                       "%<-fsanitize=address%> or %<-fsanitize=kernel-address%>");
996     }
997 
998   /* Userspace and kernel ASan conflict with each other.  */
999   if ((opts->x_flag_sanitize & SANITIZE_USER_ADDRESS)
1000       && (opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS))
1001     error_at (loc,
1002                 "%<-fsanitize=address%> is incompatible with "
1003                 "%<-fsanitize=kernel-address%>");
1004 
1005   /* And with TSan.  */
1006   if ((opts->x_flag_sanitize & SANITIZE_ADDRESS)
1007       && (opts->x_flag_sanitize & SANITIZE_THREAD))
1008     error_at (loc,
1009                 "%<-fsanitize=address%> and %<-fsanitize=kernel-address%> "
1010                 "are incompatible with %<-fsanitize=thread%>");
1011 
1012   if ((opts->x_flag_sanitize & SANITIZE_LEAK)
1013       && (opts->x_flag_sanitize & SANITIZE_THREAD))
1014     error_at (loc,
1015                 "%<-fsanitize=leak%> is incompatible with %<-fsanitize=thread%>");
1016 
1017   /* Check error recovery for -fsanitize-recover option.  */
1018   for (int i = 0; sanitizer_opts[i].name != NULL; ++i)
1019     if ((opts->x_flag_sanitize_recover & sanitizer_opts[i].flag)
1020           && !sanitizer_opts[i].can_recover)
1021       error_at (loc, "%<-fsanitize-recover=%s%> is not supported",
1022                     sanitizer_opts[i].name);
1023 
1024   /* When instrumenting the pointers, we don't want to remove
1025      the null pointer checks.  */
1026   if (opts->x_flag_sanitize & (SANITIZE_NULL | SANITIZE_NONNULL_ATTRIBUTE
1027                                         | SANITIZE_RETURNS_NONNULL_ATTRIBUTE))
1028     opts->x_flag_delete_null_pointer_checks = 0;
1029 
1030   /* Aggressive compiler optimizations may cause false negatives.  */
1031   if (opts->x_flag_sanitize & ~(SANITIZE_LEAK | SANITIZE_UNREACHABLE))
1032     opts->x_flag_aggressive_loop_optimizations = 0;
1033 
1034   /* Enable -fsanitize-address-use-after-scope if address sanitizer is
1035      enabled.  */
1036   if ((opts->x_flag_sanitize & SANITIZE_USER_ADDRESS)
1037       && !opts_set->x_flag_sanitize_address_use_after_scope)
1038     opts->x_flag_sanitize_address_use_after_scope = true;
1039 
1040   /* Force -fstack-reuse=none in case -fsanitize-address-use-after-scope
1041      is enabled.  */
1042   if (opts->x_flag_sanitize_address_use_after_scope)
1043     {
1044       if (opts->x_flag_stack_reuse != SR_NONE
1045             && opts_set->x_flag_stack_reuse != SR_NONE)
1046           error_at (loc,
1047                       "%<-fsanitize-address-use-after-scope%> requires "
1048                       "%<-fstack-reuse=none%> option");
1049 
1050       opts->x_flag_stack_reuse = SR_NONE;
1051     }
1052 
1053   if ((opts->x_flag_sanitize & SANITIZE_USER_ADDRESS) && opts->x_flag_tm)
1054     sorry ("transactional memory is not supported with %<-fsanitize=address%>");
1055 
1056   if ((opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS) && opts->x_flag_tm)
1057     sorry ("transactional memory is not supported with "
1058              "%<-fsanitize=kernel-address%>");
1059 
1060   /* Comes from final.c -- no real reason to change it.  */
1061 #define MAX_CODE_ALIGN 16
1062 #define MAX_CODE_ALIGN_VALUE (1 << MAX_CODE_ALIGN)
1063 
1064   if (opts->x_align_loops > MAX_CODE_ALIGN_VALUE)
1065     error_at (loc, "-falign-loops=%d is not between 0 and %d",
1066                 opts->x_align_loops, MAX_CODE_ALIGN_VALUE);
1067 
1068   if (opts->x_align_jumps > MAX_CODE_ALIGN_VALUE)
1069     error_at (loc, "-falign-jumps=%d is not between 0 and %d",
1070                 opts->x_align_jumps, MAX_CODE_ALIGN_VALUE);
1071 
1072   if (opts->x_align_functions > MAX_CODE_ALIGN_VALUE)
1073     error_at (loc, "-falign-functions=%d is not between 0 and %d",
1074                 opts->x_align_functions, MAX_CODE_ALIGN_VALUE);
1075 
1076   if (opts->x_align_labels > MAX_CODE_ALIGN_VALUE)
1077     error_at (loc, "-falign-labels=%d is not between 0 and %d",
1078                 opts->x_align_labels, MAX_CODE_ALIGN_VALUE);
1079 }
1080 
1081 #define LEFT_COLUMN 27
1082 
1083 /* Output ITEM, of length ITEM_WIDTH, in the left column,
1084    followed by word-wrapped HELP in a second column.  */
1085 static void
wrap_help(const char * help,const char * item,unsigned int item_width,unsigned int columns)1086 wrap_help (const char *help,
1087              const char *item,
1088              unsigned int item_width,
1089              unsigned int columns)
1090 {
1091   unsigned int col_width = LEFT_COLUMN;
1092   unsigned int remaining, room, len;
1093 
1094   remaining = strlen (help);
1095 
1096   do
1097     {
1098       room = columns - 3 - MAX (col_width, item_width);
1099       if (room > columns)
1100           room = 0;
1101       len = remaining;
1102 
1103       if (room < len)
1104           {
1105             unsigned int i;
1106 
1107             for (i = 0; help[i]; i++)
1108               {
1109                 if (i >= room && len != remaining)
1110                     break;
1111                 if (help[i] == ' ')
1112                     len = i;
1113                 else if ((help[i] == '-' || help[i] == '/')
1114                            && help[i + 1] != ' '
1115                            && i > 0 && ISALPHA (help[i - 1]))
1116                     len = i + 1;
1117               }
1118           }
1119 
1120       printf ("  %-*.*s %.*s\n", col_width, item_width, item, len, help);
1121       item_width = 0;
1122       while (help[len] == ' ')
1123           len++;
1124       help += len;
1125       remaining -= len;
1126     }
1127   while (remaining);
1128 }
1129 
1130 /* Print help for a specific front-end, etc.  */
1131 static void
print_filtered_help(unsigned int include_flags,unsigned int exclude_flags,unsigned int any_flags,unsigned int columns,struct gcc_options * opts,unsigned int lang_mask)1132 print_filtered_help (unsigned int include_flags,
1133                          unsigned int exclude_flags,
1134                          unsigned int any_flags,
1135                          unsigned int columns,
1136                          struct gcc_options *opts,
1137                          unsigned int lang_mask)
1138 {
1139   unsigned int i;
1140   const char *help;
1141   bool found = false;
1142   bool displayed = false;
1143   char new_help[256];
1144 
1145   if (include_flags == CL_PARAMS)
1146     {
1147       for (i = 0; i < LAST_PARAM; i++)
1148           {
1149             const char *param = compiler_params[i].option;
1150 
1151             help = compiler_params[i].help;
1152             if (help == NULL || *help == '\0')
1153               {
1154                 if (exclude_flags & CL_UNDOCUMENTED)
1155                     continue;
1156                 help = undocumented_msg;
1157               }
1158 
1159             /* Get the translation.  */
1160             help = _(help);
1161 
1162             if (!opts->x_quiet_flag)
1163               {
1164                 snprintf (new_help, sizeof (new_help),
1165                               _("default %d minimum %d maximum %d"),
1166                               compiler_params[i].default_value,
1167                               compiler_params[i].min_value,
1168                               compiler_params[i].max_value);
1169                 help = new_help;
1170               }
1171             wrap_help (help, param, strlen (param), columns);
1172           }
1173       putchar ('\n');
1174       return;
1175     }
1176 
1177   if (!opts->x_help_printed)
1178     opts->x_help_printed = XCNEWVAR (char, cl_options_count);
1179 
1180   if (!opts->x_help_enum_printed)
1181     opts->x_help_enum_printed = XCNEWVAR (char, cl_enums_count);
1182 
1183   for (i = 0; i < cl_options_count; i++)
1184     {
1185       const struct cl_option *option = cl_options + i;
1186       unsigned int len;
1187       const char *opt;
1188       const char *tab;
1189 
1190       if (include_flags == 0
1191             || ((option->flags & include_flags) != include_flags))
1192           {
1193             if ((option->flags & any_flags) == 0)
1194               continue;
1195           }
1196 
1197       /* Skip unwanted switches.  */
1198       if ((option->flags & exclude_flags) != 0)
1199           continue;
1200 
1201       /* The driver currently prints its own help text.  */
1202       if ((option->flags & CL_DRIVER) != 0
1203             && (option->flags & (((1U << cl_lang_count) - 1)
1204                                      | CL_COMMON | CL_TARGET)) == 0)
1205           continue;
1206 
1207       found = true;
1208       /* Skip switches that have already been printed.  */
1209       if (opts->x_help_printed[i])
1210           continue;
1211 
1212       opts->x_help_printed[i] = true;
1213 
1214       help = option->help;
1215       if (help == NULL)
1216           {
1217             if (exclude_flags & CL_UNDOCUMENTED)
1218               continue;
1219 
1220             help = undocumented_msg;
1221           }
1222 
1223       if (option->alias_target < N_OPTS
1224             && cl_options [option->alias_target].help)
1225           {
1226             if (help == undocumented_msg)
1227               {
1228                 /* For undocumented options that are aliases for other options
1229                      that are documented, point the reader to the other option in
1230                      preference of the former.  */
1231                 snprintf (new_help, sizeof new_help,
1232                               _("Same as %s.  Use the latter option instead."),
1233                               cl_options [option->alias_target].opt_text);
1234               }
1235             else
1236               {
1237                 /* For documented options with aliases, mention the aliased
1238                      option's name for reference.  */
1239                 snprintf (new_help, sizeof new_help,
1240                               _("%s  Same as %s."),
1241                               help, cl_options [option->alias_target].opt_text);
1242               }
1243 
1244             help = new_help;
1245           }
1246 
1247       if (option->warn_message)
1248           {
1249             /* Mention that the use of the option will trigger a warning.  */
1250             if (help == new_help)
1251               snprintf (new_help + strlen (new_help),
1252                           sizeof new_help - strlen (new_help),
1253                           "  %s", _(use_diagnosed_msg));
1254             else
1255               snprintf (new_help, sizeof new_help,
1256                           "%s  %s", help, _(use_diagnosed_msg));
1257 
1258             help = new_help;
1259           }
1260 
1261       /* Get the translation.  */
1262       help = _(help);
1263 
1264       /* Find the gap between the name of the
1265            option and its descriptive text.  */
1266       tab = strchr (help, '\t');
1267       if (tab)
1268           {
1269             len = tab - help;
1270             opt = help;
1271             help = tab + 1;
1272           }
1273       else
1274           {
1275             opt = option->opt_text;
1276             len = strlen (opt);
1277           }
1278 
1279       /* With the -Q option enabled we change the descriptive text associated
1280            with an option to be an indication of its current setting.  */
1281       if (!opts->x_quiet_flag)
1282           {
1283             void *flag_var = option_flag_var (i, opts);
1284 
1285             if (len < (LEFT_COLUMN + 2))
1286               strcpy (new_help, "\t\t");
1287             else
1288               strcpy (new_help, "\t");
1289 
1290             if (flag_var != NULL
1291                 && option->var_type != CLVC_DEFER)
1292               {
1293                 if (option->flags & CL_JOINED)
1294                     {
1295                       if (option->var_type == CLVC_STRING)
1296                         {
1297                           if (* (const char **) flag_var != NULL)
1298                               snprintf (new_help + strlen (new_help),
1299                                           sizeof (new_help) - strlen (new_help),
1300                                           "%s", * (const char **) flag_var);
1301                         }
1302                       else if (option->var_type == CLVC_ENUM)
1303                         {
1304                           const struct cl_enum *e = &cl_enums[option->var_enum];
1305                           int value;
1306                           const char *arg = NULL;
1307 
1308                           value = e->get (flag_var);
1309                           enum_value_to_arg (e->values, &arg, value, lang_mask);
1310                           if (arg == NULL)
1311                               arg = _("[default]");
1312                           snprintf (new_help + strlen (new_help),
1313                                         sizeof (new_help) - strlen (new_help),
1314                                         "%s", arg);
1315                         }
1316                       else
1317                         sprintf (new_help + strlen (new_help),
1318                                    "%d", * (int *) flag_var);
1319                     }
1320                 else
1321                     strcat (new_help, option_enabled (i, opts)
1322                               ? _("[enabled]") : _("[disabled]"));
1323               }
1324 
1325             help = new_help;
1326           }
1327 
1328       if (option->range_max != -1)
1329           {
1330             char b[128];
1331             snprintf (b, sizeof (b), "<%d,%d>", option->range_min,
1332                         option->range_max);
1333             opt = concat (opt, b, NULL);
1334             len += strlen (b);
1335           }
1336 
1337       wrap_help (help, opt, len, columns);
1338       displayed = true;
1339 
1340       if (option->var_type == CLVC_ENUM
1341             && opts->x_help_enum_printed[option->var_enum] != 2)
1342           opts->x_help_enum_printed[option->var_enum] = 1;
1343     }
1344 
1345   if (! found)
1346     {
1347       unsigned int langs = include_flags & CL_LANG_ALL;
1348 
1349       if (langs == 0)
1350           printf (_(" No options with the desired characteristics were found\n"));
1351       else
1352           {
1353             unsigned int i;
1354 
1355             /* PR 31349: Tell the user how to see all of the
1356                options supported by a specific front end.  */
1357             for (i = 0; (1U << i) < CL_LANG_ALL; i ++)
1358               if ((1U << i) & langs)
1359                 printf (_(" None found.  Use --help=%s to show *all* the options supported by the %s front-end.\n"),
1360                           lang_names[i], lang_names[i]);
1361           }
1362 
1363     }
1364   else if (! displayed)
1365     printf (_(" All options with the desired characteristics have already been displayed\n"));
1366 
1367   putchar ('\n');
1368 
1369   /* Print details of enumerated option arguments, if those
1370      enumerations have help text headings provided.  If no help text
1371      is provided, presume that the possible values are listed in the
1372      help text for the relevant options.  */
1373   for (i = 0; i < cl_enums_count; i++)
1374     {
1375       unsigned int j, pos;
1376 
1377       if (opts->x_help_enum_printed[i] != 1)
1378           continue;
1379       if (cl_enums[i].help == NULL)
1380           continue;
1381       printf ("  %s\n    ", _(cl_enums[i].help));
1382       pos = 4;
1383       for (j = 0; cl_enums[i].values[j].arg != NULL; j++)
1384           {
1385             unsigned int len = strlen (cl_enums[i].values[j].arg);
1386 
1387             if (pos > 4 && pos + 1 + len <= columns)
1388               {
1389                 printf (" %s", cl_enums[i].values[j].arg);
1390                 pos += 1 + len;
1391               }
1392             else
1393               {
1394                 if (pos > 4)
1395                     {
1396                       printf ("\n    ");
1397                       pos = 4;
1398                     }
1399                 printf ("%s", cl_enums[i].values[j].arg);
1400                 pos += len;
1401               }
1402           }
1403       printf ("\n\n");
1404       opts->x_help_enum_printed[i] = 2;
1405     }
1406 }
1407 
1408 /* Display help for a specified type of option.
1409    The options must have ALL of the INCLUDE_FLAGS set
1410    ANY of the flags in the ANY_FLAGS set
1411    and NONE of the EXCLUDE_FLAGS set.  The current option state is in
1412    OPTS; LANG_MASK is used for interpreting enumerated option state.  */
1413 static void
print_specific_help(unsigned int include_flags,unsigned int exclude_flags,unsigned int any_flags,struct gcc_options * opts,unsigned int lang_mask)1414 print_specific_help (unsigned int include_flags,
1415                          unsigned int exclude_flags,
1416                          unsigned int any_flags,
1417                          struct gcc_options *opts,
1418                          unsigned int lang_mask)
1419 {
1420   unsigned int all_langs_mask = (1U << cl_lang_count) - 1;
1421   const char * description = NULL;
1422   const char * descrip_extra = "";
1423   size_t i;
1424   unsigned int flag;
1425 
1426   /* Sanity check: Make sure that we do not have more
1427      languages than we have bits available to enumerate them.  */
1428   gcc_assert ((1U << cl_lang_count) <= CL_MIN_OPTION_CLASS);
1429 
1430   /* If we have not done so already, obtain
1431      the desired maximum width of the output.  */
1432   if (opts->x_help_columns == 0)
1433     {
1434       opts->x_help_columns = get_terminal_width ();
1435       if (opts->x_help_columns == INT_MAX)
1436           /* Use a reasonable default.  */
1437           opts->x_help_columns = 80;
1438     }
1439 
1440   /* Decide upon the title for the options that we are going to display.  */
1441   for (i = 0, flag = 1; flag <= CL_MAX_OPTION_CLASS; flag <<= 1, i ++)
1442     {
1443       switch (flag & include_flags)
1444           {
1445           case 0:
1446           case CL_DRIVER:
1447             break;
1448 
1449           case CL_TARGET:
1450             description = _("The following options are target specific");
1451             break;
1452           case CL_WARNING:
1453             description = _("The following options control compiler warning messages");
1454             break;
1455           case CL_OPTIMIZATION:
1456             description = _("The following options control optimizations");
1457             break;
1458           case CL_COMMON:
1459             description = _("The following options are language-independent");
1460             break;
1461           case CL_PARAMS:
1462             description = _("The --param option recognizes the following as parameters");
1463             break;
1464           default:
1465             if (i >= cl_lang_count)
1466               break;
1467             if (exclude_flags & all_langs_mask)
1468               description = _("The following options are specific to just the language ");
1469             else
1470               description = _("The following options are supported by the language ");
1471             descrip_extra = lang_names [i];
1472             break;
1473           }
1474     }
1475 
1476   if (description == NULL)
1477     {
1478       if (any_flags == 0)
1479           {
1480             if (include_flags & CL_UNDOCUMENTED)
1481               description = _("The following options are not documented");
1482             else if (include_flags & CL_SEPARATE)
1483               description = _("The following options take separate arguments");
1484             else if (include_flags & CL_JOINED)
1485               description = _("The following options take joined arguments");
1486             else
1487               {
1488                 internal_error ("unrecognized include_flags 0x%x passed to print_specific_help",
1489                                     include_flags);
1490                 return;
1491               }
1492           }
1493       else
1494           {
1495             if (any_flags & all_langs_mask)
1496               description = _("The following options are language-related");
1497             else
1498               description = _("The following options are language-independent");
1499           }
1500     }
1501 
1502   printf ("%s%s:\n", description, descrip_extra);
1503   print_filtered_help (include_flags, exclude_flags, any_flags,
1504                            opts->x_help_columns, opts, lang_mask);
1505 }
1506 
1507 /* Enable FDO-related flags.  */
1508 
1509 static void
enable_fdo_optimizations(struct gcc_options * opts,struct gcc_options * opts_set,int value)1510 enable_fdo_optimizations (struct gcc_options *opts,
1511                                 struct gcc_options *opts_set,
1512                                 int value)
1513 {
1514   if (!opts_set->x_flag_branch_probabilities)
1515     opts->x_flag_branch_probabilities = value;
1516   if (!opts_set->x_flag_profile_values)
1517     opts->x_flag_profile_values = value;
1518   if (!opts_set->x_flag_unroll_loops)
1519     opts->x_flag_unroll_loops = value;
1520   if (!opts_set->x_flag_peel_loops)
1521     opts->x_flag_peel_loops = value;
1522   if (!opts_set->x_flag_tracer)
1523     opts->x_flag_tracer = value;
1524   if (!opts_set->x_flag_value_profile_transformations)
1525     opts->x_flag_value_profile_transformations = value;
1526   if (!opts_set->x_flag_inline_functions)
1527     opts->x_flag_inline_functions = value;
1528   if (!opts_set->x_flag_ipa_cp)
1529     opts->x_flag_ipa_cp = value;
1530   if (!opts_set->x_flag_ipa_cp_clone
1531       && value && opts->x_flag_ipa_cp)
1532     opts->x_flag_ipa_cp_clone = value;
1533   if (!opts_set->x_flag_ipa_bit_cp
1534       && value && opts->x_flag_ipa_cp)
1535     opts->x_flag_ipa_bit_cp = value;
1536   if (!opts_set->x_flag_predictive_commoning)
1537     opts->x_flag_predictive_commoning = value;
1538   if (!opts_set->x_flag_split_loops)
1539     opts->x_flag_split_loops = value;
1540   if (!opts_set->x_flag_unswitch_loops)
1541     opts->x_flag_unswitch_loops = value;
1542   if (!opts_set->x_flag_gcse_after_reload)
1543     opts->x_flag_gcse_after_reload = value;
1544   if (!opts_set->x_flag_tree_loop_vectorize)
1545     opts->x_flag_tree_loop_vectorize = value;
1546   if (!opts_set->x_flag_tree_slp_vectorize)
1547     opts->x_flag_tree_slp_vectorize = value;
1548   if (!opts_set->x_flag_vect_cost_model)
1549     opts->x_flag_vect_cost_model = VECT_COST_MODEL_DYNAMIC;
1550   if (!opts_set->x_flag_tree_loop_distribute_patterns)
1551     opts->x_flag_tree_loop_distribute_patterns = value;
1552 }
1553 
1554 /* -f{,no-}sanitize{,-recover}= suboptions.  */
1555 const struct sanitizer_opts_s sanitizer_opts[] =
1556 {
1557 #define SANITIZER_OPT(name, flags, recover) \
1558     { #name, flags, sizeof #name - 1, recover }
1559   SANITIZER_OPT (address, (SANITIZE_ADDRESS | SANITIZE_USER_ADDRESS), true),
1560   SANITIZER_OPT (kernel-address, (SANITIZE_ADDRESS | SANITIZE_KERNEL_ADDRESS),
1561                      true),
1562   SANITIZER_OPT (pointer-compare, SANITIZE_POINTER_COMPARE, true),
1563   SANITIZER_OPT (pointer-subtract, SANITIZE_POINTER_SUBTRACT, true),
1564   SANITIZER_OPT (thread, SANITIZE_THREAD, false),
1565   SANITIZER_OPT (leak, SANITIZE_LEAK, false),
1566   SANITIZER_OPT (shift, SANITIZE_SHIFT, true),
1567   SANITIZER_OPT (shift-base, SANITIZE_SHIFT_BASE, true),
1568   SANITIZER_OPT (shift-exponent, SANITIZE_SHIFT_EXPONENT, true),
1569   SANITIZER_OPT (integer-divide-by-zero, SANITIZE_DIVIDE, true),
1570   SANITIZER_OPT (undefined, SANITIZE_UNDEFINED, true),
1571   SANITIZER_OPT (unreachable, SANITIZE_UNREACHABLE, false),
1572   SANITIZER_OPT (vla-bound, SANITIZE_VLA, true),
1573   SANITIZER_OPT (return, SANITIZE_RETURN, false),
1574   SANITIZER_OPT (null, SANITIZE_NULL, true),
1575   SANITIZER_OPT (signed-integer-overflow, SANITIZE_SI_OVERFLOW, true),
1576   SANITIZER_OPT (bool, SANITIZE_BOOL, true),
1577   SANITIZER_OPT (enum, SANITIZE_ENUM, true),
1578   SANITIZER_OPT (float-divide-by-zero, SANITIZE_FLOAT_DIVIDE, true),
1579   SANITIZER_OPT (float-cast-overflow, SANITIZE_FLOAT_CAST, true),
1580   SANITIZER_OPT (bounds, SANITIZE_BOUNDS, true),
1581   SANITIZER_OPT (bounds-strict, SANITIZE_BOUNDS | SANITIZE_BOUNDS_STRICT, true),
1582   SANITIZER_OPT (alignment, SANITIZE_ALIGNMENT, true),
1583   SANITIZER_OPT (nonnull-attribute, SANITIZE_NONNULL_ATTRIBUTE, true),
1584   SANITIZER_OPT (returns-nonnull-attribute, SANITIZE_RETURNS_NONNULL_ATTRIBUTE,
1585                      true),
1586   SANITIZER_OPT (object-size, SANITIZE_OBJECT_SIZE, true),
1587   SANITIZER_OPT (vptr, SANITIZE_VPTR, true),
1588   SANITIZER_OPT (pointer-overflow, SANITIZE_POINTER_OVERFLOW, true),
1589   SANITIZER_OPT (builtin, SANITIZE_BUILTIN, true),
1590   SANITIZER_OPT (all, ~0U, true),
1591 #undef SANITIZER_OPT
1592   { NULL, 0U, 0UL, false }
1593 };
1594 
1595 /* -f{,no-}sanitize-coverage= suboptions.  */
1596 const struct sanitizer_opts_s coverage_sanitizer_opts[] =
1597 {
1598 #define COVERAGE_SANITIZER_OPT(name, flags) \
1599     { #name, flags, sizeof #name - 1, true }
1600   COVERAGE_SANITIZER_OPT (trace-pc, SANITIZE_COV_TRACE_PC),
1601   COVERAGE_SANITIZER_OPT (trace-cmp, SANITIZE_COV_TRACE_CMP),
1602 #undef COVERAGE_SANITIZER_OPT
1603   { NULL, 0U, 0UL, false }
1604 };
1605 
1606 /* A struct for describing a run of chars within a string.  */
1607 
1608 struct string_fragment
1609 {
string_fragmentstring_fragment1610   string_fragment (const char *start, size_t len)
1611   : m_start (start), m_len (len) {}
1612 
1613   const char *m_start;
1614   size_t m_len;
1615 };
1616 
1617 /* Specialization of edit_distance_traits for string_fragment,
1618    for use by get_closest_sanitizer_option.  */
1619 
1620 template <>
1621 struct edit_distance_traits<const string_fragment &>
1622 {
1623   static size_t get_length (const string_fragment &fragment)
1624   {
1625     return fragment.m_len;
1626   }
1627 
1628   static const char *get_string (const string_fragment &fragment)
1629   {
1630     return fragment.m_start;
1631   }
1632 };
1633 
1634 /* Given ARG, an unrecognized sanitizer option, return the best
1635    matching sanitizer option, or NULL if there isn't one.
1636    OPTS is array of candidate sanitizer options.
1637    CODE is OPT_fsanitize_, OPT_fsanitize_recover_ or
1638    OPT_fsanitize_coverage_.
1639    VALUE is non-zero for the regular form of the option, zero
1640    for the "no-" form (e.g. "-fno-sanitize-recover=").  */
1641 
1642 static const char *
1643 get_closest_sanitizer_option (const string_fragment &arg,
1644                                     const struct sanitizer_opts_s *opts,
1645                                     enum opt_code code, int value)
1646 {
1647   best_match <const string_fragment &, const char*> bm (arg);
1648   for (int i = 0; opts[i].name != NULL; ++i)
1649     {
1650       /* -fsanitize=all is not valid, so don't offer it.  */
1651       if (code == OPT_fsanitize_
1652             && opts[i].flag == ~0U
1653             && value)
1654           continue;
1655 
1656       /* For -fsanitize-recover= (and not -fno-sanitize-recover=),
1657            don't offer the non-recoverable options.  */
1658       if (code == OPT_fsanitize_recover_
1659             && !opts[i].can_recover
1660             && value)
1661           continue;
1662 
1663       bm.consider (opts[i].name);
1664     }
1665   return bm.get_best_meaningful_candidate ();
1666 }
1667 
1668 /* Parse comma separated sanitizer suboptions from P for option SCODE,
1669    adjust previous FLAGS and return new ones.  If COMPLAIN is false,
1670    don't issue diagnostics.  */
1671 
1672 unsigned int
1673 parse_sanitizer_options (const char *p, location_t loc, int scode,
1674                                unsigned int flags, int value, bool complain)
1675 {
1676   enum opt_code code = (enum opt_code) scode;
1677 
1678   const struct sanitizer_opts_s *opts;
1679   if (code == OPT_fsanitize_coverage_)
1680     opts = coverage_sanitizer_opts;
1681   else
1682     opts = sanitizer_opts;
1683 
1684   while (*p != 0)
1685     {
1686       size_t len, i;
1687       bool found = false;
1688       const char *comma = strchr (p, ',');
1689 
1690       if (comma == NULL)
1691           len = strlen (p);
1692       else
1693           len = comma - p;
1694       if (len == 0)
1695           {
1696             p = comma + 1;
1697             continue;
1698           }
1699 
1700       /* Check to see if the string matches an option class name.  */
1701       for (i = 0; opts[i].name != NULL; ++i)
1702           if (len == opts[i].len && memcmp (p, opts[i].name, len) == 0)
1703             {
1704               /* Handle both -fsanitize and -fno-sanitize cases.  */
1705               if (value && opts[i].flag == ~0U)
1706                 {
1707                     if (code == OPT_fsanitize_)
1708                       {
1709                         if (complain)
1710                           error_at (loc, "%<-fsanitize=all%> option is not valid");
1711                       }
1712                     else
1713                       flags |= ~(SANITIZE_THREAD | SANITIZE_LEAK
1714                                    | SANITIZE_UNREACHABLE | SANITIZE_RETURN);
1715                 }
1716               else if (value)
1717                 {
1718                     /* Do not enable -fsanitize-recover=unreachable and
1719                        -fsanitize-recover=return if -fsanitize-recover=undefined
1720                        is selected.  */
1721                     if (code == OPT_fsanitize_recover_
1722                         && opts[i].flag == SANITIZE_UNDEFINED)
1723                       flags |= (SANITIZE_UNDEFINED
1724                                   & ~(SANITIZE_UNREACHABLE | SANITIZE_RETURN));
1725                     else
1726                       flags |= opts[i].flag;
1727                 }
1728               else
1729                 flags &= ~opts[i].flag;
1730               found = true;
1731               break;
1732             }
1733 
1734       if (! found && complain)
1735           {
1736             const char *hint
1737               = get_closest_sanitizer_option (string_fragment (p, len),
1738                                                       opts, code, value);
1739 
1740             const char *suffix;
1741             if (code == OPT_fsanitize_recover_)
1742               suffix = "-recover";
1743             else if (code == OPT_fsanitize_coverage_)
1744               suffix = "-coverage";
1745             else
1746               suffix = "";
1747 
1748             if (hint)
1749               error_at (loc,
1750                           "unrecognized argument to -f%ssanitize%s= option: %q.*s;"
1751                           " did you mean %qs?",
1752                           value ? "" : "no-",
1753                           suffix, (int) len, p, hint);
1754             else
1755               error_at (loc,
1756                           "unrecognized argument to -f%ssanitize%s= option: %q.*s",
1757                           value ? "" : "no-",
1758                           suffix, (int) len, p);
1759           }
1760 
1761       if (comma == NULL)
1762           break;
1763       p = comma + 1;
1764     }
1765   return flags;
1766 }
1767 
1768 /* Parse string values of no_sanitize attribute passed in VALUE.
1769    Values are separated with comma.  */
1770 
1771 unsigned int
1772 parse_no_sanitize_attribute (char *value)
1773 {
1774   unsigned int flags = 0;
1775   unsigned int i;
1776   char *q = strtok (value, ",");
1777 
1778   while (q != NULL)
1779     {
1780       for (i = 0; sanitizer_opts[i].name != NULL; ++i)
1781           if (strcmp (sanitizer_opts[i].name, q) == 0)
1782             {
1783               flags |= sanitizer_opts[i].flag;
1784               if (sanitizer_opts[i].flag == SANITIZE_UNDEFINED)
1785                 flags |= SANITIZE_UNDEFINED_NONDEFAULT;
1786               break;
1787             }
1788 
1789       if (sanitizer_opts[i].name == NULL)
1790           warning (OPT_Wattributes,
1791                      "%<%s%> attribute directive ignored", q);
1792 
1793       q = strtok (NULL, ",");
1794     }
1795 
1796   return flags;
1797 }
1798 
1799 /* Handle target- and language-independent options.  Return zero to
1800    generate an "unknown option" message.  Only options that need
1801    extra handling need to be listed here; if you simply want
1802    DECODED->value assigned to a variable, it happens automatically.  */
1803 
1804 bool
1805 common_handle_option (struct gcc_options *opts,
1806                           struct gcc_options *opts_set,
1807                           const struct cl_decoded_option *decoded,
1808                           unsigned int lang_mask, int kind ATTRIBUTE_UNUSED,
1809                           location_t loc,
1810                           const struct cl_option_handlers *handlers,
1811                           diagnostic_context *dc,
1812                           void (*target_option_override_hook) (void))
1813 {
1814   size_t scode = decoded->opt_index;
1815   const char *arg = decoded->arg;
1816   int value = decoded->value;
1817   enum opt_code code = (enum opt_code) scode;
1818 
1819   gcc_assert (decoded->canonical_option_num_elements <= 2);
1820 
1821   switch (code)
1822     {
1823     case OPT__param:
1824       handle_param (opts, opts_set, loc, arg);
1825       break;
1826 
1827     case OPT__help:
1828       {
1829           unsigned int all_langs_mask = (1U << cl_lang_count) - 1;
1830           unsigned int undoc_mask;
1831           unsigned int i;
1832 
1833           if (lang_mask == CL_DRIVER)
1834             break;
1835 
1836           undoc_mask = ((opts->x_verbose_flag | opts->x_extra_warnings)
1837                           ? 0
1838                           : CL_UNDOCUMENTED);
1839           target_option_override_hook ();
1840           /* First display any single language specific options.  */
1841           for (i = 0; i < cl_lang_count; i++)
1842             print_specific_help
1843               (1U << i, (all_langs_mask & (~ (1U << i))) | undoc_mask, 0, opts,
1844                lang_mask);
1845           /* Next display any multi language specific options.  */
1846           print_specific_help (0, undoc_mask, all_langs_mask, opts, lang_mask);
1847           /* Then display any remaining, non-language options.  */
1848           for (i = CL_MIN_OPTION_CLASS; i <= CL_MAX_OPTION_CLASS; i <<= 1)
1849             if (i != CL_DRIVER)
1850               print_specific_help (i, undoc_mask, 0, opts, lang_mask);
1851           opts->x_exit_after_options = true;
1852           break;
1853       }
1854 
1855     case OPT__target_help:
1856       if (lang_mask == CL_DRIVER)
1857           break;
1858 
1859       target_option_override_hook ();
1860       print_specific_help (CL_TARGET, CL_UNDOCUMENTED, 0, opts, lang_mask);
1861       opts->x_exit_after_options = true;
1862       break;
1863 
1864     case OPT__help_:
1865       {
1866           const char *a = arg;
1867           unsigned int include_flags = 0;
1868           /* Note - by default we include undocumented options when listing
1869              specific classes.  If you only want to see documented options
1870              then add ",^undocumented" to the --help= option.  E.g.:
1871 
1872              --help=target,^undocumented  */
1873           unsigned int exclude_flags = 0;
1874 
1875           if (lang_mask == CL_DRIVER)
1876             break;
1877 
1878           /* Walk along the argument string, parsing each word in turn.
1879              The format is:
1880              arg = [^]{word}[,{arg}]
1881              word = {optimizers|target|warnings|undocumented|
1882                        params|common|<language>}  */
1883           while (*a != 0)
1884             {
1885               static const struct
1886               {
1887                 const char *string;
1888                 unsigned int flag;
1889               }
1890               specifics[] =
1891               {
1892                 { "optimizers", CL_OPTIMIZATION },
1893                 { "target", CL_TARGET },
1894                 { "warnings", CL_WARNING },
1895                 { "undocumented", CL_UNDOCUMENTED },
1896                 { "params", CL_PARAMS },
1897                 { "joined", CL_JOINED },
1898                 { "separate", CL_SEPARATE },
1899                 { "common", CL_COMMON },
1900                 { NULL, 0 }
1901               };
1902               unsigned int *pflags;
1903               const char *comma;
1904               unsigned int lang_flag, specific_flag;
1905               unsigned int len;
1906               unsigned int i;
1907 
1908               if (*a == '^')
1909                 {
1910                     ++a;
1911                     if (*a == '\0')
1912                       {
1913                         error_at (loc, "missing argument to %qs", "--help=^");
1914                         break;
1915                       }
1916                     pflags = &exclude_flags;
1917                 }
1918               else
1919                 pflags = &include_flags;
1920 
1921               comma = strchr (a, ',');
1922               if (comma == NULL)
1923                 len = strlen (a);
1924               else
1925                 len = comma - a;
1926               if (len == 0)
1927                 {
1928                     a = comma + 1;
1929                     continue;
1930                 }
1931 
1932               /* Check to see if the string matches an option class name.  */
1933               for (i = 0, specific_flag = 0; specifics[i].string != NULL; i++)
1934                 if (strncasecmp (a, specifics[i].string, len) == 0)
1935                     {
1936                       specific_flag = specifics[i].flag;
1937                       break;
1938                     }
1939 
1940               /* Check to see if the string matches a language name.
1941                  Note - we rely upon the alpha-sorted nature of the entries in
1942                  the lang_names array, specifically that shorter names appear
1943                  before their longer variants.  (i.e. C before C++).  That way
1944                  when we are attempting to match --help=c for example we will
1945                  match with C first and not C++.  */
1946               for (i = 0, lang_flag = 0; i < cl_lang_count; i++)
1947                 if (strncasecmp (a, lang_names[i], len) == 0)
1948                     {
1949                       lang_flag = 1U << i;
1950                       break;
1951                     }
1952 
1953               if (specific_flag != 0)
1954                 {
1955                     if (lang_flag == 0)
1956                       *pflags |= specific_flag;
1957                     else
1958                       {
1959                         /* The option's argument matches both the start of a
1960                            language name and the start of an option class name.
1961                            We have a special case for when the user has
1962                            specified "--help=c", but otherwise we have to issue
1963                            a warning.  */
1964                         if (strncasecmp (a, "c", len) == 0)
1965                           *pflags |= lang_flag;
1966                         else
1967                           warning_at (loc, 0,
1968                                           "--help argument %q.*s is ambiguous, "
1969                                           "please be more specific",
1970                                           len, a);
1971                       }
1972                 }
1973               else if (lang_flag != 0)
1974                 *pflags |= lang_flag;
1975               else
1976                 warning_at (loc, 0,
1977                                 "unrecognized argument to --help= option: %q.*s",
1978                                 len, a);
1979 
1980               if (comma == NULL)
1981                 break;
1982               a = comma + 1;
1983             }
1984 
1985           if (include_flags)
1986             {
1987               target_option_override_hook ();
1988               print_specific_help (include_flags, exclude_flags, 0, opts,
1989                                          lang_mask);
1990             }
1991           opts->x_exit_after_options = true;
1992           break;
1993       }
1994 
1995     case OPT__version:
1996       if (lang_mask == CL_DRIVER)
1997           break;
1998 
1999       opts->x_exit_after_options = true;
2000       break;
2001 
2002     case OPT_fsanitize_:
2003       opts->x_flag_sanitize
2004           = parse_sanitizer_options (arg, loc, code,
2005                                            opts->x_flag_sanitize, value, true);
2006 
2007       /* Kernel ASan implies normal ASan but does not yet support
2008            all features.  */
2009       if (opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS)
2010           {
2011             maybe_set_param_value (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD,
2012                                          0, opts->x_param_values,
2013                                          opts_set->x_param_values);
2014             maybe_set_param_value (PARAM_ASAN_GLOBALS, 0, opts->x_param_values,
2015                                          opts_set->x_param_values);
2016             maybe_set_param_value (PARAM_ASAN_STACK, 0, opts->x_param_values,
2017                                          opts_set->x_param_values);
2018             maybe_set_param_value (PARAM_ASAN_PROTECT_ALLOCAS, 0,
2019                                          opts->x_param_values,
2020                                          opts_set->x_param_values);
2021             maybe_set_param_value (PARAM_ASAN_USE_AFTER_RETURN, 0,
2022                                          opts->x_param_values,
2023                                          opts_set->x_param_values);
2024           }
2025       break;
2026 
2027     case OPT_fsanitize_recover_:
2028       opts->x_flag_sanitize_recover
2029           = parse_sanitizer_options (arg, loc, code,
2030                                            opts->x_flag_sanitize_recover, value, true);
2031       break;
2032 
2033     case OPT_fasan_shadow_offset_:
2034       /* Deferred.  */
2035       break;
2036 
2037     case OPT_fsanitize_address_use_after_scope:
2038       opts->x_flag_sanitize_address_use_after_scope = value;
2039       break;
2040 
2041     case OPT_fsanitize_recover:
2042       if (value)
2043           opts->x_flag_sanitize_recover
2044             |= (SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT)
2045                & ~(SANITIZE_UNREACHABLE | SANITIZE_RETURN);
2046       else
2047           opts->x_flag_sanitize_recover
2048             &= ~(SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT);
2049       break;
2050 
2051     case OPT_fsanitize_coverage_:
2052       opts->x_flag_sanitize_coverage
2053           = parse_sanitizer_options (arg, loc, code,
2054                                            opts->x_flag_sanitize_coverage, value, true);
2055       break;
2056 
2057     case OPT_O:
2058     case OPT_Os:
2059     case OPT_Ofast:
2060     case OPT_Og:
2061       /* Currently handled in a prescan.  */
2062       break;
2063 
2064     case OPT_Werror:
2065       dc->warning_as_error_requested = value;
2066       break;
2067 
2068     case OPT_Werror_:
2069       if (lang_mask == CL_DRIVER)
2070           break;
2071 
2072       enable_warning_as_error (arg, value, lang_mask, handlers,
2073                                      opts, opts_set, loc, dc);
2074       break;
2075 
2076     case OPT_Wlarger_than_:
2077       opts->x_larger_than_size = value;
2078       opts->x_warn_larger_than = value != -1;
2079       break;
2080 
2081     case OPT_Wfatal_errors:
2082       dc->fatal_errors = value;
2083       break;
2084 
2085     case OPT_Wframe_larger_than_:
2086       opts->x_frame_larger_than_size = value;
2087       opts->x_warn_frame_larger_than = value != -1;
2088       break;
2089 
2090     case OPT_Wstack_usage_:
2091       opts->x_warn_stack_usage = value;
2092       opts->x_flag_stack_usage_info = value != -1;
2093       break;
2094 
2095     case OPT_Wstrict_aliasing:
2096       set_Wstrict_aliasing (opts, value);
2097       break;
2098 
2099     case OPT_Wstrict_overflow:
2100       opts->x_warn_strict_overflow = (value
2101                                               ? (int) WARN_STRICT_OVERFLOW_CONDITIONAL
2102                                               : 0);
2103       break;
2104 
2105     case OPT_Wsystem_headers:
2106       dc->dc_warn_system_headers = value;
2107       break;
2108 
2109     case OPT_aux_info:
2110       opts->x_flag_gen_aux_info = 1;
2111       break;
2112 
2113     case OPT_auxbase_strip:
2114       {
2115           char *tmp = xstrdup (arg);
2116           strip_off_ending (tmp, strlen (tmp));
2117           if (tmp[0])
2118             opts->x_aux_base_name = tmp;
2119           else
2120             free (tmp);
2121       }
2122       break;
2123 
2124     case OPT_d:
2125       decode_d_option (arg, opts, loc, dc);
2126       break;
2127 
2128     case OPT_fcall_used_:
2129     case OPT_fcall_saved_:
2130       /* Deferred.  */
2131       break;
2132 
2133     case OPT_fdbg_cnt_:
2134       /* Deferred.  */
2135       break;
2136 
2137     case OPT_fdbg_cnt_list:
2138       /* Deferred.  */
2139       opts->x_exit_after_options = true;
2140       break;
2141 
2142     case OPT_fdebug_prefix_map_:
2143     case OPT_ffile_prefix_map_:
2144       /* Deferred.  */
2145       break;
2146 
2147     case OPT_fdiagnostics_show_location_:
2148       diagnostic_prefixing_rule (dc) = (diagnostic_prefixing_rule_t) value;
2149       break;
2150 
2151     case OPT_fdiagnostics_show_caret:
2152       dc->show_caret = value;
2153       break;
2154 
2155     case OPT_fdiagnostics_color_:
2156       diagnostic_color_init (dc, value);
2157       break;
2158 
2159     case OPT_fdiagnostics_parseable_fixits:
2160       dc->parseable_fixits_p = value;
2161       break;
2162 
2163     case OPT_fdiagnostics_show_option:
2164       dc->show_option_requested = value;
2165       break;
2166 
2167     case OPT_fdump_:
2168       /* Deferred.  */
2169       break;
2170 
2171     case OPT_ffast_math:
2172       set_fast_math_flags (opts, value);
2173       break;
2174 
2175     case OPT_funsafe_math_optimizations:
2176       set_unsafe_math_optimizations_flags (opts, value);
2177       break;
2178 
2179     case OPT_ffixed_:
2180       /* Deferred.  */
2181       break;
2182 
2183     case OPT_finline_limit_:
2184       set_param_value ("max-inline-insns-single", value / 2,
2185                            opts->x_param_values, opts_set->x_param_values);
2186       set_param_value ("max-inline-insns-auto", value / 2,
2187                            opts->x_param_values, opts_set->x_param_values);
2188       break;
2189 
2190     case OPT_finstrument_functions_exclude_function_list_:
2191       add_comma_separated_to_vector
2192           (&opts->x_flag_instrument_functions_exclude_functions, arg);
2193       break;
2194 
2195     case OPT_finstrument_functions_exclude_file_list_:
2196       add_comma_separated_to_vector
2197           (&opts->x_flag_instrument_functions_exclude_files, arg);
2198       break;
2199 
2200     case OPT_fmessage_length_:
2201       pp_set_line_maximum_length (dc->printer, value);
2202       diagnostic_set_caret_max_width (dc, value);
2203       break;
2204 
2205     case OPT_fopt_info:
2206     case OPT_fopt_info_:
2207       /* Deferred.  */
2208       break;
2209 
2210     case OPT_foffload_:
2211       {
2212           const char *p = arg;
2213           opts->x_flag_disable_hsa = true;
2214           while (*p != 0)
2215             {
2216               const char *comma = strchr (p, ',');
2217 
2218               if ((strncmp (p, "disable", 7) == 0)
2219                     && (p[7] == ',' || p[7] == '\0'))
2220                 {
2221                     opts->x_flag_disable_hsa = true;
2222                     break;
2223                 }
2224 
2225               if ((strncmp (p, "hsa", 3) == 0)
2226                     && (p[3] == ',' || p[3] == '\0'))
2227                 {
2228 #ifdef ENABLE_HSA
2229                     opts->x_flag_disable_hsa = false;
2230 #else
2231                     sorry ("HSA has not been enabled during configuration");
2232 #endif
2233                 }
2234               if (!comma)
2235                 break;
2236               p = comma + 1;
2237             }
2238           break;
2239       }
2240 
2241 #ifndef ACCEL_COMPILER
2242     case OPT_foffload_abi_:
2243       error_at (loc, "%<-foffload-abi%> option can be specified only for "
2244                     "offload compiler");
2245       break;
2246 #endif
2247 
2248     case OPT_fpack_struct_:
2249       if (value <= 0 || (value & (value - 1)) || value > 16)
2250           error_at (loc,
2251                       "structure alignment must be a small power of two, not %d",
2252                       value);
2253       else
2254           opts->x_initial_max_fld_align = value;
2255       break;
2256 
2257     case OPT_fplugin_:
2258     case OPT_fplugin_arg_:
2259       /* Deferred.  */
2260       break;
2261 
2262     case OPT_fprofile_use_:
2263       opts->x_profile_data_prefix = xstrdup (arg);
2264       opts->x_flag_profile_use = true;
2265       value = true;
2266       /* No break here - do -fprofile-use processing. */
2267       /* FALLTHRU */
2268     case OPT_fprofile_use:
2269       enable_fdo_optimizations (opts, opts_set, value);
2270       if (!opts_set->x_flag_profile_reorder_functions)
2271             opts->x_flag_profile_reorder_functions = value;
2272           /* Indirect call profiling should do all useful transformations
2273              speculative devirtualization does.  */
2274       if (!opts_set->x_flag_devirtualize_speculatively
2275             && opts->x_flag_value_profile_transformations)
2276           opts->x_flag_devirtualize_speculatively = false;
2277       break;
2278 
2279     case OPT_fauto_profile_:
2280       opts->x_auto_profile_file = xstrdup (arg);
2281       opts->x_flag_auto_profile = true;
2282       value = true;
2283       /* No break here - do -fauto-profile processing. */
2284       /* FALLTHRU */
2285     case OPT_fauto_profile:
2286       enable_fdo_optimizations (opts, opts_set, value);
2287       if (!opts_set->x_flag_profile_correction)
2288           opts->x_flag_profile_correction = value;
2289       maybe_set_param_value (
2290           PARAM_EARLY_INLINER_MAX_ITERATIONS, 10,
2291           opts->x_param_values, opts_set->x_param_values);
2292       break;
2293 
2294     case OPT_fprofile_generate_:
2295       opts->x_profile_data_prefix = xstrdup (arg);
2296       value = true;
2297       /* No break here - do -fprofile-generate processing. */
2298       /* FALLTHRU */
2299     case OPT_fprofile_generate:
2300       if (!opts_set->x_profile_arc_flag)
2301           opts->x_profile_arc_flag = value;
2302       if (!opts_set->x_flag_profile_values)
2303           opts->x_flag_profile_values = value;
2304       if (!opts_set->x_flag_inline_functions)
2305           opts->x_flag_inline_functions = value;
2306       if (!opts_set->x_flag_ipa_bit_cp)
2307           opts->x_flag_ipa_bit_cp = value;
2308       /* FIXME: Instrumentation we insert makes ipa-reference bitmaps
2309            quadratic.  Disable the pass until better memory representation
2310            is done.  */
2311       if (!opts_set->x_flag_ipa_reference)
2312         opts->x_flag_ipa_reference = false;
2313       break;
2314 
2315     case OPT_fpatchable_function_entry_:
2316       {
2317           char *patch_area_arg = xstrdup (arg);
2318           char *comma = strchr (patch_area_arg, ',');
2319           if (comma)
2320             {
2321               *comma = '\0';
2322               function_entry_patch_area_size =
2323                 integral_argument (patch_area_arg);
2324               function_entry_patch_area_start =
2325                 integral_argument (comma + 1);
2326             }
2327           else
2328             {
2329               function_entry_patch_area_size =
2330                 integral_argument (patch_area_arg);
2331               function_entry_patch_area_start = 0;
2332             }
2333           if (function_entry_patch_area_size < 0
2334               || function_entry_patch_area_start < 0
2335               || function_entry_patch_area_size
2336                     < function_entry_patch_area_start)
2337             error ("invalid arguments for %<-fpatchable_function_entry%>");
2338           free (patch_area_arg);
2339       }
2340       break;
2341 
2342     case OPT_ftree_vectorize:
2343       /* Automatically sets -ftree-loop-vectorize and
2344            -ftree-slp-vectorize.  Nothing more to do here.  */
2345       break;
2346     case OPT_fshow_column:
2347       dc->show_column = value;
2348       break;
2349 
2350     case OPT_frandom_seed:
2351       /* The real switch is -fno-random-seed.  */
2352       if (value)
2353           return false;
2354       /* Deferred.  */
2355       break;
2356 
2357     case OPT_frandom_seed_:
2358       /* Deferred.  */
2359       break;
2360 
2361     case OPT_fsched_verbose_:
2362 #ifdef INSN_SCHEDULING
2363       /* Handled with Var in common.opt.  */
2364       break;
2365 #else
2366       return false;
2367 #endif
2368 
2369     case OPT_fsched_stalled_insns_:
2370       opts->x_flag_sched_stalled_insns = value;
2371       if (opts->x_flag_sched_stalled_insns == 0)
2372           opts->x_flag_sched_stalled_insns = -1;
2373       break;
2374 
2375     case OPT_fsched_stalled_insns_dep_:
2376       opts->x_flag_sched_stalled_insns_dep = value;
2377       break;
2378 
2379     case OPT_fstack_check_:
2380       if (!strcmp (arg, "no"))
2381           opts->x_flag_stack_check = NO_STACK_CHECK;
2382       else if (!strcmp (arg, "generic"))
2383           /* This is the old stack checking method.  */
2384           opts->x_flag_stack_check = STACK_CHECK_BUILTIN
2385                                  ? FULL_BUILTIN_STACK_CHECK
2386                                  : GENERIC_STACK_CHECK;
2387       else if (!strcmp (arg, "specific"))
2388           /* This is the new stack checking method.  */
2389           opts->x_flag_stack_check = STACK_CHECK_BUILTIN
2390                                  ? FULL_BUILTIN_STACK_CHECK
2391                                  : STACK_CHECK_STATIC_BUILTIN
2392                                    ? STATIC_BUILTIN_STACK_CHECK
2393                                    : GENERIC_STACK_CHECK;
2394       else
2395           warning_at (loc, 0, "unknown stack check parameter %qs", arg);
2396       break;
2397 
2398     case OPT_fstack_limit:
2399       /* The real switch is -fno-stack-limit.  */
2400       if (value)
2401           return false;
2402       /* Deferred.  */
2403       break;
2404 
2405     case OPT_fstack_limit_register_:
2406     case OPT_fstack_limit_symbol_:
2407       /* Deferred.  */
2408       break;
2409 
2410     case OPT_fstack_usage:
2411       opts->x_flag_stack_usage = value;
2412       opts->x_flag_stack_usage_info = value != 0;
2413       break;
2414 
2415     case OPT_g:
2416       set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, arg, opts, opts_set,
2417                        loc);
2418       break;
2419 
2420     case OPT_gdwarf:
2421       if (arg && strlen (arg) != 0)
2422         {
2423           error_at (loc, "%<-gdwarf%s%> is ambiguous; "
2424                     "use %<-gdwarf-%s%> for DWARF version "
2425                     "or %<-gdwarf -g%s%> for debug level", arg, arg, arg);
2426           break;
2427         }
2428       else
2429         value = opts->x_dwarf_version;
2430 
2431       /* FALLTHRU */
2432     case OPT_gdwarf_:
2433       if (value < 2 || value > 5)
2434           error_at (loc, "dwarf version %d is not supported", value);
2435       else
2436           opts->x_dwarf_version = value;
2437       set_debug_level (DWARF2_DEBUG, false, "", opts, opts_set, loc);
2438       break;
2439 
2440     case OPT_gsplit_dwarf:
2441       set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, "", opts, opts_set,
2442                            loc);
2443       break;
2444 
2445     case OPT_ggdb:
2446       set_debug_level (NO_DEBUG, 2, arg, opts, opts_set, loc);
2447       break;
2448 
2449     case OPT_gstabs:
2450     case OPT_gstabs_:
2451       set_debug_level (DBX_DEBUG, code == OPT_gstabs_, arg, opts, opts_set,
2452                            loc);
2453       break;
2454 
2455     case OPT_gvms:
2456       set_debug_level (VMS_DEBUG, false, arg, opts, opts_set, loc);
2457       break;
2458 
2459     case OPT_gxcoff:
2460     case OPT_gxcoff_:
2461       set_debug_level (XCOFF_DEBUG, code == OPT_gxcoff_, arg, opts, opts_set,
2462                            loc);
2463       break;
2464 
2465     case OPT_gz:
2466     case OPT_gz_:
2467       /* Handled completely via specs.  */
2468       break;
2469 
2470     case OPT_pedantic_errors:
2471       dc->pedantic_errors = 1;
2472       control_warning_option (OPT_Wpedantic, DK_ERROR, NULL, value,
2473                                     loc, lang_mask,
2474                                     handlers, opts, opts_set,
2475                               dc);
2476       break;
2477 
2478     case OPT_flto:
2479       opts->x_flag_lto = value ? "" : NULL;
2480       break;
2481 
2482     case OPT_w:
2483       dc->dc_inhibit_warnings = true;
2484       break;
2485 
2486     case OPT_fmax_errors_:
2487       dc->max_errors = value;
2488       break;
2489 
2490     case OPT_fuse_ld_bfd:
2491     case OPT_fuse_ld_gold:
2492     case OPT_fuse_linker_plugin:
2493       /* No-op. Used by the driver and passed to us because it starts with f.*/
2494       break;
2495 
2496     case OPT_fwrapv:
2497       if (value)
2498           opts->x_flag_trapv = 0;
2499       break;
2500 
2501     case OPT_ftrapv:
2502       if (value)
2503           opts->x_flag_wrapv = 0;
2504       break;
2505 
2506     case OPT_fstrict_overflow:
2507       opts->x_flag_wrapv = !value;
2508       opts->x_flag_wrapv_pointer = !value;
2509       if (!value)
2510           opts->x_flag_trapv = 0;
2511       break;
2512 
2513     case OPT_fipa_icf:
2514       opts->x_flag_ipa_icf_functions = value;
2515       opts->x_flag_ipa_icf_variables = value;
2516       break;
2517 
2518     default:
2519       /* If the flag was handled in a standard way, assume the lack of
2520            processing here is intentional.  */
2521       gcc_assert (option_flag_var (scode, opts));
2522       break;
2523     }
2524 
2525   common_handle_option_auto (opts, opts_set, decoded, lang_mask, kind,
2526                              loc, handlers, dc);
2527   return true;
2528 }
2529 
2530 /* Handle --param NAME=VALUE.  */
2531 static void
2532 handle_param (struct gcc_options *opts, struct gcc_options *opts_set,
2533                 location_t loc, const char *carg)
2534 {
2535   char *equal, *arg;
2536   int value;
2537 
2538   arg = xstrdup (carg);
2539   equal = strchr (arg, '=');
2540   if (!equal)
2541     error_at (loc, "%s: --param arguments should be of the form NAME=VALUE",
2542                 arg);
2543   else
2544     {
2545       *equal = '\0';
2546 
2547       enum compiler_param index;
2548       if (!find_param (arg, &index))
2549           {
2550             const char *suggestion = find_param_fuzzy (arg);
2551             if (suggestion)
2552               error_at (loc, "invalid --param name %qs; did you mean %qs?",
2553                           arg, suggestion);
2554             else
2555               error_at (loc, "invalid --param name %qs", arg);
2556           }
2557       else
2558           {
2559             if (!param_string_value_p (index, equal + 1, &value))
2560               value = integral_argument (equal + 1);
2561 
2562             if (value == -1)
2563               error_at (loc, "invalid --param value %qs", equal + 1);
2564             else
2565               set_param_value (arg, value,
2566                                    opts->x_param_values, opts_set->x_param_values);
2567           }
2568     }
2569 
2570   free (arg);
2571 }
2572 
2573 /* Used to set the level of strict aliasing warnings in OPTS,
2574    when no level is specified (i.e., when -Wstrict-aliasing, and not
2575    -Wstrict-aliasing=level was given).
2576    ONOFF is assumed to take value 1 when -Wstrict-aliasing is specified,
2577    and 0 otherwise.  After calling this function, wstrict_aliasing will be
2578    set to the default value of -Wstrict_aliasing=level, currently 3.  */
2579 static void
2580 set_Wstrict_aliasing (struct gcc_options *opts, int onoff)
2581 {
2582   gcc_assert (onoff == 0 || onoff == 1);
2583   if (onoff != 0)
2584     opts->x_warn_strict_aliasing = 3;
2585   else
2586     opts->x_warn_strict_aliasing = 0;
2587 }
2588 
2589 /* The following routines are useful in setting all the flags that
2590    -ffast-math and -fno-fast-math imply.  */
2591 static void
2592 set_fast_math_flags (struct gcc_options *opts, int set)
2593 {
2594   if (!opts->frontend_set_flag_unsafe_math_optimizations)
2595     {
2596       opts->x_flag_unsafe_math_optimizations = set;
2597       set_unsafe_math_optimizations_flags (opts, set);
2598     }
2599   if (!opts->frontend_set_flag_finite_math_only)
2600     opts->x_flag_finite_math_only = set;
2601   if (!opts->frontend_set_flag_errno_math)
2602     opts->x_flag_errno_math = !set;
2603   if (set)
2604     {
2605       if (opts->frontend_set_flag_excess_precision_cmdline
2606             == EXCESS_PRECISION_DEFAULT)
2607           opts->x_flag_excess_precision_cmdline
2608             = set ? EXCESS_PRECISION_FAST : EXCESS_PRECISION_DEFAULT;
2609       if (!opts->frontend_set_flag_signaling_nans)
2610           opts->x_flag_signaling_nans = 0;
2611       if (!opts->frontend_set_flag_rounding_math)
2612           opts->x_flag_rounding_math = 0;
2613       if (!opts->frontend_set_flag_cx_limited_range)
2614           opts->x_flag_cx_limited_range = 1;
2615     }
2616 }
2617 
2618 /* When -funsafe-math-optimizations is set the following
2619    flags are set as well.  */
2620 static void
2621 set_unsafe_math_optimizations_flags (struct gcc_options *opts, int set)
2622 {
2623   if (!opts->frontend_set_flag_trapping_math)
2624     opts->x_flag_trapping_math = !set;
2625   if (!opts->frontend_set_flag_signed_zeros)
2626     opts->x_flag_signed_zeros = !set;
2627   if (!opts->frontend_set_flag_associative_math)
2628     opts->x_flag_associative_math = set;
2629   if (!opts->frontend_set_flag_reciprocal_math)
2630     opts->x_flag_reciprocal_math = set;
2631 }
2632 
2633 /* Return true iff flags in OPTS are set as if -ffast-math.  */
2634 bool
2635 fast_math_flags_set_p (const struct gcc_options *opts)
2636 {
2637   return (!opts->x_flag_trapping_math
2638             && opts->x_flag_unsafe_math_optimizations
2639             && opts->x_flag_finite_math_only
2640             && !opts->x_flag_signed_zeros
2641             && !opts->x_flag_errno_math
2642             && opts->x_flag_excess_precision_cmdline
2643                == EXCESS_PRECISION_FAST);
2644 }
2645 
2646 /* Return true iff flags are set as if -ffast-math but using the flags stored
2647    in the struct cl_optimization structure.  */
2648 bool
2649 fast_math_flags_struct_set_p (struct cl_optimization *opt)
2650 {
2651   return (!opt->x_flag_trapping_math
2652             && opt->x_flag_unsafe_math_optimizations
2653             && opt->x_flag_finite_math_only
2654             && !opt->x_flag_signed_zeros
2655             && !opt->x_flag_errno_math);
2656 }
2657 
2658 /* Handle a debug output -g switch for options OPTS
2659    (OPTS_SET->x_write_symbols storing whether a debug type was passed
2660    explicitly), location LOC.  EXTENDED is true or false to support
2661    extended output (2 is special and means "-ggdb" was given).  */
2662 static void
2663 set_debug_level (enum debug_info_type type, int extended, const char *arg,
2664                      struct gcc_options *opts, struct gcc_options *opts_set,
2665                      location_t loc)
2666 {
2667   opts->x_use_gnu_debug_info_extensions = extended;
2668 
2669   if (type == NO_DEBUG)
2670     {
2671       if (opts->x_write_symbols == NO_DEBUG)
2672           {
2673             opts->x_write_symbols = PREFERRED_DEBUGGING_TYPE;
2674 
2675             if (extended == 2)
2676               {
2677 #if defined DWARF2_DEBUGGING_INFO || defined DWARF2_LINENO_DEBUGGING_INFO
2678                 opts->x_write_symbols = DWARF2_DEBUG;
2679 #elif defined DBX_DEBUGGING_INFO
2680                 opts->x_write_symbols = DBX_DEBUG;
2681 #endif
2682               }
2683 
2684             if (opts->x_write_symbols == NO_DEBUG)
2685               warning_at (loc, 0, "target system does not support debug output");
2686           }
2687     }
2688   else
2689     {
2690       /* Does it conflict with an already selected type?  */
2691       if (opts_set->x_write_symbols != NO_DEBUG
2692             && opts->x_write_symbols != NO_DEBUG
2693             && type != opts->x_write_symbols)
2694           error_at (loc, "debug format %qs conflicts with prior selection",
2695                       debug_type_names[type]);
2696       opts->x_write_symbols = type;
2697       opts_set->x_write_symbols = type;
2698     }
2699 
2700   /* A debug flag without a level defaults to level 2.
2701      If off or at level 1, set it to level 2, but if already
2702      at level 3, don't lower it.  */
2703   if (*arg == '\0')
2704     {
2705       if (opts->x_debug_info_level < DINFO_LEVEL_NORMAL)
2706           opts->x_debug_info_level = DINFO_LEVEL_NORMAL;
2707     }
2708   else
2709     {
2710       int argval = integral_argument (arg);
2711       if (argval == -1)
2712           error_at (loc, "unrecognized debug output level %qs", arg);
2713       else if (argval > 3)
2714           error_at (loc, "debug output level %qs is too high", arg);
2715       else
2716           opts->x_debug_info_level = (enum debug_info_levels) argval;
2717     }
2718 }
2719 
2720 /* Arrange to dump core on error for diagnostic context DC.  (The
2721    regular error message is still printed first, except in the case of
2722    abort ().)  */
2723 
2724 static void
2725 setup_core_dumping (diagnostic_context *dc)
2726 {
2727 #ifdef SIGABRT
2728   signal (SIGABRT, SIG_DFL);
2729 #endif
2730 #if defined(HAVE_SETRLIMIT)
2731   {
2732     struct rlimit rlim;
2733     if (getrlimit (RLIMIT_CORE, &rlim) != 0)
2734       fatal_error (input_location, "getting core file size maximum limit: %m");
2735     rlim.rlim_cur = rlim.rlim_max;
2736     if (setrlimit (RLIMIT_CORE, &rlim) != 0)
2737       fatal_error (input_location,
2738                        "setting core file size limit to maximum: %m");
2739   }
2740 #endif
2741   diagnostic_abort_on_error (dc);
2742 }
2743 
2744 /* Parse a -d<ARG> command line switch for OPTS, location LOC,
2745    diagnostic context DC.  */
2746 
2747 static void
2748 decode_d_option (const char *arg, struct gcc_options *opts,
2749                      location_t loc, diagnostic_context *dc)
2750 {
2751   int c;
2752 
2753   while (*arg)
2754     switch (c = *arg++)
2755       {
2756       case 'A':
2757           opts->x_flag_debug_asm = 1;
2758           break;
2759       case 'p':
2760           opts->x_flag_print_asm_name = 1;
2761           break;
2762       case 'P':
2763           opts->x_flag_dump_rtl_in_asm = 1;
2764           opts->x_flag_print_asm_name = 1;
2765           break;
2766       case 'x':
2767           opts->x_rtl_dump_and_exit = 1;
2768           break;
2769       case 'D':     /* These are handled by the preprocessor.  */
2770       case 'I':
2771       case 'M':
2772       case 'N':
2773       case 'U':
2774           break;
2775       case 'H':
2776           setup_core_dumping (dc);
2777           break;
2778       case 'a':
2779           opts->x_flag_dump_all_passed = true;
2780           break;
2781 
2782       default:
2783             warning_at (loc, 0, "unrecognized gcc debugging option: %c", c);
2784           break;
2785       }
2786 }
2787 
2788 /* Enable (or disable if VALUE is 0) a warning option ARG (language
2789    mask LANG_MASK, option handlers HANDLERS) as an error for option
2790    structures OPTS and OPTS_SET, diagnostic context DC (possibly
2791    NULL), location LOC.  This is used by -Werror=.  */
2792 
2793 static void
2794 enable_warning_as_error (const char *arg, int value, unsigned int lang_mask,
2795                                const struct cl_option_handlers *handlers,
2796                                struct gcc_options *opts,
2797                                struct gcc_options *opts_set,
2798                                location_t loc, diagnostic_context *dc)
2799 {
2800   char *new_option;
2801   int option_index;
2802 
2803   new_option = XNEWVEC (char, strlen (arg) + 2);
2804   new_option[0] = 'W';
2805   strcpy (new_option + 1, arg);
2806   option_index = find_opt (new_option, lang_mask);
2807   if (option_index == OPT_SPECIAL_unknown)
2808     error_at (loc, "-Werror=%s: no option -%s", arg, new_option);
2809   else if (!(cl_options[option_index].flags & CL_WARNING))
2810     error_at (loc, "-Werror=%s: -%s is not an option that controls warnings",
2811                 arg, new_option);
2812   else
2813     {
2814       const diagnostic_t kind = value ? DK_ERROR : DK_WARNING;
2815       const char *arg = NULL;
2816 
2817       if (cl_options[option_index].flags & CL_JOINED)
2818           arg = new_option + cl_options[option_index].opt_len;
2819       control_warning_option (option_index, (int) kind, arg, value,
2820                                     loc, lang_mask,
2821                                     handlers, opts, opts_set, dc);
2822     }
2823   free (new_option);
2824 }
2825 
2826 /* Return malloced memory for the name of the option OPTION_INDEX
2827    which enabled a diagnostic (context CONTEXT), originally of type
2828    ORIG_DIAG_KIND but possibly converted to DIAG_KIND by options such
2829    as -Werror.  */
2830 
2831 char *
2832 option_name (diagnostic_context *context, int option_index,
2833                diagnostic_t orig_diag_kind, diagnostic_t diag_kind)
2834 {
2835   if (option_index)
2836     {
2837       /* A warning classified as an error.  */
2838       if ((orig_diag_kind == DK_WARNING || orig_diag_kind == DK_PEDWARN)
2839             && diag_kind == DK_ERROR)
2840           return concat (cl_options[OPT_Werror_].opt_text,
2841                            /* Skip over "-W".  */
2842                            cl_options[option_index].opt_text + 2,
2843                            NULL);
2844       /* A warning with option.  */
2845       else
2846           return xstrdup (cl_options[option_index].opt_text);
2847     }
2848   /* A warning without option classified as an error.  */
2849   else if ((orig_diag_kind == DK_WARNING || orig_diag_kind == DK_PEDWARN
2850               || diag_kind == DK_WARNING)
2851              && context->warning_as_error_requested)
2852     return xstrdup (cl_options[OPT_Werror].opt_text);
2853   else
2854     return NULL;
2855 }
2856