[PATCH] RISC-V: Move UNSPEC_SSP_SET and UNSPEC_SSP_TEST to correct enum
[gcc.git] / gcc / opts.cc
blob23900c7b1c04f400ba318de3d7fc1f9103df631c
1 /* Command line option handling.
2 Copyright (C) 2002-2025 Free Software Foundation, Inc.
3 Contributed by Neil Booth.
5 This file is part of GCC.
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.
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.
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/>. */
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 "diagnostic-format.h"
36 #include "version.h"
37 #include "selftest.h"
38 #include "file-prefix-map.h"
40 /* In this file all option sets are explicit. */
41 #undef OPTION_SET_P
43 /* Set by -fcanon-prefix-map. */
44 bool flag_canon_prefix_map;
46 /* Set by finish_options when flag_stack_protector was set only because of
47 -fhardened. Yuck. */
48 bool flag_stack_protector_set_by_fhardened_p;
50 static void set_Wstrict_aliasing (struct gcc_options *opts, int onoff);
52 /* Names of fundamental debug info formats indexed by enum
53 debug_info_type. */
55 const char *const debug_type_names[] =
57 "none", "dwarf-2", "vms", "ctf", "btf", "codeview"
60 /* Bitmasks of fundamental debug info formats indexed by enum
61 debug_info_type. */
63 static uint32_t debug_type_masks[] =
65 NO_DEBUG, DWARF2_DEBUG, VMS_DEBUG,
66 CTF_DEBUG, BTF_DEBUG, CODEVIEW_DEBUG
69 /* Names of the set of debug formats requested by user. Updated and accessed
70 via debug_set_names. */
72 static char df_set_names[sizeof "none dwarf-2 vms ctf btf codeview"];
74 /* Get enum debug_info_type of the specified debug format, for error messages.
75 Can be used only for individual debug format types. */
77 enum debug_info_type
78 debug_set_to_format (uint32_t debug_info_set)
80 int idx = 0;
81 enum debug_info_type dinfo_type = DINFO_TYPE_NONE;
82 /* Find first set bit. */
83 if (debug_info_set)
84 idx = exact_log2 (debug_info_set & - debug_info_set);
85 /* Check that only one bit is set, if at all. This function is meant to be
86 used only for vanilla debug_info_set bitmask values, i.e. for individual
87 debug format types upto DINFO_TYPE_MAX. */
88 gcc_assert ((debug_info_set & (debug_info_set - 1)) == 0);
89 dinfo_type = (enum debug_info_type)idx;
90 gcc_assert (dinfo_type <= DINFO_TYPE_MAX);
91 return dinfo_type;
94 /* Get the number of debug formats enabled for output. */
96 unsigned int
97 debug_set_count (uint32_t w_symbols)
99 unsigned int count = 0;
100 while (w_symbols)
102 ++ count;
103 w_symbols &= ~ (w_symbols & - w_symbols);
105 return count;
108 /* Get the names of the debug formats enabled for output. */
110 const char *
111 debug_set_names (uint32_t w_symbols)
113 uint32_t df_mask = 0;
114 /* Reset the string to be returned. */
115 memset (df_set_names, 0, sizeof (df_set_names));
116 /* Get the popcount. */
117 int num_set_df = debug_set_count (w_symbols);
118 /* Iterate over the debug formats. Add name string for those enabled. */
119 for (int i = DINFO_TYPE_NONE; i <= DINFO_TYPE_MAX; i++)
121 df_mask = debug_type_masks[i];
122 if (w_symbols & df_mask)
124 strcat (df_set_names, debug_type_names[i]);
125 num_set_df--;
126 if (num_set_df)
127 strcat (df_set_names, " ");
128 else
129 break;
131 else if (!w_symbols)
133 /* No debug formats enabled. */
134 gcc_assert (i == DINFO_TYPE_NONE);
135 strcat (df_set_names, debug_type_names[i]);
136 break;
139 return df_set_names;
142 /* Return TRUE iff BTF debug info is enabled. */
144 bool
145 btf_debuginfo_p ()
147 return (write_symbols & BTF_DEBUG);
150 /* Return TRUE iff BTF with CO-RE debug info is enabled. */
152 bool
153 btf_with_core_debuginfo_p ()
155 return (write_symbols & BTF_WITH_CORE_DEBUG);
158 /* Return TRUE iff CTF debug info is enabled. */
160 bool
161 ctf_debuginfo_p ()
163 return (write_symbols & CTF_DEBUG);
166 /* Return TRUE iff CodeView debug info is enabled. */
168 bool
169 codeview_debuginfo_p ()
171 return (write_symbols & CODEVIEW_DEBUG);
174 /* Return TRUE iff dwarf2 debug info is enabled. */
176 bool
177 dwarf_debuginfo_p (struct gcc_options *opts)
179 return (opts->x_write_symbols & DWARF2_DEBUG);
182 /* Return true iff the debug info format is to be generated based on DWARF
183 DIEs (like CTF and BTF debug info formats). */
185 bool dwarf_based_debuginfo_p ()
187 return ((write_symbols & CTF_DEBUG)
188 || (write_symbols & BTF_DEBUG)
189 || (write_symbols & CODEVIEW_DEBUG));
192 /* All flag uses below need to explicitely reference the option sets
193 to operate on. */
194 #define global_options DO_NOT_USE
195 #define global_options_set DO_NOT_USE
197 /* Parse the -femit-struct-debug-detailed option value
198 and set the flag variables. */
200 #define MATCH( prefix, string ) \
201 ((strncmp (prefix, string, sizeof prefix - 1) == 0) \
202 ? ((string += sizeof prefix - 1), 1) : 0)
204 void
205 set_struct_debug_option (struct gcc_options *opts, location_t loc,
206 const char *spec)
208 /* various labels for comparison */
209 static const char dfn_lbl[] = "dfn:", dir_lbl[] = "dir:", ind_lbl[] = "ind:";
210 static const char ord_lbl[] = "ord:", gen_lbl[] = "gen:";
211 static const char none_lbl[] = "none", any_lbl[] = "any";
212 static const char base_lbl[] = "base", sys_lbl[] = "sys";
214 enum debug_struct_file files = DINFO_STRUCT_FILE_ANY;
215 /* Default is to apply to as much as possible. */
216 enum debug_info_usage usage = DINFO_USAGE_NUM_ENUMS;
217 int ord = 1, gen = 1;
219 /* What usage? */
220 if (MATCH (dfn_lbl, spec))
221 usage = DINFO_USAGE_DFN;
222 else if (MATCH (dir_lbl, spec))
223 usage = DINFO_USAGE_DIR_USE;
224 else if (MATCH (ind_lbl, spec))
225 usage = DINFO_USAGE_IND_USE;
227 /* Generics or not? */
228 if (MATCH (ord_lbl, spec))
229 gen = 0;
230 else if (MATCH (gen_lbl, spec))
231 ord = 0;
233 /* What allowable environment? */
234 if (MATCH (none_lbl, spec))
235 files = DINFO_STRUCT_FILE_NONE;
236 else if (MATCH (any_lbl, spec))
237 files = DINFO_STRUCT_FILE_ANY;
238 else if (MATCH (sys_lbl, spec))
239 files = DINFO_STRUCT_FILE_SYS;
240 else if (MATCH (base_lbl, spec))
241 files = DINFO_STRUCT_FILE_BASE;
242 else
243 error_at (loc,
244 "argument %qs to %<-femit-struct-debug-detailed%> "
245 "not recognized",
246 spec);
248 /* Effect the specification. */
249 if (usage == DINFO_USAGE_NUM_ENUMS)
251 if (ord)
253 opts->x_debug_struct_ordinary[DINFO_USAGE_DFN] = files;
254 opts->x_debug_struct_ordinary[DINFO_USAGE_DIR_USE] = files;
255 opts->x_debug_struct_ordinary[DINFO_USAGE_IND_USE] = files;
257 if (gen)
259 opts->x_debug_struct_generic[DINFO_USAGE_DFN] = files;
260 opts->x_debug_struct_generic[DINFO_USAGE_DIR_USE] = files;
261 opts->x_debug_struct_generic[DINFO_USAGE_IND_USE] = files;
264 else
266 if (ord)
267 opts->x_debug_struct_ordinary[usage] = files;
268 if (gen)
269 opts->x_debug_struct_generic[usage] = files;
272 if (*spec == ',')
273 set_struct_debug_option (opts, loc, spec+1);
274 else
276 /* No more -femit-struct-debug-detailed specifications.
277 Do final checks. */
278 if (*spec != '\0')
279 error_at (loc,
280 "argument %qs to %<-femit-struct-debug-detailed%> unknown",
281 spec);
282 if (opts->x_debug_struct_ordinary[DINFO_USAGE_DIR_USE]
283 < opts->x_debug_struct_ordinary[DINFO_USAGE_IND_USE]
284 || opts->x_debug_struct_generic[DINFO_USAGE_DIR_USE]
285 < opts->x_debug_struct_generic[DINFO_USAGE_IND_USE])
286 error_at (loc,
287 "%<-femit-struct-debug-detailed=dir:...%> must allow "
288 "at least as much as "
289 "%<-femit-struct-debug-detailed=ind:...%>");
293 /* Strip off a legitimate source ending from the input string NAME of
294 length LEN. Rather than having to know the names used by all of
295 our front ends, we strip off an ending of a period followed by
296 up to fource characters. (C++ uses ".cpp".) */
298 void
299 strip_off_ending (char *name, int len)
301 int i;
302 for (i = 2; i < 5 && len > i; i++)
304 if (name[len - i] == '.')
306 name[len - i] = '\0';
307 break;
312 /* Find the base name of a path, stripping off both directories and
313 a single final extension. */
315 base_of_path (const char *path, const char **base_out)
317 const char *base = path;
318 const char *dot = 0;
319 const char *p = path;
320 char c = *p;
321 while (c)
323 if (IS_DIR_SEPARATOR (c))
325 base = p + 1;
326 dot = 0;
328 else if (c == '.')
329 dot = p;
330 c = *++p;
332 if (!dot)
333 dot = p;
334 *base_out = base;
335 return dot - base;
338 /* What to print when a switch has no documentation. */
339 static const char undocumented_msg[] = N_("This option lacks documentation.");
340 static const char use_diagnosed_msg[] = N_("Uses of this option are diagnosed.");
342 typedef char *char_p; /* For DEF_VEC_P. */
344 static void set_debug_level (uint32_t dinfo, int extended,
345 const char *arg, struct gcc_options *opts,
346 struct gcc_options *opts_set,
347 location_t loc);
348 static void set_fast_math_flags (struct gcc_options *opts, int set);
349 static void decode_d_option (const char *arg, struct gcc_options *opts,
350 location_t loc, diagnostic_context *dc);
351 static void set_unsafe_math_optimizations_flags (struct gcc_options *opts,
352 int set);
353 static void enable_warning_as_error (const char *arg, int value,
354 unsigned int lang_mask,
355 const struct cl_option_handlers *handlers,
356 struct gcc_options *opts,
357 struct gcc_options *opts_set,
358 location_t loc,
359 diagnostic_context *dc);
361 /* Handle a back-end option; arguments and return value as for
362 handle_option. */
364 bool
365 target_handle_option (struct gcc_options *opts,
366 struct gcc_options *opts_set,
367 const struct cl_decoded_option *decoded,
368 unsigned int lang_mask ATTRIBUTE_UNUSED, int kind,
369 location_t loc,
370 const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED,
371 diagnostic_context *dc, void (*) (void))
373 gcc_assert (dc == global_dc);
374 gcc_assert (kind == DK_UNSPECIFIED);
375 return targetm_common.handle_option (opts, opts_set, decoded, loc);
378 /* Add comma-separated strings to a char_p vector. */
380 static void
381 add_comma_separated_to_vector (void **pvec, const char *arg)
383 char *tmp;
384 char *r;
385 char *w;
386 char *token_start;
387 vec<char_p> *v = (vec<char_p> *) *pvec;
389 vec_check_alloc (v, 1);
391 /* We never free this string. */
392 tmp = xstrdup (arg);
394 r = tmp;
395 w = tmp;
396 token_start = tmp;
398 while (*r != '\0')
400 if (*r == ',')
402 *w++ = '\0';
403 ++r;
404 v->safe_push (token_start);
405 token_start = w;
407 if (*r == '\\' && r[1] == ',')
409 *w++ = ',';
410 r += 2;
412 else
413 *w++ = *r++;
416 *w = '\0';
417 if (*token_start != '\0')
418 v->safe_push (token_start);
420 *pvec = v;
423 /* Initialize opts_obstack. */
425 void
426 init_opts_obstack (void)
428 gcc_obstack_init (&opts_obstack);
431 /* Initialize OPTS and OPTS_SET before using them in parsing options. */
433 void
434 init_options_struct (struct gcc_options *opts, struct gcc_options *opts_set)
436 /* Ensure that opts_obstack has already been initialized by the time
437 that we initialize any gcc_options instances (PR jit/68446). */
438 gcc_assert (opts_obstack.chunk_size > 0);
440 *opts = global_options_init;
442 if (opts_set)
443 memset (opts_set, 0, sizeof (*opts_set));
445 /* Initialize whether `char' is signed. */
446 opts->x_flag_signed_char = DEFAULT_SIGNED_CHAR;
448 /* Initialize target_flags before default_options_optimization
449 so the latter can modify it. */
450 opts->x_target_flags = targetm_common.default_target_flags;
452 /* Some targets have ABI-specified unwind tables. */
453 opts->x_flag_unwind_tables = targetm_common.unwind_tables_default;
455 /* Some targets have other target-specific initialization. */
456 targetm_common.option_init_struct (opts);
459 /* If indicated by the optimization level LEVEL (-Os if SIZE is set,
460 -Ofast if FAST is set, -Og if DEBUG is set), apply the option DEFAULT_OPT
461 to OPTS and OPTS_SET, diagnostic context DC, location LOC, with language
462 mask LANG_MASK and option handlers HANDLERS. */
464 static void
465 maybe_default_option (struct gcc_options *opts,
466 struct gcc_options *opts_set,
467 const struct default_options *default_opt,
468 int level, bool size, bool fast, bool debug,
469 unsigned int lang_mask,
470 const struct cl_option_handlers *handlers,
471 location_t loc,
472 diagnostic_context *dc)
474 const struct cl_option *option = &cl_options[default_opt->opt_index];
475 bool enabled;
477 if (size)
478 gcc_assert (level == 2);
479 if (fast)
480 gcc_assert (level == 3);
481 if (debug)
482 gcc_assert (level == 1);
484 switch (default_opt->levels)
486 case OPT_LEVELS_ALL:
487 enabled = true;
488 break;
490 case OPT_LEVELS_0_ONLY:
491 enabled = (level == 0);
492 break;
494 case OPT_LEVELS_1_PLUS:
495 enabled = (level >= 1);
496 break;
498 case OPT_LEVELS_1_PLUS_SPEED_ONLY:
499 enabled = (level >= 1 && !size && !debug);
500 break;
502 case OPT_LEVELS_1_PLUS_NOT_DEBUG:
503 enabled = (level >= 1 && !debug);
504 break;
506 case OPT_LEVELS_2_PLUS:
507 enabled = (level >= 2);
508 break;
510 case OPT_LEVELS_2_PLUS_SPEED_ONLY:
511 enabled = (level >= 2 && !size && !debug);
512 break;
514 case OPT_LEVELS_3_PLUS:
515 enabled = (level >= 3);
516 break;
518 case OPT_LEVELS_3_PLUS_AND_SIZE:
519 enabled = (level >= 3 || size);
520 break;
522 case OPT_LEVELS_SIZE:
523 enabled = size;
524 break;
526 case OPT_LEVELS_FAST:
527 enabled = fast;
528 break;
530 case OPT_LEVELS_NONE:
531 default:
532 gcc_unreachable ();
535 if (enabled)
536 handle_generated_option (opts, opts_set, default_opt->opt_index,
537 default_opt->arg, default_opt->value,
538 lang_mask, DK_UNSPECIFIED, loc,
539 handlers, true, dc);
540 else if (default_opt->arg == NULL
541 && !option->cl_reject_negative
542 && !(option->flags & CL_PARAMS))
543 handle_generated_option (opts, opts_set, default_opt->opt_index,
544 default_opt->arg, !default_opt->value,
545 lang_mask, DK_UNSPECIFIED, loc,
546 handlers, true, dc);
549 /* As indicated by the optimization level LEVEL (-Os if SIZE is set,
550 -Ofast if FAST is set), apply the options in array DEFAULT_OPTS to
551 OPTS and OPTS_SET, diagnostic context DC, location LOC, with
552 language mask LANG_MASK and option handlers HANDLERS. */
554 static void
555 maybe_default_options (struct gcc_options *opts,
556 struct gcc_options *opts_set,
557 const struct default_options *default_opts,
558 int level, bool size, bool fast, bool debug,
559 unsigned int lang_mask,
560 const struct cl_option_handlers *handlers,
561 location_t loc,
562 diagnostic_context *dc)
564 size_t i;
566 for (i = 0; default_opts[i].levels != OPT_LEVELS_NONE; i++)
567 maybe_default_option (opts, opts_set, &default_opts[i],
568 level, size, fast, debug,
569 lang_mask, handlers, loc, dc);
572 /* Table of options enabled by default at different levels.
573 Please keep this list sorted by level and alphabetized within
574 each level; this makes it easier to keep the documentation
575 in sync. */
577 static const struct default_options default_options_table[] =
579 /* -O1 and -Og optimizations. */
580 { OPT_LEVELS_1_PLUS, OPT_fcombine_stack_adjustments, NULL, 1 },
581 { OPT_LEVELS_1_PLUS, OPT_fcompare_elim, NULL, 1 },
582 { OPT_LEVELS_1_PLUS, OPT_fcprop_registers, NULL, 1 },
583 { OPT_LEVELS_1_PLUS, OPT_fdefer_pop, NULL, 1 },
584 { OPT_LEVELS_1_PLUS, OPT_fforward_propagate, NULL, 1 },
585 { OPT_LEVELS_1_PLUS, OPT_fguess_branch_probability, NULL, 1 },
586 { OPT_LEVELS_1_PLUS, OPT_fipa_profile, NULL, 1 },
587 { OPT_LEVELS_1_PLUS, OPT_fipa_pure_const, NULL, 1 },
588 { OPT_LEVELS_1_PLUS, OPT_fipa_reference, NULL, 1 },
589 { OPT_LEVELS_1_PLUS, OPT_fipa_reference_addressable, NULL, 1 },
590 { OPT_LEVELS_1_PLUS, OPT_fmerge_constants, NULL, 1 },
591 { OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
592 { OPT_LEVELS_1_PLUS, OPT_freorder_blocks, NULL, 1 },
593 { OPT_LEVELS_1_PLUS, OPT_fshrink_wrap, NULL, 1 },
594 { OPT_LEVELS_1_PLUS, OPT_fsplit_wide_types, NULL, 1 },
595 { OPT_LEVELS_1_PLUS, OPT_fthread_jumps, NULL, 1 },
596 { OPT_LEVELS_1_PLUS, OPT_ftree_builtin_call_dce, NULL, 1 },
597 { OPT_LEVELS_1_PLUS, OPT_ftree_ccp, NULL, 1 },
598 { OPT_LEVELS_1_PLUS, OPT_ftree_ch, NULL, 1 },
599 { OPT_LEVELS_1_PLUS, OPT_ftree_coalesce_vars, NULL, 1 },
600 { OPT_LEVELS_1_PLUS, OPT_ftree_copy_prop, NULL, 1 },
601 { OPT_LEVELS_1_PLUS, OPT_ftree_dce, NULL, 1 },
602 { OPT_LEVELS_1_PLUS, OPT_ftree_dominator_opts, NULL, 1 },
603 { OPT_LEVELS_1_PLUS, OPT_ftree_fre, NULL, 1 },
604 { OPT_LEVELS_1_PLUS, OPT_ftree_sink, NULL, 1 },
605 { OPT_LEVELS_1_PLUS, OPT_ftree_slsr, NULL, 1 },
606 { OPT_LEVELS_1_PLUS, OPT_ftree_ter, NULL, 1 },
607 { OPT_LEVELS_1_PLUS, OPT_fvar_tracking, NULL, 1 },
609 /* -O1 (and not -Og) optimizations. */
610 { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fbit_tests, NULL, 1 },
611 { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fbranch_count_reg, NULL, 1 },
612 #if DELAY_SLOTS
613 { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fdelayed_branch, NULL, 1 },
614 #endif
615 { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fdse, NULL, 1 },
616 { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fif_conversion, NULL, 1 },
617 { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fif_conversion2, NULL, 1 },
618 { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_finline_functions_called_once, NULL, 1 },
619 { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fjump_tables, NULL, 1 },
620 { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fmove_loop_invariants, NULL, 1 },
621 { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fmove_loop_stores, NULL, 1 },
622 { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fssa_phiopt, NULL, 1 },
623 { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fipa_modref, NULL, 1 },
624 { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_bit_ccp, NULL, 1 },
625 { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_dse, NULL, 1 },
626 { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_pta, NULL, 1 },
627 { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_sra, NULL, 1 },
629 /* -O2 and -Os optimizations. */
630 { OPT_LEVELS_2_PLUS, OPT_fcaller_saves, NULL, 1 },
631 { OPT_LEVELS_2_PLUS, OPT_fcode_hoisting, NULL, 1 },
632 { OPT_LEVELS_2_PLUS, OPT_fcrossjumping, NULL, 1 },
633 { OPT_LEVELS_2_PLUS, OPT_fcse_follow_jumps, NULL, 1 },
634 { OPT_LEVELS_2_PLUS, OPT_fdevirtualize, NULL, 1 },
635 { OPT_LEVELS_2_PLUS, OPT_fdevirtualize_speculatively, NULL, 1 },
636 { OPT_LEVELS_2_PLUS, OPT_fexpensive_optimizations, NULL, 1 },
637 { OPT_LEVELS_2_PLUS, OPT_fext_dce, NULL, 1 },
638 { OPT_LEVELS_2_PLUS, OPT_fgcse, NULL, 1 },
639 { OPT_LEVELS_2_PLUS, OPT_fhoist_adjacent_loads, NULL, 1 },
640 { OPT_LEVELS_2_PLUS, OPT_findirect_inlining, NULL, 1 },
641 { OPT_LEVELS_2_PLUS, OPT_finline_small_functions, NULL, 1 },
642 { OPT_LEVELS_2_PLUS, OPT_fipa_bit_cp, NULL, 1 },
643 { OPT_LEVELS_2_PLUS, OPT_fipa_cp, NULL, 1 },
644 { OPT_LEVELS_2_PLUS, OPT_fipa_icf, NULL, 1 },
645 { OPT_LEVELS_2_PLUS, OPT_fipa_ra, NULL, 1 },
646 { OPT_LEVELS_2_PLUS, OPT_fipa_sra, NULL, 1 },
647 { OPT_LEVELS_2_PLUS, OPT_fipa_vrp, NULL, 1 },
648 { OPT_LEVELS_2_PLUS, OPT_fisolate_erroneous_paths_dereference, NULL, 1 },
649 { OPT_LEVELS_2_PLUS, OPT_flra_remat, NULL, 1 },
650 { OPT_LEVELS_2_PLUS, OPT_foptimize_sibling_calls, NULL, 1 },
651 { OPT_LEVELS_2_PLUS, OPT_fpartial_inlining, NULL, 1 },
652 { OPT_LEVELS_2_PLUS, OPT_fpeephole2, NULL, 1 },
653 { OPT_LEVELS_2_PLUS, OPT_freorder_functions, NULL, 1 },
654 { OPT_LEVELS_2_PLUS, OPT_frerun_cse_after_loop, NULL, 1 },
655 #ifdef INSN_SCHEDULING
656 { OPT_LEVELS_2_PLUS, OPT_fschedule_insns2, NULL, 1 },
657 #endif
658 { OPT_LEVELS_2_PLUS, OPT_fstrict_aliasing, NULL, 1 },
659 { OPT_LEVELS_2_PLUS, OPT_fstore_merging, NULL, 1 },
660 { OPT_LEVELS_2_PLUS, OPT_ftree_pre, NULL, 1 },
661 { OPT_LEVELS_2_PLUS, OPT_ftree_switch_conversion, NULL, 1 },
662 { OPT_LEVELS_2_PLUS, OPT_ftree_tail_merge, NULL, 1 },
663 { OPT_LEVELS_2_PLUS, OPT_ftree_vrp, NULL, 1 },
664 { OPT_LEVELS_2_PLUS, OPT_fvect_cost_model_, NULL,
665 VECT_COST_MODEL_VERY_CHEAP },
666 { OPT_LEVELS_2_PLUS, OPT_finline_functions, NULL, 1 },
667 { OPT_LEVELS_2_PLUS, OPT_ftree_loop_distribute_patterns, NULL, 1 },
668 { OPT_LEVELS_2_PLUS, OPT_foptimize_crc, NULL, 1 },
669 { OPT_LEVELS_2_PLUS, OPT_flate_combine_instructions, NULL, 1 },
671 /* -O2 and above optimizations, but not -Os or -Og. */
672 { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_falign_functions, NULL, 1 },
673 { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_falign_jumps, NULL, 1 },
674 { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_falign_labels, NULL, 1 },
675 { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_falign_loops, NULL, 1 },
676 { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_foptimize_strlen, NULL, 1 },
677 { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_freorder_blocks_algorithm_, NULL,
678 REORDER_BLOCKS_ALGORITHM_STC },
679 { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_ftree_loop_vectorize, NULL, 1 },
680 { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_ftree_slp_vectorize, NULL, 1 },
681 { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_fopenmp_target_simd_clone_, NULL,
682 OMP_TARGET_SIMD_CLONE_NOHOST },
683 #ifdef INSN_SCHEDULING
684 /* Only run the pre-regalloc scheduling pass if optimizing for speed. */
685 { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_fschedule_insns, NULL, 1 },
686 #endif
688 /* -O3 and -Os optimizations. */
690 /* -O3 optimizations. */
691 { OPT_LEVELS_3_PLUS, OPT_fgcse_after_reload, NULL, 1 },
692 { OPT_LEVELS_3_PLUS, OPT_fipa_cp_clone, NULL, 1 },
693 { OPT_LEVELS_3_PLUS, OPT_floop_interchange, NULL, 1 },
694 { OPT_LEVELS_3_PLUS, OPT_floop_unroll_and_jam, NULL, 1 },
695 { OPT_LEVELS_3_PLUS, OPT_fpeel_loops, NULL, 1 },
696 { OPT_LEVELS_3_PLUS, OPT_fpredictive_commoning, NULL, 1 },
697 { OPT_LEVELS_3_PLUS, OPT_fsplit_loops, NULL, 1 },
698 { OPT_LEVELS_3_PLUS, OPT_fsplit_paths, NULL, 1 },
699 { OPT_LEVELS_3_PLUS, OPT_ftree_loop_distribution, NULL, 1 },
700 { OPT_LEVELS_3_PLUS, OPT_ftree_partial_pre, NULL, 1 },
701 { OPT_LEVELS_3_PLUS, OPT_funswitch_loops, NULL, 1 },
702 { OPT_LEVELS_3_PLUS, OPT_fvect_cost_model_, NULL, VECT_COST_MODEL_DYNAMIC },
703 { OPT_LEVELS_3_PLUS, OPT_fversion_loops_for_strides, NULL, 1 },
705 /* -O3 parameters. */
706 { OPT_LEVELS_3_PLUS, OPT__param_max_inline_insns_auto_, NULL, 30 },
707 { OPT_LEVELS_3_PLUS, OPT__param_early_inlining_insns_, NULL, 14 },
708 { OPT_LEVELS_3_PLUS, OPT__param_inline_heuristics_hint_percent_, NULL, 600 },
709 { OPT_LEVELS_3_PLUS, OPT__param_inline_min_speedup_, NULL, 15 },
710 { OPT_LEVELS_3_PLUS, OPT__param_max_inline_insns_single_, NULL, 200 },
712 /* -Ofast adds optimizations to -O3. */
713 { OPT_LEVELS_FAST, OPT_ffast_math, NULL, 1 },
714 { OPT_LEVELS_FAST, OPT_fallow_store_data_races, NULL, 1 },
715 { OPT_LEVELS_FAST, OPT_fsemantic_interposition, NULL, 0 },
717 { OPT_LEVELS_NONE, 0, NULL, 0 }
720 /* Default the options in OPTS and OPTS_SET based on the optimization
721 settings in DECODED_OPTIONS and DECODED_OPTIONS_COUNT. */
722 void
723 default_options_optimization (struct gcc_options *opts,
724 struct gcc_options *opts_set,
725 struct cl_decoded_option *decoded_options,
726 unsigned int decoded_options_count,
727 location_t loc,
728 unsigned int lang_mask,
729 const struct cl_option_handlers *handlers,
730 diagnostic_context *dc)
732 unsigned int i;
733 int opt2;
734 bool openacc_mode = false;
736 /* Scan to see what optimization level has been specified. That will
737 determine the default value of many flags. */
738 for (i = 1; i < decoded_options_count; i++)
740 struct cl_decoded_option *opt = &decoded_options[i];
741 switch (opt->opt_index)
743 case OPT_O:
744 if (*opt->arg == '\0')
746 opts->x_optimize = 1;
747 opts->x_optimize_size = 0;
748 opts->x_optimize_fast = 0;
749 opts->x_optimize_debug = 0;
751 else
753 const int optimize_val = integral_argument (opt->arg);
754 if (optimize_val == -1)
755 error_at (loc, "argument to %<-O%> should be a non-negative "
756 "integer, %<g%>, %<s%>, %<z%> or %<fast%>");
757 else
759 opts->x_optimize = optimize_val;
760 if ((unsigned int) opts->x_optimize > 255)
761 opts->x_optimize = 255;
762 opts->x_optimize_size = 0;
763 opts->x_optimize_fast = 0;
764 opts->x_optimize_debug = 0;
767 break;
769 case OPT_Os:
770 opts->x_optimize_size = 1;
772 /* Optimizing for size forces optimize to be 2. */
773 opts->x_optimize = 2;
774 opts->x_optimize_fast = 0;
775 opts->x_optimize_debug = 0;
776 break;
778 case OPT_Oz:
779 opts->x_optimize_size = 2;
781 /* Optimizing for size forces optimize to be 2. */
782 opts->x_optimize = 2;
783 opts->x_optimize_fast = 0;
784 opts->x_optimize_debug = 0;
785 break;
787 case OPT_Ofast:
788 /* -Ofast only adds flags to -O3. */
789 opts->x_optimize_size = 0;
790 opts->x_optimize = 3;
791 opts->x_optimize_fast = 1;
792 opts->x_optimize_debug = 0;
793 break;
795 case OPT_Og:
796 /* -Og selects optimization level 1. */
797 opts->x_optimize_size = 0;
798 opts->x_optimize = 1;
799 opts->x_optimize_fast = 0;
800 opts->x_optimize_debug = 1;
801 break;
803 case OPT_fopenacc:
804 if (opt->value)
805 openacc_mode = true;
806 break;
808 default:
809 /* Ignore other options in this prescan. */
810 break;
814 maybe_default_options (opts, opts_set, default_options_table,
815 opts->x_optimize, opts->x_optimize_size,
816 opts->x_optimize_fast, opts->x_optimize_debug,
817 lang_mask, handlers, loc, dc);
819 /* -O2 param settings. */
820 opt2 = (opts->x_optimize >= 2);
822 if (openacc_mode)
823 SET_OPTION_IF_UNSET (opts, opts_set, flag_ipa_pta, true);
825 /* Track fields in field-sensitive alias analysis. */
826 if (opt2)
827 SET_OPTION_IF_UNSET (opts, opts_set, param_max_fields_for_field_sensitive,
828 100);
830 if (opts->x_optimize_size)
831 /* We want to crossjump as much as possible. */
832 SET_OPTION_IF_UNSET (opts, opts_set, param_min_crossjump_insns, 1);
834 /* Restrict the amount of work combine does at -Og while retaining
835 most of its useful transforms. */
836 if (opts->x_optimize_debug)
837 SET_OPTION_IF_UNSET (opts, opts_set, param_max_combine_insns, 2);
839 /* Allow default optimizations to be specified on a per-machine basis. */
840 maybe_default_options (opts, opts_set,
841 targetm_common.option_optimization_table,
842 opts->x_optimize, opts->x_optimize_size,
843 opts->x_optimize_fast, opts->x_optimize_debug,
844 lang_mask, handlers, loc, dc);
847 /* Control IPA optimizations based on different live patching LEVEL. */
848 static void
849 control_options_for_live_patching (struct gcc_options *opts,
850 struct gcc_options *opts_set,
851 enum live_patching_level level,
852 location_t loc)
854 gcc_assert (level > LIVE_PATCHING_NONE);
856 switch (level)
858 case LIVE_PATCHING_INLINE_ONLY_STATIC:
859 #define LIVE_PATCHING_OPTION "-flive-patching=inline-only-static"
860 if (opts_set->x_flag_ipa_cp_clone && opts->x_flag_ipa_cp_clone)
861 error_at (loc, "%qs is incompatible with %qs",
862 "-fipa-cp-clone", LIVE_PATCHING_OPTION);
863 else
864 opts->x_flag_ipa_cp_clone = 0;
866 if (opts_set->x_flag_ipa_sra && opts->x_flag_ipa_sra)
867 error_at (loc, "%qs is incompatible with %qs",
868 "-fipa-sra", LIVE_PATCHING_OPTION);
869 else
870 opts->x_flag_ipa_sra = 0;
872 if (opts_set->x_flag_partial_inlining && opts->x_flag_partial_inlining)
873 error_at (loc, "%qs is incompatible with %qs",
874 "-fpartial-inlining", LIVE_PATCHING_OPTION);
875 else
876 opts->x_flag_partial_inlining = 0;
878 if (opts_set->x_flag_ipa_cp && opts->x_flag_ipa_cp)
879 error_at (loc, "%qs is incompatible with %qs",
880 "-fipa-cp", LIVE_PATCHING_OPTION);
881 else
882 opts->x_flag_ipa_cp = 0;
884 /* FALLTHROUGH. */
885 case LIVE_PATCHING_INLINE_CLONE:
886 #undef LIVE_PATCHING_OPTION
887 #define LIVE_PATCHING_OPTION "-flive-patching=inline-only-static|inline-clone"
888 /* live patching should disable whole-program optimization. */
889 if (opts_set->x_flag_whole_program && opts->x_flag_whole_program)
890 error_at (loc, "%qs is incompatible with %qs",
891 "-fwhole-program", LIVE_PATCHING_OPTION);
892 else
893 opts->x_flag_whole_program = 0;
895 /* visibility change should be excluded by !flag_whole_program
896 && !in_lto_p && !flag_ipa_cp_clone && !flag_ipa_sra
897 && !flag_partial_inlining. */
899 if (opts_set->x_flag_ipa_pta && opts->x_flag_ipa_pta)
900 error_at (loc, "%qs is incompatible with %qs",
901 "-fipa-pta", LIVE_PATCHING_OPTION);
902 else
903 opts->x_flag_ipa_pta = 0;
905 if (opts_set->x_flag_ipa_reference && opts->x_flag_ipa_reference)
906 error_at (loc, "%qs is incompatible with %qs",
907 "-fipa-reference", LIVE_PATCHING_OPTION);
908 else
909 opts->x_flag_ipa_reference = 0;
911 if (opts_set->x_flag_ipa_ra && opts->x_flag_ipa_ra)
912 error_at (loc, "%qs is incompatible with %qs",
913 "-fipa-ra", LIVE_PATCHING_OPTION);
914 else
915 opts->x_flag_ipa_ra = 0;
917 if (opts_set->x_flag_ipa_icf && opts->x_flag_ipa_icf)
918 error_at (loc, "%qs is incompatible with %qs",
919 "-fipa-icf", LIVE_PATCHING_OPTION);
920 else
921 opts->x_flag_ipa_icf = 0;
923 if (opts_set->x_flag_ipa_icf_functions && opts->x_flag_ipa_icf_functions)
924 error_at (loc, "%qs is incompatible with %qs",
925 "-fipa-icf-functions", LIVE_PATCHING_OPTION);
926 else
927 opts->x_flag_ipa_icf_functions = 0;
929 if (opts_set->x_flag_ipa_icf_variables && opts->x_flag_ipa_icf_variables)
930 error_at (loc, "%qs is incompatible with %qs",
931 "-fipa-icf-variables", LIVE_PATCHING_OPTION);
932 else
933 opts->x_flag_ipa_icf_variables = 0;
935 if (opts_set->x_flag_ipa_bit_cp && opts->x_flag_ipa_bit_cp)
936 error_at (loc, "%qs is incompatible with %qs",
937 "-fipa-bit-cp", LIVE_PATCHING_OPTION);
938 else
939 opts->x_flag_ipa_bit_cp = 0;
941 if (opts_set->x_flag_ipa_vrp && opts->x_flag_ipa_vrp)
942 error_at (loc, "%qs is incompatible with %qs",
943 "-fipa-vrp", LIVE_PATCHING_OPTION);
944 else
945 opts->x_flag_ipa_vrp = 0;
947 if (opts_set->x_flag_ipa_pure_const && opts->x_flag_ipa_pure_const)
948 error_at (loc, "%qs is incompatible with %qs",
949 "-fipa-pure-const", LIVE_PATCHING_OPTION);
950 else
951 opts->x_flag_ipa_pure_const = 0;
953 if (opts_set->x_flag_ipa_modref && opts->x_flag_ipa_modref)
954 error_at (loc,
955 "%<-fipa-modref%> is incompatible with %qs",
956 LIVE_PATCHING_OPTION);
957 else
958 opts->x_flag_ipa_modref = 0;
960 /* FIXME: disable unreachable code removal. */
962 /* discovery of functions/variables with no address taken. */
963 if (opts_set->x_flag_ipa_reference_addressable
964 && opts->x_flag_ipa_reference_addressable)
965 error_at (loc, "%qs is incompatible with %qs",
966 "-fipa-reference-addressable", LIVE_PATCHING_OPTION);
967 else
968 opts->x_flag_ipa_reference_addressable = 0;
970 /* ipa stack alignment propagation. */
971 if (opts_set->x_flag_ipa_stack_alignment
972 && opts->x_flag_ipa_stack_alignment)
973 error_at (loc, "%qs is incompatible with %qs",
974 "-fipa-stack-alignment", LIVE_PATCHING_OPTION);
975 else
976 opts->x_flag_ipa_stack_alignment = 0;
977 break;
978 default:
979 gcc_unreachable ();
982 #undef LIVE_PATCHING_OPTION
985 /* --help option argument if set. */
986 vec<const char *> help_option_arguments;
988 /* Return the string name describing a sanitizer argument which has been
989 provided on the command line and has set this particular flag. */
990 const char *
991 find_sanitizer_argument (struct gcc_options *opts, unsigned int flags)
993 for (int i = 0; sanitizer_opts[i].name != NULL; ++i)
995 /* Need to find the sanitizer_opts element which:
996 a) Could have set the flags requested.
997 b) Has been set on the command line.
999 Can have (a) without (b) if the flag requested is e.g.
1000 SANITIZE_ADDRESS, since both -fsanitize=address and
1001 -fsanitize=kernel-address set this flag.
1003 Can have (b) without (a) by requesting more than one sanitizer on the
1004 command line. */
1005 if ((sanitizer_opts[i].flag & opts->x_flag_sanitize)
1006 != sanitizer_opts[i].flag)
1007 continue;
1008 if ((sanitizer_opts[i].flag & flags) != flags)
1009 continue;
1010 return sanitizer_opts[i].name;
1012 return NULL;
1016 /* Report an error to the user about sanitizer options they have requested
1017 which have set conflicting flags.
1019 LEFT and RIGHT indicate sanitizer flags which conflict with each other, this
1020 function reports an error if both have been set in OPTS->x_flag_sanitize and
1021 ensures the error identifies the requested command line options that have
1022 set these flags. */
1023 static void
1024 report_conflicting_sanitizer_options (struct gcc_options *opts, location_t loc,
1025 unsigned int left, unsigned int right)
1027 unsigned int left_seen = (opts->x_flag_sanitize & left);
1028 unsigned int right_seen = (opts->x_flag_sanitize & right);
1029 if (left_seen && right_seen)
1031 const char* left_arg = find_sanitizer_argument (opts, left_seen);
1032 const char* right_arg = find_sanitizer_argument (opts, right_seen);
1033 gcc_assert (left_arg && right_arg);
1034 error_at (loc,
1035 "%<-fsanitize=%s%> is incompatible with %<-fsanitize=%s%>",
1036 left_arg, right_arg);
1040 /* After all options at LOC have been read into OPTS and OPTS_SET,
1041 finalize settings of those options and diagnose incompatible
1042 combinations. */
1043 void
1044 finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
1045 location_t loc)
1047 if (opts->x_dump_base_name
1048 && ! opts->x_dump_base_name_prefixed)
1050 const char *sep = opts->x_dump_base_name;
1052 for (; *sep; sep++)
1053 if (IS_DIR_SEPARATOR (*sep))
1054 break;
1056 if (*sep)
1057 /* If dump_base_path contains subdirectories, don't prepend
1058 anything. */;
1059 else if (opts->x_dump_dir_name)
1060 /* We have a DUMP_DIR_NAME, prepend that. */
1061 opts->x_dump_base_name = opts_concat (opts->x_dump_dir_name,
1062 opts->x_dump_base_name, NULL);
1064 /* It is definitely prefixed now. */
1065 opts->x_dump_base_name_prefixed = true;
1068 /* Handle related options for unit-at-a-time, toplevel-reorder, and
1069 section-anchors. */
1070 if (!opts->x_flag_unit_at_a_time)
1072 if (opts->x_flag_section_anchors && opts_set->x_flag_section_anchors)
1073 error_at (loc, "section anchors must be disabled when unit-at-a-time "
1074 "is disabled");
1075 opts->x_flag_section_anchors = 0;
1076 if (opts->x_flag_toplevel_reorder == 1)
1077 error_at (loc, "toplevel reorder must be disabled when unit-at-a-time "
1078 "is disabled");
1079 opts->x_flag_toplevel_reorder = 0;
1082 /* -fself-test depends on the state of the compiler prior to
1083 compiling anything. Ideally it should be run on an empty source
1084 file. However, in case we get run with actual source, assume
1085 -fsyntax-only which will inhibit any compiler initialization
1086 which may confuse the self tests. */
1087 if (opts->x_flag_self_test)
1088 opts->x_flag_syntax_only = 1;
1090 if (opts->x_flag_tm && opts->x_flag_non_call_exceptions)
1091 sorry ("transactional memory is not supported with non-call exceptions");
1093 /* Unless the user has asked for section anchors, we disable toplevel
1094 reordering at -O0 to disable transformations that might be surprising
1095 to end users and to get -fno-toplevel-reorder tested. */
1096 if (!opts->x_optimize
1097 && opts->x_flag_toplevel_reorder == 2
1098 && !(opts->x_flag_section_anchors && opts_set->x_flag_section_anchors))
1100 opts->x_flag_toplevel_reorder = 0;
1101 opts->x_flag_section_anchors = 0;
1103 if (!opts->x_flag_toplevel_reorder)
1105 if (opts->x_flag_section_anchors && opts_set->x_flag_section_anchors)
1106 error_at (loc, "section anchors must be disabled when toplevel reorder"
1107 " is disabled");
1108 opts->x_flag_section_anchors = 0;
1111 if (opts->x_flag_hardened)
1113 if (!opts_set->x_flag_auto_var_init)
1114 opts->x_flag_auto_var_init = AUTO_INIT_ZERO;
1115 else if (opts->x_flag_auto_var_init != AUTO_INIT_ZERO)
1116 warning_at (loc, OPT_Whardened,
1117 "%<-ftrivial-auto-var-init=zero%> is not enabled by "
1118 "%<-fhardened%> because it was specified on the command "
1119 "line");
1122 if (!opts->x_flag_opts_finished)
1124 /* We initialize opts->x_flag_pie to -1 so that targets can set a
1125 default value. */
1126 if (opts->x_flag_pie == -1)
1128 /* We initialize opts->x_flag_pic to -1 so that we can tell if
1129 -fpic, -fPIC, -fno-pic or -fno-PIC is used. */
1130 if (opts->x_flag_pic == -1)
1131 opts->x_flag_pie = (opts->x_flag_hardened
1132 ? /*-fPIE*/ 2 : DEFAULT_FLAG_PIE);
1133 else
1134 opts->x_flag_pie = 0;
1136 /* If -fPIE or -fpie is used, turn on PIC. */
1137 if (opts->x_flag_pie)
1138 opts->x_flag_pic = opts->x_flag_pie;
1139 else if (opts->x_flag_pic == -1)
1140 opts->x_flag_pic = 0;
1141 if (opts->x_flag_pic && !opts->x_flag_pie)
1142 opts->x_flag_shlib = 1;
1143 opts->x_flag_opts_finished = true;
1146 /* We initialize opts->x_flag_stack_protect to -1 so that targets
1147 can set a default value. With --enable-default-ssp or -fhardened
1148 the default is -fstack-protector-strong. */
1149 if (opts->x_flag_stack_protect == -1)
1151 /* This should check FRAME_GROWS_DOWNWARD, but on some targets it's
1152 defined in such a way that it uses flag_stack_protect which can't
1153 be used here. Moreover, some targets like BPF don't support
1154 -fstack-protector at all but we don't know that here. So remember
1155 that flag_stack_protect was set at the behest of -fhardened. */
1156 if (opts->x_flag_hardened)
1158 opts->x_flag_stack_protect = SPCT_FLAG_STRONG;
1159 flag_stack_protector_set_by_fhardened_p = true;
1161 else
1162 opts->x_flag_stack_protect = DEFAULT_FLAG_SSP;
1164 else if (opts->x_flag_hardened
1165 && opts->x_flag_stack_protect != SPCT_FLAG_STRONG)
1166 warning_at (UNKNOWN_LOCATION, OPT_Whardened,
1167 "%<-fstack-protector-strong%> is not enabled by "
1168 "%<-fhardened%> because it was specified on the command "
1169 "line");
1171 if (opts->x_optimize == 0)
1173 /* Inlining does not work if not optimizing,
1174 so force it not to be done. */
1175 opts->x_warn_inline = 0;
1176 opts->x_flag_no_inline = 1;
1179 /* At -O0 or -Og, turn __builtin_unreachable into a trap. */
1180 if (!opts->x_optimize || opts->x_optimize_debug)
1181 SET_OPTION_IF_UNSET (opts, opts_set, flag_unreachable_traps, true);
1183 /* Pipelining of outer loops is only possible when general pipelining
1184 capabilities are requested. */
1185 if (!opts->x_flag_sel_sched_pipelining)
1186 opts->x_flag_sel_sched_pipelining_outer_loops = 0;
1188 if (opts->x_flag_conserve_stack)
1190 SET_OPTION_IF_UNSET (opts, opts_set, param_large_stack_frame, 100);
1191 SET_OPTION_IF_UNSET (opts, opts_set, param_stack_frame_growth, 40);
1194 if (opts->x_flag_lto)
1196 #ifdef ENABLE_LTO
1197 opts->x_flag_generate_lto = 1;
1199 /* When generating IL, do not operate in whole-program mode.
1200 Otherwise, symbols will be privatized too early, causing link
1201 errors later. */
1202 opts->x_flag_whole_program = 0;
1203 #else
1204 error_at (loc, "LTO support has not been enabled in this configuration");
1205 #endif
1206 if (!opts->x_flag_fat_lto_objects
1207 && (!HAVE_LTO_PLUGIN
1208 || (opts_set->x_flag_use_linker_plugin
1209 && !opts->x_flag_use_linker_plugin)))
1211 if (opts_set->x_flag_fat_lto_objects)
1212 error_at (loc, "%<-fno-fat-lto-objects%> are supported only with "
1213 "linker plugin");
1214 opts->x_flag_fat_lto_objects = 1;
1217 /* -gsplit-dwarf isn't compatible with LTO, see PR88389. */
1218 if (opts->x_dwarf_split_debug_info)
1220 inform (loc, "%<-gsplit-dwarf%> is not supported with LTO,"
1221 " disabling");
1222 opts->x_dwarf_split_debug_info = 0;
1226 /* We initialize opts->x_flag_split_stack to -1 so that targets can set a
1227 default value if they choose based on other options. */
1228 if (opts->x_flag_split_stack == -1)
1229 opts->x_flag_split_stack = 0;
1230 else if (opts->x_flag_split_stack)
1232 if (!targetm_common.supports_split_stack (true, opts))
1234 error_at (loc, "%<-fsplit-stack%> is not supported by "
1235 "this compiler configuration");
1236 opts->x_flag_split_stack = 0;
1240 /* If stack splitting is turned on, and the user did not explicitly
1241 request function partitioning, turn off partitioning, as it
1242 confuses the linker when trying to handle partitioned split-stack
1243 code that calls a non-split-stack functions. But if partitioning
1244 was turned on explicitly just hope for the best. */
1245 if (opts->x_flag_split_stack
1246 && opts->x_flag_reorder_blocks_and_partition)
1247 SET_OPTION_IF_UNSET (opts, opts_set, flag_reorder_blocks_and_partition, 0);
1249 if (opts->x_flag_reorder_blocks_and_partition)
1250 SET_OPTION_IF_UNSET (opts, opts_set, flag_reorder_functions, 1);
1252 /* The -gsplit-dwarf option requires -ggnu-pubnames. */
1253 if (opts->x_dwarf_split_debug_info)
1254 opts->x_debug_generate_pub_sections = 2;
1256 if ((opts->x_flag_sanitize
1257 & (SANITIZE_USER_ADDRESS | SANITIZE_KERNEL_ADDRESS)) == 0)
1259 if (opts->x_flag_sanitize & SANITIZE_POINTER_COMPARE)
1260 error_at (loc,
1261 "%<-fsanitize=pointer-compare%> must be combined with "
1262 "%<-fsanitize=address%> or %<-fsanitize=kernel-address%>");
1263 if (opts->x_flag_sanitize & SANITIZE_POINTER_SUBTRACT)
1264 error_at (loc,
1265 "%<-fsanitize=pointer-subtract%> must be combined with "
1266 "%<-fsanitize=address%> or %<-fsanitize=kernel-address%>");
1269 /* Address sanitizers conflict with the thread sanitizer. */
1270 report_conflicting_sanitizer_options (opts, loc, SANITIZE_THREAD,
1271 SANITIZE_ADDRESS);
1272 report_conflicting_sanitizer_options (opts, loc, SANITIZE_THREAD,
1273 SANITIZE_HWADDRESS);
1274 /* The leak sanitizer conflicts with the thread sanitizer. */
1275 report_conflicting_sanitizer_options (opts, loc, SANITIZE_LEAK,
1276 SANITIZE_THREAD);
1278 /* No combination of HWASAN and ASAN work together. */
1279 report_conflicting_sanitizer_options (opts, loc,
1280 SANITIZE_HWADDRESS, SANITIZE_ADDRESS);
1282 /* The userspace and kernel address sanitizers conflict with each other. */
1283 report_conflicting_sanitizer_options (opts, loc, SANITIZE_USER_HWADDRESS,
1284 SANITIZE_KERNEL_HWADDRESS);
1285 report_conflicting_sanitizer_options (opts, loc, SANITIZE_USER_ADDRESS,
1286 SANITIZE_KERNEL_ADDRESS);
1288 /* Check error recovery for -fsanitize-recover option. */
1289 for (int i = 0; sanitizer_opts[i].name != NULL; ++i)
1290 if ((opts->x_flag_sanitize_recover & sanitizer_opts[i].flag)
1291 && !sanitizer_opts[i].can_recover)
1292 error_at (loc, "%<-fsanitize-recover=%s%> is not supported",
1293 sanitizer_opts[i].name);
1295 /* Check -fsanitize-trap option. */
1296 for (int i = 0; sanitizer_opts[i].name != NULL; ++i)
1297 if ((opts->x_flag_sanitize_trap & sanitizer_opts[i].flag)
1298 && !sanitizer_opts[i].can_trap
1299 /* Allow -fsanitize-trap=all or -fsanitize-trap=undefined
1300 to set flag_sanitize_trap & SANITIZE_VPTR bit which will
1301 effectively disable -fsanitize=vptr, just disallow
1302 explicit -fsanitize-trap=vptr. */
1303 && sanitizer_opts[i].flag != SANITIZE_VPTR)
1304 error_at (loc, "%<-fsanitize-trap=%s%> is not supported",
1305 sanitizer_opts[i].name);
1307 /* When instrumenting the pointers, we don't want to remove
1308 the null pointer checks. */
1309 if (opts->x_flag_sanitize & (SANITIZE_NULL | SANITIZE_NONNULL_ATTRIBUTE
1310 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE))
1311 opts->x_flag_delete_null_pointer_checks = 0;
1313 /* Aggressive compiler optimizations may cause false negatives. */
1314 if (opts->x_flag_sanitize & ~(SANITIZE_LEAK | SANITIZE_UNREACHABLE))
1315 opts->x_flag_aggressive_loop_optimizations = 0;
1317 /* Enable -fsanitize-address-use-after-scope if either address sanitizer is
1318 enabled. */
1319 if (opts->x_flag_sanitize
1320 & (SANITIZE_USER_ADDRESS | SANITIZE_USER_HWADDRESS))
1321 SET_OPTION_IF_UNSET (opts, opts_set, flag_sanitize_address_use_after_scope,
1322 true);
1324 /* Force -fstack-reuse=none in case -fsanitize-address-use-after-scope
1325 is enabled. */
1326 if (opts->x_flag_sanitize_address_use_after_scope)
1328 if (opts->x_flag_stack_reuse != SR_NONE
1329 && opts_set->x_flag_stack_reuse != SR_NONE)
1330 error_at (loc,
1331 "%<-fsanitize-address-use-after-scope%> requires "
1332 "%<-fstack-reuse=none%> option");
1334 opts->x_flag_stack_reuse = SR_NONE;
1337 if ((opts->x_flag_sanitize & SANITIZE_USER_ADDRESS) && opts->x_flag_tm)
1338 sorry ("transactional memory is not supported with %<-fsanitize=address%>");
1340 if ((opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS) && opts->x_flag_tm)
1341 sorry ("transactional memory is not supported with "
1342 "%<-fsanitize=kernel-address%>");
1344 /* Currently live patching is not support for LTO. */
1345 if (opts->x_flag_live_patching == LIVE_PATCHING_INLINE_ONLY_STATIC && opts->x_flag_lto)
1346 sorry ("live patching (with %qs) is not supported with LTO",
1347 "inline-only-static");
1349 /* Currently vtable verification is not supported for LTO */
1350 if (opts->x_flag_vtable_verify && opts->x_flag_lto)
1351 sorry ("vtable verification is not supported with LTO");
1353 /* Control IPA optimizations based on different -flive-patching level. */
1354 if (opts->x_flag_live_patching)
1355 control_options_for_live_patching (opts, opts_set,
1356 opts->x_flag_live_patching,
1357 loc);
1359 /* Allow cunroll to grow size accordingly. */
1360 if (!opts_set->x_flag_cunroll_grow_size)
1361 opts->x_flag_cunroll_grow_size
1362 = (opts->x_flag_unroll_loops
1363 || opts->x_flag_peel_loops
1364 || opts->x_optimize >= 3);
1366 /* With -fcx-limited-range, we do cheap and quick complex arithmetic. */
1367 if (opts->x_flag_cx_limited_range)
1368 opts->x_flag_complex_method = 0;
1369 else if (opts_set->x_flag_cx_limited_range)
1370 opts->x_flag_complex_method = opts->x_flag_default_complex_method;
1372 /* With -fcx-fortran-rules, we do something in-between cheap and C99. */
1373 if (opts->x_flag_cx_fortran_rules)
1374 opts->x_flag_complex_method = 1;
1375 else if (opts_set->x_flag_cx_fortran_rules)
1376 opts->x_flag_complex_method = opts->x_flag_default_complex_method;
1378 /* Use -fvect-cost-model=cheap instead of -fvect-cost-mode=very-cheap
1379 by default with explicit -ftree-{loop,slp}-vectorize. */
1380 if (opts->x_optimize == 2
1381 && (opts_set->x_flag_tree_loop_vectorize
1382 || opts_set->x_flag_tree_vectorize))
1383 SET_OPTION_IF_UNSET (opts, opts_set, flag_vect_cost_model,
1384 VECT_COST_MODEL_CHEAP);
1386 if (opts->x_flag_gtoggle)
1388 /* Make sure to process -gtoggle only once. */
1389 opts->x_flag_gtoggle = false;
1390 if (opts->x_debug_info_level == DINFO_LEVEL_NONE)
1392 opts->x_debug_info_level = DINFO_LEVEL_NORMAL;
1394 if (opts->x_write_symbols == NO_DEBUG)
1395 opts->x_write_symbols = PREFERRED_DEBUGGING_TYPE;
1397 else
1398 opts->x_debug_info_level = DINFO_LEVEL_NONE;
1401 if (!opts_set->x_debug_nonbind_markers_p)
1402 opts->x_debug_nonbind_markers_p
1403 = (opts->x_optimize
1404 && opts->x_debug_info_level >= DINFO_LEVEL_NORMAL
1405 && (dwarf_debuginfo_p (opts) || codeview_debuginfo_p ())
1406 && !(opts->x_flag_selective_scheduling
1407 || opts->x_flag_selective_scheduling2));
1409 /* We know which debug output will be used so we can set flag_var_tracking
1410 and flag_var_tracking_uninit if the user has not specified them. */
1411 if (opts->x_debug_info_level < DINFO_LEVEL_NORMAL
1412 || (!dwarf_debuginfo_p (opts) && !codeview_debuginfo_p ())
1413 /* We have not yet initialized debug hooks so match that to check
1414 whether we're only doing DWARF2_LINENO_DEBUGGING_INFO. */
1415 #ifndef DWARF2_DEBUGGING_INFO
1416 || true
1417 #endif
1420 if ((opts_set->x_flag_var_tracking && opts->x_flag_var_tracking == 1)
1421 || (opts_set->x_flag_var_tracking_uninit
1422 && opts->x_flag_var_tracking_uninit == 1))
1424 if (opts->x_debug_info_level < DINFO_LEVEL_NORMAL)
1425 warning_at (UNKNOWN_LOCATION, 0,
1426 "variable tracking requested, but useless unless "
1427 "producing debug info");
1428 else
1429 warning_at (UNKNOWN_LOCATION, 0,
1430 "variable tracking requested, but not supported "
1431 "by this debug format");
1433 opts->x_flag_var_tracking = 0;
1434 opts->x_flag_var_tracking_uninit = 0;
1435 opts->x_flag_var_tracking_assignments = 0;
1438 /* One could use EnabledBy, but it would lead to a circular dependency. */
1439 if (!opts_set->x_flag_var_tracking_uninit)
1440 opts->x_flag_var_tracking_uninit = opts->x_flag_var_tracking;
1442 if (!opts_set->x_flag_var_tracking_assignments)
1443 opts->x_flag_var_tracking_assignments
1444 = (opts->x_flag_var_tracking
1445 && !(opts->x_flag_selective_scheduling
1446 || opts->x_flag_selective_scheduling2));
1448 if (opts->x_flag_var_tracking_assignments_toggle)
1449 opts->x_flag_var_tracking_assignments
1450 = !opts->x_flag_var_tracking_assignments;
1452 if (opts->x_flag_var_tracking_assignments && !opts->x_flag_var_tracking)
1453 opts->x_flag_var_tracking = opts->x_flag_var_tracking_assignments = -1;
1455 if (opts->x_flag_var_tracking_assignments
1456 && (opts->x_flag_selective_scheduling
1457 || opts->x_flag_selective_scheduling2))
1458 warning_at (loc, 0,
1459 "var-tracking-assignments changes selective scheduling");
1461 if (opts->x_flag_syntax_only)
1463 opts->x_write_symbols = NO_DEBUG;
1464 opts->x_profile_flag = 0;
1467 if (opts->x_warn_strict_flex_arrays)
1468 if (opts->x_flag_strict_flex_arrays == 0)
1470 opts->x_warn_strict_flex_arrays = 0;
1471 warning_at (UNKNOWN_LOCATION, 0,
1472 "%<-Wstrict-flex-arrays%> is ignored when"
1473 " %<-fstrict-flex-arrays%> is not present");
1476 diagnose_options (opts, opts_set, loc);
1479 /* The function diagnoses incompatible combinations for provided options
1480 (OPTS and OPTS_SET) at a given LOCation. The function is called both
1481 when command line is parsed (after the target optimization hook) and
1482 when an optimize/target attribute (or pragma) is used. */
1484 void diagnose_options (gcc_options *opts, gcc_options *opts_set,
1485 location_t loc)
1487 /* The optimization to partition hot and cold basic blocks into separate
1488 sections of the .o and executable files does not work (currently)
1489 with exception handling. This is because there is no support for
1490 generating unwind info. If opts->x_flag_exceptions is turned on
1491 we need to turn off the partitioning optimization. */
1493 enum unwind_info_type ui_except
1494 = targetm_common.except_unwind_info (opts);
1496 if (opts->x_flag_exceptions
1497 && opts->x_flag_reorder_blocks_and_partition
1498 && (ui_except == UI_SJLJ || ui_except >= UI_TARGET))
1500 if (opts_set->x_flag_reorder_blocks_and_partition)
1501 inform (loc,
1502 "%<-freorder-blocks-and-partition%> does not work "
1503 "with exceptions on this architecture");
1504 opts->x_flag_reorder_blocks_and_partition = 0;
1505 opts->x_flag_reorder_blocks = 1;
1508 /* If user requested unwind info, then turn off the partitioning
1509 optimization. */
1511 if (opts->x_flag_unwind_tables
1512 && !targetm_common.unwind_tables_default
1513 && opts->x_flag_reorder_blocks_and_partition
1514 && (ui_except == UI_SJLJ || ui_except >= UI_TARGET))
1516 if (opts_set->x_flag_reorder_blocks_and_partition)
1517 inform (loc,
1518 "%<-freorder-blocks-and-partition%> does not support "
1519 "unwind info on this architecture");
1520 opts->x_flag_reorder_blocks_and_partition = 0;
1521 opts->x_flag_reorder_blocks = 1;
1524 /* If the target requested unwind info, then turn off the partitioning
1525 optimization with a different message. Likewise, if the target does not
1526 support named sections. */
1528 if (opts->x_flag_reorder_blocks_and_partition
1529 && (!targetm_common.have_named_sections
1530 || (opts->x_flag_unwind_tables
1531 && targetm_common.unwind_tables_default
1532 && (ui_except == UI_SJLJ || ui_except >= UI_TARGET))))
1534 if (opts_set->x_flag_reorder_blocks_and_partition)
1535 inform (loc,
1536 "%<-freorder-blocks-and-partition%> does not work "
1537 "on this architecture");
1538 opts->x_flag_reorder_blocks_and_partition = 0;
1539 opts->x_flag_reorder_blocks = 1;
1545 #define LEFT_COLUMN 27
1547 /* Output ITEM, of length ITEM_WIDTH, in the left column,
1548 followed by word-wrapped HELP in a second column. */
1549 static void
1550 wrap_help (const char *help,
1551 const char *item,
1552 unsigned int item_width,
1553 unsigned int columns)
1555 unsigned int col_width = LEFT_COLUMN;
1556 unsigned int remaining, room, len;
1558 remaining = strlen (help);
1562 room = columns - 3 - MAX (col_width, item_width);
1563 if (room > columns)
1564 room = 0;
1565 len = remaining;
1567 if (room < len)
1569 unsigned int i;
1571 for (i = 0; help[i]; i++)
1573 if (i >= room && len != remaining)
1574 break;
1575 if (help[i] == ' ')
1576 len = i;
1577 else if ((help[i] == '-' || help[i] == '/')
1578 && help[i + 1] != ' '
1579 && i > 0 && ISALPHA (help[i - 1]))
1580 len = i + 1;
1584 printf (" %-*.*s %.*s\n", col_width, item_width, item, len, help);
1585 item_width = 0;
1586 while (help[len] == ' ')
1587 len++;
1588 help += len;
1589 remaining -= len;
1591 while (remaining);
1594 /* Data structure used to print list of valid option values. */
1596 class option_help_tuple
1598 public:
1599 option_help_tuple (int code, vec<const char *> values):
1600 m_code (code), m_values (values)
1603 /* Code of an option. */
1604 int m_code;
1606 /* List of possible values. */
1607 vec<const char *> m_values;
1610 /* Print help for a specific front-end, etc. */
1611 static void
1612 print_filtered_help (unsigned int include_flags,
1613 unsigned int exclude_flags,
1614 unsigned int any_flags,
1615 unsigned int columns,
1616 struct gcc_options *opts,
1617 unsigned int lang_mask)
1619 unsigned int i;
1620 const char *help;
1621 bool found = false;
1622 bool displayed = false;
1623 char new_help[256];
1625 if (!opts->x_help_printed)
1626 opts->x_help_printed = XCNEWVAR (char, cl_options_count);
1628 if (!opts->x_help_enum_printed)
1629 opts->x_help_enum_printed = XCNEWVAR (char, cl_enums_count);
1631 auto_vec<option_help_tuple> help_tuples;
1633 for (i = 0; i < cl_options_count; i++)
1635 const struct cl_option *option = cl_options + i;
1636 unsigned int len;
1637 const char *opt;
1638 const char *tab;
1640 if (include_flags == 0
1641 || ((option->flags & include_flags) != include_flags))
1643 if ((option->flags & any_flags) == 0)
1644 continue;
1647 /* Skip unwanted switches. */
1648 if ((option->flags & exclude_flags) != 0)
1649 continue;
1651 /* The driver currently prints its own help text. */
1652 if ((option->flags & CL_DRIVER) != 0
1653 && (option->flags & (((1U << cl_lang_count) - 1)
1654 | CL_COMMON | CL_TARGET)) == 0)
1655 continue;
1657 /* If an option contains a language specification,
1658 exclude it from common unless all languages are present. */
1659 if ((include_flags & CL_COMMON)
1660 && !(option->flags & CL_DRIVER)
1661 && (option->flags & CL_LANG_ALL)
1662 && (option->flags & CL_LANG_ALL) != CL_LANG_ALL)
1663 continue;
1665 found = true;
1666 /* Skip switches that have already been printed. */
1667 if (opts->x_help_printed[i])
1668 continue;
1670 opts->x_help_printed[i] = true;
1672 help = option->help;
1673 if (help == NULL)
1675 if (exclude_flags & CL_UNDOCUMENTED)
1676 continue;
1678 help = undocumented_msg;
1681 /* Get the translation. */
1682 help = _(help);
1684 if (option->alias_target < N_OPTS
1685 && cl_options [option->alias_target].help)
1687 const struct cl_option *target = cl_options + option->alias_target;
1688 if (option->help == NULL)
1690 /* The option is undocumented but is an alias for an option that
1691 is documented. If the option has alias arguments, then its
1692 purpose is to provide certain arguments to the other option, so
1693 inform the reader of this. Otherwise, point the reader to the
1694 other option in preference to the former. */
1696 if (option->alias_arg)
1698 if (option->neg_alias_arg)
1699 snprintf (new_help, sizeof new_help,
1700 _("Same as %s%s (or, in negated form, %s%s)."),
1701 target->opt_text, option->alias_arg,
1702 target->opt_text, option->neg_alias_arg);
1703 else
1704 snprintf (new_help, sizeof new_help,
1705 _("Same as %s%s."),
1706 target->opt_text, option->alias_arg);
1708 else
1709 snprintf (new_help, sizeof new_help,
1710 _("Same as %s."),
1711 target->opt_text);
1713 else
1715 /* For documented options with aliases, mention the aliased
1716 option's name for reference. */
1717 snprintf (new_help, sizeof new_help,
1718 _("%s Same as %s."),
1719 help, cl_options [option->alias_target].opt_text);
1722 help = new_help;
1725 if (option->warn_message)
1727 /* Mention that the use of the option will trigger a warning. */
1728 if (help == new_help)
1729 snprintf (new_help + strlen (new_help),
1730 sizeof new_help - strlen (new_help),
1731 " %s", _(use_diagnosed_msg));
1732 else
1733 snprintf (new_help, sizeof new_help,
1734 "%s %s", help, _(use_diagnosed_msg));
1736 help = new_help;
1739 /* Find the gap between the name of the
1740 option and its descriptive text. */
1741 tab = strchr (help, '\t');
1742 if (tab)
1744 len = tab - help;
1745 opt = help;
1746 help = tab + 1;
1748 else
1750 opt = option->opt_text;
1751 len = strlen (opt);
1754 /* With the -Q option enabled we change the descriptive text associated
1755 with an option to be an indication of its current setting. */
1756 if (!opts->x_quiet_flag)
1758 void *flag_var = option_flag_var (i, opts);
1760 if (len < (LEFT_COLUMN + 2))
1761 strcpy (new_help, "\t\t");
1762 else
1763 strcpy (new_help, "\t");
1765 /* Set to print whether the option is enabled or disabled,
1766 or, if it's an alias for another option, the name of
1767 the aliased option. */
1768 bool print_state = false;
1770 if (flag_var != NULL
1771 && option->var_type != CLVC_DEFER)
1773 /* If OPTION is only available for a specific subset
1774 of languages other than this one, mention them. */
1775 bool avail_for_lang = true;
1776 if (unsigned langset = option->flags & CL_LANG_ALL)
1778 if (!(langset & lang_mask))
1780 avail_for_lang = false;
1781 strcat (new_help, _("[available in "));
1782 for (unsigned i = 0, n = 0; (1U << i) < CL_LANG_ALL; ++i)
1783 if (langset & (1U << i))
1785 if (n++)
1786 strcat (new_help, ", ");
1787 strcat (new_help, lang_names[i]);
1789 strcat (new_help, "]");
1792 if (!avail_for_lang)
1793 ; /* Print nothing else if the option is not available
1794 in the current language. */
1795 else if (option->flags & CL_JOINED)
1797 if (option->var_type == CLVC_STRING)
1799 if (* (const char **) flag_var != NULL)
1800 snprintf (new_help + strlen (new_help),
1801 sizeof (new_help) - strlen (new_help),
1802 "%s", * (const char **) flag_var);
1804 else if (option->var_type == CLVC_ENUM)
1806 const struct cl_enum *e = &cl_enums[option->var_enum];
1807 int value;
1808 const char *arg = NULL;
1810 value = e->get (flag_var);
1811 enum_value_to_arg (e->values, &arg, value, lang_mask);
1812 if (arg == NULL)
1813 arg = _("[default]");
1814 snprintf (new_help + strlen (new_help),
1815 sizeof (new_help) - strlen (new_help),
1816 "%s", arg);
1818 else
1820 if (option->cl_host_wide_int)
1821 sprintf (new_help + strlen (new_help),
1822 _("%llu bytes"), (unsigned long long)
1823 *(unsigned HOST_WIDE_INT *) flag_var);
1824 else
1825 sprintf (new_help + strlen (new_help),
1826 "%i", * (int *) flag_var);
1829 else
1830 print_state = true;
1832 else
1833 /* When there is no argument, print the option state only
1834 if the option takes no argument. */
1835 print_state = !(option->flags & CL_JOINED);
1837 if (print_state)
1839 if (option->alias_target < N_OPTS
1840 && option->alias_target != OPT_SPECIAL_warn_removed
1841 && option->alias_target != OPT_SPECIAL_ignore
1842 && option->alias_target != OPT_SPECIAL_input_file
1843 && option->alias_target != OPT_SPECIAL_program_name
1844 && option->alias_target != OPT_SPECIAL_unknown)
1846 const struct cl_option *target
1847 = &cl_options[option->alias_target];
1848 sprintf (new_help + strlen (new_help), "%s%s",
1849 target->opt_text,
1850 option->alias_arg ? option->alias_arg : "");
1852 else if (option->alias_target == OPT_SPECIAL_ignore)
1853 strcat (new_help, ("[ignored]"));
1854 else
1856 /* Print the state for an on/off option. */
1857 int ena = option_enabled (i, lang_mask, opts);
1858 if (ena > 0)
1859 strcat (new_help, _("[enabled]"));
1860 else if (ena == 0)
1861 strcat (new_help, _("[disabled]"));
1865 help = new_help;
1868 if (option->range_max != -1 && tab == NULL)
1870 char b[128];
1871 snprintf (b, sizeof (b), "<%d,%d>", option->range_min,
1872 option->range_max);
1873 opt = concat (opt, b, NULL);
1874 len += strlen (b);
1877 wrap_help (help, opt, len, columns);
1878 displayed = true;
1880 if (option->var_type == CLVC_ENUM
1881 && opts->x_help_enum_printed[option->var_enum] != 2)
1882 opts->x_help_enum_printed[option->var_enum] = 1;
1883 else
1885 vec<const char *> option_values
1886 = targetm_common.get_valid_option_values (i, NULL);
1887 if (!option_values.is_empty ())
1888 help_tuples.safe_push (option_help_tuple (i, option_values));
1892 if (! found)
1894 unsigned int langs = include_flags & CL_LANG_ALL;
1896 if (langs == 0)
1897 printf (_(" No options with the desired characteristics were found\n"));
1898 else
1900 unsigned int i;
1902 /* PR 31349: Tell the user how to see all of the
1903 options supported by a specific front end. */
1904 for (i = 0; (1U << i) < CL_LANG_ALL; i ++)
1905 if ((1U << i) & langs)
1906 printf (_(" None found. Use --help=%s to show *all* the options supported by the %s front-end.\n"),
1907 lang_names[i], lang_names[i]);
1911 else if (! displayed)
1912 printf (_(" All options with the desired characteristics have already been displayed\n"));
1914 putchar ('\n');
1916 /* Print details of enumerated option arguments, if those
1917 enumerations have help text headings provided. If no help text
1918 is provided, presume that the possible values are listed in the
1919 help text for the relevant options. */
1920 for (i = 0; i < cl_enums_count; i++)
1922 unsigned int j, pos;
1924 if (opts->x_help_enum_printed[i] != 1)
1925 continue;
1926 if (cl_enums[i].help == NULL)
1927 continue;
1928 printf (" %s\n ", _(cl_enums[i].help));
1929 pos = 4;
1930 for (j = 0; cl_enums[i].values[j].arg != NULL; j++)
1932 unsigned int len = strlen (cl_enums[i].values[j].arg);
1934 if (pos > 4 && pos + 1 + len <= columns)
1936 printf (" %s", cl_enums[i].values[j].arg);
1937 pos += 1 + len;
1939 else
1941 if (pos > 4)
1943 printf ("\n ");
1944 pos = 4;
1946 printf ("%s", cl_enums[i].values[j].arg);
1947 pos += len;
1950 printf ("\n\n");
1951 opts->x_help_enum_printed[i] = 2;
1954 for (unsigned i = 0; i < help_tuples.length (); i++)
1956 const struct cl_option *option = cl_options + help_tuples[i].m_code;
1957 printf (_(" Known valid arguments for %s option:\n "),
1958 option->opt_text);
1959 for (unsigned j = 0; j < help_tuples[i].m_values.length (); j++)
1960 printf (" %s", help_tuples[i].m_values[j]);
1961 printf ("\n\n");
1965 /* Display help for a specified type of option.
1966 The options must have ALL of the INCLUDE_FLAGS set
1967 ANY of the flags in the ANY_FLAGS set
1968 and NONE of the EXCLUDE_FLAGS set. The current option state is in
1969 OPTS; LANG_MASK is used for interpreting enumerated option state. */
1970 static void
1971 print_specific_help (unsigned int include_flags,
1972 unsigned int exclude_flags,
1973 unsigned int any_flags,
1974 struct gcc_options *opts,
1975 unsigned int lang_mask)
1977 unsigned int all_langs_mask = (1U << cl_lang_count) - 1;
1978 const char * description = NULL;
1979 const char * descrip_extra = "";
1980 size_t i;
1981 unsigned int flag;
1983 /* Sanity check: Make sure that we do not have more
1984 languages than we have bits available to enumerate them. */
1985 gcc_assert ((1U << cl_lang_count) <= CL_MIN_OPTION_CLASS);
1987 /* If we have not done so already, obtain
1988 the desired maximum width of the output. */
1989 if (opts->x_help_columns == 0)
1991 opts->x_help_columns = get_terminal_width ();
1992 if (opts->x_help_columns == INT_MAX)
1993 /* Use a reasonable default. */
1994 opts->x_help_columns = 80;
1997 /* Decide upon the title for the options that we are going to display. */
1998 for (i = 0, flag = 1; flag <= CL_MAX_OPTION_CLASS; flag <<= 1, i ++)
2000 switch (flag & include_flags)
2002 case 0:
2003 case CL_DRIVER:
2004 break;
2006 case CL_TARGET:
2007 description = _("The following options are target specific");
2008 break;
2009 case CL_WARNING:
2010 description = _("The following options control compiler warning messages");
2011 break;
2012 case CL_OPTIMIZATION:
2013 description = _("The following options control optimizations");
2014 break;
2015 case CL_COMMON:
2016 description = _("The following options are language-independent");
2017 break;
2018 case CL_PARAMS:
2019 description = _("The following options control parameters");
2020 break;
2021 default:
2022 if (i >= cl_lang_count)
2023 break;
2024 if (exclude_flags & all_langs_mask)
2025 description = _("The following options are specific to just the language ");
2026 else
2027 description = _("The following options are supported by the language ");
2028 descrip_extra = lang_names [i];
2029 break;
2033 if (description == NULL)
2035 if (any_flags == 0)
2037 if (include_flags & CL_UNDOCUMENTED)
2038 description = _("The following options are not documented");
2039 else if (include_flags & CL_SEPARATE)
2040 description = _("The following options take separate arguments");
2041 else if (include_flags & CL_JOINED)
2042 description = _("The following options take joined arguments");
2043 else
2045 internal_error ("unrecognized %<include_flags 0x%x%> passed "
2046 "to %<print_specific_help%>",
2047 include_flags);
2048 return;
2051 else
2053 if (any_flags & all_langs_mask)
2054 description = _("The following options are language-related");
2055 else
2056 description = _("The following options are language-independent");
2060 printf ("%s%s:\n", description, descrip_extra);
2061 print_filtered_help (include_flags, exclude_flags, any_flags,
2062 opts->x_help_columns, opts, lang_mask);
2065 /* Enable FDO-related flags. */
2067 static void
2068 enable_fdo_optimizations (struct gcc_options *opts,
2069 struct gcc_options *opts_set,
2070 int value)
2072 SET_OPTION_IF_UNSET (opts, opts_set, flag_branch_probabilities, value);
2073 SET_OPTION_IF_UNSET (opts, opts_set, flag_profile_values, value);
2074 SET_OPTION_IF_UNSET (opts, opts_set, flag_unroll_loops, value);
2075 SET_OPTION_IF_UNSET (opts, opts_set, flag_peel_loops, value);
2076 SET_OPTION_IF_UNSET (opts, opts_set, flag_tracer, value);
2077 SET_OPTION_IF_UNSET (opts, opts_set, flag_value_profile_transformations,
2078 value);
2079 SET_OPTION_IF_UNSET (opts, opts_set, flag_inline_functions, value);
2080 SET_OPTION_IF_UNSET (opts, opts_set, flag_ipa_cp, value);
2081 if (value)
2083 SET_OPTION_IF_UNSET (opts, opts_set, flag_ipa_cp_clone, 1);
2084 SET_OPTION_IF_UNSET (opts, opts_set, flag_ipa_bit_cp, 1);
2086 SET_OPTION_IF_UNSET (opts, opts_set, flag_predictive_commoning, value);
2087 SET_OPTION_IF_UNSET (opts, opts_set, flag_split_loops, value);
2088 SET_OPTION_IF_UNSET (opts, opts_set, flag_unswitch_loops, value);
2089 SET_OPTION_IF_UNSET (opts, opts_set, flag_gcse_after_reload, value);
2090 SET_OPTION_IF_UNSET (opts, opts_set, flag_tree_loop_vectorize, value);
2091 SET_OPTION_IF_UNSET (opts, opts_set, flag_tree_slp_vectorize, value);
2092 SET_OPTION_IF_UNSET (opts, opts_set, flag_version_loops_for_strides, value);
2093 SET_OPTION_IF_UNSET (opts, opts_set, flag_vect_cost_model,
2094 VECT_COST_MODEL_DYNAMIC);
2095 SET_OPTION_IF_UNSET (opts, opts_set, flag_tree_loop_distribute_patterns,
2096 value);
2097 SET_OPTION_IF_UNSET (opts, opts_set, flag_loop_interchange, value);
2098 SET_OPTION_IF_UNSET (opts, opts_set, flag_unroll_jam, value);
2099 SET_OPTION_IF_UNSET (opts, opts_set, flag_tree_loop_distribution, value);
2100 SET_OPTION_IF_UNSET (opts, opts_set, flag_optimize_crc, value);
2103 /* -f{,no-}sanitize{,-recover}= suboptions. */
2104 const struct sanitizer_opts_s sanitizer_opts[] =
2106 #define SANITIZER_OPT(name, flags, recover, trap) \
2107 { #name, flags, sizeof #name - 1, recover, trap }
2108 SANITIZER_OPT (address, (SANITIZE_ADDRESS | SANITIZE_USER_ADDRESS), true,
2109 false),
2110 SANITIZER_OPT (hwaddress, (SANITIZE_HWADDRESS | SANITIZE_USER_HWADDRESS),
2111 true, false),
2112 SANITIZER_OPT (kernel-address, (SANITIZE_ADDRESS | SANITIZE_KERNEL_ADDRESS),
2113 true, false),
2114 SANITIZER_OPT (kernel-hwaddress,
2115 (SANITIZE_HWADDRESS | SANITIZE_KERNEL_HWADDRESS),
2116 true, false),
2117 SANITIZER_OPT (pointer-compare, SANITIZE_POINTER_COMPARE, true, false),
2118 SANITIZER_OPT (pointer-subtract, SANITIZE_POINTER_SUBTRACT, true, false),
2119 SANITIZER_OPT (thread, SANITIZE_THREAD, false, false),
2120 SANITIZER_OPT (leak, SANITIZE_LEAK, false, false),
2121 SANITIZER_OPT (shift, SANITIZE_SHIFT, true, true),
2122 SANITIZER_OPT (shift-base, SANITIZE_SHIFT_BASE, true, true),
2123 SANITIZER_OPT (shift-exponent, SANITIZE_SHIFT_EXPONENT, true, true),
2124 SANITIZER_OPT (integer-divide-by-zero, SANITIZE_DIVIDE, true, true),
2125 SANITIZER_OPT (undefined, SANITIZE_UNDEFINED, true, true),
2126 SANITIZER_OPT (unreachable, SANITIZE_UNREACHABLE, false, true),
2127 SANITIZER_OPT (vla-bound, SANITIZE_VLA, true, true),
2128 SANITIZER_OPT (return, SANITIZE_RETURN, false, true),
2129 SANITIZER_OPT (null, SANITIZE_NULL, true, true),
2130 SANITIZER_OPT (signed-integer-overflow, SANITIZE_SI_OVERFLOW, true, true),
2131 SANITIZER_OPT (bool, SANITIZE_BOOL, true, true),
2132 SANITIZER_OPT (enum, SANITIZE_ENUM, true, true),
2133 SANITIZER_OPT (float-divide-by-zero, SANITIZE_FLOAT_DIVIDE, true, true),
2134 SANITIZER_OPT (float-cast-overflow, SANITIZE_FLOAT_CAST, true, true),
2135 SANITIZER_OPT (bounds, SANITIZE_BOUNDS, true, true),
2136 SANITIZER_OPT (bounds-strict, SANITIZE_BOUNDS | SANITIZE_BOUNDS_STRICT, true,
2137 true),
2138 SANITIZER_OPT (alignment, SANITIZE_ALIGNMENT, true, true),
2139 SANITIZER_OPT (nonnull-attribute, SANITIZE_NONNULL_ATTRIBUTE, true, true),
2140 SANITIZER_OPT (returns-nonnull-attribute, SANITIZE_RETURNS_NONNULL_ATTRIBUTE,
2141 true, true),
2142 SANITIZER_OPT (object-size, SANITIZE_OBJECT_SIZE, true, true),
2143 SANITIZER_OPT (vptr, SANITIZE_VPTR, true, false),
2144 SANITIZER_OPT (pointer-overflow, SANITIZE_POINTER_OVERFLOW, true, true),
2145 SANITIZER_OPT (builtin, SANITIZE_BUILTIN, true, true),
2146 SANITIZER_OPT (shadow-call-stack, SANITIZE_SHADOW_CALL_STACK, false, false),
2147 SANITIZER_OPT (all, ~0U, true, true),
2148 #undef SANITIZER_OPT
2149 { NULL, 0U, 0UL, false, false }
2152 /* -fzero-call-used-regs= suboptions. */
2153 const struct zero_call_used_regs_opts_s zero_call_used_regs_opts[] =
2155 #define ZERO_CALL_USED_REGS_OPT(name, flags) \
2156 { #name, flags }
2157 ZERO_CALL_USED_REGS_OPT (skip, zero_regs_flags::SKIP),
2158 ZERO_CALL_USED_REGS_OPT (used-gpr-arg, zero_regs_flags::USED_GPR_ARG),
2159 ZERO_CALL_USED_REGS_OPT (used-gpr, zero_regs_flags::USED_GPR),
2160 ZERO_CALL_USED_REGS_OPT (used-arg, zero_regs_flags::USED_ARG),
2161 ZERO_CALL_USED_REGS_OPT (used, zero_regs_flags::USED),
2162 ZERO_CALL_USED_REGS_OPT (all-gpr-arg, zero_regs_flags::ALL_GPR_ARG),
2163 ZERO_CALL_USED_REGS_OPT (all-gpr, zero_regs_flags::ALL_GPR),
2164 ZERO_CALL_USED_REGS_OPT (all-arg, zero_regs_flags::ALL_ARG),
2165 ZERO_CALL_USED_REGS_OPT (all, zero_regs_flags::ALL),
2166 ZERO_CALL_USED_REGS_OPT (leafy-gpr-arg, zero_regs_flags::LEAFY_GPR_ARG),
2167 ZERO_CALL_USED_REGS_OPT (leafy-gpr, zero_regs_flags::LEAFY_GPR),
2168 ZERO_CALL_USED_REGS_OPT (leafy-arg, zero_regs_flags::LEAFY_ARG),
2169 ZERO_CALL_USED_REGS_OPT (leafy, zero_regs_flags::LEAFY),
2170 #undef ZERO_CALL_USED_REGS_OPT
2171 {NULL, 0U}
2174 /* A struct for describing a run of chars within a string. */
2176 class string_fragment
2178 public:
2179 string_fragment (const char *start, size_t len)
2180 : m_start (start), m_len (len) {}
2182 const char *m_start;
2183 size_t m_len;
2186 /* Specialization of edit_distance_traits for string_fragment,
2187 for use by get_closest_sanitizer_option. */
2189 template <>
2190 struct edit_distance_traits<const string_fragment &>
2192 static size_t get_length (const string_fragment &fragment)
2194 return fragment.m_len;
2197 static const char *get_string (const string_fragment &fragment)
2199 return fragment.m_start;
2203 /* Given ARG, an unrecognized sanitizer option, return the best
2204 matching sanitizer option, or NULL if there isn't one.
2205 OPTS is array of candidate sanitizer options.
2206 CODE is OPT_fsanitize_, OPT_fsanitize_recover_ or OPT_fsanitize_trap_.
2207 VALUE is non-zero for the regular form of the option, zero
2208 for the "no-" form (e.g. "-fno-sanitize-recover="). */
2210 static const char *
2211 get_closest_sanitizer_option (const string_fragment &arg,
2212 const struct sanitizer_opts_s *opts,
2213 enum opt_code code, int value)
2215 best_match <const string_fragment &, const char*> bm (arg);
2216 for (int i = 0; opts[i].name != NULL; ++i)
2218 /* -fsanitize=all is not valid, so don't offer it. */
2219 if (code == OPT_fsanitize_
2220 && opts[i].flag == ~0U
2221 && value)
2222 continue;
2224 /* For -fsanitize-recover= (and not -fno-sanitize-recover=),
2225 don't offer the non-recoverable options. */
2226 if (code == OPT_fsanitize_recover_
2227 && !opts[i].can_recover
2228 && value)
2229 continue;
2231 /* For -fsanitize-trap= (and not -fno-sanitize-trap=),
2232 don't offer the non-trapping options. */
2233 if (code == OPT_fsanitize_trap_
2234 && !opts[i].can_trap
2235 && value)
2236 continue;
2238 bm.consider (opts[i].name);
2240 return bm.get_best_meaningful_candidate ();
2243 /* Parse comma separated sanitizer suboptions from P for option SCODE,
2244 adjust previous FLAGS and return new ones. If COMPLAIN is false,
2245 don't issue diagnostics. */
2247 unsigned int
2248 parse_sanitizer_options (const char *p, location_t loc, int scode,
2249 unsigned int flags, int value, bool complain)
2251 enum opt_code code = (enum opt_code) scode;
2253 while (*p != 0)
2255 size_t len, i;
2256 bool found = false;
2257 const char *comma = strchr (p, ',');
2259 if (comma == NULL)
2260 len = strlen (p);
2261 else
2262 len = comma - p;
2263 if (len == 0)
2265 p = comma + 1;
2266 continue;
2269 /* Check to see if the string matches an option class name. */
2270 for (i = 0; sanitizer_opts[i].name != NULL; ++i)
2271 if (len == sanitizer_opts[i].len
2272 && memcmp (p, sanitizer_opts[i].name, len) == 0)
2274 /* Handle both -fsanitize and -fno-sanitize cases. */
2275 if (value && sanitizer_opts[i].flag == ~0U)
2277 if (code == OPT_fsanitize_)
2279 if (complain)
2280 error_at (loc, "%<-fsanitize=all%> option is not valid");
2282 else if (code == OPT_fsanitize_recover_)
2283 flags |= ~(SANITIZE_THREAD | SANITIZE_LEAK
2284 | SANITIZE_UNREACHABLE | SANITIZE_RETURN
2285 | SANITIZE_SHADOW_CALL_STACK);
2286 else /* if (code == OPT_fsanitize_trap_) */
2287 flags |= (SANITIZE_UNDEFINED
2288 | SANITIZE_UNDEFINED_NONDEFAULT);
2290 else if (value)
2292 /* Do not enable -fsanitize-recover=unreachable and
2293 -fsanitize-recover=return if -fsanitize-recover=undefined
2294 is selected. */
2295 if (code == OPT_fsanitize_recover_
2296 && sanitizer_opts[i].flag == SANITIZE_UNDEFINED)
2297 flags |= (SANITIZE_UNDEFINED
2298 & ~(SANITIZE_UNREACHABLE | SANITIZE_RETURN));
2299 else if (code == OPT_fsanitize_trap_
2300 && sanitizer_opts[i].flag == SANITIZE_VPTR)
2301 error_at (loc, "%<-fsanitize-trap=%s%> is not supported",
2302 sanitizer_opts[i].name);
2303 else
2304 flags |= sanitizer_opts[i].flag;
2306 else
2308 flags &= ~sanitizer_opts[i].flag;
2309 /* Don't always clear SANITIZE_ADDRESS if it was previously
2310 set: -fsanitize=address -fno-sanitize=kernel-address should
2311 leave SANITIZE_ADDRESS set. */
2312 if (flags & (SANITIZE_KERNEL_ADDRESS | SANITIZE_USER_ADDRESS))
2313 flags |= SANITIZE_ADDRESS;
2315 found = true;
2316 break;
2319 if (! found && complain)
2321 const char *hint
2322 = get_closest_sanitizer_option (string_fragment (p, len),
2323 sanitizer_opts, code, value);
2325 const char *suffix;
2326 if (code == OPT_fsanitize_recover_)
2327 suffix = "-recover";
2328 else if (code == OPT_fsanitize_trap_)
2329 suffix = "-trap";
2330 else
2331 suffix = "";
2333 if (hint)
2334 error_at (loc,
2335 "unrecognized argument to %<-f%ssanitize%s=%> "
2336 "option: %q.*s; did you mean %qs?",
2337 value ? "" : "no-",
2338 suffix, (int) len, p, hint);
2339 else
2340 error_at (loc,
2341 "unrecognized argument to %<-f%ssanitize%s=%> option: "
2342 "%q.*s", value ? "" : "no-",
2343 suffix, (int) len, p);
2346 if (comma == NULL)
2347 break;
2348 p = comma + 1;
2350 return flags;
2353 /* Parse string values of no_sanitize attribute passed in VALUE.
2354 Values are separated with comma. */
2356 unsigned int
2357 parse_no_sanitize_attribute (char *value)
2359 unsigned int flags = 0;
2360 unsigned int i;
2361 char *q = strtok (value, ",");
2363 while (q != NULL)
2365 for (i = 0; sanitizer_opts[i].name != NULL; ++i)
2366 if (strcmp (sanitizer_opts[i].name, q) == 0)
2368 flags |= sanitizer_opts[i].flag;
2369 if (sanitizer_opts[i].flag == SANITIZE_UNDEFINED)
2370 flags |= SANITIZE_UNDEFINED_NONDEFAULT;
2371 break;
2374 if (sanitizer_opts[i].name == NULL)
2375 warning (OPT_Wattributes,
2376 "%qs attribute directive ignored", q);
2378 q = strtok (NULL, ",");
2381 return flags;
2384 /* Parse -fzero-call-used-regs suboptions from ARG, return the FLAGS. */
2386 unsigned int
2387 parse_zero_call_used_regs_options (const char *arg)
2389 unsigned int flags = 0;
2391 /* Check to see if the string matches a sub-option name. */
2392 for (unsigned int i = 0; zero_call_used_regs_opts[i].name != NULL; ++i)
2393 if (strcmp (arg, zero_call_used_regs_opts[i].name) == 0)
2395 flags = zero_call_used_regs_opts[i].flag;
2396 break;
2399 if (!flags)
2400 error ("unrecognized argument to %<-fzero-call-used-regs=%>: %qs", arg);
2402 return flags;
2405 /* Parse -falign-NAME format for a FLAG value. Return individual
2406 parsed integer values into RESULT_VALUES array. If REPORT_ERROR is
2407 set, print error message at LOC location. */
2409 bool
2410 parse_and_check_align_values (const char *flag,
2411 const char *name,
2412 auto_vec<unsigned> &result_values,
2413 bool report_error,
2414 location_t loc)
2416 char *str = xstrdup (flag);
2417 for (char *p = strtok (str, ":"); p; p = strtok (NULL, ":"))
2419 char *end;
2420 int v = strtol (p, &end, 10);
2421 if (*end != '\0' || v < 0)
2423 if (report_error)
2424 error_at (loc, "invalid arguments for %<-falign-%s%> option: %qs",
2425 name, flag);
2427 return false;
2430 result_values.safe_push ((unsigned)v);
2433 free (str);
2435 /* Check that we have a correct number of values. */
2436 if (result_values.is_empty () || result_values.length () > 4)
2438 if (report_error)
2439 error_at (loc, "invalid number of arguments for %<-falign-%s%> "
2440 "option: %qs", name, flag);
2441 return false;
2444 for (unsigned i = 0; i < result_values.length (); i++)
2445 if (result_values[i] > MAX_CODE_ALIGN_VALUE)
2447 if (report_error)
2448 error_at (loc, "%<-falign-%s%> is not between 0 and %d",
2449 name, MAX_CODE_ALIGN_VALUE);
2450 return false;
2453 return true;
2456 /* Check that alignment value FLAG for -falign-NAME is valid at a given
2457 location LOC. OPT_STR points to the stored -falign-NAME=argument and
2458 OPT_FLAG points to the associated -falign-NAME on/off flag. */
2460 static void
2461 check_alignment_argument (location_t loc, const char *flag, const char *name,
2462 int *opt_flag, const char **opt_str)
2464 auto_vec<unsigned> align_result;
2465 parse_and_check_align_values (flag, name, align_result, true, loc);
2467 if (align_result.length() >= 1 && align_result[0] == 0)
2469 *opt_flag = 1;
2470 *opt_str = NULL;
2474 /* Parse argument of -fpatchable-function-entry option ARG and store
2475 corresponding values to PATCH_AREA_SIZE and PATCH_AREA_START.
2476 If REPORT_ERROR is set to true, generate error for a problematic
2477 option arguments. */
2479 void
2480 parse_and_check_patch_area (const char *arg, bool report_error,
2481 HOST_WIDE_INT *patch_area_size,
2482 HOST_WIDE_INT *patch_area_start)
2484 *patch_area_size = 0;
2485 *patch_area_start = 0;
2487 if (arg == NULL)
2488 return;
2490 char *patch_area_arg = xstrdup (arg);
2491 char *comma = strchr (patch_area_arg, ',');
2492 if (comma)
2494 *comma = '\0';
2495 *patch_area_size = integral_argument (patch_area_arg);
2496 *patch_area_start = integral_argument (comma + 1);
2498 else
2499 *patch_area_size = integral_argument (patch_area_arg);
2501 if (*patch_area_size < 0
2502 || *patch_area_size > USHRT_MAX
2503 || *patch_area_start < 0
2504 || *patch_area_start > USHRT_MAX
2505 || *patch_area_size < *patch_area_start)
2506 if (report_error)
2507 error ("invalid arguments for %<-fpatchable-function-entry%>");
2509 free (patch_area_arg);
2512 /* Print options enabled by -fhardened. Keep this in sync with the manual! */
2514 static void
2515 print_help_hardened ()
2517 printf ("%s\n", "The following options are enabled by -fhardened:");
2518 /* Unfortunately, I can't seem to use targetm.fortify_source_default_level
2519 here. */
2520 printf (" %s\n", "-D_FORTIFY_SOURCE=3 (or =2 for glibc < 2.35)");
2521 printf (" %s\n", "-D_GLIBCXX_ASSERTIONS");
2522 printf (" %s\n", "-ftrivial-auto-var-init=zero");
2523 #ifdef HAVE_LD_PIE
2524 printf (" %s %s\n", "-fPIE", "-pie");
2525 #endif
2526 if (HAVE_LD_NOW_SUPPORT)
2527 printf (" %s\n", "-Wl,-z,now");
2528 if (HAVE_LD_RELRO_SUPPORT)
2529 printf (" %s\n", "-Wl,-z,relro");
2530 printf (" %s\n", "-fstack-protector-strong");
2531 printf (" %s\n", "-fstack-clash-protection");
2532 printf (" %s\n", "-fcf-protection=full");
2533 putchar ('\n');
2536 /* Print help when OPT__help_ is set. */
2538 void
2539 print_help (struct gcc_options *opts, unsigned int lang_mask,
2540 const char *help_option_argument)
2542 const char *a = help_option_argument;
2543 unsigned int include_flags = 0;
2544 /* Note - by default we include undocumented options when listing
2545 specific classes. If you only want to see documented options
2546 then add ",^undocumented" to the --help= option. E.g.:
2548 --help=target,^undocumented */
2549 unsigned int exclude_flags = 0;
2551 if (lang_mask == CL_DRIVER)
2552 return;
2554 /* Walk along the argument string, parsing each word in turn.
2555 The format is:
2556 arg = [^]{word}[,{arg}]
2557 word = {optimizers|target|warnings|undocumented|
2558 params|common|<language>} */
2559 while (*a != 0)
2561 static const struct
2563 const char *string;
2564 unsigned int flag;
2566 specifics[] =
2568 { "optimizers", CL_OPTIMIZATION },
2569 { "target", CL_TARGET },
2570 { "warnings", CL_WARNING },
2571 { "undocumented", CL_UNDOCUMENTED },
2572 { "params", CL_PARAMS },
2573 { "joined", CL_JOINED },
2574 { "separate", CL_SEPARATE },
2575 { "common", CL_COMMON },
2576 { NULL, 0 }
2578 unsigned int *pflags;
2579 const char *comma;
2580 unsigned int lang_flag, specific_flag;
2581 unsigned int len;
2582 unsigned int i;
2584 if (*a == '^')
2586 ++a;
2587 if (*a == '\0')
2589 error ("missing argument to %qs", "--help=^");
2590 break;
2592 pflags = &exclude_flags;
2594 else
2595 pflags = &include_flags;
2597 comma = strchr (a, ',');
2598 if (comma == NULL)
2599 len = strlen (a);
2600 else
2601 len = comma - a;
2602 if (len == 0)
2604 a = comma + 1;
2605 continue;
2608 /* Check to see if the string matches an option class name. */
2609 for (i = 0, specific_flag = 0; specifics[i].string != NULL; i++)
2610 if (strncasecmp (a, specifics[i].string, len) == 0)
2612 specific_flag = specifics[i].flag;
2613 break;
2616 /* Check to see if the string matches a language name.
2617 Note - we rely upon the alpha-sorted nature of the entries in
2618 the lang_names array, specifically that shorter names appear
2619 before their longer variants. (i.e. C before C++). That way
2620 when we are attempting to match --help=c for example we will
2621 match with C first and not C++. */
2622 for (i = 0, lang_flag = 0; i < cl_lang_count; i++)
2623 if (strncasecmp (a, lang_names[i], len) == 0)
2625 lang_flag = 1U << i;
2626 break;
2629 if (specific_flag != 0)
2631 if (lang_flag == 0)
2632 *pflags |= specific_flag;
2633 else
2635 /* The option's argument matches both the start of a
2636 language name and the start of an option class name.
2637 We have a special case for when the user has
2638 specified "--help=c", but otherwise we have to issue
2639 a warning. */
2640 if (strncasecmp (a, "c", len) == 0)
2641 *pflags |= lang_flag;
2642 else
2643 warning (0,
2644 "%<--help%> argument %q.*s is ambiguous, "
2645 "please be more specific",
2646 len, a);
2649 else if (lang_flag != 0)
2650 *pflags |= lang_flag;
2651 else if (strncasecmp (a, "hardened", len) == 0)
2652 print_help_hardened ();
2653 else
2654 warning (0,
2655 "unrecognized argument to %<--help=%> option: %q.*s",
2656 len, a);
2658 if (comma == NULL)
2659 break;
2660 a = comma + 1;
2663 /* We started using PerFunction/Optimization for parameters and
2664 a warning. We should exclude these from optimization options. */
2665 if (include_flags & CL_OPTIMIZATION)
2666 exclude_flags |= CL_WARNING;
2667 if (!(include_flags & CL_PARAMS))
2668 exclude_flags |= CL_PARAMS;
2670 if (include_flags)
2671 print_specific_help (include_flags, exclude_flags, 0, opts,
2672 lang_mask);
2675 /* Handle target- and language-independent options. Return zero to
2676 generate an "unknown option" message. Only options that need
2677 extra handling need to be listed here; if you simply want
2678 DECODED->value assigned to a variable, it happens automatically. */
2680 bool
2681 common_handle_option (struct gcc_options *opts,
2682 struct gcc_options *opts_set,
2683 const struct cl_decoded_option *decoded,
2684 unsigned int lang_mask, int kind ATTRIBUTE_UNUSED,
2685 location_t loc,
2686 const struct cl_option_handlers *handlers,
2687 diagnostic_context *dc,
2688 void (*target_option_override_hook) (void))
2690 size_t scode = decoded->opt_index;
2691 const char *arg = decoded->arg;
2692 HOST_WIDE_INT value = decoded->value;
2693 enum opt_code code = (enum opt_code) scode;
2695 gcc_assert (decoded->canonical_option_num_elements <= 2);
2697 switch (code)
2699 case OPT__help:
2701 unsigned int all_langs_mask = (1U << cl_lang_count) - 1;
2702 unsigned int undoc_mask;
2703 unsigned int i;
2705 if (lang_mask == CL_DRIVER)
2706 break;
2708 undoc_mask = ((opts->x_verbose_flag | opts->x_extra_warnings)
2710 : CL_UNDOCUMENTED);
2711 target_option_override_hook ();
2712 /* First display any single language specific options. */
2713 for (i = 0; i < cl_lang_count; i++)
2714 print_specific_help
2715 (1U << i, (all_langs_mask & (~ (1U << i))) | undoc_mask, 0, opts,
2716 lang_mask);
2717 /* Next display any multi language specific options. */
2718 print_specific_help (0, undoc_mask, all_langs_mask, opts, lang_mask);
2719 /* Then display any remaining, non-language options. */
2720 for (i = CL_MIN_OPTION_CLASS; i <= CL_MAX_OPTION_CLASS; i <<= 1)
2721 if (i != CL_DRIVER)
2722 print_specific_help (i, undoc_mask, 0, opts, lang_mask);
2723 opts->x_exit_after_options = true;
2724 break;
2727 case OPT__target_help:
2728 if (lang_mask == CL_DRIVER)
2729 break;
2731 target_option_override_hook ();
2732 print_specific_help (CL_TARGET, 0, 0, opts, lang_mask);
2733 opts->x_exit_after_options = true;
2734 break;
2736 case OPT__help_:
2738 help_option_arguments.safe_push (arg);
2739 opts->x_exit_after_options = true;
2740 break;
2743 case OPT__version:
2744 if (lang_mask == CL_DRIVER)
2745 break;
2747 opts->x_exit_after_options = true;
2748 break;
2750 case OPT__completion_:
2751 break;
2753 case OPT_fsanitize_:
2754 opts_set->x_flag_sanitize = true;
2755 opts->x_flag_sanitize
2756 = parse_sanitizer_options (arg, loc, code,
2757 opts->x_flag_sanitize, value, true);
2759 /* Kernel ASan implies normal ASan but does not yet support
2760 all features. */
2761 if (opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS)
2763 SET_OPTION_IF_UNSET (opts, opts_set,
2764 param_asan_instrumentation_with_call_threshold,
2766 SET_OPTION_IF_UNSET (opts, opts_set, param_asan_globals, 0);
2767 SET_OPTION_IF_UNSET (opts, opts_set, param_asan_stack, 0);
2768 SET_OPTION_IF_UNSET (opts, opts_set, param_asan_protect_allocas, 0);
2769 SET_OPTION_IF_UNSET (opts, opts_set, param_asan_use_after_return, 0);
2771 if (opts->x_flag_sanitize & SANITIZE_KERNEL_HWADDRESS)
2773 SET_OPTION_IF_UNSET (opts, opts_set,
2774 param_hwasan_instrument_stack, 0);
2775 SET_OPTION_IF_UNSET (opts, opts_set,
2776 param_hwasan_random_frame_tag, 0);
2777 SET_OPTION_IF_UNSET (opts, opts_set,
2778 param_hwasan_instrument_allocas, 0);
2780 break;
2782 case OPT_fsanitize_recover_:
2783 opts->x_flag_sanitize_recover
2784 = parse_sanitizer_options (arg, loc, code,
2785 opts->x_flag_sanitize_recover, value, true);
2786 break;
2788 case OPT_fsanitize_trap_:
2789 opts->x_flag_sanitize_trap
2790 = parse_sanitizer_options (arg, loc, code,
2791 opts->x_flag_sanitize_trap, value, true);
2792 break;
2794 case OPT_fasan_shadow_offset_:
2795 /* Deferred. */
2796 break;
2798 case OPT_fsanitize_address_use_after_scope:
2799 opts->x_flag_sanitize_address_use_after_scope = value;
2800 break;
2802 case OPT_fsanitize_recover:
2803 if (value)
2804 opts->x_flag_sanitize_recover
2805 |= (SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT)
2806 & ~(SANITIZE_UNREACHABLE | SANITIZE_RETURN);
2807 else
2808 opts->x_flag_sanitize_recover
2809 &= ~(SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT);
2810 break;
2812 case OPT_fsanitize_trap:
2813 if (value)
2814 opts->x_flag_sanitize_trap
2815 |= (SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT);
2816 else
2817 opts->x_flag_sanitize_trap
2818 &= ~(SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT);
2819 break;
2821 case OPT_O:
2822 case OPT_Os:
2823 case OPT_Ofast:
2824 case OPT_Og:
2825 case OPT_Oz:
2826 /* Currently handled in a prescan. */
2827 break;
2829 case OPT_Wattributes_:
2830 if (lang_mask == CL_DRIVER)
2831 break;
2833 if (value)
2835 error_at (loc, "arguments ignored for %<-Wattributes=%>; use "
2836 "%<-Wno-attributes=%> instead");
2837 break;
2839 else if (arg[strlen (arg) - 1] == ',')
2841 error_at (loc, "trailing %<,%> in arguments for "
2842 "%<-Wno-attributes=%>");
2843 break;
2846 add_comma_separated_to_vector (&opts->x_flag_ignored_attributes, arg);
2847 break;
2849 case OPT_Werror:
2850 dc->set_warning_as_error_requested (value);
2851 break;
2853 case OPT_Werror_:
2854 if (lang_mask == CL_DRIVER)
2855 break;
2857 enable_warning_as_error (arg, value, lang_mask, handlers,
2858 opts, opts_set, loc, dc);
2859 break;
2861 case OPT_Wfatal_errors:
2862 dc->m_fatal_errors = value;
2863 break;
2865 case OPT_Wstack_usage_:
2866 opts->x_flag_stack_usage_info = value != -1;
2867 break;
2869 case OPT_Wstrict_aliasing:
2870 set_Wstrict_aliasing (opts, value);
2871 break;
2873 case OPT_Wstrict_overflow:
2874 opts->x_warn_strict_overflow = (value
2875 ? (int) WARN_STRICT_OVERFLOW_CONDITIONAL
2876 : 0);
2877 break;
2879 case OPT_Wsystem_headers:
2880 dc->m_warn_system_headers = value;
2881 break;
2883 case OPT_aux_info:
2884 opts->x_flag_gen_aux_info = 1;
2885 break;
2887 case OPT_d:
2888 decode_d_option (arg, opts, loc, dc);
2889 break;
2891 case OPT_fcall_used_:
2892 case OPT_fcall_saved_:
2893 /* Deferred. */
2894 break;
2896 case OPT_fdbg_cnt_:
2897 /* Deferred. */
2898 break;
2900 case OPT_fdebug_prefix_map_:
2901 case OPT_ffile_prefix_map_:
2902 case OPT_fprofile_prefix_map_:
2903 /* Deferred. */
2904 break;
2906 case OPT_fcanon_prefix_map:
2907 flag_canon_prefix_map = value;
2908 break;
2910 case OPT_fcallgraph_info:
2911 opts->x_flag_callgraph_info = CALLGRAPH_INFO_NAKED;
2912 break;
2914 case OPT_fcallgraph_info_:
2916 char *my_arg, *p;
2917 my_arg = xstrdup (arg);
2918 p = strtok (my_arg, ",");
2919 while (p)
2921 if (strcmp (p, "su") == 0)
2923 opts->x_flag_callgraph_info |= CALLGRAPH_INFO_STACK_USAGE;
2924 opts->x_flag_stack_usage_info = true;
2926 else if (strcmp (p, "da") == 0)
2927 opts->x_flag_callgraph_info |= CALLGRAPH_INFO_DYNAMIC_ALLOC;
2928 else
2929 return 0;
2930 p = strtok (NULL, ",");
2932 free (my_arg);
2934 break;
2936 case OPT_fdiagnostics_show_location_:
2937 dc->set_prefixing_rule ((diagnostic_prefixing_rule_t) value);
2938 break;
2940 case OPT_fdiagnostics_show_caret:
2941 dc->m_source_printing.enabled = value;
2942 break;
2944 case OPT_fdiagnostics_show_event_links:
2945 dc->m_source_printing.show_event_links_p = value;
2946 break;
2948 case OPT_fdiagnostics_show_labels:
2949 dc->m_source_printing.show_labels_p = value;
2950 break;
2952 case OPT_fdiagnostics_show_line_numbers:
2953 dc->m_source_printing.show_line_numbers_p = value;
2954 break;
2956 case OPT_fdiagnostics_color_:
2957 diagnostic_color_init (dc, value);
2958 break;
2960 case OPT_fdiagnostics_urls_:
2961 diagnostic_urls_init (dc, value);
2962 break;
2964 case OPT_fdiagnostics_format_:
2966 const char *basename = (opts->x_dump_base_name ? opts->x_dump_base_name
2967 : opts->x_main_input_basename);
2968 gcc_assert (dc);
2969 diagnostic_output_format_init (*dc,
2970 opts->x_main_input_filename, basename,
2971 (enum diagnostics_output_format)value,
2972 opts->x_flag_diagnostics_json_formatting);
2973 break;
2976 case OPT_fdiagnostics_add_output_:
2977 handle_OPT_fdiagnostics_add_output_ (*opts, *dc, arg, loc);
2978 break;
2980 case OPT_fdiagnostics_set_output_:
2981 handle_OPT_fdiagnostics_set_output_ (*opts, *dc, arg, loc);
2982 break;
2984 case OPT_fdiagnostics_text_art_charset_:
2985 dc->set_text_art_charset ((enum diagnostic_text_art_charset)value);
2986 break;
2988 case OPT_fdiagnostics_parseable_fixits:
2989 dc->set_extra_output_kind (value
2990 ? EXTRA_DIAGNOSTIC_OUTPUT_fixits_v1
2991 : EXTRA_DIAGNOSTIC_OUTPUT_none);
2992 break;
2994 case OPT_fdiagnostics_column_unit_:
2995 dc->m_column_unit = (enum diagnostics_column_unit)value;
2996 break;
2998 case OPT_fdiagnostics_column_origin_:
2999 dc->m_column_origin = value;
3000 break;
3002 case OPT_fdiagnostics_escape_format_:
3003 dc->set_escape_format ((enum diagnostics_escape_format)value);
3004 break;
3006 case OPT_fdiagnostics_show_highlight_colors:
3007 dc->set_show_highlight_colors (value);
3008 break;
3010 case OPT_fdiagnostics_show_cwe:
3011 dc->set_show_cwe (value);
3012 break;
3014 case OPT_fdiagnostics_show_rules:
3015 dc->set_show_rules (value);
3016 break;
3018 case OPT_fdiagnostics_path_format_:
3019 dc->set_path_format ((enum diagnostic_path_format)value);
3020 break;
3022 case OPT_fdiagnostics_show_path_depths:
3023 dc->set_show_path_depths (value);
3024 break;
3026 case OPT_fdiagnostics_show_option:
3027 dc->set_show_option_requested (value);
3028 break;
3030 case OPT_fdiagnostics_minimum_margin_width_:
3031 dc->m_source_printing.min_margin_width = value;
3032 break;
3034 case OPT_fdump_:
3035 /* Deferred. */
3036 break;
3038 case OPT_ffast_math:
3039 set_fast_math_flags (opts, value);
3040 break;
3042 case OPT_funsafe_math_optimizations:
3043 set_unsafe_math_optimizations_flags (opts, value);
3044 break;
3046 case OPT_ffixed_:
3047 /* Deferred. */
3048 break;
3050 case OPT_finline_limit_:
3051 SET_OPTION_IF_UNSET (opts, opts_set, param_max_inline_insns_single,
3052 value / 2);
3053 SET_OPTION_IF_UNSET (opts, opts_set, param_max_inline_insns_auto,
3054 value / 2);
3055 break;
3057 case OPT_finstrument_functions_exclude_function_list_:
3058 add_comma_separated_to_vector
3059 (&opts->x_flag_instrument_functions_exclude_functions, arg);
3060 break;
3062 case OPT_finstrument_functions_exclude_file_list_:
3063 add_comma_separated_to_vector
3064 (&opts->x_flag_instrument_functions_exclude_files, arg);
3065 break;
3067 case OPT_fmessage_length_:
3068 pp_set_line_maximum_length (dc->get_reference_printer (), value);
3069 diagnostic_set_caret_max_width (dc, value);
3070 break;
3072 case OPT_fopt_info:
3073 case OPT_fopt_info_:
3074 /* Deferred. */
3075 break;
3077 case OPT_foffload_options_:
3078 /* Deferred. */
3079 break;
3081 case OPT_foffload_abi_:
3082 case OPT_foffload_abi_host_opts_:
3083 #ifdef ACCEL_COMPILER
3084 /* Handled in the 'mkoffload's. */
3085 #else
3086 error_at (loc,
3087 "%qs option can be specified only for offload compiler",
3088 (code == OPT_foffload_abi_) ? "-foffload-abi"
3089 : "-foffload-abi-host-opts");
3090 #endif
3091 break;
3093 case OPT_fpack_struct_:
3094 if (value <= 0 || (value & (value - 1)) || value > 16)
3095 error_at (loc,
3096 "structure alignment must be a small power of two, not %wu",
3097 value);
3098 else
3099 opts->x_initial_max_fld_align = value;
3100 break;
3102 case OPT_fplugin_:
3103 case OPT_fplugin_arg_:
3104 /* Deferred. */
3105 break;
3107 case OPT_fprofile_use_:
3108 opts->x_profile_data_prefix = xstrdup (arg);
3109 opts->x_flag_profile_use = true;
3110 value = true;
3111 /* No break here - do -fprofile-use processing. */
3112 /* FALLTHRU */
3113 case OPT_fprofile_use:
3114 enable_fdo_optimizations (opts, opts_set, value);
3115 SET_OPTION_IF_UNSET (opts, opts_set, flag_profile_reorder_functions,
3116 value);
3117 /* Indirect call profiling should do all useful transformations
3118 speculative devirtualization does. */
3119 if (opts->x_flag_value_profile_transformations)
3120 SET_OPTION_IF_UNSET (opts, opts_set, flag_devirtualize_speculatively,
3121 false);
3122 break;
3124 case OPT_fauto_profile_:
3125 opts->x_auto_profile_file = xstrdup (arg);
3126 opts->x_flag_auto_profile = true;
3127 value = true;
3128 /* No break here - do -fauto-profile processing. */
3129 /* FALLTHRU */
3130 case OPT_fauto_profile:
3131 enable_fdo_optimizations (opts, opts_set, value);
3132 SET_OPTION_IF_UNSET (opts, opts_set, flag_profile_correction, value);
3133 break;
3135 case OPT_fprofile_generate_:
3136 opts->x_profile_data_prefix = xstrdup (arg);
3137 value = true;
3138 /* No break here - do -fprofile-generate processing. */
3139 /* FALLTHRU */
3140 case OPT_fprofile_generate:
3141 SET_OPTION_IF_UNSET (opts, opts_set, profile_arc_flag, value);
3142 SET_OPTION_IF_UNSET (opts, opts_set, flag_profile_values, value);
3143 SET_OPTION_IF_UNSET (opts, opts_set, flag_inline_functions, value);
3144 SET_OPTION_IF_UNSET (opts, opts_set, flag_ipa_bit_cp, value);
3145 break;
3147 case OPT_fprofile_info_section:
3148 opts->x_profile_info_section = ".gcov_info";
3149 break;
3151 case OPT_fpatchable_function_entry_:
3153 HOST_WIDE_INT patch_area_size, patch_area_start;
3154 parse_and_check_patch_area (arg, true, &patch_area_size,
3155 &patch_area_start);
3157 break;
3159 case OPT_ftree_vectorize:
3160 /* Automatically sets -ftree-loop-vectorize and
3161 -ftree-slp-vectorize. Nothing more to do here. */
3162 break;
3163 case OPT_fzero_call_used_regs_:
3164 opts->x_flag_zero_call_used_regs
3165 = parse_zero_call_used_regs_options (arg);
3166 break;
3168 case OPT_fshow_column:
3169 dc->m_show_column = value;
3170 break;
3172 case OPT_frandom_seed:
3173 /* The real switch is -fno-random-seed. */
3174 if (value)
3175 return false;
3176 /* Deferred. */
3177 break;
3179 case OPT_frandom_seed_:
3180 /* Deferred. */
3181 break;
3183 case OPT_fsched_verbose_:
3184 #ifdef INSN_SCHEDULING
3185 /* Handled with Var in common.opt. */
3186 break;
3187 #else
3188 return false;
3189 #endif
3191 case OPT_fsched_stalled_insns_:
3192 opts->x_flag_sched_stalled_insns = value;
3193 if (opts->x_flag_sched_stalled_insns == 0)
3194 opts->x_flag_sched_stalled_insns = -1;
3195 break;
3197 case OPT_fsched_stalled_insns_dep_:
3198 opts->x_flag_sched_stalled_insns_dep = value;
3199 break;
3201 case OPT_fstack_check_:
3202 if (!strcmp (arg, "no"))
3203 opts->x_flag_stack_check = NO_STACK_CHECK;
3204 else if (!strcmp (arg, "generic"))
3205 /* This is the old stack checking method. */
3206 opts->x_flag_stack_check = STACK_CHECK_BUILTIN
3207 ? FULL_BUILTIN_STACK_CHECK
3208 : GENERIC_STACK_CHECK;
3209 else if (!strcmp (arg, "specific"))
3210 /* This is the new stack checking method. */
3211 opts->x_flag_stack_check = STACK_CHECK_BUILTIN
3212 ? FULL_BUILTIN_STACK_CHECK
3213 : STACK_CHECK_STATIC_BUILTIN
3214 ? STATIC_BUILTIN_STACK_CHECK
3215 : GENERIC_STACK_CHECK;
3216 else
3217 warning_at (loc, 0, "unknown stack check parameter %qs", arg);
3218 break;
3220 case OPT_fstack_limit:
3221 /* The real switch is -fno-stack-limit. */
3222 if (value)
3223 return false;
3224 /* Deferred. */
3225 break;
3227 case OPT_fstack_limit_register_:
3228 case OPT_fstack_limit_symbol_:
3229 /* Deferred. */
3230 break;
3232 case OPT_fstack_usage:
3233 opts->x_flag_stack_usage = value;
3234 opts->x_flag_stack_usage_info = value != 0;
3235 break;
3237 case OPT_g:
3238 set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, arg, opts, opts_set,
3239 loc);
3240 break;
3242 case OPT_gcodeview:
3243 set_debug_level (CODEVIEW_DEBUG, false, arg, opts, opts_set, loc);
3244 if (opts->x_debug_info_level < DINFO_LEVEL_NORMAL)
3245 opts->x_debug_info_level = DINFO_LEVEL_NORMAL;
3246 break;
3248 case OPT_gbtf:
3249 set_debug_level (BTF_DEBUG, false, arg, opts, opts_set, loc);
3250 /* set the debug level to level 2, but if already at level 3,
3251 don't lower it. */
3252 if (opts->x_debug_info_level < DINFO_LEVEL_NORMAL)
3253 opts->x_debug_info_level = DINFO_LEVEL_NORMAL;
3254 break;
3256 case OPT_gctf:
3257 set_debug_level (CTF_DEBUG, false, arg, opts, opts_set, loc);
3258 /* CTF generation feeds off DWARF dies. For optimal CTF, switch debug
3259 info level to 2. If off or at level 1, set it to level 2, but if
3260 already at level 3, don't lower it. */
3261 if (opts->x_debug_info_level < DINFO_LEVEL_NORMAL
3262 && opts->x_ctf_debug_info_level > CTFINFO_LEVEL_NONE)
3263 opts->x_debug_info_level = DINFO_LEVEL_NORMAL;
3264 break;
3266 case OPT_gdwarf:
3267 if (arg && strlen (arg) != 0)
3269 error_at (loc, "%<-gdwarf%s%> is ambiguous; "
3270 "use %<-gdwarf-%s%> for DWARF version "
3271 "or %<-gdwarf%> %<-g%s%> for debug level", arg, arg, arg);
3272 break;
3274 else
3275 value = opts->x_dwarf_version;
3277 /* FALLTHRU */
3278 case OPT_gdwarf_:
3279 if (value < 2 || value > 5)
3280 error_at (loc, "dwarf version %wu is not supported", value);
3281 else
3282 opts->x_dwarf_version = value;
3283 set_debug_level (DWARF2_DEBUG, false, "", opts, opts_set, loc);
3284 break;
3286 case OPT_ggdb:
3287 set_debug_level (NO_DEBUG, 2, arg, opts, opts_set, loc);
3288 break;
3290 case OPT_gvms:
3291 set_debug_level (VMS_DEBUG, false, arg, opts, opts_set, loc);
3292 break;
3294 case OPT_gz:
3295 case OPT_gz_:
3296 /* Handled completely via specs. */
3297 break;
3299 case OPT_pedantic_errors:
3300 dc->m_pedantic_errors = 1;
3301 control_warning_option (OPT_Wpedantic, DK_ERROR, NULL, value,
3302 loc, lang_mask,
3303 handlers, opts, opts_set,
3304 dc);
3305 break;
3307 case OPT_flto:
3308 opts->x_flag_lto = value ? "" : NULL;
3309 break;
3311 case OPT_flto_:
3312 if (strcmp (arg, "none") != 0
3313 && strcmp (arg, "jobserver") != 0
3314 && strcmp (arg, "auto") != 0
3315 && atoi (arg) == 0)
3316 error_at (loc,
3317 "unrecognized argument to %<-flto=%> option: %qs", arg);
3318 break;
3320 case OPT_w:
3321 dc->m_inhibit_warnings = true;
3322 break;
3324 case OPT_fmax_errors_:
3325 dc->set_max_errors (value);
3326 break;
3328 case OPT_fuse_ld_bfd:
3329 case OPT_fuse_ld_gold:
3330 case OPT_fuse_ld_lld:
3331 case OPT_fuse_ld_mold:
3332 case OPT_fuse_linker_plugin:
3333 /* No-op. Used by the driver and passed to us because it starts with f.*/
3334 break;
3336 case OPT_fwrapv:
3337 if (value)
3338 opts->x_flag_trapv = 0;
3339 break;
3341 case OPT_ftrapv:
3342 if (value)
3343 opts->x_flag_wrapv = 0;
3344 break;
3346 case OPT_fstrict_overflow:
3347 opts->x_flag_wrapv = !value;
3348 opts->x_flag_wrapv_pointer = !value;
3349 if (!value)
3350 opts->x_flag_trapv = 0;
3351 break;
3353 case OPT_fipa_icf:
3354 opts->x_flag_ipa_icf_functions = value;
3355 opts->x_flag_ipa_icf_variables = value;
3356 break;
3358 case OPT_falign_loops_:
3359 check_alignment_argument (loc, arg, "loops",
3360 &opts->x_flag_align_loops,
3361 &opts->x_str_align_loops);
3362 break;
3364 case OPT_falign_jumps_:
3365 check_alignment_argument (loc, arg, "jumps",
3366 &opts->x_flag_align_jumps,
3367 &opts->x_str_align_jumps);
3368 break;
3370 case OPT_falign_labels_:
3371 check_alignment_argument (loc, arg, "labels",
3372 &opts->x_flag_align_labels,
3373 &opts->x_str_align_labels);
3374 break;
3376 case OPT_falign_functions_:
3377 check_alignment_argument (loc, arg, "functions",
3378 &opts->x_flag_align_functions,
3379 &opts->x_str_align_functions);
3380 break;
3382 case OPT_ftabstop_:
3383 /* It is documented that we silently ignore silly values. */
3384 if (value >= 1 && value <= 100)
3385 dc->m_tabstop = value;
3386 break;
3388 case OPT_freport_bug:
3389 dc->set_report_bug (value);
3390 break;
3392 case OPT_fmultiflags:
3393 gcc_checking_assert (lang_mask == CL_DRIVER);
3394 break;
3396 default:
3397 /* If the flag was handled in a standard way, assume the lack of
3398 processing here is intentional. */
3399 gcc_assert (option_flag_var (scode, opts));
3400 break;
3403 common_handle_option_auto (opts, opts_set, decoded, lang_mask, kind,
3404 loc, handlers, dc);
3405 return true;
3408 /* Used to set the level of strict aliasing warnings in OPTS,
3409 when no level is specified (i.e., when -Wstrict-aliasing, and not
3410 -Wstrict-aliasing=level was given).
3411 ONOFF is assumed to take value 1 when -Wstrict-aliasing is specified,
3412 and 0 otherwise. After calling this function, wstrict_aliasing will be
3413 set to the default value of -Wstrict_aliasing=level, currently 3. */
3414 static void
3415 set_Wstrict_aliasing (struct gcc_options *opts, int onoff)
3417 gcc_assert (onoff == 0 || onoff == 1);
3418 if (onoff != 0)
3419 opts->x_warn_strict_aliasing = 3;
3420 else
3421 opts->x_warn_strict_aliasing = 0;
3424 /* The following routines are useful in setting all the flags that
3425 -ffast-math and -fno-fast-math imply. */
3426 static void
3427 set_fast_math_flags (struct gcc_options *opts, int set)
3429 if (!opts->frontend_set_flag_unsafe_math_optimizations)
3431 opts->x_flag_unsafe_math_optimizations = set;
3432 set_unsafe_math_optimizations_flags (opts, set);
3434 if (!opts->frontend_set_flag_finite_math_only)
3435 opts->x_flag_finite_math_only = set;
3436 if (!opts->frontend_set_flag_errno_math)
3437 opts->x_flag_errno_math = !set;
3438 if (set)
3440 if (opts->frontend_set_flag_excess_precision == EXCESS_PRECISION_DEFAULT)
3441 opts->x_flag_excess_precision
3442 = set ? EXCESS_PRECISION_FAST : EXCESS_PRECISION_DEFAULT;
3443 if (!opts->frontend_set_flag_signaling_nans)
3444 opts->x_flag_signaling_nans = 0;
3445 if (!opts->frontend_set_flag_rounding_math)
3446 opts->x_flag_rounding_math = 0;
3447 if (!opts->frontend_set_flag_cx_limited_range)
3448 opts->x_flag_cx_limited_range = 1;
3452 /* When -funsafe-math-optimizations is set the following
3453 flags are set as well. */
3454 static void
3455 set_unsafe_math_optimizations_flags (struct gcc_options *opts, int set)
3457 if (!opts->frontend_set_flag_trapping_math)
3458 opts->x_flag_trapping_math = !set;
3459 if (!opts->frontend_set_flag_signed_zeros)
3460 opts->x_flag_signed_zeros = !set;
3461 if (!opts->frontend_set_flag_associative_math)
3462 opts->x_flag_associative_math = set;
3463 if (!opts->frontend_set_flag_reciprocal_math)
3464 opts->x_flag_reciprocal_math = set;
3467 /* Return true iff flags in OPTS are set as if -ffast-math. */
3468 bool
3469 fast_math_flags_set_p (const struct gcc_options *opts)
3471 return (!opts->x_flag_trapping_math
3472 && opts->x_flag_unsafe_math_optimizations
3473 && opts->x_flag_finite_math_only
3474 && !opts->x_flag_signed_zeros
3475 && !opts->x_flag_errno_math
3476 && opts->x_flag_excess_precision == EXCESS_PRECISION_FAST);
3479 /* Return true iff flags are set as if -ffast-math but using the flags stored
3480 in the struct cl_optimization structure. */
3481 bool
3482 fast_math_flags_struct_set_p (struct cl_optimization *opt)
3484 return (!opt->x_flag_trapping_math
3485 && opt->x_flag_unsafe_math_optimizations
3486 && opt->x_flag_finite_math_only
3487 && !opt->x_flag_signed_zeros
3488 && !opt->x_flag_errno_math);
3491 /* Handle a debug output -g switch for options OPTS
3492 (OPTS_SET->x_write_symbols storing whether a debug format was passed
3493 explicitly), location LOC. EXTENDED is true or false to support
3494 extended output (2 is special and means "-ggdb" was given). */
3495 static void
3496 set_debug_level (uint32_t dinfo, int extended, const char *arg,
3497 struct gcc_options *opts, struct gcc_options *opts_set,
3498 location_t loc)
3500 if (dinfo == NO_DEBUG)
3502 if (opts->x_write_symbols == NO_DEBUG)
3504 opts->x_write_symbols = PREFERRED_DEBUGGING_TYPE;
3506 if (extended == 2)
3508 #if defined DWARF2_DEBUGGING_INFO || defined DWARF2_LINENO_DEBUGGING_INFO
3509 if (opts->x_write_symbols & CTF_DEBUG)
3510 opts->x_write_symbols |= DWARF2_DEBUG;
3511 else
3512 opts->x_write_symbols = DWARF2_DEBUG;
3513 #endif
3516 if (opts->x_write_symbols == NO_DEBUG)
3517 warning_at (loc, 0, "target system does not support debug output");
3519 else if ((opts->x_write_symbols & CTF_DEBUG)
3520 || (opts->x_write_symbols & BTF_DEBUG)
3521 || (opts->x_write_symbols & CODEVIEW_DEBUG))
3523 opts->x_write_symbols |= DWARF2_DEBUG;
3524 opts_set->x_write_symbols |= DWARF2_DEBUG;
3527 else
3529 /* Make and retain the choice if both CTF and DWARF debug info are to
3530 be generated. */
3531 if (((dinfo == DWARF2_DEBUG) || (dinfo == CTF_DEBUG))
3532 && ((opts->x_write_symbols == (DWARF2_DEBUG|CTF_DEBUG))
3533 || (opts->x_write_symbols == DWARF2_DEBUG)
3534 || (opts->x_write_symbols == CTF_DEBUG)))
3536 opts->x_write_symbols |= dinfo;
3537 opts_set->x_write_symbols |= dinfo;
3539 /* However, CTF and BTF are not allowed together at this time. */
3540 else if (((dinfo == DWARF2_DEBUG) || (dinfo == BTF_DEBUG))
3541 && ((opts->x_write_symbols == (DWARF2_DEBUG|BTF_DEBUG))
3542 || (opts->x_write_symbols == DWARF2_DEBUG)
3543 || (opts->x_write_symbols == BTF_DEBUG)))
3545 opts->x_write_symbols |= dinfo;
3546 opts_set->x_write_symbols |= dinfo;
3548 else
3550 /* Does it conflict with an already selected debug format? */
3551 if (opts_set->x_write_symbols != NO_DEBUG
3552 && opts->x_write_symbols != NO_DEBUG
3553 && dinfo != opts->x_write_symbols)
3555 gcc_assert (debug_set_count (dinfo) <= 1);
3556 error_at (loc, "debug format %qs conflicts with prior selection",
3557 debug_type_names[debug_set_to_format (dinfo)]);
3559 opts->x_write_symbols = dinfo;
3560 opts_set->x_write_symbols = dinfo;
3564 if (dinfo != BTF_DEBUG)
3566 /* A debug flag without a level defaults to level 2.
3567 If off or at level 1, set it to level 2, but if already
3568 at level 3, don't lower it. */
3569 if (*arg == '\0')
3571 if (dinfo == CTF_DEBUG)
3572 opts->x_ctf_debug_info_level = CTFINFO_LEVEL_NORMAL;
3573 else if (opts->x_debug_info_level < DINFO_LEVEL_NORMAL)
3574 opts->x_debug_info_level = DINFO_LEVEL_NORMAL;
3576 else
3578 int argval = integral_argument (arg);
3579 if (argval == -1)
3580 error_at (loc, "unrecognized debug output level %qs", arg);
3581 else if (argval > 3)
3582 error_at (loc, "debug output level %qs is too high", arg);
3583 else
3585 if (dinfo == CTF_DEBUG)
3586 opts->x_ctf_debug_info_level
3587 = (enum ctf_debug_info_levels) argval;
3588 else
3589 opts->x_debug_info_level = (enum debug_info_levels) argval;
3593 else if (*arg != '\0')
3594 error_at (loc, "unrecognized btf debug output level %qs", arg);
3597 /* Arrange to dump core on error for diagnostic context DC. (The
3598 regular error message is still printed first, except in the case of
3599 abort ().) */
3601 static void
3602 setup_core_dumping (diagnostic_context *dc)
3604 #ifdef SIGABRT
3605 signal (SIGABRT, SIG_DFL);
3606 #endif
3607 #if defined(HAVE_SETRLIMIT)
3609 struct rlimit rlim;
3610 if (getrlimit (RLIMIT_CORE, &rlim) != 0)
3611 fatal_error (input_location, "getting core file size maximum limit: %m");
3612 rlim.rlim_cur = rlim.rlim_max;
3613 if (setrlimit (RLIMIT_CORE, &rlim) != 0)
3614 fatal_error (input_location,
3615 "setting core file size limit to maximum: %m");
3617 #endif
3618 diagnostic_abort_on_error (dc);
3621 /* Parse a -d<ARG> command line switch for OPTS, location LOC,
3622 diagnostic context DC. */
3624 static void
3625 decode_d_option (const char *arg, struct gcc_options *opts,
3626 location_t loc, diagnostic_context *dc)
3628 int c;
3630 while (*arg)
3631 switch (c = *arg++)
3633 case 'A':
3634 opts->x_flag_debug_asm = 1;
3635 break;
3636 case 'p':
3637 opts->x_flag_print_asm_name = 1;
3638 break;
3639 case 'P':
3640 opts->x_flag_dump_rtl_in_asm = 1;
3641 opts->x_flag_print_asm_name = 1;
3642 break;
3643 case 'x':
3644 opts->x_rtl_dump_and_exit = 1;
3645 break;
3646 case 'D': /* These are handled by the preprocessor. */
3647 case 'I':
3648 case 'M':
3649 case 'N':
3650 case 'U':
3651 break;
3652 case 'H':
3653 setup_core_dumping (dc);
3654 break;
3655 case 'a':
3656 opts->x_flag_dump_all_passed = true;
3657 break;
3659 default:
3660 warning_at (loc, 0, "unrecognized gcc debugging option: %c", c);
3661 break;
3665 /* Enable (or disable if VALUE is 0) a warning option ARG (language
3666 mask LANG_MASK, option handlers HANDLERS) as an error for option
3667 structures OPTS and OPTS_SET, diagnostic context DC (possibly
3668 NULL), location LOC. This is used by -Werror=. */
3670 static void
3671 enable_warning_as_error (const char *arg, int value, unsigned int lang_mask,
3672 const struct cl_option_handlers *handlers,
3673 struct gcc_options *opts,
3674 struct gcc_options *opts_set,
3675 location_t loc, diagnostic_context *dc)
3677 char *new_option;
3678 int option_index;
3680 new_option = XNEWVEC (char, strlen (arg) + 2);
3681 new_option[0] = 'W';
3682 strcpy (new_option + 1, arg);
3683 option_index = find_opt (new_option, lang_mask);
3684 if (option_index == OPT_SPECIAL_unknown)
3686 option_proposer op;
3687 const char *hint = op.suggest_option (new_option);
3688 if (hint)
3689 error_at (loc, "%<-W%serror=%s%>: no option %<-%s%>;"
3690 " did you mean %<-%s%>?", value ? "" : "no-",
3691 arg, new_option, hint);
3692 else
3693 error_at (loc, "%<-W%serror=%s%>: no option %<-%s%>",
3694 value ? "" : "no-", arg, new_option);
3696 else if (!(cl_options[option_index].flags & CL_WARNING))
3697 error_at (loc, "%<-Werror=%s%>: %<-%s%> is not an option that "
3698 "controls warnings", arg, new_option);
3699 else
3701 const diagnostic_t kind = value ? DK_ERROR : DK_WARNING;
3702 const char *arg = NULL;
3704 if (cl_options[option_index].flags & CL_JOINED)
3705 arg = new_option + cl_options[option_index].opt_len;
3706 control_warning_option (option_index, (int) kind, arg, value,
3707 loc, lang_mask,
3708 handlers, opts, opts_set, dc);
3710 free (new_option);
3713 /* Return malloced memory for the name of the option OPTION_INDEX
3714 which enabled a diagnostic, originally of type
3715 ORIG_DIAG_KIND but possibly converted to DIAG_KIND by options such
3716 as -Werror. */
3718 char *
3719 compiler_diagnostic_option_manager::
3720 make_option_name (diagnostic_option_id option_id,
3721 diagnostic_t orig_diag_kind,
3722 diagnostic_t diag_kind) const
3724 if (option_id.m_idx)
3726 /* A warning classified as an error. */
3727 if ((orig_diag_kind == DK_WARNING || orig_diag_kind == DK_PEDWARN)
3728 && diag_kind == DK_ERROR)
3729 return concat (cl_options[OPT_Werror_].opt_text,
3730 /* Skip over "-W". */
3731 cl_options[option_id.m_idx].opt_text + 2,
3732 NULL);
3733 /* A warning with option. */
3734 else
3735 return xstrdup (cl_options[option_id.m_idx].opt_text);
3737 /* A warning without option classified as an error. */
3738 else if ((orig_diag_kind == DK_WARNING || orig_diag_kind == DK_PEDWARN
3739 || diag_kind == DK_WARNING)
3740 && m_context.warning_as_error_requested_p ())
3741 return xstrdup (cl_options[OPT_Werror].opt_text);
3742 else
3743 return NULL;
3746 /* Get the page within the documentation for this option. */
3748 static const char *
3749 get_option_html_page (int option_index)
3751 const cl_option *cl_opt = &cl_options[option_index];
3753 #ifdef CL_Fortran
3754 if ((cl_opt->flags & CL_Fortran) != 0
3755 /* If it is option common to both C/C++ and Fortran, it is documented
3756 in gcc/ rather than gfortran/ docs. */
3757 && (cl_opt->flags & CL_C) == 0
3758 #ifdef CL_CXX
3759 && (cl_opt->flags & CL_CXX) == 0
3760 #endif
3762 return "gfortran/Error-and-Warning-Options.html";
3763 #endif
3765 return nullptr;
3768 /* Get the url within the documentation for this option, or NULL. */
3770 label_text
3771 get_option_url_suffix (int option_index, unsigned lang_mask)
3773 if (const char *url = get_opt_url_suffix (option_index, lang_mask))
3775 return label_text::borrow (url);
3777 /* Fallback code for some options that aren't handled byt opt_url_suffixes
3778 e.g. links below "gfortran/". */
3779 if (const char *html_page = get_option_html_page (option_index))
3780 return label_text::take
3781 (concat (html_page,
3782 /* Expect an anchor of the form "index-Wfoo" e.g.
3783 <a name="index-Wformat"></a>, and thus an id within
3784 the page of "#index-Wformat". */
3785 "#index",
3786 cl_options[option_index].opt_text,
3787 NULL));
3789 return label_text ();
3792 /* Return malloced memory for a URL describing the option OPTION_INDEX
3793 which enabled a diagnostic. */
3795 char *
3796 gcc_diagnostic_option_manager::
3797 make_option_url (diagnostic_option_id option_id) const
3799 if (option_id.m_idx)
3801 label_text url_suffix = get_option_url_suffix (option_id.m_idx,
3802 m_lang_mask);
3803 if (url_suffix.get ())
3804 return concat (DOCUMENTATION_ROOT_URL, url_suffix.get (), nullptr);
3807 return nullptr;
3810 /* Return a heap allocated producer with command line options. */
3812 char *
3813 gen_command_line_string (cl_decoded_option *options,
3814 unsigned int options_count)
3816 auto_vec<const char *> switches;
3817 char *options_string, *tail;
3818 const char *p;
3819 size_t len = 0;
3821 for (unsigned i = 0; i < options_count; i++)
3822 switch (options[i].opt_index)
3824 case OPT_o:
3825 case OPT_d:
3826 case OPT_dumpbase:
3827 case OPT_dumpbase_ext:
3828 case OPT_dumpdir:
3829 case OPT_quiet:
3830 case OPT_version:
3831 case OPT_v:
3832 case OPT_w:
3833 case OPT_L:
3834 case OPT_D:
3835 case OPT_I:
3836 case OPT_U:
3837 case OPT_SPECIAL_unknown:
3838 case OPT_SPECIAL_ignore:
3839 case OPT_SPECIAL_warn_removed:
3840 case OPT_SPECIAL_program_name:
3841 case OPT_SPECIAL_input_file:
3842 case OPT_grecord_gcc_switches:
3843 case OPT_frecord_gcc_switches:
3844 case OPT__output_pch:
3845 case OPT_fdiagnostics_show_highlight_colors:
3846 case OPT_fdiagnostics_show_location_:
3847 case OPT_fdiagnostics_show_option:
3848 case OPT_fdiagnostics_show_caret:
3849 case OPT_fdiagnostics_show_event_links:
3850 case OPT_fdiagnostics_show_labels:
3851 case OPT_fdiagnostics_show_line_numbers:
3852 case OPT_fdiagnostics_color_:
3853 case OPT_fdiagnostics_format_:
3854 case OPT_fverbose_asm:
3855 case OPT____:
3856 case OPT__sysroot_:
3857 case OPT_nostdinc:
3858 case OPT_nostdinc__:
3859 case OPT_fpreprocessed:
3860 case OPT_fltrans_output_list_:
3861 case OPT_fresolution_:
3862 case OPT_fdebug_prefix_map_:
3863 case OPT_fmacro_prefix_map_:
3864 case OPT_ffile_prefix_map_:
3865 case OPT_fprofile_prefix_map_:
3866 case OPT_fcanon_prefix_map:
3867 case OPT_fcompare_debug:
3868 case OPT_fchecking:
3869 case OPT_fchecking_:
3870 /* Ignore these. */
3871 continue;
3872 case OPT_flto_:
3874 const char *lto_canonical = "-flto";
3875 switches.safe_push (lto_canonical);
3876 len += strlen (lto_canonical) + 1;
3877 break;
3879 default:
3880 if (cl_options[options[i].opt_index].flags
3881 & CL_NO_DWARF_RECORD)
3882 continue;
3883 gcc_checking_assert (options[i].canonical_option[0][0] == '-');
3884 switch (options[i].canonical_option[0][1])
3886 case 'M':
3887 case 'i':
3888 case 'W':
3889 continue;
3890 case 'f':
3891 if (strncmp (options[i].canonical_option[0] + 2,
3892 "dump", 4) == 0)
3893 continue;
3894 break;
3895 default:
3896 break;
3898 switches.safe_push (options[i].orig_option_with_args_text);
3899 len += strlen (options[i].orig_option_with_args_text) + 1;
3900 break;
3903 options_string = XNEWVEC (char, len + 1);
3904 tail = options_string;
3906 unsigned i;
3907 FOR_EACH_VEC_ELT (switches, i, p)
3909 len = strlen (p);
3910 memcpy (tail, p, len);
3911 tail += len;
3912 if (i != switches.length () - 1)
3914 *tail = ' ';
3915 ++tail;
3919 *tail = '\0';
3920 return options_string;
3923 /* Return a heap allocated producer string including command line options. */
3925 char *
3926 gen_producer_string (const char *language_string, cl_decoded_option *options,
3927 unsigned int options_count)
3929 char *cmdline = gen_command_line_string (options, options_count);
3930 char *combined = concat (language_string, " ", version_string, " ",
3931 cmdline, NULL);
3932 free (cmdline);
3933 return combined;
3936 #if CHECKING_P
3938 namespace selftest {
3940 /* Verify that get_option_url_suffix works as expected. */
3942 static void
3943 test_get_option_url_suffix ()
3945 ASSERT_STREQ (get_option_url_suffix (OPT_Wcpp, 0).get (),
3946 "gcc/Warning-Options.html#index-Wcpp");
3947 ASSERT_STREQ (get_option_url_suffix (OPT_Wanalyzer_double_free, 0).get (),
3948 "gcc/Static-Analyzer-Options.html#index-Wanalyzer-double-free");
3950 /* Test of a D-specific option. */
3951 #ifdef CL_D
3952 ASSERT_EQ (get_option_url_suffix (OPT_fbounds_check_, 0).get (), nullptr);
3953 ASSERT_STREQ (get_option_url_suffix (OPT_fbounds_check_, CL_D).get (),
3954 "gdc/Runtime-Options.html#index-fbounds-check");
3956 /* Test of a D-specific override to an option URL. */
3957 /* Generic URL. */
3958 ASSERT_STREQ (get_option_url_suffix (OPT_fmax_errors_, 0).get (),
3959 "gcc/Warning-Options.html#index-fmax-errors");
3960 /* D-specific URL. */
3961 ASSERT_STREQ (get_option_url_suffix (OPT_fmax_errors_, CL_D).get (),
3962 "gdc/Warnings.html#index-fmax-errors");
3963 #endif
3965 #ifdef CL_Fortran
3966 ASSERT_STREQ
3967 (get_option_url_suffix (OPT_Wline_truncation, CL_Fortran).get (),
3968 "gfortran/Error-and-Warning-Options.html#index-Wline-truncation");
3969 #endif
3972 /* Verify EnumSet and EnumBitSet requirements. */
3974 static void
3975 test_enum_sets ()
3977 for (unsigned i = 0; i < cl_options_count; ++i)
3978 if (cl_options[i].var_type == CLVC_ENUM
3979 && cl_options[i].var_value != CLEV_NORMAL)
3981 const struct cl_enum *e = &cl_enums[cl_options[i].var_enum];
3982 unsigned HOST_WIDE_INT used_sets = 0;
3983 unsigned HOST_WIDE_INT mask = 0;
3984 unsigned highest_set = 0;
3985 for (unsigned j = 0; e->values[j].arg; ++j)
3987 unsigned set = e->values[j].flags >> CL_ENUM_SET_SHIFT;
3988 if (cl_options[i].var_value == CLEV_BITSET)
3990 /* For EnumBitSet Set shouldn't be used and Value should
3991 be a power of two. */
3992 ASSERT_TRUE (set == 0);
3993 ASSERT_TRUE (pow2p_hwi (e->values[j].value));
3994 continue;
3996 /* Test that enumerators referenced in EnumSet have all
3997 Set(n) on them within the valid range. */
3998 ASSERT_TRUE (set >= 1 && set <= HOST_BITS_PER_WIDE_INT);
3999 highest_set = MAX (set, highest_set);
4000 used_sets |= HOST_WIDE_INT_1U << (set - 1);
4002 if (cl_options[i].var_value == CLEV_BITSET)
4003 continue;
4004 /* If there is just one set, no point to using EnumSet. */
4005 ASSERT_TRUE (highest_set >= 2);
4006 /* Test that there are no gaps in between the sets. */
4007 if (highest_set == HOST_BITS_PER_WIDE_INT)
4008 ASSERT_TRUE (used_sets == HOST_WIDE_INT_M1U);
4009 else
4010 ASSERT_TRUE (used_sets == (HOST_WIDE_INT_1U << highest_set) - 1);
4011 for (unsigned int j = 1; j <= highest_set; ++j)
4013 unsigned HOST_WIDE_INT this_mask = 0;
4014 for (unsigned k = 0; e->values[k].arg; ++k)
4016 unsigned set = e->values[j].flags >> CL_ENUM_SET_SHIFT;
4017 if (set == j)
4018 this_mask |= e->values[j].value;
4020 ASSERT_TRUE ((mask & this_mask) == 0);
4021 mask |= this_mask;
4026 /* Run all of the selftests within this file. */
4028 void
4029 opts_cc_tests ()
4031 test_get_option_url_suffix ();
4032 test_enum_sets ();
4035 } // namespace selftest
4037 #endif /* #if CHECKING_P */