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