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