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
set_struct_debug_option(struct gcc_options * opts,location_t loc,const char * spec)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
strip_off_ending(char * name,int len)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
base_of_path(const char * path,const char ** base_out)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
target_handle_option(struct gcc_options * opts,struct gcc_options * opts_set,const struct cl_decoded_option * decoded,unsigned int lang_mask ATTRIBUTE_UNUSED,int kind,location_t loc,const struct cl_option_handlers * handlers ATTRIBUTE_UNUSED,diagnostic_context * dc,void (*)(void))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
add_comma_separated_to_vector(void ** pvec,const char * arg)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
init_opts_obstack(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
init_options_struct(struct gcc_options * opts,struct gcc_options * opts_set)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
maybe_default_option(struct gcc_options * opts,struct gcc_options * opts_set,const struct default_options * default_opt,int level,bool size,bool fast,bool debug,unsigned int lang_mask,const struct cl_option_handlers * handlers,location_t loc,diagnostic_context * dc)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
maybe_default_options(struct gcc_options * opts,struct gcc_options * opts_set,const struct default_options * default_opts,int level,bool size,bool fast,bool debug,unsigned int lang_mask,const struct cl_option_handlers * handlers,location_t loc,diagnostic_context * dc)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
default_options_optimization(struct gcc_options * opts,struct gcc_options * opts_set,struct cl_decoded_option * decoded_options,unsigned int decoded_options_count,location_t loc,unsigned int lang_mask,const struct cl_option_handlers * handlers,diagnostic_context * dc)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
control_options_for_live_patching(struct gcc_options * opts,struct gcc_options * opts_set,enum live_patching_level level,location_t loc)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 *
find_sanitizer_argument(struct gcc_options * opts,unsigned int flags)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
report_conflicting_sanitizer_options(struct gcc_options * opts,location_t loc,unsigned int left,unsigned int right)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
finish_options(struct gcc_options * opts,struct gcc_options * opts_set,location_t loc)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
wrap_help(const char * help,const char * item,unsigned int item_width,unsigned int columns)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:
option_help_tuple(int code,vec<const char * > values)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
print_filtered_help(unsigned int include_flags,unsigned int exclude_flags,unsigned int any_flags,unsigned int columns,struct gcc_options * opts,unsigned int lang_mask)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
print_specific_help(unsigned int include_flags,unsigned int exclude_flags,unsigned int any_flags,struct gcc_options * opts,unsigned int lang_mask)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
enable_fdo_optimizations(struct gcc_options * opts,struct gcc_options * opts_set,int value)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:
string_fragment(const char * start,size_t len)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 /* Parse argument of -fpatchable-function-entry option ARG and store
2134 corresponding values to PATCH_AREA_SIZE and PATCH_AREA_START.
2135 If REPORT_ERROR is set to true, generate error for a problematic
2136 option arguments. */
2137
2138 void
2139 parse_and_check_patch_area (const char *arg, bool report_error,
2140 HOST_WIDE_INT *patch_area_size,
2141 HOST_WIDE_INT *patch_area_start)
2142 {
2143 *patch_area_size = 0;
2144 *patch_area_start = 0;
2145
2146 if (arg == NULL)
2147 return;
2148
2149 char *patch_area_arg = xstrdup (arg);
2150 char *comma = strchr (patch_area_arg, ',');
2151 if (comma)
2152 {
2153 *comma = '\0';
2154 *patch_area_size = integral_argument (patch_area_arg);
2155 *patch_area_start = integral_argument (comma + 1);
2156 }
2157 else
2158 *patch_area_size = integral_argument (patch_area_arg);
2159
2160 if (*patch_area_size < 0
2161 || *patch_area_size > USHRT_MAX
2162 || *patch_area_start < 0
2163 || *patch_area_start > USHRT_MAX
2164 || *patch_area_size < *patch_area_start)
2165 if (report_error)
2166 error ("invalid arguments for %<-fpatchable-function-entry%>");
2167
2168 free (patch_area_arg);
2169 }
2170
2171 /* Print help when OPT__help_ is set. */
2172
2173 void
2174 print_help (struct gcc_options *opts, unsigned int lang_mask,
2175 const char *help_option_argument)
2176 {
2177 const char *a = help_option_argument;
2178 unsigned int include_flags = 0;
2179 /* Note - by default we include undocumented options when listing
2180 specific classes. If you only want to see documented options
2181 then add ",^undocumented" to the --help= option. E.g.:
2182
2183 --help=target,^undocumented */
2184 unsigned int exclude_flags = 0;
2185
2186 if (lang_mask == CL_DRIVER)
2187 return;
2188
2189 /* Walk along the argument string, parsing each word in turn.
2190 The format is:
2191 arg = [^]{word}[,{arg}]
2192 word = {optimizers|target|warnings|undocumented|
2193 params|common|<language>} */
2194 while (*a != 0)
2195 {
2196 static const struct
2197 {
2198 const char *string;
2199 unsigned int flag;
2200 }
2201 specifics[] =
2202 {
2203 { "optimizers", CL_OPTIMIZATION },
2204 { "target", CL_TARGET },
2205 { "warnings", CL_WARNING },
2206 { "undocumented", CL_UNDOCUMENTED },
2207 { "params", CL_PARAMS },
2208 { "joined", CL_JOINED },
2209 { "separate", CL_SEPARATE },
2210 { "common", CL_COMMON },
2211 { NULL, 0 }
2212 };
2213 unsigned int *pflags;
2214 const char *comma;
2215 unsigned int lang_flag, specific_flag;
2216 unsigned int len;
2217 unsigned int i;
2218
2219 if (*a == '^')
2220 {
2221 ++a;
2222 if (*a == '\0')
2223 {
2224 error ("missing argument to %qs", "--help=^");
2225 break;
2226 }
2227 pflags = &exclude_flags;
2228 }
2229 else
2230 pflags = &include_flags;
2231
2232 comma = strchr (a, ',');
2233 if (comma == NULL)
2234 len = strlen (a);
2235 else
2236 len = comma - a;
2237 if (len == 0)
2238 {
2239 a = comma + 1;
2240 continue;
2241 }
2242
2243 /* Check to see if the string matches an option class name. */
2244 for (i = 0, specific_flag = 0; specifics[i].string != NULL; i++)
2245 if (strncasecmp (a, specifics[i].string, len) == 0)
2246 {
2247 specific_flag = specifics[i].flag;
2248 break;
2249 }
2250
2251 /* Check to see if the string matches a language name.
2252 Note - we rely upon the alpha-sorted nature of the entries in
2253 the lang_names array, specifically that shorter names appear
2254 before their longer variants. (i.e. C before C++). That way
2255 when we are attempting to match --help=c for example we will
2256 match with C first and not C++. */
2257 for (i = 0, lang_flag = 0; i < cl_lang_count; i++)
2258 if (strncasecmp (a, lang_names[i], len) == 0)
2259 {
2260 lang_flag = 1U << i;
2261 break;
2262 }
2263
2264 if (specific_flag != 0)
2265 {
2266 if (lang_flag == 0)
2267 *pflags |= specific_flag;
2268 else
2269 {
2270 /* The option's argument matches both the start of a
2271 language name and the start of an option class name.
2272 We have a special case for when the user has
2273 specified "--help=c", but otherwise we have to issue
2274 a warning. */
2275 if (strncasecmp (a, "c", len) == 0)
2276 *pflags |= lang_flag;
2277 else
2278 warning (0,
2279 "%<--help%> argument %q.*s is ambiguous, "
2280 "please be more specific",
2281 len, a);
2282 }
2283 }
2284 else if (lang_flag != 0)
2285 *pflags |= lang_flag;
2286 else
2287 warning (0,
2288 "unrecognized argument to %<--help=%> option: %q.*s",
2289 len, a);
2290
2291 if (comma == NULL)
2292 break;
2293 a = comma + 1;
2294 }
2295
2296 /* We started using PerFunction/Optimization for parameters and
2297 a warning. We should exclude these from optimization options. */
2298 if (include_flags & CL_OPTIMIZATION)
2299 exclude_flags |= CL_WARNING;
2300 if (!(include_flags & CL_PARAMS))
2301 exclude_flags |= CL_PARAMS;
2302
2303 if (include_flags)
2304 print_specific_help (include_flags, exclude_flags, 0, opts,
2305 lang_mask);
2306 }
2307
2308 /* Handle target- and language-independent options. Return zero to
2309 generate an "unknown option" message. Only options that need
2310 extra handling need to be listed here; if you simply want
2311 DECODED->value assigned to a variable, it happens automatically. */
2312
2313 bool
2314 common_handle_option (struct gcc_options *opts,
2315 struct gcc_options *opts_set,
2316 const struct cl_decoded_option *decoded,
2317 unsigned int lang_mask, int kind ATTRIBUTE_UNUSED,
2318 location_t loc,
2319 const struct cl_option_handlers *handlers,
2320 diagnostic_context *dc,
2321 void (*target_option_override_hook) (void))
2322 {
2323 size_t scode = decoded->opt_index;
2324 const char *arg = decoded->arg;
2325 HOST_WIDE_INT value = decoded->value;
2326 enum opt_code code = (enum opt_code) scode;
2327
2328 gcc_assert (decoded->canonical_option_num_elements <= 2);
2329
2330 switch (code)
2331 {
2332 case OPT__help:
2333 {
2334 unsigned int all_langs_mask = (1U << cl_lang_count) - 1;
2335 unsigned int undoc_mask;
2336 unsigned int i;
2337
2338 if (lang_mask == CL_DRIVER)
2339 break;
2340
2341 undoc_mask = ((opts->x_verbose_flag | opts->x_extra_warnings)
2342 ? 0
2343 : CL_UNDOCUMENTED);
2344 target_option_override_hook ();
2345 /* First display any single language specific options. */
2346 for (i = 0; i < cl_lang_count; i++)
2347 print_specific_help
2348 (1U << i, (all_langs_mask & (~ (1U << i))) | undoc_mask, 0, opts,
2349 lang_mask);
2350 /* Next display any multi language specific options. */
2351 print_specific_help (0, undoc_mask, all_langs_mask, opts, lang_mask);
2352 /* Then display any remaining, non-language options. */
2353 for (i = CL_MIN_OPTION_CLASS; i <= CL_MAX_OPTION_CLASS; i <<= 1)
2354 if (i != CL_DRIVER)
2355 print_specific_help (i, undoc_mask, 0, opts, lang_mask);
2356 opts->x_exit_after_options = true;
2357 break;
2358 }
2359
2360 case OPT__target_help:
2361 if (lang_mask == CL_DRIVER)
2362 break;
2363
2364 target_option_override_hook ();
2365 print_specific_help (CL_TARGET, CL_UNDOCUMENTED, 0, opts, lang_mask);
2366 opts->x_exit_after_options = true;
2367 break;
2368
2369 case OPT__help_:
2370 {
2371 help_option_arguments.safe_push (arg);
2372 opts->x_exit_after_options = true;
2373 break;
2374 }
2375
2376 case OPT__version:
2377 if (lang_mask == CL_DRIVER)
2378 break;
2379
2380 opts->x_exit_after_options = true;
2381 break;
2382
2383 case OPT__completion_:
2384 break;
2385
2386 case OPT_fsanitize_:
2387 opts->x_flag_sanitize
2388 = parse_sanitizer_options (arg, loc, code,
2389 opts->x_flag_sanitize, value, true);
2390
2391 /* Kernel ASan implies normal ASan but does not yet support
2392 all features. */
2393 if (opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS)
2394 {
2395 SET_OPTION_IF_UNSET (opts, opts_set,
2396 param_asan_instrumentation_with_call_threshold,
2397 0);
2398 SET_OPTION_IF_UNSET (opts, opts_set, param_asan_globals, 0);
2399 SET_OPTION_IF_UNSET (opts, opts_set, param_asan_stack, 0);
2400 SET_OPTION_IF_UNSET (opts, opts_set, param_asan_protect_allocas, 0);
2401 SET_OPTION_IF_UNSET (opts, opts_set, param_asan_use_after_return, 0);
2402 }
2403 if (opts->x_flag_sanitize & SANITIZE_KERNEL_HWADDRESS)
2404 {
2405 SET_OPTION_IF_UNSET (opts, opts_set,
2406 param_hwasan_instrument_stack, 0);
2407 SET_OPTION_IF_UNSET (opts, opts_set,
2408 param_hwasan_random_frame_tag, 0);
2409 SET_OPTION_IF_UNSET (opts, opts_set,
2410 param_hwasan_instrument_allocas, 0);
2411 }
2412 break;
2413
2414 case OPT_fsanitize_recover_:
2415 opts->x_flag_sanitize_recover
2416 = parse_sanitizer_options (arg, loc, code,
2417 opts->x_flag_sanitize_recover, value, true);
2418 break;
2419
2420 case OPT_fasan_shadow_offset_:
2421 /* Deferred. */
2422 break;
2423
2424 case OPT_fsanitize_address_use_after_scope:
2425 opts->x_flag_sanitize_address_use_after_scope = value;
2426 break;
2427
2428 case OPT_fsanitize_recover:
2429 if (value)
2430 opts->x_flag_sanitize_recover
2431 |= (SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT)
2432 & ~(SANITIZE_UNREACHABLE | SANITIZE_RETURN);
2433 else
2434 opts->x_flag_sanitize_recover
2435 &= ~(SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT);
2436 break;
2437
2438 case OPT_fsanitize_coverage_:
2439 opts->x_flag_sanitize_coverage
2440 = parse_sanitizer_options (arg, loc, code,
2441 opts->x_flag_sanitize_coverage, value, true);
2442 break;
2443
2444 case OPT_O:
2445 case OPT_Os:
2446 case OPT_Ofast:
2447 case OPT_Og:
2448 /* Currently handled in a prescan. */
2449 break;
2450
2451 case OPT_Werror:
2452 dc->warning_as_error_requested = value;
2453 break;
2454
2455 case OPT_Werror_:
2456 if (lang_mask == CL_DRIVER)
2457 break;
2458
2459 enable_warning_as_error (arg, value, lang_mask, handlers,
2460 opts, opts_set, loc, dc);
2461 break;
2462
2463 case OPT_Wfatal_errors:
2464 dc->fatal_errors = value;
2465 break;
2466
2467 case OPT_Wstack_usage_:
2468 opts->x_flag_stack_usage_info = value != -1;
2469 break;
2470
2471 case OPT_Wstrict_aliasing:
2472 set_Wstrict_aliasing (opts, value);
2473 break;
2474
2475 case OPT_Wstrict_overflow:
2476 opts->x_warn_strict_overflow = (value
2477 ? (int) WARN_STRICT_OVERFLOW_CONDITIONAL
2478 : 0);
2479 break;
2480
2481 case OPT_Wsystem_headers:
2482 dc->dc_warn_system_headers = value;
2483 break;
2484
2485 case OPT_aux_info:
2486 opts->x_flag_gen_aux_info = 1;
2487 break;
2488
2489 case OPT_d:
2490 decode_d_option (arg, opts, loc, dc);
2491 break;
2492
2493 case OPT_fcall_used_:
2494 case OPT_fcall_saved_:
2495 /* Deferred. */
2496 break;
2497
2498 case OPT_fdbg_cnt_:
2499 /* Deferred. */
2500 break;
2501
2502 case OPT_fdebug_prefix_map_:
2503 case OPT_ffile_prefix_map_:
2504 /* Deferred. */
2505 break;
2506
2507 case OPT_fcallgraph_info:
2508 opts->x_flag_callgraph_info = CALLGRAPH_INFO_NAKED;
2509 break;
2510
2511 case OPT_fcallgraph_info_:
2512 {
2513 char *my_arg, *p;
2514 my_arg = xstrdup (arg);
2515 p = strtok (my_arg, ",");
2516 while (p)
2517 {
2518 if (strcmp (p, "su") == 0)
2519 {
2520 opts->x_flag_callgraph_info |= CALLGRAPH_INFO_STACK_USAGE;
2521 opts->x_flag_stack_usage_info = true;
2522 }
2523 else if (strcmp (p, "da") == 0)
2524 opts->x_flag_callgraph_info |= CALLGRAPH_INFO_DYNAMIC_ALLOC;
2525 else
2526 return 0;
2527 p = strtok (NULL, ",");
2528 }
2529 free (my_arg);
2530 }
2531 break;
2532
2533 case OPT_fdiagnostics_show_location_:
2534 diagnostic_prefixing_rule (dc) = (diagnostic_prefixing_rule_t) value;
2535 break;
2536
2537 case OPT_fdiagnostics_show_caret:
2538 dc->show_caret = value;
2539 break;
2540
2541 case OPT_fdiagnostics_show_labels:
2542 dc->show_labels_p = value;
2543 break;
2544
2545 case OPT_fdiagnostics_show_line_numbers:
2546 dc->show_line_numbers_p = value;
2547 break;
2548
2549 case OPT_fdiagnostics_color_:
2550 diagnostic_color_init (dc, value);
2551 break;
2552
2553 case OPT_fdiagnostics_urls_:
2554 diagnostic_urls_init (dc, value);
2555 break;
2556
2557 case OPT_fdiagnostics_format_:
2558 diagnostic_output_format_init (dc,
2559 (enum diagnostics_output_format)value);
2560 break;
2561
2562 case OPT_fdiagnostics_parseable_fixits:
2563 dc->extra_output_kind = (value
2564 ? EXTRA_DIAGNOSTIC_OUTPUT_fixits_v1
2565 : EXTRA_DIAGNOSTIC_OUTPUT_none);
2566 break;
2567
2568 case OPT_fdiagnostics_column_unit_:
2569 dc->column_unit = (enum diagnostics_column_unit)value;
2570 break;
2571
2572 case OPT_fdiagnostics_column_origin_:
2573 dc->column_origin = value;
2574 break;
2575
2576 case OPT_fdiagnostics_show_cwe:
2577 dc->show_cwe = value;
2578 break;
2579
2580 case OPT_fdiagnostics_path_format_:
2581 dc->path_format = (enum diagnostic_path_format)value;
2582 break;
2583
2584 case OPT_fdiagnostics_show_path_depths:
2585 dc->show_path_depths = value;
2586 break;
2587
2588 case OPT_fdiagnostics_show_option:
2589 dc->show_option_requested = value;
2590 break;
2591
2592 case OPT_fdiagnostics_minimum_margin_width_:
2593 dc->min_margin_width = value;
2594 break;
2595
2596 case OPT_fdump_:
2597 /* Deferred. */
2598 break;
2599
2600 case OPT_ffast_math:
2601 set_fast_math_flags (opts, value);
2602 break;
2603
2604 case OPT_funsafe_math_optimizations:
2605 set_unsafe_math_optimizations_flags (opts, value);
2606 break;
2607
2608 case OPT_ffixed_:
2609 /* Deferred. */
2610 break;
2611
2612 case OPT_finline_limit_:
2613 SET_OPTION_IF_UNSET (opts, opts_set, param_max_inline_insns_single,
2614 value / 2);
2615 SET_OPTION_IF_UNSET (opts, opts_set, param_max_inline_insns_auto,
2616 value / 2);
2617 break;
2618
2619 case OPT_finstrument_functions_exclude_function_list_:
2620 add_comma_separated_to_vector
2621 (&opts->x_flag_instrument_functions_exclude_functions, arg);
2622 break;
2623
2624 case OPT_finstrument_functions_exclude_file_list_:
2625 add_comma_separated_to_vector
2626 (&opts->x_flag_instrument_functions_exclude_files, arg);
2627 break;
2628
2629 case OPT_fmessage_length_:
2630 pp_set_line_maximum_length (dc->printer, value);
2631 diagnostic_set_caret_max_width (dc, value);
2632 break;
2633
2634 case OPT_fopt_info:
2635 case OPT_fopt_info_:
2636 /* Deferred. */
2637 break;
2638
2639 case OPT_foffload_:
2640 /* Deferred. */
2641 break;
2642
2643 #ifndef ACCEL_COMPILER
2644 case OPT_foffload_abi_:
2645 error_at (loc, "%<-foffload-abi%> option can be specified only for "
2646 "offload compiler");
2647 break;
2648 #endif
2649
2650 case OPT_fpack_struct_:
2651 if (value <= 0 || (value & (value - 1)) || value > 16)
2652 error_at (loc,
2653 "structure alignment must be a small power of two, not %wu",
2654 value);
2655 else
2656 opts->x_initial_max_fld_align = value;
2657 break;
2658
2659 case OPT_fplugin_:
2660 case OPT_fplugin_arg_:
2661 /* Deferred. */
2662 break;
2663
2664 case OPT_fprofile_use_:
2665 opts->x_profile_data_prefix = xstrdup (arg);
2666 opts->x_flag_profile_use = true;
2667 value = true;
2668 /* No break here - do -fprofile-use processing. */
2669 /* FALLTHRU */
2670 case OPT_fprofile_use:
2671 enable_fdo_optimizations (opts, opts_set, value);
2672 SET_OPTION_IF_UNSET (opts, opts_set, flag_profile_reorder_functions,
2673 value);
2674 /* Indirect call profiling should do all useful transformations
2675 speculative devirtualization does. */
2676 if (opts->x_flag_value_profile_transformations)
2677 SET_OPTION_IF_UNSET (opts, opts_set, flag_devirtualize_speculatively,
2678 false);
2679 break;
2680
2681 case OPT_fauto_profile_:
2682 opts->x_auto_profile_file = xstrdup (arg);
2683 opts->x_flag_auto_profile = true;
2684 value = true;
2685 /* No break here - do -fauto-profile processing. */
2686 /* FALLTHRU */
2687 case OPT_fauto_profile:
2688 enable_fdo_optimizations (opts, opts_set, value);
2689 SET_OPTION_IF_UNSET (opts, opts_set, flag_profile_correction, value);
2690 SET_OPTION_IF_UNSET (opts, opts_set,
2691 param_early_inliner_max_iterations, 10);
2692 break;
2693
2694 case OPT_fprofile_generate_:
2695 opts->x_profile_data_prefix = xstrdup (arg);
2696 value = true;
2697 /* No break here - do -fprofile-generate processing. */
2698 /* FALLTHRU */
2699 case OPT_fprofile_generate:
2700 SET_OPTION_IF_UNSET (opts, opts_set, profile_arc_flag, value);
2701 SET_OPTION_IF_UNSET (opts, opts_set, flag_profile_values, value);
2702 SET_OPTION_IF_UNSET (opts, opts_set, flag_inline_functions, value);
2703 SET_OPTION_IF_UNSET (opts, opts_set, flag_ipa_bit_cp, value);
2704 break;
2705
2706 case OPT_fprofile_info_section:
2707 opts->x_profile_info_section = ".gcov_info";
2708 break;
2709
2710 case OPT_fpatchable_function_entry_:
2711 {
2712 HOST_WIDE_INT patch_area_size, patch_area_start;
2713 parse_and_check_patch_area (arg, true, &patch_area_size,
2714 &patch_area_start);
2715 }
2716 break;
2717
2718 case OPT_ftree_vectorize:
2719 /* Automatically sets -ftree-loop-vectorize and
2720 -ftree-slp-vectorize. Nothing more to do here. */
2721 break;
2722 case OPT_fzero_call_used_regs_:
2723 opts->x_flag_zero_call_used_regs
2724 = parse_zero_call_used_regs_options (arg);
2725 break;
2726
2727 case OPT_fshow_column:
2728 dc->show_column = value;
2729 break;
2730
2731 case OPT_frandom_seed:
2732 /* The real switch is -fno-random-seed. */
2733 if (value)
2734 return false;
2735 /* Deferred. */
2736 break;
2737
2738 case OPT_frandom_seed_:
2739 /* Deferred. */
2740 break;
2741
2742 case OPT_fsched_verbose_:
2743 #ifdef INSN_SCHEDULING
2744 /* Handled with Var in common.opt. */
2745 break;
2746 #else
2747 return false;
2748 #endif
2749
2750 case OPT_fsched_stalled_insns_:
2751 opts->x_flag_sched_stalled_insns = value;
2752 if (opts->x_flag_sched_stalled_insns == 0)
2753 opts->x_flag_sched_stalled_insns = -1;
2754 break;
2755
2756 case OPT_fsched_stalled_insns_dep_:
2757 opts->x_flag_sched_stalled_insns_dep = value;
2758 break;
2759
2760 case OPT_fstack_check_:
2761 if (!strcmp (arg, "no"))
2762 opts->x_flag_stack_check = NO_STACK_CHECK;
2763 else if (!strcmp (arg, "generic"))
2764 /* This is the old stack checking method. */
2765 opts->x_flag_stack_check = STACK_CHECK_BUILTIN
2766 ? FULL_BUILTIN_STACK_CHECK
2767 : GENERIC_STACK_CHECK;
2768 else if (!strcmp (arg, "specific"))
2769 /* This is the new stack checking method. */
2770 opts->x_flag_stack_check = STACK_CHECK_BUILTIN
2771 ? FULL_BUILTIN_STACK_CHECK
2772 : STACK_CHECK_STATIC_BUILTIN
2773 ? STATIC_BUILTIN_STACK_CHECK
2774 : GENERIC_STACK_CHECK;
2775 else
2776 warning_at (loc, 0, "unknown stack check parameter %qs", arg);
2777 break;
2778
2779 case OPT_fstack_limit:
2780 /* The real switch is -fno-stack-limit. */
2781 if (value)
2782 return false;
2783 /* Deferred. */
2784 break;
2785
2786 case OPT_fstack_limit_register_:
2787 case OPT_fstack_limit_symbol_:
2788 /* Deferred. */
2789 break;
2790
2791 case OPT_fstack_usage:
2792 opts->x_flag_stack_usage = value;
2793 opts->x_flag_stack_usage_info = value != 0;
2794 break;
2795
2796 case OPT_g:
2797 set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, arg, opts, opts_set,
2798 loc);
2799 break;
2800
2801 case OPT_gdwarf:
2802 if (arg && strlen (arg) != 0)
2803 {
2804 error_at (loc, "%<-gdwarf%s%> is ambiguous; "
2805 "use %<-gdwarf-%s%> for DWARF version "
2806 "or %<-gdwarf%> %<-g%s%> for debug level", arg, arg, arg);
2807 break;
2808 }
2809 else
2810 value = opts->x_dwarf_version;
2811
2812 /* FALLTHRU */
2813 case OPT_gdwarf_:
2814 if (value < 2 || value > 5)
2815 error_at (loc, "dwarf version %wu is not supported", value);
2816 else
2817 opts->x_dwarf_version = value;
2818 set_debug_level (DWARF2_DEBUG, false, "", opts, opts_set, loc);
2819 break;
2820
2821 case OPT_ggdb:
2822 set_debug_level (NO_DEBUG, 2, arg, opts, opts_set, loc);
2823 break;
2824
2825 case OPT_gstabs:
2826 case OPT_gstabs_:
2827 set_debug_level (DBX_DEBUG, code == OPT_gstabs_, arg, opts, opts_set,
2828 loc);
2829 break;
2830
2831 case OPT_gvms:
2832 set_debug_level (VMS_DEBUG, false, arg, opts, opts_set, loc);
2833 break;
2834
2835 case OPT_gxcoff:
2836 case OPT_gxcoff_:
2837 set_debug_level (XCOFF_DEBUG, code == OPT_gxcoff_, arg, opts, opts_set,
2838 loc);
2839 break;
2840
2841 case OPT_gz:
2842 case OPT_gz_:
2843 /* Handled completely via specs. */
2844 break;
2845
2846 case OPT_pedantic_errors:
2847 dc->pedantic_errors = 1;
2848 control_warning_option (OPT_Wpedantic, DK_ERROR, NULL, value,
2849 loc, lang_mask,
2850 handlers, opts, opts_set,
2851 dc);
2852 break;
2853
2854 case OPT_flto:
2855 opts->x_flag_lto = value ? "" : NULL;
2856 break;
2857
2858 case OPT_flto_:
2859 if (strcmp (arg, "none") != 0
2860 && strcmp (arg, "jobserver") != 0
2861 && strcmp (arg, "auto") != 0
2862 && atoi (arg) == 0)
2863 error_at (loc,
2864 "unrecognized argument to %<-flto=%> option: %qs", arg);
2865 break;
2866
2867 case OPT_w:
2868 dc->dc_inhibit_warnings = true;
2869 break;
2870
2871 case OPT_fmax_errors_:
2872 dc->max_errors = value;
2873 break;
2874
2875 case OPT_fuse_ld_bfd:
2876 case OPT_fuse_ld_gold:
2877 case OPT_fuse_ld_lld:
2878 case OPT_fuse_linker_plugin:
2879 /* No-op. Used by the driver and passed to us because it starts with f.*/
2880 break;
2881
2882 case OPT_fwrapv:
2883 if (value)
2884 opts->x_flag_trapv = 0;
2885 break;
2886
2887 case OPT_ftrapv:
2888 if (value)
2889 opts->x_flag_wrapv = 0;
2890 break;
2891
2892 case OPT_fstrict_overflow:
2893 opts->x_flag_wrapv = !value;
2894 opts->x_flag_wrapv_pointer = !value;
2895 if (!value)
2896 opts->x_flag_trapv = 0;
2897 break;
2898
2899 case OPT_fipa_icf:
2900 opts->x_flag_ipa_icf_functions = value;
2901 opts->x_flag_ipa_icf_variables = value;
2902 break;
2903
2904 case OPT_falign_loops_:
2905 check_alignment_argument (loc, arg, "loops",
2906 &opts->x_flag_align_loops,
2907 &opts->x_str_align_loops);
2908 break;
2909
2910 case OPT_falign_jumps_:
2911 check_alignment_argument (loc, arg, "jumps",
2912 &opts->x_flag_align_jumps,
2913 &opts->x_str_align_jumps);
2914 break;
2915
2916 case OPT_falign_labels_:
2917 check_alignment_argument (loc, arg, "labels",
2918 &opts->x_flag_align_labels,
2919 &opts->x_str_align_labels);
2920 break;
2921
2922 case OPT_falign_functions_:
2923 check_alignment_argument (loc, arg, "functions",
2924 &opts->x_flag_align_functions,
2925 &opts->x_str_align_functions);
2926 break;
2927
2928 case OPT_ftabstop_:
2929 /* It is documented that we silently ignore silly values. */
2930 if (value >= 1 && value <= 100)
2931 dc->tabstop = value;
2932 break;
2933
2934 default:
2935 /* If the flag was handled in a standard way, assume the lack of
2936 processing here is intentional. */
2937 gcc_assert (option_flag_var (scode, opts));
2938 break;
2939 }
2940
2941 common_handle_option_auto (opts, opts_set, decoded, lang_mask, kind,
2942 loc, handlers, dc);
2943 return true;
2944 }
2945
2946 /* Used to set the level of strict aliasing warnings in OPTS,
2947 when no level is specified (i.e., when -Wstrict-aliasing, and not
2948 -Wstrict-aliasing=level was given).
2949 ONOFF is assumed to take value 1 when -Wstrict-aliasing is specified,
2950 and 0 otherwise. After calling this function, wstrict_aliasing will be
2951 set to the default value of -Wstrict_aliasing=level, currently 3. */
2952 static void
2953 set_Wstrict_aliasing (struct gcc_options *opts, int onoff)
2954 {
2955 gcc_assert (onoff == 0 || onoff == 1);
2956 if (onoff != 0)
2957 opts->x_warn_strict_aliasing = 3;
2958 else
2959 opts->x_warn_strict_aliasing = 0;
2960 }
2961
2962 /* The following routines are useful in setting all the flags that
2963 -ffast-math and -fno-fast-math imply. */
2964 static void
2965 set_fast_math_flags (struct gcc_options *opts, int set)
2966 {
2967 if (!opts->frontend_set_flag_unsafe_math_optimizations)
2968 {
2969 opts->x_flag_unsafe_math_optimizations = set;
2970 set_unsafe_math_optimizations_flags (opts, set);
2971 }
2972 if (!opts->frontend_set_flag_finite_math_only)
2973 opts->x_flag_finite_math_only = set;
2974 if (!opts->frontend_set_flag_errno_math)
2975 opts->x_flag_errno_math = !set;
2976 if (set)
2977 {
2978 if (opts->frontend_set_flag_excess_precision == EXCESS_PRECISION_DEFAULT)
2979 opts->x_flag_excess_precision
2980 = set ? EXCESS_PRECISION_FAST : EXCESS_PRECISION_DEFAULT;
2981 if (!opts->frontend_set_flag_signaling_nans)
2982 opts->x_flag_signaling_nans = 0;
2983 if (!opts->frontend_set_flag_rounding_math)
2984 opts->x_flag_rounding_math = 0;
2985 if (!opts->frontend_set_flag_cx_limited_range)
2986 opts->x_flag_cx_limited_range = 1;
2987 }
2988 }
2989
2990 /* When -funsafe-math-optimizations is set the following
2991 flags are set as well. */
2992 static void
2993 set_unsafe_math_optimizations_flags (struct gcc_options *opts, int set)
2994 {
2995 if (!opts->frontend_set_flag_trapping_math)
2996 opts->x_flag_trapping_math = !set;
2997 if (!opts->frontend_set_flag_signed_zeros)
2998 opts->x_flag_signed_zeros = !set;
2999 if (!opts->frontend_set_flag_associative_math)
3000 opts->x_flag_associative_math = set;
3001 if (!opts->frontend_set_flag_reciprocal_math)
3002 opts->x_flag_reciprocal_math = set;
3003 }
3004
3005 /* Return true iff flags in OPTS are set as if -ffast-math. */
3006 bool
3007 fast_math_flags_set_p (const struct gcc_options *opts)
3008 {
3009 return (!opts->x_flag_trapping_math
3010 && opts->x_flag_unsafe_math_optimizations
3011 && opts->x_flag_finite_math_only
3012 && !opts->x_flag_signed_zeros
3013 && !opts->x_flag_errno_math
3014 && opts->x_flag_excess_precision == EXCESS_PRECISION_FAST);
3015 }
3016
3017 /* Return true iff flags are set as if -ffast-math but using the flags stored
3018 in the struct cl_optimization structure. */
3019 bool
3020 fast_math_flags_struct_set_p (struct cl_optimization *opt)
3021 {
3022 return (!opt->x_flag_trapping_math
3023 && opt->x_flag_unsafe_math_optimizations
3024 && opt->x_flag_finite_math_only
3025 && !opt->x_flag_signed_zeros
3026 && !opt->x_flag_errno_math);
3027 }
3028
3029 /* Handle a debug output -g switch for options OPTS
3030 (OPTS_SET->x_write_symbols storing whether a debug type was passed
3031 explicitly), location LOC. EXTENDED is true or false to support
3032 extended output (2 is special and means "-ggdb" was given). */
3033 static void
3034 set_debug_level (enum debug_info_type type, int extended, const char *arg,
3035 struct gcc_options *opts, struct gcc_options *opts_set,
3036 location_t loc)
3037 {
3038 opts->x_use_gnu_debug_info_extensions = extended;
3039
3040 if (type == NO_DEBUG)
3041 {
3042 if (opts->x_write_symbols == NO_DEBUG)
3043 {
3044 opts->x_write_symbols = PREFERRED_DEBUGGING_TYPE;
3045
3046 if (extended == 2)
3047 {
3048 #if defined DWARF2_DEBUGGING_INFO || defined DWARF2_LINENO_DEBUGGING_INFO
3049 opts->x_write_symbols = DWARF2_DEBUG;
3050 #elif defined DBX_DEBUGGING_INFO
3051 opts->x_write_symbols = DBX_DEBUG;
3052 #endif
3053 }
3054
3055 if (opts->x_write_symbols == NO_DEBUG)
3056 warning_at (loc, 0, "target system does not support debug output");
3057 }
3058 }
3059 else
3060 {
3061 /* Does it conflict with an already selected type? */
3062 if (opts_set->x_write_symbols != NO_DEBUG
3063 && opts->x_write_symbols != NO_DEBUG
3064 && type != opts->x_write_symbols)
3065 error_at (loc, "debug format %qs conflicts with prior selection",
3066 debug_type_names[type]);
3067 opts->x_write_symbols = type;
3068 opts_set->x_write_symbols = type;
3069 }
3070
3071 /* A debug flag without a level defaults to level 2.
3072 If off or at level 1, set it to level 2, but if already
3073 at level 3, don't lower it. */
3074 if (*arg == '\0')
3075 {
3076 if (opts->x_debug_info_level < DINFO_LEVEL_NORMAL)
3077 opts->x_debug_info_level = DINFO_LEVEL_NORMAL;
3078 }
3079 else
3080 {
3081 int argval = integral_argument (arg);
3082 if (argval == -1)
3083 error_at (loc, "unrecognized debug output level %qs", arg);
3084 else if (argval > 3)
3085 error_at (loc, "debug output level %qs is too high", arg);
3086 else
3087 opts->x_debug_info_level = (enum debug_info_levels) argval;
3088 }
3089 }
3090
3091 /* Arrange to dump core on error for diagnostic context DC. (The
3092 regular error message is still printed first, except in the case of
3093 abort ().) */
3094
3095 static void
3096 setup_core_dumping (diagnostic_context *dc)
3097 {
3098 #ifdef SIGABRT
3099 signal (SIGABRT, SIG_DFL);
3100 #endif
3101 #if defined(HAVE_SETRLIMIT)
3102 {
3103 struct rlimit rlim;
3104 if (getrlimit (RLIMIT_CORE, &rlim) != 0)
3105 fatal_error (input_location, "getting core file size maximum limit: %m");
3106 rlim.rlim_cur = rlim.rlim_max;
3107 if (setrlimit (RLIMIT_CORE, &rlim) != 0)
3108 fatal_error (input_location,
3109 "setting core file size limit to maximum: %m");
3110 }
3111 #endif
3112 diagnostic_abort_on_error (dc);
3113 }
3114
3115 /* Parse a -d<ARG> command line switch for OPTS, location LOC,
3116 diagnostic context DC. */
3117
3118 static void
3119 decode_d_option (const char *arg, struct gcc_options *opts,
3120 location_t loc, diagnostic_context *dc)
3121 {
3122 int c;
3123
3124 while (*arg)
3125 switch (c = *arg++)
3126 {
3127 case 'A':
3128 opts->x_flag_debug_asm = 1;
3129 break;
3130 case 'p':
3131 opts->x_flag_print_asm_name = 1;
3132 break;
3133 case 'P':
3134 opts->x_flag_dump_rtl_in_asm = 1;
3135 opts->x_flag_print_asm_name = 1;
3136 break;
3137 case 'x':
3138 opts->x_rtl_dump_and_exit = 1;
3139 break;
3140 case 'D': /* These are handled by the preprocessor. */
3141 case 'I':
3142 case 'M':
3143 case 'N':
3144 case 'U':
3145 break;
3146 case 'H':
3147 setup_core_dumping (dc);
3148 break;
3149 case 'a':
3150 opts->x_flag_dump_all_passed = true;
3151 break;
3152
3153 default:
3154 warning_at (loc, 0, "unrecognized gcc debugging option: %c", c);
3155 break;
3156 }
3157 }
3158
3159 /* Enable (or disable if VALUE is 0) a warning option ARG (language
3160 mask LANG_MASK, option handlers HANDLERS) as an error for option
3161 structures OPTS and OPTS_SET, diagnostic context DC (possibly
3162 NULL), location LOC. This is used by -Werror=. */
3163
3164 static void
3165 enable_warning_as_error (const char *arg, int value, unsigned int lang_mask,
3166 const struct cl_option_handlers *handlers,
3167 struct gcc_options *opts,
3168 struct gcc_options *opts_set,
3169 location_t loc, diagnostic_context *dc)
3170 {
3171 char *new_option;
3172 int option_index;
3173
3174 new_option = XNEWVEC (char, strlen (arg) + 2);
3175 new_option[0] = 'W';
3176 strcpy (new_option + 1, arg);
3177 option_index = find_opt (new_option, lang_mask);
3178 if (option_index == OPT_SPECIAL_unknown)
3179 {
3180 option_proposer op;
3181 const char *hint = op.suggest_option (new_option);
3182 if (hint)
3183 error_at (loc, "%<-W%serror=%s%>: no option %<-%s%>;"
3184 " did you mean %<-%s%>?", value ? "" : "no-",
3185 arg, new_option, hint);
3186 else
3187 error_at (loc, "%<-W%serror=%s%>: no option %<-%s%>",
3188 value ? "" : "no-", arg, new_option);
3189 }
3190 else if (!(cl_options[option_index].flags & CL_WARNING))
3191 error_at (loc, "%<-Werror=%s%>: %<-%s%> is not an option that "
3192 "controls warnings", arg, new_option);
3193 else
3194 {
3195 const diagnostic_t kind = value ? DK_ERROR : DK_WARNING;
3196 const char *arg = NULL;
3197
3198 if (cl_options[option_index].flags & CL_JOINED)
3199 arg = new_option + cl_options[option_index].opt_len;
3200 control_warning_option (option_index, (int) kind, arg, value,
3201 loc, lang_mask,
3202 handlers, opts, opts_set, dc);
3203 }
3204 free (new_option);
3205 }
3206
3207 /* Return malloced memory for the name of the option OPTION_INDEX
3208 which enabled a diagnostic (context CONTEXT), originally of type
3209 ORIG_DIAG_KIND but possibly converted to DIAG_KIND by options such
3210 as -Werror. */
3211
3212 char *
3213 option_name (diagnostic_context *context, int option_index,
3214 diagnostic_t orig_diag_kind, diagnostic_t diag_kind)
3215 {
3216 if (option_index)
3217 {
3218 /* A warning classified as an error. */
3219 if ((orig_diag_kind == DK_WARNING || orig_diag_kind == DK_PEDWARN)
3220 && diag_kind == DK_ERROR)
3221 return concat (cl_options[OPT_Werror_].opt_text,
3222 /* Skip over "-W". */
3223 cl_options[option_index].opt_text + 2,
3224 NULL);
3225 /* A warning with option. */
3226 else
3227 return xstrdup (cl_options[option_index].opt_text);
3228 }
3229 /* A warning without option classified as an error. */
3230 else if ((orig_diag_kind == DK_WARNING || orig_diag_kind == DK_PEDWARN
3231 || diag_kind == DK_WARNING)
3232 && context->warning_as_error_requested)
3233 return xstrdup (cl_options[OPT_Werror].opt_text);
3234 else
3235 return NULL;
3236 }
3237
3238 /* Get the page within the documentation for this option. */
3239
3240 static const char *
3241 get_option_html_page (int option_index)
3242 {
3243 const cl_option *cl_opt = &cl_options[option_index];
3244
3245 /* Analyzer options are on their own page. */
3246 if (strstr(cl_opt->opt_text, "analyzer-"))
3247 return "gcc/Static-Analyzer-Options.html";
3248
3249 #ifdef CL_Fortran
3250 if ((cl_opt->flags & CL_Fortran) != 0
3251 /* If it is option common to both C/C++ and Fortran, it is documented
3252 in gcc/ rather than gfortran/ docs. */
3253 && (cl_opt->flags & CL_C) == 0
3254 #ifdef CL_CXX
3255 && (cl_opt->flags & CL_CXX) == 0
3256 #endif
3257 )
3258 return "gfortran/Error-and-Warning-Options.html";
3259 #endif
3260
3261 return "gcc/Warning-Options.html";
3262 }
3263
3264 /* Return malloced memory for a URL describing the option OPTION_INDEX
3265 which enabled a diagnostic (context CONTEXT). */
3266
3267 char *
3268 get_option_url (diagnostic_context *, int option_index)
3269 {
3270 if (option_index)
3271 return concat (/* DOCUMENTATION_ROOT_URL should be supplied via -D by
3272 the Makefile (see --with-documentation-root-url), and
3273 should have a trailing slash. */
3274 DOCUMENTATION_ROOT_URL,
3275
3276 /* get_option_html_page will return something like
3277 "gcc/Warning-Options.html". */
3278 get_option_html_page (option_index),
3279
3280 /* Expect an anchor of the form "index-Wfoo" e.g.
3281 <a name="index-Wformat"></a>, and thus an id within
3282 the URL of "#index-Wformat". */
3283 "#index", cl_options[option_index].opt_text,
3284 NULL);
3285 else
3286 return NULL;
3287 }
3288
3289 /* Return a heap allocated producer with command line options. */
3290
3291 char *
3292 gen_command_line_string (cl_decoded_option *options,
3293 unsigned int options_count)
3294 {
3295 auto_vec<const char *> switches;
3296 char *options_string, *tail;
3297 const char *p;
3298 size_t len = 0;
3299
3300 for (unsigned i = 0; i < options_count; i++)
3301 switch (options[i].opt_index)
3302 {
3303 case OPT_o:
3304 case OPT_d:
3305 case OPT_dumpbase:
3306 case OPT_dumpbase_ext:
3307 case OPT_dumpdir:
3308 case OPT_quiet:
3309 case OPT_version:
3310 case OPT_v:
3311 case OPT_w:
3312 case OPT_L:
3313 case OPT_D:
3314 case OPT_I:
3315 case OPT_U:
3316 case OPT_SPECIAL_unknown:
3317 case OPT_SPECIAL_ignore:
3318 case OPT_SPECIAL_warn_removed:
3319 case OPT_SPECIAL_program_name:
3320 case OPT_SPECIAL_input_file:
3321 case OPT_grecord_gcc_switches:
3322 case OPT_frecord_gcc_switches:
3323 case OPT__output_pch_:
3324 case OPT_fdiagnostics_show_location_:
3325 case OPT_fdiagnostics_show_option:
3326 case OPT_fdiagnostics_show_caret:
3327 case OPT_fdiagnostics_show_labels:
3328 case OPT_fdiagnostics_show_line_numbers:
3329 case OPT_fdiagnostics_color_:
3330 case OPT_fdiagnostics_format_:
3331 case OPT_fverbose_asm:
3332 case OPT____:
3333 case OPT__sysroot_:
3334 case OPT_nostdinc:
3335 case OPT_nostdinc__:
3336 case OPT_fpreprocessed:
3337 case OPT_fltrans_output_list_:
3338 case OPT_fresolution_:
3339 case OPT_fdebug_prefix_map_:
3340 case OPT_fmacro_prefix_map_:
3341 case OPT_ffile_prefix_map_:
3342 case OPT_fcompare_debug:
3343 case OPT_fchecking:
3344 case OPT_fchecking_:
3345 /* Ignore these. */
3346 continue;
3347 case OPT_flto_:
3348 {
3349 const char *lto_canonical = "-flto";
3350 switches.safe_push (lto_canonical);
3351 len += strlen (lto_canonical) + 1;
3352 break;
3353 }
3354 default:
3355 if (cl_options[options[i].opt_index].flags
3356 & CL_NO_DWARF_RECORD)
3357 continue;
3358 gcc_checking_assert (options[i].canonical_option[0][0] == '-');
3359 switch (options[i].canonical_option[0][1])
3360 {
3361 case 'M':
3362 case 'i':
3363 case 'W':
3364 continue;
3365 case 'f':
3366 if (strncmp (options[i].canonical_option[0] + 2,
3367 "dump", 4) == 0)
3368 continue;
3369 break;
3370 default:
3371 break;
3372 }
3373 switches.safe_push (options[i].orig_option_with_args_text);
3374 len += strlen (options[i].orig_option_with_args_text) + 1;
3375 break;
3376 }
3377
3378 options_string = XNEWVEC (char, len + 1);
3379 tail = options_string;
3380
3381 unsigned i;
3382 FOR_EACH_VEC_ELT (switches, i, p)
3383 {
3384 len = strlen (p);
3385 memcpy (tail, p, len);
3386 tail += len;
3387 if (i != switches.length () - 1)
3388 {
3389 *tail = ' ';
3390 ++tail;
3391 }
3392 }
3393
3394 *tail = '\0';
3395 return options_string;
3396 }
3397
3398 /* Return a heap allocated producer string including command line options. */
3399
3400 char *
3401 gen_producer_string (const char *language_string, cl_decoded_option *options,
3402 unsigned int options_count)
3403 {
3404 char *cmdline = gen_command_line_string (options, options_count);
3405 char *combined = concat (language_string, " ", version_string, " ",
3406 cmdline, NULL);
3407 free (cmdline);
3408 return combined;
3409 }
3410
3411 #if CHECKING_P
3412
3413 namespace selftest {
3414
3415 /* Verify that get_option_html_page works as expected. */
3416
3417 static void
3418 test_get_option_html_page ()
3419 {
3420 ASSERT_STREQ (get_option_html_page (OPT_Wcpp), "gcc/Warning-Options.html");
3421 ASSERT_STREQ (get_option_html_page (OPT_Wanalyzer_double_free),
3422 "gcc/Static-Analyzer-Options.html");
3423 #ifdef CL_Fortran
3424 ASSERT_STREQ (get_option_html_page (OPT_Wline_truncation),
3425 "gfortran/Error-and-Warning-Options.html");
3426 #endif
3427 }
3428
3429 /* Run all of the selftests within this file. */
3430
3431 void
3432 opts_c_tests ()
3433 {
3434 test_get_option_html_page ();
3435 }
3436
3437 } // namespace selftest
3438
3439 #endif /* #if CHECKING_P */
3440