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