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