]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/opts.c
Delete obsolete SDB debug info support.
[thirdparty/gcc.git] / gcc / opts.c
CommitLineData
2772ef3e 1/* Command line option handling.
cbe34bb5 2 Copyright (C) 2002-2017 Free Software Foundation, Inc.
2772ef3e
NB
3 Contributed by Neil Booth.
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9dcd6f09 9Software Foundation; either version 3, or (at your option) any later
2772ef3e
NB
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
9dcd6f09
NC
18along with GCC; see the file COPYING3. If not see
19<http://www.gnu.org/licenses/>. */
2772ef3e
NB
20
21#include "config.h"
22#include "system.h"
cf03fd63 23#include "intl.h"
2772ef3e 24#include "coretypes.h"
7d5a5747 25#include "opts.h"
903f5c23 26#include "tm.h"
d7b42618 27#include "flags.h"
903caebf 28#include "params.h"
de32c0cb 29#include "diagnostic.h"
5f0f4a3b 30#include "opts-diagnostic.h"
88a00ef7 31#include "insn-attr-common.h"
677f3fa8 32#include "common/common-target.h"
19ff0049 33#include "spellcheck.h"
2772ef3e 34
65d4f2cd
MLI
35static void set_Wstrict_aliasing (struct gcc_options *opts, int onoff);
36
a7d0d30f
JM
37/* Indexed by enum debug_info_type. */
38const char *const debug_type_names[] =
39{
180295ed 40 "none", "stabs", "dwarf-2", "xcoff", "vms"
a7d0d30f
JM
41};
42
39ef6592
LC
43/* Parse the -femit-struct-debug-detailed option value
44 and set the flag variables. */
45
46#define MATCH( prefix, string ) \
47 ((strncmp (prefix, string, sizeof prefix - 1) == 0) \
48 ? ((string += sizeof prefix - 1), 1) : 0)
49
50void
299404a1
JM
51set_struct_debug_option (struct gcc_options *opts, location_t loc,
52 const char *spec)
39ef6592
LC
53{
54 /* various labels for comparison */
0576d21f
JM
55 static const char dfn_lbl[] = "dfn:", dir_lbl[] = "dir:", ind_lbl[] = "ind:";
56 static const char ord_lbl[] = "ord:", gen_lbl[] = "gen:";
57 static const char none_lbl[] = "none", any_lbl[] = "any";
58 static const char base_lbl[] = "base", sys_lbl[] = "sys";
39ef6592
LC
59
60 enum debug_struct_file files = DINFO_STRUCT_FILE_ANY;
61 /* Default is to apply to as much as possible. */
62 enum debug_info_usage usage = DINFO_USAGE_NUM_ENUMS;
63 int ord = 1, gen = 1;
64
65 /* What usage? */
66 if (MATCH (dfn_lbl, spec))
67 usage = DINFO_USAGE_DFN;
68 else if (MATCH (dir_lbl, spec))
69 usage = DINFO_USAGE_DIR_USE;
70 else if (MATCH (ind_lbl, spec))
71 usage = DINFO_USAGE_IND_USE;
72
73 /* Generics or not? */
74 if (MATCH (ord_lbl, spec))
75 gen = 0;
76 else if (MATCH (gen_lbl, spec))
77 ord = 0;
78
79 /* What allowable environment? */
80 if (MATCH (none_lbl, spec))
81 files = DINFO_STRUCT_FILE_NONE;
82 else if (MATCH (any_lbl, spec))
83 files = DINFO_STRUCT_FILE_ANY;
84 else if (MATCH (sys_lbl, spec))
85 files = DINFO_STRUCT_FILE_SYS;
86 else if (MATCH (base_lbl, spec))
87 files = DINFO_STRUCT_FILE_BASE;
88 else
299404a1
JM
89 error_at (loc,
90 "argument %qs to %<-femit-struct-debug-detailed%> "
91 "not recognized",
92 spec);
39ef6592
LC
93
94 /* Effect the specification. */
95 if (usage == DINFO_USAGE_NUM_ENUMS)
96 {
97 if (ord)
98 {
69ccdddb
JM
99 opts->x_debug_struct_ordinary[DINFO_USAGE_DFN] = files;
100 opts->x_debug_struct_ordinary[DINFO_USAGE_DIR_USE] = files;
101 opts->x_debug_struct_ordinary[DINFO_USAGE_IND_USE] = files;
39ef6592
LC
102 }
103 if (gen)
104 {
69ccdddb
JM
105 opts->x_debug_struct_generic[DINFO_USAGE_DFN] = files;
106 opts->x_debug_struct_generic[DINFO_USAGE_DIR_USE] = files;
107 opts->x_debug_struct_generic[DINFO_USAGE_IND_USE] = files;
39ef6592
LC
108 }
109 }
110 else
111 {
112 if (ord)
69ccdddb 113 opts->x_debug_struct_ordinary[usage] = files;
39ef6592 114 if (gen)
69ccdddb 115 opts->x_debug_struct_generic[usage] = files;
39ef6592
LC
116 }
117
118 if (*spec == ',')
299404a1 119 set_struct_debug_option (opts, loc, spec+1);
39ef6592
LC
120 else
121 {
122 /* No more -femit-struct-debug-detailed specifications.
123 Do final checks. */
124 if (*spec != '\0')
299404a1
JM
125 error_at (loc,
126 "argument %qs to %<-femit-struct-debug-detailed%> unknown",
127 spec);
69ccdddb
JM
128 if (opts->x_debug_struct_ordinary[DINFO_USAGE_DIR_USE]
129 < opts->x_debug_struct_ordinary[DINFO_USAGE_IND_USE]
130 || opts->x_debug_struct_generic[DINFO_USAGE_DIR_USE]
131 < opts->x_debug_struct_generic[DINFO_USAGE_IND_USE])
299404a1
JM
132 error_at (loc,
133 "%<-femit-struct-debug-detailed=dir:...%> must allow "
134 "at least as much as "
135 "%<-femit-struct-debug-detailed=ind:...%>");
39ef6592
LC
136 }
137}
138
c98cd5bf
JM
139/* Strip off a legitimate source ending from the input string NAME of
140 length LEN. Rather than having to know the names used by all of
141 our front ends, we strip off an ending of a period followed by
ed5cd5bc 142 up to fource characters. (C++ uses ".cpp".) */
c98cd5bf
JM
143
144void
145strip_off_ending (char *name, int len)
146{
147 int i;
ed5cd5bc 148 for (i = 2; i < 5 && len > i; i++)
c98cd5bf
JM
149 {
150 if (name[len - i] == '.')
151 {
152 name[len - i] = '\0';
153 break;
154 }
155 }
156}
157
39ef6592
LC
158/* Find the base name of a path, stripping off both directories and
159 a single final extension. */
69ccdddb 160int
39ef6592
LC
161base_of_path (const char *path, const char **base_out)
162{
163 const char *base = path;
164 const char *dot = 0;
165 const char *p = path;
166 char c = *p;
167 while (c)
168 {
c3284718 169 if (IS_DIR_SEPARATOR (c))
39ef6592
LC
170 {
171 base = p + 1;
172 dot = 0;
173 }
174 else if (c == '.')
175 dot = p;
176 c = *++p;
177 }
178 if (!dot)
179 dot = p;
180 *base_out = base;
181 return dot - base;
182}
183
2cc98056 184/* What to print when a switch has no documentation. */
a7b2e184
MS
185static const char undocumented_msg[] = N_("This option lacks documentation.");
186static const char use_diagnosed_msg[] = N_("Uses of this option are diagnosed.");
2cc98056 187
8d5a7d1f 188typedef char *char_p; /* For DEF_VEC_P. */
8d5a7d1f 189
48476d13 190static void handle_param (struct gcc_options *opts,
299404a1
JM
191 struct gcc_options *opts_set, location_t loc,
192 const char *carg);
df38ffef 193static void set_debug_level (enum debug_info_type type, int extended,
0576d21f 194 const char *arg, struct gcc_options *opts,
299404a1
JM
195 struct gcc_options *opts_set,
196 location_t loc);
d5478783 197static void set_fast_math_flags (struct gcc_options *opts, int set);
299404a1
JM
198static void decode_d_option (const char *arg, struct gcc_options *opts,
199 location_t loc, diagnostic_context *dc);
d5478783
JM
200static void set_unsafe_math_optimizations_flags (struct gcc_options *opts,
201 int set);
a4d8c676
JM
202static void enable_warning_as_error (const char *arg, int value,
203 unsigned int lang_mask,
204 const struct cl_option_handlers *handlers,
c5fa0890
JM
205 struct gcc_options *opts,
206 struct gcc_options *opts_set,
a4d8c676
JM
207 location_t loc,
208 diagnostic_context *dc);
2772ef3e 209
5f20c657
JM
210/* Handle a back-end option; arguments and return value as for
211 handle_option. */
2772ef3e 212
c98cd5bf 213bool
46625112 214target_handle_option (struct gcc_options *opts,
d4d24ba4 215 struct gcc_options *opts_set,
46625112 216 const struct cl_decoded_option *decoded,
481e1176 217 unsigned int lang_mask ATTRIBUTE_UNUSED, int kind,
96e45421 218 location_t loc,
d5478783 219 const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED,
130fcab0 220 diagnostic_context *dc, void (*) (void))
5f20c657 221{
d5478783 222 gcc_assert (dc == global_dc);
5f20c657 223 gcc_assert (kind == DK_UNSPECIFIED);
677f3fa8 224 return targetm_common.handle_option (opts, opts_set, decoded, loc);
2772ef3e 225}
d7b42618 226
1ebc7e68 227/* Add comma-separated strings to a char_p vector. */
8d5a7d1f
ILT
228
229static void
6a1f6c9c 230add_comma_separated_to_vector (void **pvec, const char *arg)
8d5a7d1f
ILT
231{
232 char *tmp;
233 char *r;
234 char *w;
235 char *token_start;
9771b263
DN
236 vec<char_p> *v = (vec<char_p> *) *pvec;
237
238 vec_check_alloc (v, 1);
8d5a7d1f
ILT
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;
9771b263 253 v->safe_push (token_start);
8d5a7d1f
ILT
254 token_start = w;
255 }
256 if (*r == '\\' && r[1] == ',')
257 {
258 *w++ = ',';
259 r += 2;
260 }
261 else
262 *w++ = *r++;
263 }
264 if (*token_start != '\0')
9771b263 265 v->safe_push (token_start);
8d5a7d1f 266
9771b263 267 *pvec = v;
8d5a7d1f
ILT
268}
269
d6874f56 270/* Initialize opts_obstack. */
de5672fc
ML
271
272void
273init_opts_obstack (void)
274{
d6874f56 275 gcc_obstack_init (&opts_obstack);
de5672fc
ML
276}
277
a75bfaa6
JM
278/* Initialize OPTS and OPTS_SET before using them in parsing options. */
279
280void
281init_options_struct (struct gcc_options *opts, struct gcc_options *opts_set)
282{
48476d13
JM
283 size_t num_params = get_num_compiler_params ();
284
d6874f56
DM
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);
dc357798 288
a75bfaa6 289 *opts = global_options_init;
bf7b5747
ST
290
291 if (opts_set)
292 memset (opts_set, 0, sizeof (*opts_set));
a75bfaa6 293
48476d13 294 opts->x_param_values = XNEWVEC (int, num_params);
bf7b5747
ST
295
296 if (opts_set)
297 opts_set->x_param_values = XCNEWVEC (int, num_params);
298
48476d13
JM
299 init_param_values (opts->x_param_values);
300
a75bfaa6
JM
301 /* Initialize whether `char' is signed. */
302 opts->x_flag_signed_char = DEFAULT_SIGNED_CHAR;
303 /* Set this to a special "uninitialized" value. The actual default
304 is set after target options have been processed. */
305 opts->x_flag_short_enums = 2;
306
677f3fa8 307 /* Initialize target_flags before default_options_optimization
a75bfaa6 308 so the latter can modify it. */
677f3fa8 309 opts->x_target_flags = targetm_common.default_target_flags;
a75bfaa6
JM
310
311 /* Some targets have ABI-specified unwind tables. */
677f3fa8 312 opts->x_flag_unwind_tables = targetm_common.unwind_tables_default;
7e4aae92
JM
313
314 /* Some targets have other target-specific initialization. */
677f3fa8 315 targetm_common.option_init_struct (opts);
a75bfaa6
JM
316}
317
0ef443cf
DM
318/* Release any allocations owned by OPTS. */
319
320void
321finalize_options_struct (struct gcc_options *opts)
322{
323 XDELETEVEC (opts->x_param_values);
324}
325
3020190e 326/* If indicated by the optimization level LEVEL (-Os if SIZE is set,
bf7a7185
RG
327 -Ofast if FAST is set, -Og if DEBUG is set), apply the option DEFAULT_OPT
328 to OPTS and OPTS_SET, diagnostic context DC, location LOC, with language
329 mask LANG_MASK and option handlers HANDLERS. */
3020190e
JM
330
331static void
332maybe_default_option (struct gcc_options *opts,
333 struct gcc_options *opts_set,
334 const struct default_options *default_opt,
bf7a7185 335 int level, bool size, bool fast, bool debug,
3020190e
JM
336 unsigned int lang_mask,
337 const struct cl_option_handlers *handlers,
a4d8c676 338 location_t loc,
3020190e
JM
339 diagnostic_context *dc)
340{
341 const struct cl_option *option = &cl_options[default_opt->opt_index];
342 bool enabled;
343
344 if (size)
345 gcc_assert (level == 2);
346 if (fast)
347 gcc_assert (level == 3);
bf7a7185
RG
348 if (debug)
349 gcc_assert (level == 1);
3020190e
JM
350
351 switch (default_opt->levels)
352 {
353 case OPT_LEVELS_ALL:
354 enabled = true;
355 break;
356
357 case OPT_LEVELS_0_ONLY:
358 enabled = (level == 0);
359 break;
360
361 case OPT_LEVELS_1_PLUS:
362 enabled = (level >= 1);
363 break;
364
365 case OPT_LEVELS_1_PLUS_SPEED_ONLY:
bf7a7185
RG
366 enabled = (level >= 1 && !size && !debug);
367 break;
368
369 case OPT_LEVELS_1_PLUS_NOT_DEBUG:
370 enabled = (level >= 1 && !debug);
3020190e
JM
371 break;
372
373 case OPT_LEVELS_2_PLUS:
374 enabled = (level >= 2);
375 break;
376
377 case OPT_LEVELS_2_PLUS_SPEED_ONLY:
bf7a7185 378 enabled = (level >= 2 && !size && !debug);
3020190e
JM
379 break;
380
381 case OPT_LEVELS_3_PLUS:
382 enabled = (level >= 3);
383 break;
384
385 case OPT_LEVELS_3_PLUS_AND_SIZE:
386 enabled = (level >= 3 || size);
387 break;
388
389 case OPT_LEVELS_SIZE:
390 enabled = size;
391 break;
392
393 case OPT_LEVELS_FAST:
394 enabled = fast;
395 break;
396
397 case OPT_LEVELS_NONE:
398 default:
399 gcc_unreachable ();
400 }
401
402 if (enabled)
403 handle_generated_option (opts, opts_set, default_opt->opt_index,
404 default_opt->arg, default_opt->value,
a4d8c676 405 lang_mask, DK_UNSPECIFIED, loc,
b9822443 406 handlers, true, dc);
3020190e 407 else if (default_opt->arg == NULL
300d83d9 408 && !option->cl_reject_negative)
3020190e
JM
409 handle_generated_option (opts, opts_set, default_opt->opt_index,
410 default_opt->arg, !default_opt->value,
a4d8c676 411 lang_mask, DK_UNSPECIFIED, loc,
b9822443 412 handlers, true, dc);
3020190e
JM
413}
414
415/* As indicated by the optimization level LEVEL (-Os if SIZE is set,
416 -Ofast if FAST is set), apply the options in array DEFAULT_OPTS to
a4d8c676
JM
417 OPTS and OPTS_SET, diagnostic context DC, location LOC, with
418 language mask LANG_MASK and option handlers HANDLERS. */
3020190e
JM
419
420static void
421maybe_default_options (struct gcc_options *opts,
422 struct gcc_options *opts_set,
423 const struct default_options *default_opts,
bf7a7185 424 int level, bool size, bool fast, bool debug,
3020190e
JM
425 unsigned int lang_mask,
426 const struct cl_option_handlers *handlers,
a4d8c676 427 location_t loc,
3020190e
JM
428 diagnostic_context *dc)
429{
430 size_t i;
431
432 for (i = 0; default_opts[i].levels != OPT_LEVELS_NONE; i++)
433 maybe_default_option (opts, opts_set, &default_opts[i],
bf7a7185
RG
434 level, size, fast, debug,
435 lang_mask, handlers, loc, dc);
3020190e
JM
436}
437
438/* Table of options enabled by default at different levels. */
439
440static const struct default_options default_options_table[] =
441 {
442 /* -O1 optimizations. */
443 { OPT_LEVELS_1_PLUS, OPT_fdefer_pop, NULL, 1 },
e90bedf5 444#if DELAY_SLOTS
3020190e
JM
445 { OPT_LEVELS_1_PLUS, OPT_fdelayed_branch, NULL, 1 },
446#endif
447 { OPT_LEVELS_1_PLUS, OPT_fguess_branch_probability, NULL, 1 },
448 { OPT_LEVELS_1_PLUS, OPT_fcprop_registers, NULL, 1 },
449 { OPT_LEVELS_1_PLUS, OPT_fforward_propagate, NULL, 1 },
eeee2277
JY
450 { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fif_conversion, NULL, 1 },
451 { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fif_conversion2, NULL, 1 },
3020190e
JM
452 { OPT_LEVELS_1_PLUS, OPT_fipa_pure_const, NULL, 1 },
453 { OPT_LEVELS_1_PLUS, OPT_fipa_reference, NULL, 1 },
454 { OPT_LEVELS_1_PLUS, OPT_fipa_profile, NULL, 1 },
455 { OPT_LEVELS_1_PLUS, OPT_fmerge_constants, NULL, 1 },
59faab7c 456 { OPT_LEVELS_1_PLUS, OPT_freorder_blocks, NULL, 1 },
484db665 457 { OPT_LEVELS_1_PLUS, OPT_fshrink_wrap, NULL, 1 },
3020190e
JM
458 { OPT_LEVELS_1_PLUS, OPT_fsplit_wide_types, NULL, 1 },
459 { OPT_LEVELS_1_PLUS, OPT_ftree_ccp, NULL, 1 },
78d22941 460 { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_bit_ccp, NULL, 1 },
1f9ceff1 461 { OPT_LEVELS_1_PLUS, OPT_ftree_coalesce_vars, NULL, 1 },
3020190e
JM
462 { OPT_LEVELS_1_PLUS, OPT_ftree_dce, NULL, 1 },
463 { OPT_LEVELS_1_PLUS, OPT_ftree_dominator_opts, NULL, 1 },
464 { OPT_LEVELS_1_PLUS, OPT_ftree_dse, NULL, 1 },
465 { OPT_LEVELS_1_PLUS, OPT_ftree_ter, NULL, 1 },
bf7a7185 466 { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_sra, NULL, 1 },
3020190e
JM
467 { OPT_LEVELS_1_PLUS, OPT_ftree_fre, NULL, 1 },
468 { OPT_LEVELS_1_PLUS, OPT_ftree_copy_prop, NULL, 1 },
469 { OPT_LEVELS_1_PLUS, OPT_ftree_sink, NULL, 1 },
470 { OPT_LEVELS_1_PLUS, OPT_ftree_ch, NULL, 1 },
471 { OPT_LEVELS_1_PLUS, OPT_fcombine_stack_adjustments, NULL, 1 },
e692f276 472 { OPT_LEVELS_1_PLUS, OPT_fcompare_elim, NULL, 1 },
75cfe445 473 { OPT_LEVELS_1_PLUS, OPT_ftree_slsr, NULL, 1 },
14379e66
RB
474 { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fbranch_count_reg, NULL, 1 },
475 { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fmove_loop_invariants, NULL, 1 },
476 { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_pta, NULL, 1 },
68f6df73 477 { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fssa_phiopt, NULL, 1 },
883cabde 478 { OPT_LEVELS_1_PLUS, OPT_ftree_builtin_call_dce, NULL, 1 },
3020190e
JM
479
480 /* -O2 optimizations. */
481 { OPT_LEVELS_2_PLUS, OPT_finline_small_functions, NULL, 1 },
482 { OPT_LEVELS_2_PLUS, OPT_findirect_inlining, NULL, 1 },
483 { OPT_LEVELS_2_PLUS, OPT_fpartial_inlining, NULL, 1 },
484 { OPT_LEVELS_2_PLUS, OPT_fthread_jumps, NULL, 1 },
485 { OPT_LEVELS_2_PLUS, OPT_fcrossjumping, NULL, 1 },
486 { OPT_LEVELS_2_PLUS, OPT_foptimize_sibling_calls, NULL, 1 },
487 { OPT_LEVELS_2_PLUS, OPT_fcse_follow_jumps, NULL, 1 },
488 { OPT_LEVELS_2_PLUS, OPT_fgcse, NULL, 1 },
489 { OPT_LEVELS_2_PLUS, OPT_fexpensive_optimizations, NULL, 1 },
490 { OPT_LEVELS_2_PLUS, OPT_frerun_cse_after_loop, NULL, 1 },
491 { OPT_LEVELS_2_PLUS, OPT_fcaller_saves, NULL, 1 },
492 { OPT_LEVELS_2_PLUS, OPT_fpeephole2, NULL, 1 },
493#ifdef INSN_SCHEDULING
494 /* Only run the pre-regalloc scheduling pass if optimizing for speed. */
495 { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_fschedule_insns, NULL, 1 },
496 { OPT_LEVELS_2_PLUS, OPT_fschedule_insns2, NULL, 1 },
497#endif
3020190e 498 { OPT_LEVELS_2_PLUS, OPT_fstrict_aliasing, NULL, 1 },
59faab7c
SB
499 { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_freorder_blocks_algorithm_, NULL,
500 REORDER_BLOCKS_ALGORITHM_STC },
3020190e
JM
501 { OPT_LEVELS_2_PLUS, OPT_freorder_functions, NULL, 1 },
502 { OPT_LEVELS_2_PLUS, OPT_ftree_vrp, NULL, 1 },
37ccb0ba 503 { OPT_LEVELS_2_PLUS, OPT_fcode_hoisting, NULL, 1 },
3020190e
JM
504 { OPT_LEVELS_2_PLUS, OPT_ftree_pre, NULL, 1 },
505 { OPT_LEVELS_2_PLUS, OPT_ftree_switch_conversion, NULL, 1 },
506 { OPT_LEVELS_2_PLUS, OPT_fipa_cp, NULL, 1 },
209ca542 507 { OPT_LEVELS_2_PLUS, OPT_fipa_bit_cp, NULL, 1 },
8bc5448f 508 { OPT_LEVELS_2_PLUS, OPT_fipa_vrp, NULL, 1 },
05842ff5 509 { OPT_LEVELS_2_PLUS, OPT_fdevirtualize, NULL, 1 },
bbc9396b 510 { OPT_LEVELS_2_PLUS, OPT_fdevirtualize_speculatively, NULL, 1 },
3020190e
JM
511 { OPT_LEVELS_2_PLUS, OPT_fipa_sra, NULL, 1 },
512 { OPT_LEVELS_2_PLUS, OPT_falign_loops, NULL, 1 },
513 { OPT_LEVELS_2_PLUS, OPT_falign_jumps, NULL, 1 },
514 { OPT_LEVELS_2_PLUS, OPT_falign_labels, NULL, 1 },
515 { OPT_LEVELS_2_PLUS, OPT_falign_functions, NULL, 1 },
c9e93168 516 { OPT_LEVELS_2_PLUS, OPT_ftree_tail_merge, NULL, 1 },
d6d11272 517 { OPT_LEVELS_2_PLUS, OPT_fvect_cost_model_, NULL, VECT_COST_MODEL_CHEAP },
d8878031 518 { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_foptimize_strlen, NULL, 1 },
372a6eb8 519 { OPT_LEVELS_2_PLUS, OPT_fhoist_adjacent_loads, NULL, 1 },
b84d4347 520 { OPT_LEVELS_2_PLUS, OPT_fipa_icf, NULL, 1 },
ae93744d 521 { OPT_LEVELS_2_PLUS, OPT_fisolate_erroneous_paths_dereference, NULL, 1 },
1e288103 522 { OPT_LEVELS_2_PLUS, OPT_fipa_ra, NULL, 1 },
d9cf932c 523 { OPT_LEVELS_2_PLUS, OPT_flra_remat, NULL, 1 },
f663d9ad 524 { OPT_LEVELS_2_PLUS, OPT_fstore_merging, NULL, 1 },
3020190e
JM
525
526 /* -O3 optimizations. */
527 { OPT_LEVELS_3_PLUS, OPT_ftree_loop_distribute_patterns, NULL, 1 },
5a115661 528 { OPT_LEVELS_3_PLUS, OPT_ftree_loop_distribution, NULL, 1 },
3020190e 529 { OPT_LEVELS_3_PLUS, OPT_fpredictive_commoning, NULL, 1 },
72ca20f9 530 { OPT_LEVELS_3_PLUS, OPT_fsplit_paths, NULL, 1 },
3020190e
JM
531 /* Inlining of functions reducing size is a good idea with -Os
532 regardless of them being declared inline. */
533 { OPT_LEVELS_3_PLUS_AND_SIZE, OPT_finline_functions, NULL, 1 },
bf7a7185 534 { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_finline_functions_called_once, NULL, 1 },
28df8730 535 { OPT_LEVELS_3_PLUS, OPT_fsplit_loops, NULL, 1 },
3020190e
JM
536 { OPT_LEVELS_3_PLUS, OPT_funswitch_loops, NULL, 1 },
537 { OPT_LEVELS_3_PLUS, OPT_fgcse_after_reload, NULL, 1 },
ea0f3e87
XDL
538 { OPT_LEVELS_3_PLUS, OPT_ftree_loop_vectorize, NULL, 1 },
539 { OPT_LEVELS_3_PLUS, OPT_ftree_slp_vectorize, NULL, 1 },
d6d11272 540 { OPT_LEVELS_3_PLUS, OPT_fvect_cost_model_, NULL, VECT_COST_MODEL_DYNAMIC },
3020190e 541 { OPT_LEVELS_3_PLUS, OPT_fipa_cp_clone, NULL, 1 },
fa06ad0d 542 { OPT_LEVELS_3_PLUS, OPT_ftree_partial_pre, NULL, 1 },
a448ff40 543 { OPT_LEVELS_3_PLUS, OPT_fpeel_loops, NULL, 1 },
3020190e
JM
544
545 /* -Ofast adds optimizations to -O3. */
546 { OPT_LEVELS_FAST, OPT_ffast_math, NULL, 1 },
547
548 { OPT_LEVELS_NONE, 0, NULL, 0 }
549 };
550
a75bfaa6
JM
551/* Default the options in OPTS and OPTS_SET based on the optimization
552 settings in DECODED_OPTIONS and DECODED_OPTIONS_COUNT. */
c98cd5bf 553void
a75bfaa6
JM
554default_options_optimization (struct gcc_options *opts,
555 struct gcc_options *opts_set,
556 struct cl_decoded_option *decoded_options,
3020190e 557 unsigned int decoded_options_count,
a4d8c676 558 location_t loc,
3020190e
JM
559 unsigned int lang_mask,
560 const struct cl_option_handlers *handlers,
561 diagnostic_context *dc)
a75bfaa6
JM
562{
563 unsigned int i;
ab442df7 564 int opt2;
597a8ab9 565 bool openacc_mode = false;
9756310a
NB
566
567 /* Scan to see what optimization level has been specified. That will
568 determine the default value of many flags. */
a75bfaa6 569 for (i = 1; i < decoded_options_count; i++)
9756310a 570 {
a75bfaa6 571 struct cl_decoded_option *opt = &decoded_options[i];
6e2f1956 572 switch (opt->opt_index)
9756310a 573 {
6e2f1956
JM
574 case OPT_O:
575 if (*opt->arg == '\0')
be6d3f0e 576 {
3020190e
JM
577 opts->x_optimize = 1;
578 opts->x_optimize_size = 0;
0a8134ca 579 opts->x_optimize_fast = 0;
bf7a7185 580 opts->x_optimize_debug = 0;
9756310a
NB
581 }
582 else
583 {
6e2f1956
JM
584 const int optimize_val = integral_argument (opt->arg);
585 if (optimize_val == -1)
33879b9f
MP
586 error_at (loc, "argument to %<-O%> should be a non-negative "
587 "integer, %<g%>, %<s%> or %<fast%>");
6e2f1956 588 else
9756310a 589 {
3020190e
JM
590 opts->x_optimize = optimize_val;
591 if ((unsigned int) opts->x_optimize > 255)
592 opts->x_optimize = 255;
593 opts->x_optimize_size = 0;
0a8134ca 594 opts->x_optimize_fast = 0;
bf7a7185 595 opts->x_optimize_debug = 0;
9756310a
NB
596 }
597 }
6e2f1956
JM
598 break;
599
600 case OPT_Os:
3020190e 601 opts->x_optimize_size = 1;
6e2f1956
JM
602
603 /* Optimizing for size forces optimize to be 2. */
3020190e 604 opts->x_optimize = 2;
0a8134ca 605 opts->x_optimize_fast = 0;
bf7a7185 606 opts->x_optimize_debug = 0;
6e2f1956
JM
607 break;
608
609 case OPT_Ofast:
610 /* -Ofast only adds flags to -O3. */
3020190e
JM
611 opts->x_optimize_size = 0;
612 opts->x_optimize = 3;
0a8134ca 613 opts->x_optimize_fast = 1;
bf7a7185
RG
614 opts->x_optimize_debug = 0;
615 break;
616
617 case OPT_Og:
618 /* -Og selects optimization level 1. */
619 opts->x_optimize_size = 0;
620 opts->x_optimize = 1;
621 opts->x_optimize_fast = 0;
622 opts->x_optimize_debug = 1;
6e2f1956
JM
623 break;
624
597a8ab9
TV
625 case OPT_fopenacc:
626 if (opt->value)
627 openacc_mode = true;
628 break;
629
6e2f1956
JM
630 default:
631 /* Ignore other options in this prescan. */
632 break;
9756310a
NB
633 }
634 }
b8698a0f 635
3020190e
JM
636 maybe_default_options (opts, opts_set, default_options_table,
637 opts->x_optimize, opts->x_optimize_size,
bf7a7185
RG
638 opts->x_optimize_fast, opts->x_optimize_debug,
639 lang_mask, handlers, loc, dc);
3020190e
JM
640
641 /* -O2 param settings. */
642 opt2 = (opts->x_optimize >= 2);
116cb604 643
597a8ab9
TV
644 if (openacc_mode
645 && !opts_set->x_flag_ipa_pta)
646 opts->x_flag_ipa_pta = true;
647
ab442df7 648 /* Track fields in field-sensitive alias analysis. */
48476d13
JM
649 maybe_set_param_value
650 (PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE,
651 opt2 ? 100 : default_param_value (PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE),
652 opts->x_param_values, opts_set->x_param_values);
e9e0aa2c 653
b1fb9f56 654 /* For -O1 only do loop invariant motion for very small loops. */
48476d13
JM
655 maybe_set_param_value
656 (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP,
657 opt2 ? default_param_value (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP) : 1000,
658 opts->x_param_values, opts_set->x_param_values);
b1fb9f56 659
680a5a7c
MJ
660 /* At -Ofast, allow store motion to introduce potential race conditions. */
661 maybe_set_param_value
662 (PARAM_ALLOW_STORE_DATA_RACES,
663 opts->x_optimize_fast ? 1
664 : default_param_value (PARAM_ALLOW_STORE_DATA_RACES),
665 opts->x_param_values, opts_set->x_param_values);
666
3020190e
JM
667 if (opts->x_optimize_size)
668 /* We want to crossjump as much as possible. */
669 maybe_set_param_value (PARAM_MIN_CROSSJUMP_INSNS, 1,
670 opts->x_param_values, opts_set->x_param_values);
ab442df7 671 else
128dc8e2 672 maybe_set_param_value (PARAM_MIN_CROSSJUMP_INSNS,
48476d13
JM
673 default_param_value (PARAM_MIN_CROSSJUMP_INSNS),
674 opts->x_param_values, opts_set->x_param_values);
f736cb3e 675
b30e733a
RB
676 /* Restrict the amount of work combine does at -Og while retaining
677 most of its useful transforms. */
678 if (opts->x_optimize_debug)
679 maybe_set_param_value (PARAM_MAX_COMBINE_INSNS, 2,
680 opts->x_param_values, opts_set->x_param_values);
681
a75bfaa6 682 /* Allow default optimizations to be specified on a per-machine basis. */
3020190e 683 maybe_default_options (opts, opts_set,
677f3fa8 684 targetm_common.option_optimization_table,
3020190e 685 opts->x_optimize, opts->x_optimize_size,
bf7a7185
RG
686 opts->x_optimize_fast, opts->x_optimize_debug,
687 lang_mask, handlers, loc, dc);
a75bfaa6
JM
688}
689
299404a1
JM
690/* After all options at LOC have been read into OPTS and OPTS_SET,
691 finalize settings of those options and diagnose incompatible
a75bfaa6 692 combinations. */
c98cd5bf 693void
299404a1
JM
694finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
695 location_t loc)
a75bfaa6 696{
a75bfaa6
JM
697 enum unwind_info_type ui_except;
698
91035653
JJ
699 if (opts->x_dump_base_name
700 && ! IS_ABSOLUTE_PATH (opts->x_dump_base_name)
701 && ! opts->x_dump_base_name_prefixed)
e71da632 702 {
d5478783
JM
703 /* First try to make OPTS->X_DUMP_BASE_NAME relative to the
704 OPTS->X_DUMP_DIR_NAME directory. Then try to make
705 OPTS->X_DUMP_BASE_NAME relative to the OPTS->X_AUX_BASE_NAME
706 directory, typically the directory to contain the object
707 file. */
708 if (opts->x_dump_dir_name)
dc357798
JJ
709 opts->x_dump_base_name = opts_concat (opts->x_dump_dir_name,
710 opts->x_dump_base_name, NULL);
dd3b31fb
L
711 else if (opts->x_aux_base_name
712 && strcmp (opts->x_aux_base_name, HOST_BIT_BUCKET) != 0)
e71da632 713 {
d7fb0a6d
L
714 const char *aux_base;
715
d5478783
JM
716 base_of_path (opts->x_aux_base_name, &aux_base);
717 if (opts->x_aux_base_name != aux_base)
d7fb0a6d 718 {
d5478783 719 int dir_len = aux_base - opts->x_aux_base_name;
dc357798
JJ
720 char *new_dump_base_name
721 = XOBNEWVEC (&opts_obstack, char,
722 strlen (opts->x_dump_base_name) + dir_len + 1);
d7fb0a6d 723
d5478783
JM
724 /* Copy directory component from OPTS->X_AUX_BASE_NAME. */
725 memcpy (new_dump_base_name, opts->x_aux_base_name, dir_len);
726 /* Append existing OPTS->X_DUMP_BASE_NAME. */
727 strcpy (new_dump_base_name + dir_len, opts->x_dump_base_name);
728 opts->x_dump_base_name = new_dump_base_name;
d7fb0a6d 729 }
e71da632 730 }
91035653 731 opts->x_dump_base_name_prefixed = true;
e71da632
MH
732 }
733
93a4f5e0
JJ
734 /* Handle related options for unit-at-a-time, toplevel-reorder, and
735 section-anchors. */
d5478783 736 if (!opts->x_flag_unit_at_a_time)
57b08d04 737 {
d5478783 738 if (opts->x_flag_section_anchors && opts_set->x_flag_section_anchors)
299404a1
JM
739 error_at (loc, "section anchors must be disabled when unit-at-a-time "
740 "is disabled");
d5478783
JM
741 opts->x_flag_section_anchors = 0;
742 if (opts->x_flag_toplevel_reorder == 1)
299404a1
JM
743 error_at (loc, "toplevel reorder must be disabled when unit-at-a-time "
744 "is disabled");
d5478783 745 opts->x_flag_toplevel_reorder = 0;
57b08d04 746 }
7ea6b6cf 747
3615816d
AH
748 /* -fself-test depends on the state of the compiler prior to
749 compiling anything. Ideally it should be run on an empty source
750 file. However, in case we get run with actual source, assume
751 -fsyntax-only which will inhibit any compiler initialization
752 which may confuse the self tests. */
753 if (opts->x_flag_self_test)
754 opts->x_flag_syntax_only = 1;
755
ee777b71
AH
756 if (opts->x_flag_tm && opts->x_flag_non_call_exceptions)
757 sorry ("transactional memory is not supported with non-call exceptions");
758
5ffebee7
JJ
759 /* Unless the user has asked for section anchors, we disable toplevel
760 reordering at -O0 to disable transformations that might be surprising
761 to end users and to get -fno-toplevel-reorder tested. */
299404a1 762 if (!opts->x_optimize
d5478783
JM
763 && opts->x_flag_toplevel_reorder == 2
764 && !(opts->x_flag_section_anchors && opts_set->x_flag_section_anchors))
93a4f5e0 765 {
d5478783
JM
766 opts->x_flag_toplevel_reorder = 0;
767 opts->x_flag_section_anchors = 0;
93a4f5e0 768 }
d5478783 769 if (!opts->x_flag_toplevel_reorder)
57b08d04 770 {
d5478783 771 if (opts->x_flag_section_anchors && opts_set->x_flag_section_anchors)
299404a1
JM
772 error_at (loc, "section anchors must be disabled when toplevel reorder"
773 " is disabled");
d5478783 774 opts->x_flag_section_anchors = 0;
57b08d04
ST
775 }
776
299404a1 777 if (!opts->x_flag_opts_finished)
ab442df7 778 {
428b3812
L
779 /* We initialize opts->x_flag_pie to -1 so that targets can set a
780 default value. */
781 if (opts->x_flag_pie == -1)
782 {
b57e6e18
L
783 /* We initialize opts->x_flag_pic to -1 so that we can tell if
784 -fpic, -fPIC, -fno-pic or -fno-PIC is used. */
785 if (opts->x_flag_pic == -1)
428b3812
L
786 opts->x_flag_pie = DEFAULT_FLAG_PIE;
787 else
788 opts->x_flag_pie = 0;
789 }
b57e6e18 790 /* If -fPIE or -fpie is used, turn on PIC. */
d5478783
JM
791 if (opts->x_flag_pie)
792 opts->x_flag_pic = opts->x_flag_pie;
b57e6e18
L
793 else if (opts->x_flag_pic == -1)
794 opts->x_flag_pic = 0;
d5478783
JM
795 if (opts->x_flag_pic && !opts->x_flag_pie)
796 opts->x_flag_shlib = 1;
b294a75e 797 opts->x_flag_opts_finished = true;
ab442df7 798 }
9756310a 799
e0f6cba0
MG
800 /* We initialize opts->x_flag_stack_protect to -1 so that targets
801 can set a default value. */
802 if (opts->x_flag_stack_protect == -1)
803 opts->x_flag_stack_protect = DEFAULT_FLAG_SSP;
804
299404a1 805 if (opts->x_optimize == 0)
9756310a
NB
806 {
807 /* Inlining does not work if not optimizing,
808 so force it not to be done. */
d5478783
JM
809 opts->x_warn_inline = 0;
810 opts->x_flag_no_inline = 1;
9756310a
NB
811 }
812
750054a2
CT
813 /* The optimization to partition hot and cold basic blocks into separate
814 sections of the .o and executable files does not work (currently)
e395963f 815 with exception handling. This is because there is no support for
d5478783
JM
816 generating unwind info. If opts->x_flag_exceptions is turned on
817 we need to turn off the partitioning optimization. */
750054a2 818
677f3fa8 819 ui_except = targetm_common.except_unwind_info (opts);
f0a0390e 820
d5478783
JM
821 if (opts->x_flag_exceptions
822 && opts->x_flag_reorder_blocks_and_partition
bf1431e3 823 && (ui_except == UI_SJLJ || ui_except >= UI_TARGET))
750054a2 824 {
32ad0f03
TJ
825 if (opts_set->x_flag_reorder_blocks_and_partition)
826 inform (loc,
4f4b35a0
ML
827 "%<-freorder-blocks-and-partition%> does not work "
828 "with exceptions on this architecture");
d5478783
JM
829 opts->x_flag_reorder_blocks_and_partition = 0;
830 opts->x_flag_reorder_blocks = 1;
750054a2 831 }
c7466dee 832
e395963f
JW
833 /* If user requested unwind info, then turn off the partitioning
834 optimization. */
835
d5478783 836 if (opts->x_flag_unwind_tables
677f3fa8 837 && !targetm_common.unwind_tables_default
d5478783 838 && opts->x_flag_reorder_blocks_and_partition
bf1431e3 839 && (ui_except == UI_SJLJ || ui_except >= UI_TARGET))
e395963f 840 {
32ad0f03
TJ
841 if (opts_set->x_flag_reorder_blocks_and_partition)
842 inform (loc,
4f4b35a0
ML
843 "%<-freorder-blocks-and-partition%> does not support "
844 "unwind info on this architecture");
d5478783
JM
845 opts->x_flag_reorder_blocks_and_partition = 0;
846 opts->x_flag_reorder_blocks = 1;
e395963f
JW
847 }
848
849 /* If the target requested unwind info, then turn off the partitioning
850 optimization with a different message. Likewise, if the target does not
851 support named sections. */
852
d5478783 853 if (opts->x_flag_reorder_blocks_and_partition
677f3fa8 854 && (!targetm_common.have_named_sections
d5478783 855 || (opts->x_flag_unwind_tables
677f3fa8 856 && targetm_common.unwind_tables_default
bf1431e3 857 && (ui_except == UI_SJLJ || ui_except >= UI_TARGET))))
c7466dee 858 {
32ad0f03
TJ
859 if (opts_set->x_flag_reorder_blocks_and_partition)
860 inform (loc,
4f4b35a0
ML
861 "%<-freorder-blocks-and-partition%> does not work "
862 "on this architecture");
d5478783
JM
863 opts->x_flag_reorder_blocks_and_partition = 0;
864 opts->x_flag_reorder_blocks = 1;
c7466dee 865 }
ab442df7 866
940c4160 867
e855c69d
AB
868 /* Pipelining of outer loops is only possible when general pipelining
869 capabilities are requested. */
d5478783
JM
870 if (!opts->x_flag_sel_sched_pipelining)
871 opts->x_flag_sel_sched_pipelining_outer_loops = 0;
e855c69d 872
d5478783 873 if (opts->x_flag_conserve_stack)
6a78eaa3 874 {
48476d13
JM
875 maybe_set_param_value (PARAM_LARGE_STACK_FRAME, 100,
876 opts->x_param_values, opts_set->x_param_values);
877 maybe_set_param_value (PARAM_STACK_FRAME_GROWTH, 40,
878 opts->x_param_values, opts_set->x_param_values);
6a78eaa3
JH
879 }
880
014d92e1 881 if (opts->x_flag_lto)
e3b8749b
RG
882 {
883#ifdef ENABLE_LTO
d5478783 884 opts->x_flag_generate_lto = 1;
e3b8749b
RG
885
886 /* When generating IL, do not operate in whole-program mode.
887 Otherwise, symbols will be privatized too early, causing link
888 errors later. */
d5478783 889 opts->x_flag_whole_program = 0;
e3b8749b 890#else
299404a1 891 error_at (loc, "LTO support has not been enabled in this configuration");
e3b8749b 892#endif
063d671d
JH
893 if (!opts->x_flag_fat_lto_objects
894 && (!HAVE_LTO_PLUGIN
895 || (opts_set->x_flag_use_linker_plugin
896 && !opts->x_flag_use_linker_plugin)))
e9f67e62
JH
897 {
898 if (opts_set->x_flag_fat_lto_objects)
4f4b35a0
ML
899 error_at (loc, "%<-fno-fat-lto-objects%> are supported only with "
900 "linker plugin");
e9f67e62
JH
901 opts->x_flag_fat_lto_objects = 1;
902 }
903 }
e3b8749b 904
d5478783 905 /* We initialize opts->x_flag_split_stack to -1 so that targets can set a
7458026b 906 default value if they choose based on other options. */
d5478783
JM
907 if (opts->x_flag_split_stack == -1)
908 opts->x_flag_split_stack = 0;
909 else if (opts->x_flag_split_stack)
7458026b 910 {
677f3fa8 911 if (!targetm_common.supports_split_stack (true, opts))
7458026b 912 {
299404a1
JM
913 error_at (loc, "%<-fsplit-stack%> is not supported by "
914 "this compiler configuration");
d5478783 915 opts->x_flag_split_stack = 0;
7458026b
ILT
916 }
917 }
bfe068c3 918
227b76c3
JH
919 /* If stack splitting is turned on, and the user did not explicitly
920 request function partitioning, turn off partitioning, as it
921 confuses the linker when trying to handle partitioned split-stack
922 code that calls a non-split-stack functions. But if partitioning
923 was turned on explicitly just hope for the best. */
924 if (opts->x_flag_split_stack
925 && opts->x_flag_reorder_blocks_and_partition
926 && !opts_set->x_flag_reorder_blocks_and_partition)
927 opts->x_flag_reorder_blocks_and_partition = 0;
928
929 if (opts->x_flag_reorder_blocks_and_partition
930 && !opts_set->x_flag_reorder_functions)
931 opts->x_flag_reorder_functions = 1;
932
d6d11272
XDL
933 /* Tune vectorization related parametees according to cost model. */
934 if (opts->x_flag_vect_cost_model == VECT_COST_MODEL_CHEAP)
935 {
936 maybe_set_param_value (PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS,
937 6, opts->x_param_values, opts_set->x_param_values);
938 maybe_set_param_value (PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS,
939 0, opts->x_param_values, opts_set->x_param_values);
940 maybe_set_param_value (PARAM_VECT_MAX_PEELING_FOR_ALIGNMENT,
941 0, opts->x_param_values, opts_set->x_param_values);
942 }
943
bfe068c3
IR
944 /* Set PARAM_MAX_STORES_TO_SINK to 0 if either vectorization or if-conversion
945 is disabled. */
ea0f3e87
XDL
946 if ((!opts->x_flag_tree_loop_vectorize && !opts->x_flag_tree_slp_vectorize)
947 || !opts->x_flag_tree_loop_if_convert)
bfe068c3
IR
948 maybe_set_param_value (PARAM_MAX_STORES_TO_SINK, 0,
949 opts->x_param_values, opts_set->x_param_values);
e9f8dcf9 950
bd5c3baa 951 /* The -gsplit-dwarf option requires -ggnu-pubnames. */
99ea153e 952 if (opts->x_dwarf_split_debug_info)
bd5c3baa 953 opts->x_debug_generate_pub_sections = 2;
fec4842d 954
fed4de37 955 /* Userspace and kernel ASan conflict with each other. */
d95a2703
JJ
956 if ((opts->x_flag_sanitize & SANITIZE_USER_ADDRESS)
957 && (opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS))
fec4842d 958 error_at (loc,
6d28654e
ML
959 "%<-fsanitize=address%> is incompatible with "
960 "%<-fsanitize=kernel-address%>");
fec4842d 961
fed4de37 962 /* And with TSan. */
d95a2703
JJ
963 if ((opts->x_flag_sanitize & SANITIZE_ADDRESS)
964 && (opts->x_flag_sanitize & SANITIZE_THREAD))
fec4842d 965 error_at (loc,
6d28654e
ML
966 "%<-fsanitize=address%> and %<-fsanitize=kernel-address%> "
967 "are incompatible with %<-fsanitize=thread%>");
d95a2703 968
5cc6c41c
ML
969 if ((opts->x_flag_sanitize & SANITIZE_LEAK)
970 && (opts->x_flag_sanitize & SANITIZE_THREAD))
971 error_at (loc,
6d28654e 972 "%<-fsanitize=leak%> is incompatible with %<-fsanitize=thread%>");
d95a2703 973
5cc6c41c
ML
974 /* Check error recovery for -fsanitize-recover option. */
975 for (int i = 0; sanitizer_opts[i].name != NULL; ++i)
976 if ((opts->x_flag_sanitize_recover & sanitizer_opts[i].flag)
977 && !sanitizer_opts[i].can_recover)
6d28654e 978 error_at (loc, "%<-fsanitize-recover=%s%> is not supported",
5cc6c41c 979 sanitizer_opts[i].name);
9ca0032c
MZ
980
981 /* When instrumenting the pointers, we don't want to remove
982 the null pointer checks. */
983 if (opts->x_flag_sanitize & (SANITIZE_NULL | SANITIZE_NONNULL_ATTRIBUTE
984 | SANITIZE_RETURNS_NONNULL_ATTRIBUTE))
985 opts->x_flag_delete_null_pointer_checks = 0;
986
987 /* Aggressive compiler optimizations may cause false negatives. */
866c72a8 988 if (opts->x_flag_sanitize & ~(SANITIZE_LEAK | SANITIZE_UNREACHABLE))
2bf54d93 989 opts->x_flag_aggressive_loop_optimizations = 0;
6dc4a604
ML
990
991 /* Enable -fsanitize-address-use-after-scope if address sanitizer is
992 enabled. */
04bfa1e4 993 if ((opts->x_flag_sanitize & SANITIZE_USER_ADDRESS)
6dc4a604
ML
994 && !opts_set->x_flag_sanitize_address_use_after_scope)
995 opts->x_flag_sanitize_address_use_after_scope = true;
996
997 /* Force -fstack-reuse=none in case -fsanitize-address-use-after-scope
998 is enabled. */
999 if (opts->x_flag_sanitize_address_use_after_scope)
1000 {
1001 if (opts->x_flag_stack_reuse != SR_NONE
1002 && opts_set->x_flag_stack_reuse != SR_NONE)
1003 error_at (loc,
6d28654e
ML
1004 "%<-fsanitize-address-use-after-scope%> requires "
1005 "%<-fstack-reuse=none%> option");
6dc4a604
ML
1006
1007 opts->x_flag_stack_reuse = SR_NONE;
1008 }
26c5b549
ML
1009
1010 if ((opts->x_flag_sanitize & SANITIZE_USER_ADDRESS) && opts->x_flag_tm)
1011 sorry ("transactional memory is not supported with %<-fsanitize=address%>");
1012
1013 if ((opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS) && opts->x_flag_tm)
1014 sorry ("transactional memory is not supported with "
1015 "%<-fsanitize=kernel-address%>");
9756310a
NB
1016}
1017
c662432e
NC
1018#define LEFT_COLUMN 27
1019
1020/* Output ITEM, of length ITEM_WIDTH, in the left column,
1021 followed by word-wrapped HELP in a second column. */
1022static void
1023wrap_help (const char *help,
1024 const char *item,
1025 unsigned int item_width,
1026 unsigned int columns)
1027{
1028 unsigned int col_width = LEFT_COLUMN;
1029 unsigned int remaining, room, len;
1030
1031 remaining = strlen (help);
1032
1033 do
1034 {
1035 room = columns - 3 - MAX (col_width, item_width);
1036 if (room > columns)
1037 room = 0;
1038 len = remaining;
1039
1040 if (room < len)
1041 {
1042 unsigned int i;
1043
1044 for (i = 0; help[i]; i++)
1045 {
1046 if (i >= room && len != remaining)
1047 break;
1048 if (help[i] == ' ')
1049 len = i;
1050 else if ((help[i] == '-' || help[i] == '/')
1051 && help[i + 1] != ' '
1052 && i > 0 && ISALPHA (help[i - 1]))
1053 len = i + 1;
1054 }
1055 }
1056
c3284718 1057 printf (" %-*.*s %.*s\n", col_width, item_width, item, len, help);
c662432e
NC
1058 item_width = 0;
1059 while (help[len] == ' ')
1060 len++;
1061 help += len;
1062 remaining -= len;
1063 }
1064 while (remaining);
1065}
1066
1067/* Print help for a specific front-end, etc. */
1068static void
1069print_filtered_help (unsigned int include_flags,
1070 unsigned int exclude_flags,
1071 unsigned int any_flags,
0576d21f 1072 unsigned int columns,
e6d4b984
JM
1073 struct gcc_options *opts,
1074 unsigned int lang_mask)
c662432e
NC
1075{
1076 unsigned int i;
1077 const char *help;
c662432e
NC
1078 bool found = false;
1079 bool displayed = false;
a7b2e184 1080 char new_help[256];
c662432e
NC
1081
1082 if (include_flags == CL_PARAMS)
1083 {
1084 for (i = 0; i < LAST_PARAM; i++)
1085 {
1086 const char *param = compiler_params[i].option;
1087
1088 help = compiler_params[i].help;
1089 if (help == NULL || *help == '\0')
1090 {
1091 if (exclude_flags & CL_UNDOCUMENTED)
1092 continue;
1093 help = undocumented_msg;
1094 }
1095
1096 /* Get the translation. */
1097 help = _(help);
1098
ff5101bf
AK
1099 if (!opts->x_quiet_flag)
1100 {
1101 snprintf (new_help, sizeof (new_help),
1102 _("default %d minimum %d maximum %d"),
1103 compiler_params[i].default_value,
1104 compiler_params[i].min_value,
1105 compiler_params[i].max_value);
1106 help = new_help;
1107 }
c662432e
NC
1108 wrap_help (help, param, strlen (param), columns);
1109 }
1110 putchar ('\n');
1111 return;
1112 }
1113
299404a1
JM
1114 if (!opts->x_help_printed)
1115 opts->x_help_printed = XCNEWVAR (char, cl_options_count);
c662432e 1116
e6d4b984
JM
1117 if (!opts->x_help_enum_printed)
1118 opts->x_help_enum_printed = XCNEWVAR (char, cl_enums_count);
1119
c662432e
NC
1120 for (i = 0; i < cl_options_count; i++)
1121 {
c662432e
NC
1122 const struct cl_option *option = cl_options + i;
1123 unsigned int len;
1124 const char *opt;
1125 const char *tab;
1126
1127 if (include_flags == 0
1128 || ((option->flags & include_flags) != include_flags))
1129 {
1130 if ((option->flags & any_flags) == 0)
1131 continue;
1132 }
1133
1134 /* Skip unwanted switches. */
1135 if ((option->flags & exclude_flags) != 0)
1136 continue;
1137
603349bf
JM
1138 /* The driver currently prints its own help text. */
1139 if ((option->flags & CL_DRIVER) != 0
1140 && (option->flags & (((1U << cl_lang_count) - 1)
1141 | CL_COMMON | CL_TARGET)) == 0)
1142 continue;
1143
c662432e
NC
1144 found = true;
1145 /* Skip switches that have already been printed. */
299404a1 1146 if (opts->x_help_printed[i])
c662432e
NC
1147 continue;
1148
299404a1 1149 opts->x_help_printed[i] = true;
c662432e
NC
1150
1151 help = option->help;
1152 if (help == NULL)
1153 {
1154 if (exclude_flags & CL_UNDOCUMENTED)
1155 continue;
a7b2e184 1156
c662432e
NC
1157 help = undocumented_msg;
1158 }
1159
a7b2e184
MS
1160 if (option->alias_target < N_OPTS
1161 && cl_options [option->alias_target].help)
1162 {
1163 if (help == undocumented_msg)
1164 {
1165 /* For undocumented options that are aliases for other options
1166 that are documented, point the reader to the other option in
1167 preference of the former. */
1168 snprintf (new_help, sizeof new_help,
1169 _("Same as %s. Use the latter option instead."),
1170 cl_options [option->alias_target].opt_text);
1171 }
1172 else
1173 {
1174 /* For documented options with aliases, mention the aliased
1175 option's name for reference. */
1176 snprintf (new_help, sizeof new_help,
1177 _("%s Same as %s."),
1178 help, cl_options [option->alias_target].opt_text);
1179 }
1180
1181 help = new_help;
1182 }
1183
1184 if (option->warn_message)
1185 {
1186 /* Mention that the use of the option will trigger a warning. */
1187 if (help == new_help)
1188 snprintf (new_help + strlen (new_help),
1189 sizeof new_help - strlen (new_help),
1190 " %s", _(use_diagnosed_msg));
1191 else
1192 snprintf (new_help, sizeof new_help,
1193 "%s %s", help, _(use_diagnosed_msg));
1194
1195 help = new_help;
1196 }
1197
c662432e
NC
1198 /* Get the translation. */
1199 help = _(help);
1200
1201 /* Find the gap between the name of the
1202 option and its descriptive text. */
1203 tab = strchr (help, '\t');
1204 if (tab)
1205 {
1206 len = tab - help;
1207 opt = help;
1208 help = tab + 1;
1209 }
1210 else
1211 {
1212 opt = option->opt_text;
1213 len = strlen (opt);
1214 }
1215
1216 /* With the -Q option enabled we change the descriptive text associated
1217 with an option to be an indication of its current setting. */
a7d0d30f 1218 if (!opts->x_quiet_flag)
c662432e 1219 {
0576d21f 1220 void *flag_var = option_flag_var (i, opts);
46625112 1221
c662432e
NC
1222 if (len < (LEFT_COLUMN + 2))
1223 strcpy (new_help, "\t\t");
1224 else
1225 strcpy (new_help, "\t");
1226
21bf1558
JM
1227 if (flag_var != NULL
1228 && option->var_type != CLVC_DEFER)
c662432e
NC
1229 {
1230 if (option->flags & CL_JOINED)
1231 {
1232 if (option->var_type == CLVC_STRING)
1233 {
46625112 1234 if (* (const char **) flag_var != NULL)
c662432e
NC
1235 snprintf (new_help + strlen (new_help),
1236 sizeof (new_help) - strlen (new_help),
81018dcf 1237 "%s", * (const char **) flag_var);
c662432e 1238 }
e6d4b984
JM
1239 else if (option->var_type == CLVC_ENUM)
1240 {
1241 const struct cl_enum *e = &cl_enums[option->var_enum];
1242 int value;
1243 const char *arg = NULL;
1244
1245 value = e->get (flag_var);
1246 enum_value_to_arg (e->values, &arg, value, lang_mask);
1247 if (arg == NULL)
1248 arg = _("[default]");
1249 snprintf (new_help + strlen (new_help),
1250 sizeof (new_help) - strlen (new_help),
81018dcf 1251 "%s", arg);
e6d4b984 1252 }
c662432e
NC
1253 else
1254 sprintf (new_help + strlen (new_help),
9453ba0a 1255 "%d", * (int *) flag_var);
c662432e
NC
1256 }
1257 else
0576d21f 1258 strcat (new_help, option_enabled (i, opts)
c662432e
NC
1259 ? _("[enabled]") : _("[disabled]"));
1260 }
1261
1262 help = new_help;
1263 }
1264
63010089
ML
1265 if (option->range_max != -1)
1266 {
1267 char b[128];
1268 snprintf (b, sizeof (b), "<%d,%d>", option->range_min,
1269 option->range_max);
1270 opt = concat (opt, b, NULL);
1271 len += strlen (b);
1272 }
1273
c662432e
NC
1274 wrap_help (help, opt, len, columns);
1275 displayed = true;
e6d4b984
JM
1276
1277 if (option->var_type == CLVC_ENUM
1278 && opts->x_help_enum_printed[option->var_enum] != 2)
1279 opts->x_help_enum_printed[option->var_enum] = 1;
c662432e
NC
1280 }
1281
1282 if (! found)
b3eaaf1a
NC
1283 {
1284 unsigned int langs = include_flags & CL_LANG_ALL;
1285
1286 if (langs == 0)
1287 printf (_(" No options with the desired characteristics were found\n"));
1288 else
1289 {
1290 unsigned int i;
1291
1292 /* PR 31349: Tell the user how to see all of the
1293 options supported by a specific front end. */
1294 for (i = 0; (1U << i) < CL_LANG_ALL; i ++)
1295 if ((1U << i) & langs)
a7b2e184 1296 printf (_(" None found. Use --help=%s to show *all* the options supported by the %s front-end.\n"),
b3eaaf1a
NC
1297 lang_names[i], lang_names[i]);
1298 }
b8698a0f 1299
b3eaaf1a 1300 }
c662432e
NC
1301 else if (! displayed)
1302 printf (_(" All options with the desired characteristics have already been displayed\n"));
1303
1304 putchar ('\n');
e6d4b984
JM
1305
1306 /* Print details of enumerated option arguments, if those
1307 enumerations have help text headings provided. If no help text
1308 is provided, presume that the possible values are listed in the
1309 help text for the relevant options. */
1310 for (i = 0; i < cl_enums_count; i++)
1311 {
1312 unsigned int j, pos;
1313
1314 if (opts->x_help_enum_printed[i] != 1)
1315 continue;
1316 if (cl_enums[i].help == NULL)
1317 continue;
1318 printf (" %s\n ", _(cl_enums[i].help));
1319 pos = 4;
1320 for (j = 0; cl_enums[i].values[j].arg != NULL; j++)
1321 {
1322 unsigned int len = strlen (cl_enums[i].values[j].arg);
1323
1324 if (pos > 4 && pos + 1 + len <= columns)
1325 {
1326 printf (" %s", cl_enums[i].values[j].arg);
1327 pos += 1 + len;
1328 }
1329 else
1330 {
1331 if (pos > 4)
1332 {
1333 printf ("\n ");
1334 pos = 4;
1335 }
1336 printf ("%s", cl_enums[i].values[j].arg);
1337 pos += len;
1338 }
1339 }
1340 printf ("\n\n");
1341 opts->x_help_enum_printed[i] = 2;
1342 }
c662432e
NC
1343}
1344
1345/* Display help for a specified type of option.
1346 The options must have ALL of the INCLUDE_FLAGS set
1347 ANY of the flags in the ANY_FLAGS set
0576d21f 1348 and NONE of the EXCLUDE_FLAGS set. The current option state is in
e6d4b984 1349 OPTS; LANG_MASK is used for interpreting enumerated option state. */
c662432e
NC
1350static void
1351print_specific_help (unsigned int include_flags,
1352 unsigned int exclude_flags,
0576d21f 1353 unsigned int any_flags,
e6d4b984
JM
1354 struct gcc_options *opts,
1355 unsigned int lang_mask)
c662432e
NC
1356{
1357 unsigned int all_langs_mask = (1U << cl_lang_count) - 1;
1358 const char * description = NULL;
1359 const char * descrip_extra = "";
1360 size_t i;
1361 unsigned int flag;
c662432e
NC
1362
1363 /* Sanity check: Make sure that we do not have more
1364 languages than we have bits available to enumerate them. */
58265ea6 1365 gcc_assert ((1U << cl_lang_count) <= CL_MIN_OPTION_CLASS);
c662432e
NC
1366
1367 /* If we have not done so already, obtain
1368 the desired maximum width of the output. */
299404a1 1369 if (opts->x_help_columns == 0)
c662432e 1370 {
c9db45aa
TB
1371 opts->x_help_columns = get_terminal_width ();
1372 if (opts->x_help_columns == INT_MAX)
c662432e 1373 /* Use a reasonable default. */
299404a1 1374 opts->x_help_columns = 80;
c662432e
NC
1375 }
1376
1377 /* Decide upon the title for the options that we are going to display. */
1378 for (i = 0, flag = 1; flag <= CL_MAX_OPTION_CLASS; flag <<= 1, i ++)
1379 {
1380 switch (flag & include_flags)
1381 {
1382 case 0:
603349bf 1383 case CL_DRIVER:
c662432e
NC
1384 break;
1385
1386 case CL_TARGET:
1387 description = _("The following options are target specific");
1388 break;
1389 case CL_WARNING:
1390 description = _("The following options control compiler warning messages");
1391 break;
1392 case CL_OPTIMIZATION:
1393 description = _("The following options control optimizations");
1394 break;
1395 case CL_COMMON:
1396 description = _("The following options are language-independent");
1397 break;
1398 case CL_PARAMS:
1399 description = _("The --param option recognizes the following as parameters");
1400 break;
1401 default:
1402 if (i >= cl_lang_count)
1403 break;
0631b69f 1404 if (exclude_flags & all_langs_mask)
c01c261d 1405 description = _("The following options are specific to just the language ");
c662432e 1406 else
b5456e04 1407 description = _("The following options are supported by the language ");
b3eaaf1a 1408 descrip_extra = lang_names [i];
c662432e
NC
1409 break;
1410 }
1411 }
1412
1413 if (description == NULL)
1414 {
1415 if (any_flags == 0)
1416 {
0631b69f 1417 if (include_flags & CL_UNDOCUMENTED)
c662432e 1418 description = _("The following options are not documented");
0631b69f
RW
1419 else if (include_flags & CL_SEPARATE)
1420 description = _("The following options take separate arguments");
1421 else if (include_flags & CL_JOINED)
1422 description = _("The following options take joined arguments");
c662432e
NC
1423 else
1424 {
1425 internal_error ("unrecognized include_flags 0x%x passed to print_specific_help",
1426 include_flags);
1427 return;
1428 }
1429 }
1430 else
1431 {
1432 if (any_flags & all_langs_mask)
1433 description = _("The following options are language-related");
1434 else
1435 description = _("The following options are language-independent");
1436 }
1437 }
1438
1439 printf ("%s%s:\n", description, descrip_extra);
299404a1 1440 print_filtered_help (include_flags, exclude_flags, any_flags,
e6d4b984 1441 opts->x_help_columns, opts, lang_mask);
c662432e
NC
1442}
1443
be3c16c4
DC
1444/* Enable FDO-related flags. */
1445
1446static void
1447enable_fdo_optimizations (struct gcc_options *opts,
1448 struct gcc_options *opts_set,
1449 int value)
1450{
1451 if (!opts_set->x_flag_branch_probabilities)
1452 opts->x_flag_branch_probabilities = value;
1453 if (!opts_set->x_flag_profile_values)
1454 opts->x_flag_profile_values = value;
1455 if (!opts_set->x_flag_unroll_loops)
1456 opts->x_flag_unroll_loops = value;
1457 if (!opts_set->x_flag_peel_loops)
1458 opts->x_flag_peel_loops = value;
1459 if (!opts_set->x_flag_tracer)
1460 opts->x_flag_tracer = value;
1461 if (!opts_set->x_flag_value_profile_transformations)
1462 opts->x_flag_value_profile_transformations = value;
1463 if (!opts_set->x_flag_inline_functions)
1464 opts->x_flag_inline_functions = value;
1465 if (!opts_set->x_flag_ipa_cp)
1466 opts->x_flag_ipa_cp = value;
1467 if (!opts_set->x_flag_ipa_cp_clone
1468 && value && opts->x_flag_ipa_cp)
1469 opts->x_flag_ipa_cp_clone = value;
209ca542
PK
1470 if (!opts_set->x_flag_ipa_bit_cp
1471 && value && opts->x_flag_ipa_cp)
1472 opts->x_flag_ipa_bit_cp = value;
be3c16c4
DC
1473 if (!opts_set->x_flag_predictive_commoning)
1474 opts->x_flag_predictive_commoning = value;
28df8730
MM
1475 if (!opts_set->x_flag_split_loops)
1476 opts->x_flag_split_loops = value;
be3c16c4
DC
1477 if (!opts_set->x_flag_unswitch_loops)
1478 opts->x_flag_unswitch_loops = value;
1479 if (!opts_set->x_flag_gcse_after_reload)
1480 opts->x_flag_gcse_after_reload = value;
26d476cd 1481 if (!opts_set->x_flag_tree_loop_vectorize)
be3c16c4 1482 opts->x_flag_tree_loop_vectorize = value;
26d476cd 1483 if (!opts_set->x_flag_tree_slp_vectorize)
be3c16c4
DC
1484 opts->x_flag_tree_slp_vectorize = value;
1485 if (!opts_set->x_flag_vect_cost_model)
1486 opts->x_flag_vect_cost_model = VECT_COST_MODEL_DYNAMIC;
1487 if (!opts_set->x_flag_tree_loop_distribute_patterns)
1488 opts->x_flag_tree_loop_distribute_patterns = value;
1489}
1490
b1b46af0 1491/* -f{,no-}sanitize{,-recover}= suboptions. */
61789eed 1492const struct sanitizer_opts_s sanitizer_opts[] =
b1b46af0 1493{
5cc6c41c
ML
1494#define SANITIZER_OPT(name, flags, recover) \
1495 { #name, flags, sizeof #name - 1, recover }
6dc4a604
ML
1496 SANITIZER_OPT (address, (SANITIZE_ADDRESS | SANITIZE_USER_ADDRESS), true),
1497 SANITIZER_OPT (kernel-address, (SANITIZE_ADDRESS | SANITIZE_KERNEL_ADDRESS),
5cc6c41c
ML
1498 true),
1499 SANITIZER_OPT (thread, SANITIZE_THREAD, false),
1500 SANITIZER_OPT (leak, SANITIZE_LEAK, false),
1501 SANITIZER_OPT (shift, SANITIZE_SHIFT, true),
2e955d50
JJ
1502 SANITIZER_OPT (shift-base, SANITIZE_SHIFT_BASE, true),
1503 SANITIZER_OPT (shift-exponent, SANITIZE_SHIFT_EXPONENT, true),
5cc6c41c
ML
1504 SANITIZER_OPT (integer-divide-by-zero, SANITIZE_DIVIDE, true),
1505 SANITIZER_OPT (undefined, SANITIZE_UNDEFINED, true),
1506 SANITIZER_OPT (unreachable, SANITIZE_UNREACHABLE, false),
1507 SANITIZER_OPT (vla-bound, SANITIZE_VLA, true),
1508 SANITIZER_OPT (return, SANITIZE_RETURN, false),
1509 SANITIZER_OPT (null, SANITIZE_NULL, true),
1510 SANITIZER_OPT (signed-integer-overflow, SANITIZE_SI_OVERFLOW, true),
1511 SANITIZER_OPT (bool, SANITIZE_BOOL, true),
1512 SANITIZER_OPT (enum, SANITIZE_ENUM, true),
1513 SANITIZER_OPT (float-divide-by-zero, SANITIZE_FLOAT_DIVIDE, true),
1514 SANITIZER_OPT (float-cast-overflow, SANITIZE_FLOAT_CAST, true),
1515 SANITIZER_OPT (bounds, SANITIZE_BOUNDS, true),
1516 SANITIZER_OPT (bounds-strict, SANITIZE_BOUNDS | SANITIZE_BOUNDS_STRICT, true),
1517 SANITIZER_OPT (alignment, SANITIZE_ALIGNMENT, true),
1518 SANITIZER_OPT (nonnull-attribute, SANITIZE_NONNULL_ATTRIBUTE, true),
1519 SANITIZER_OPT (returns-nonnull-attribute, SANITIZE_RETURNS_NONNULL_ATTRIBUTE,
1520 true),
1521 SANITIZER_OPT (object-size, SANITIZE_OBJECT_SIZE, true),
1522 SANITIZER_OPT (vptr, SANITIZE_VPTR, true),
c9b39a49 1523 SANITIZER_OPT (pointer-overflow, SANITIZE_POINTER_OVERFLOW, true),
07d7c611 1524 SANITIZER_OPT (builtin, SANITIZE_BUILTIN, true),
5cc6c41c 1525 SANITIZER_OPT (all, ~0U, true),
b1b46af0 1526#undef SANITIZER_OPT
5cc6c41c 1527 { NULL, 0U, 0UL, false }
b1b46af0
JJ
1528};
1529
f6e50a7d
WW
1530/* -f{,no-}sanitize-coverage= suboptions. */
1531const struct sanitizer_opts_s coverage_sanitizer_opts[] =
1532{
1533#define COVERAGE_SANITIZER_OPT(name, flags) \
1534 { #name, flags, sizeof #name - 1, true }
1535 COVERAGE_SANITIZER_OPT (trace-pc, SANITIZE_COV_TRACE_PC),
1536 COVERAGE_SANITIZER_OPT (trace-cmp, SANITIZE_COV_TRACE_CMP),
1537#undef COVERAGE_SANITIZER_OPT
1538 { NULL, 0U, 0UL, false }
1539};
1540
19ff0049
DM
1541/* A struct for describing a run of chars within a string. */
1542
1543struct string_fragment
1544{
1545 string_fragment (const char *start, size_t len)
1546 : m_start (start), m_len (len) {}
1547
1548 const char *m_start;
1549 size_t m_len;
1550};
1551
1552/* Specialization of edit_distance_traits for string_fragment,
1553 for use by get_closest_sanitizer_option. */
1554
1555template <>
1556struct edit_distance_traits<const string_fragment &>
1557{
1558 static size_t get_length (const string_fragment &fragment)
1559 {
1560 return fragment.m_len;
1561 }
1562
1563 static const char *get_string (const string_fragment &fragment)
1564 {
1565 return fragment.m_start;
1566 }
1567};
1568
1569/* Given ARG, an unrecognized sanitizer option, return the best
1570 matching sanitizer option, or NULL if there isn't one.
f6e50a7d
WW
1571 OPTS is array of candidate sanitizer options.
1572 CODE is OPT_fsanitize_, OPT_fsanitize_recover_ or
1573 OPT_fsanitize_coverage_.
19ff0049
DM
1574 VALUE is non-zero for the regular form of the option, zero
1575 for the "no-" form (e.g. "-fno-sanitize-recover="). */
1576
1577static const char *
1578get_closest_sanitizer_option (const string_fragment &arg,
f6e50a7d 1579 const struct sanitizer_opts_s *opts,
19ff0049
DM
1580 enum opt_code code, int value)
1581{
1582 best_match <const string_fragment &, const char*> bm (arg);
f6e50a7d 1583 for (int i = 0; opts[i].name != NULL; ++i)
19ff0049
DM
1584 {
1585 /* -fsanitize=all is not valid, so don't offer it. */
f6e50a7d
WW
1586 if (code == OPT_fsanitize_
1587 && opts[i].flag == ~0U
19ff0049
DM
1588 && value)
1589 continue;
1590
1591 /* For -fsanitize-recover= (and not -fno-sanitize-recover=),
1592 don't offer the non-recoverable options. */
f6e50a7d
WW
1593 if (code == OPT_fsanitize_recover_
1594 && !opts[i].can_recover
19ff0049
DM
1595 && value)
1596 continue;
1597
f6e50a7d 1598 bm.consider (opts[i].name);
19ff0049
DM
1599 }
1600 return bm.get_best_meaningful_candidate ();
1601}
1602
b1b46af0
JJ
1603/* Parse comma separated sanitizer suboptions from P for option SCODE,
1604 adjust previous FLAGS and return new ones. If COMPLAIN is false,
1605 don't issue diagnostics. */
1606
1607unsigned int
1608parse_sanitizer_options (const char *p, location_t loc, int scode,
1609 unsigned int flags, int value, bool complain)
1610{
1611 enum opt_code code = (enum opt_code) scode;
f6e50a7d
WW
1612
1613 const struct sanitizer_opts_s *opts;
1614 if (code == OPT_fsanitize_coverage_)
1615 opts = coverage_sanitizer_opts;
1616 else
1617 opts = sanitizer_opts;
1618
b1b46af0
JJ
1619 while (*p != 0)
1620 {
1621 size_t len, i;
1622 bool found = false;
1623 const char *comma = strchr (p, ',');
1624
1625 if (comma == NULL)
1626 len = strlen (p);
1627 else
1628 len = comma - p;
1629 if (len == 0)
1630 {
1631 p = comma + 1;
1632 continue;
1633 }
1634
1635 /* Check to see if the string matches an option class name. */
f6e50a7d
WW
1636 for (i = 0; opts[i].name != NULL; ++i)
1637 if (len == opts[i].len && memcmp (p, opts[i].name, len) == 0)
b1b46af0
JJ
1638 {
1639 /* Handle both -fsanitize and -fno-sanitize cases. */
f6e50a7d 1640 if (value && opts[i].flag == ~0U)
b1b46af0
JJ
1641 {
1642 if (code == OPT_fsanitize_)
1643 {
1644 if (complain)
6d28654e 1645 error_at (loc, "%<-fsanitize=all%> option is not valid");
b1b46af0
JJ
1646 }
1647 else
5cc6c41c
ML
1648 flags |= ~(SANITIZE_THREAD | SANITIZE_LEAK
1649 | SANITIZE_UNREACHABLE | SANITIZE_RETURN);
b1b46af0
JJ
1650 }
1651 else if (value)
5cc6c41c
ML
1652 {
1653 /* Do not enable -fsanitize-recover=unreachable and
1654 -fsanitize-recover=return if -fsanitize-recover=undefined
1655 is selected. */
c944c6a2 1656 if (code == OPT_fsanitize_recover_
f6e50a7d 1657 && opts[i].flag == SANITIZE_UNDEFINED)
5cc6c41c
ML
1658 flags |= (SANITIZE_UNDEFINED
1659 & ~(SANITIZE_UNREACHABLE | SANITIZE_RETURN));
1660 else
f6e50a7d 1661 flags |= opts[i].flag;
5cc6c41c 1662 }
b1b46af0 1663 else
f6e50a7d 1664 flags &= ~opts[i].flag;
b1b46af0
JJ
1665 found = true;
1666 break;
1667 }
1668
1669 if (! found && complain)
19ff0049
DM
1670 {
1671 const char *hint
1672 = get_closest_sanitizer_option (string_fragment (p, len),
f6e50a7d
WW
1673 opts, code, value);
1674
1675 const char *suffix;
1676 if (code == OPT_fsanitize_recover_)
1677 suffix = "-recover";
1678 else if (code == OPT_fsanitize_coverage_)
1679 suffix = "-coverage";
1680 else
1681 suffix = "";
19ff0049
DM
1682
1683 if (hint)
1684 error_at (loc,
1685 "unrecognized argument to -f%ssanitize%s= option: %q.*s;"
fdb1880f 1686 " did you mean %qs?",
19ff0049 1687 value ? "" : "no-",
f6e50a7d 1688 suffix, (int) len, p, hint);
19ff0049
DM
1689 else
1690 error_at (loc,
1691 "unrecognized argument to -f%ssanitize%s= option: %q.*s",
1692 value ? "" : "no-",
f6e50a7d 1693 suffix, (int) len, p);
19ff0049 1694 }
b1b46af0
JJ
1695
1696 if (comma == NULL)
1697 break;
1698 p = comma + 1;
1699 }
1700 return flags;
1701}
1702
45b2222a 1703/* Parse string values of no_sanitize attribute passed in VALUE.
3a266bcd 1704 Values are separated with comma. */
45b2222a
ML
1705
1706unsigned int
3a266bcd 1707parse_no_sanitize_attribute (char *value)
45b2222a
ML
1708{
1709 unsigned int flags = 0;
1710 unsigned int i;
1711 char *q = strtok (value, ",");
1712
1713 while (q != NULL)
1714 {
1715 for (i = 0; sanitizer_opts[i].name != NULL; ++i)
1716 if (strcmp (sanitizer_opts[i].name, q) == 0)
1717 {
1718 flags |= sanitizer_opts[i].flag;
1719 if (sanitizer_opts[i].flag == SANITIZE_UNDEFINED)
1720 flags |= SANITIZE_UNDEFINED_NONDEFAULT;
1721 break;
1722 }
1723
1724 if (sanitizer_opts[i].name == NULL)
3a266bcd
ML
1725 warning (OPT_Wattributes,
1726 "%<%s%> attribute directive ignored", q);
45b2222a
ML
1727
1728 q = strtok (NULL, ",");
1729 }
1730
1731 return flags;
1732}
1733
d7b42618 1734/* Handle target- and language-independent options. Return zero to
50431bc4
ZD
1735 generate an "unknown option" message. Only options that need
1736 extra handling need to be listed here; if you simply want
481e1176 1737 DECODED->value assigned to a variable, it happens automatically. */
50431bc4 1738
c98cd5bf 1739bool
46625112 1740common_handle_option (struct gcc_options *opts,
d4d24ba4 1741 struct gcc_options *opts_set,
46625112 1742 const struct cl_decoded_option *decoded,
5f20c657 1743 unsigned int lang_mask, int kind ATTRIBUTE_UNUSED,
a4d8c676 1744 location_t loc,
d5478783 1745 const struct cl_option_handlers *handlers,
130fcab0
ML
1746 diagnostic_context *dc,
1747 void (*target_option_override_hook) (void))
d7b42618 1748{
481e1176
JM
1749 size_t scode = decoded->opt_index;
1750 const char *arg = decoded->arg;
1751 int value = decoded->value;
d7b42618
NB
1752 enum opt_code code = (enum opt_code) scode;
1753
481e1176
JM
1754 gcc_assert (decoded->canonical_option_num_elements <= 2);
1755
d7b42618
NB
1756 switch (code)
1757 {
903caebf 1758 case OPT__param:
299404a1 1759 handle_param (opts, opts_set, loc, arg);
903caebf
NB
1760 break;
1761
c662432e
NC
1762 case OPT__help:
1763 {
1764 unsigned int all_langs_mask = (1U << cl_lang_count) - 1;
1765 unsigned int undoc_mask;
1766 unsigned int i;
1767
a7d0d30f 1768 if (lang_mask == CL_DRIVER)
6f3d1a5e 1769 break;
a7d0d30f 1770
d5478783
JM
1771 undoc_mask = ((opts->x_verbose_flag | opts->x_extra_warnings)
1772 ? 0
1773 : CL_UNDOCUMENTED);
130fcab0 1774 target_option_override_hook ();
c662432e
NC
1775 /* First display any single language specific options. */
1776 for (i = 0; i < cl_lang_count; i++)
1777 print_specific_help
e6d4b984
JM
1778 (1U << i, (all_langs_mask & (~ (1U << i))) | undoc_mask, 0, opts,
1779 lang_mask);
c662432e 1780 /* Next display any multi language specific options. */
e6d4b984 1781 print_specific_help (0, undoc_mask, all_langs_mask, opts, lang_mask);
c662432e
NC
1782 /* Then display any remaining, non-language options. */
1783 for (i = CL_MIN_OPTION_CLASS; i <= CL_MAX_OPTION_CLASS; i <<= 1)
603349bf 1784 if (i != CL_DRIVER)
e6d4b984 1785 print_specific_help (i, undoc_mask, 0, opts, lang_mask);
0576d21f 1786 opts->x_exit_after_options = true;
c662432e
NC
1787 break;
1788 }
1789
d185d268 1790 case OPT__target_help:
a7d0d30f
JM
1791 if (lang_mask == CL_DRIVER)
1792 break;
1793
130fcab0 1794 target_option_override_hook ();
e6d4b984 1795 print_specific_help (CL_TARGET, CL_UNDOCUMENTED, 0, opts, lang_mask);
0576d21f 1796 opts->x_exit_after_options = true;
d185d268
NB
1797 break;
1798
c662432e
NC
1799 case OPT__help_:
1800 {
a5fbf76d 1801 const char *a = arg;
c662432e
NC
1802 unsigned int include_flags = 0;
1803 /* Note - by default we include undocumented options when listing
1804 specific classes. If you only want to see documented options
fa10beec 1805 then add ",^undocumented" to the --help= option. E.g.:
c662432e
NC
1806
1807 --help=target,^undocumented */
1808 unsigned int exclude_flags = 0;
1809
a7d0d30f
JM
1810 if (lang_mask == CL_DRIVER)
1811 break;
1812
c662432e
NC
1813 /* Walk along the argument string, parsing each word in turn.
1814 The format is:
1815 arg = [^]{word}[,{arg}]
b5456e04
BM
1816 word = {optimizers|target|warnings|undocumented|
1817 params|common|<language>} */
a5fbf76d 1818 while (*a != 0)
c662432e 1819 {
0576d21f 1820 static const struct
c662432e 1821 {
a5fbf76d 1822 const char *string;
c662432e
NC
1823 unsigned int flag;
1824 }
1825 specifics[] =
1826 {
1827 { "optimizers", CL_OPTIMIZATION },
1828 { "target", CL_TARGET },
1829 { "warnings", CL_WARNING },
1830 { "undocumented", CL_UNDOCUMENTED },
1831 { "params", CL_PARAMS },
66811228
RW
1832 { "joined", CL_JOINED },
1833 { "separate", CL_SEPARATE },
b5456e04 1834 { "common", CL_COMMON },
c662432e
NC
1835 { NULL, 0 }
1836 };
a5fbf76d
MP
1837 unsigned int *pflags;
1838 const char *comma;
b3eaaf1a 1839 unsigned int lang_flag, specific_flag;
c662432e
NC
1840 unsigned int len;
1841 unsigned int i;
1842
a5fbf76d 1843 if (*a == '^')
c662432e 1844 {
a5fbf76d
MP
1845 ++a;
1846 if (*a == '\0')
1847 {
1848 error_at (loc, "missing argument to %qs", "--help=^");
1849 break;
1850 }
1851 pflags = &exclude_flags;
c662432e
NC
1852 }
1853 else
a5fbf76d 1854 pflags = &include_flags;
c662432e
NC
1855
1856 comma = strchr (a, ',');
1857 if (comma == NULL)
1858 len = strlen (a);
1859 else
1860 len = comma - a;
0631b69f
RW
1861 if (len == 0)
1862 {
1863 a = comma + 1;
1864 continue;
1865 }
c662432e 1866
b3eaaf1a
NC
1867 /* Check to see if the string matches an option class name. */
1868 for (i = 0, specific_flag = 0; specifics[i].string != NULL; i++)
c662432e
NC
1869 if (strncasecmp (a, specifics[i].string, len) == 0)
1870 {
b3eaaf1a
NC
1871 specific_flag = specifics[i].flag;
1872 break;
1873 }
0631b69f 1874
b3eaaf1a
NC
1875 /* Check to see if the string matches a language name.
1876 Note - we rely upon the alpha-sorted nature of the entries in
1877 the lang_names array, specifically that shorter names appear
fa10beec 1878 before their longer variants. (i.e. C before C++). That way
b3eaaf1a
NC
1879 when we are attempting to match --help=c for example we will
1880 match with C first and not C++. */
1881 for (i = 0, lang_flag = 0; i < cl_lang_count; i++)
1882 if (strncasecmp (a, lang_names[i], len) == 0)
1883 {
1884 lang_flag = 1U << i;
c662432e
NC
1885 break;
1886 }
1887
b3eaaf1a 1888 if (specific_flag != 0)
c662432e 1889 {
b3eaaf1a 1890 if (lang_flag == 0)
a5fbf76d 1891 *pflags |= specific_flag;
b3eaaf1a
NC
1892 else
1893 {
1894 /* The option's argument matches both the start of a
1895 language name and the start of an option class name.
1896 We have a special case for when the user has
1897 specified "--help=c", but otherwise we have to issue
1898 a warning. */
1899 if (strncasecmp (a, "c", len) == 0)
a5fbf76d 1900 *pflags |= lang_flag;
b3eaaf1a 1901 else
299404a1
JM
1902 warning_at (loc, 0,
1903 "--help argument %q.*s is ambiguous, "
1904 "please be more specific",
1905 len, a);
b3eaaf1a 1906 }
c662432e 1907 }
b3eaaf1a 1908 else if (lang_flag != 0)
a5fbf76d 1909 *pflags |= lang_flag;
b3eaaf1a 1910 else
299404a1
JM
1911 warning_at (loc, 0,
1912 "unrecognized argument to --help= option: %q.*s",
1913 len, a);
c662432e
NC
1914
1915 if (comma == NULL)
1916 break;
1917 a = comma + 1;
1918 }
1919
1920 if (include_flags)
130fcab0
ML
1921 {
1922 target_option_override_hook ();
1923 print_specific_help (include_flags, exclude_flags, 0, opts,
1924 lang_mask);
1925 }
0576d21f 1926 opts->x_exit_after_options = true;
c662432e
NC
1927 break;
1928 }
1929
d185d268 1930 case OPT__version:
a7d0d30f
JM
1931 if (lang_mask == CL_DRIVER)
1932 break;
1933
0576d21f 1934 opts->x_exit_after_options = true;
d185d268
NB
1935 break;
1936
de5a5fa1 1937 case OPT_fsanitize_:
b1b46af0
JJ
1938 opts->x_flag_sanitize
1939 = parse_sanitizer_options (arg, loc, code,
1940 opts->x_flag_sanitize, value, true);
de5a5fa1 1941
b1b46af0
JJ
1942 /* Kernel ASan implies normal ASan but does not yet support
1943 all features. */
1944 if (opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS)
1945 {
1946 maybe_set_param_value (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD,
1947 0, opts->x_param_values,
1948 opts_set->x_param_values);
1949 maybe_set_param_value (PARAM_ASAN_GLOBALS, 0, opts->x_param_values,
1950 opts_set->x_param_values);
1951 maybe_set_param_value (PARAM_ASAN_STACK, 0, opts->x_param_values,
1952 opts_set->x_param_values);
5094f7d5
MO
1953 maybe_set_param_value (PARAM_ASAN_PROTECT_ALLOCAS, 0,
1954 opts->x_param_values,
1955 opts_set->x_param_values);
b1b46af0
JJ
1956 maybe_set_param_value (PARAM_ASAN_USE_AFTER_RETURN, 0,
1957 opts->x_param_values,
1958 opts_set->x_param_values);
1959 }
1960 break;
fec4842d 1961
b1b46af0
JJ
1962 case OPT_fsanitize_recover_:
1963 opts->x_flag_sanitize_recover
1964 = parse_sanitizer_options (arg, loc, code,
1965 opts->x_flag_sanitize_recover, value, true);
1966 break;
de5a5fa1 1967
fd960af2
YG
1968 case OPT_fasan_shadow_offset_:
1969 /* Deferred. */
1970 break;
1971
6dc4a604
ML
1972 case OPT_fsanitize_address_use_after_scope:
1973 opts->x_flag_sanitize_address_use_after_scope = value;
1974 break;
1975
d95a2703
JJ
1976 case OPT_fsanitize_recover:
1977 if (value)
1978 opts->x_flag_sanitize_recover
45b2222a 1979 |= (SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT)
5cc6c41c 1980 & ~(SANITIZE_UNREACHABLE | SANITIZE_RETURN);
d95a2703
JJ
1981 else
1982 opts->x_flag_sanitize_recover
45b2222a 1983 &= ~(SANITIZE_UNDEFINED | SANITIZE_UNDEFINED_NONDEFAULT);
d95a2703
JJ
1984 break;
1985
f6e50a7d
WW
1986 case OPT_fsanitize_coverage_:
1987 opts->x_flag_sanitize_coverage
1988 = parse_sanitizer_options (arg, loc, code,
1989 opts->x_flag_sanitize_coverage, value, true);
1990 break;
1991
903caebf
NB
1992 case OPT_O:
1993 case OPT_Os:
c3a02647 1994 case OPT_Ofast:
bf7a7185 1995 case OPT_Og:
903caebf
NB
1996 /* Currently handled in a prescan. */
1997 break;
1998
aee15221
RG
1999 case OPT_Werror:
2000 dc->warning_as_error_requested = value;
2001 break;
2002
79cf5994 2003 case OPT_Werror_:
a7d0d30f
JM
2004 if (lang_mask == CL_DRIVER)
2005 break;
2006
c5fa0890
JM
2007 enable_warning_as_error (arg, value, lang_mask, handlers,
2008 opts, opts_set, loc, dc);
79cf5994
DD
2009 break;
2010
e01cc6dc 2011 case OPT_Wlarger_than_:
d5478783
JM
2012 opts->x_larger_than_size = value;
2013 opts->x_warn_larger_than = value != -1;
e01cc6dc
NB
2014 break;
2015
5f0f4a3b 2016 case OPT_Wfatal_errors:
d5478783 2017 dc->fatal_errors = value;
5f0f4a3b
JM
2018 break;
2019
a214518f 2020 case OPT_Wframe_larger_than_:
d5478783
JM
2021 opts->x_frame_larger_than_size = value;
2022 opts->x_warn_frame_larger_than = value != -1;
a214518f
SP
2023 break;
2024
a11e0df4
EB
2025 case OPT_Wstack_usage_:
2026 opts->x_warn_stack_usage = value;
2027 opts->x_flag_stack_usage_info = value != -1;
2028 break;
2029
e01cc6dc 2030 case OPT_Wstrict_aliasing:
d5478783 2031 set_Wstrict_aliasing (opts, value);
e01cc6dc
NB
2032 break;
2033
6ac01510 2034 case OPT_Wstrict_overflow:
d5478783
JM
2035 opts->x_warn_strict_overflow = (value
2036 ? (int) WARN_STRICT_OVERFLOW_CONDITIONAL
2037 : 0);
6ac01510
ILT
2038 break;
2039
5f0f4a3b 2040 case OPT_Wsystem_headers:
d5478783 2041 dc->dc_warn_system_headers = value;
903caebf
NB
2042 break;
2043
d185d268 2044 case OPT_aux_info:
d5478783 2045 opts->x_flag_gen_aux_info = 1;
d185d268
NB
2046 break;
2047
2048 case OPT_auxbase_strip:
2049 {
2050 char *tmp = xstrdup (arg);
2051 strip_off_ending (tmp, strlen (tmp));
2052 if (tmp[0])
d5478783 2053 opts->x_aux_base_name = tmp;
fc429b48
TB
2054 else
2055 free (tmp);
d185d268
NB
2056 }
2057 break;
2058
2059 case OPT_d:
299404a1 2060 decode_d_option (arg, opts, loc, dc);
d185d268
NB
2061 break;
2062
058de654 2063 case OPT_fcall_used_:
058de654 2064 case OPT_fcall_saved_:
21bf1558 2065 /* Deferred. */
058de654 2066 break;
6fb5fa3c
DB
2067
2068 case OPT_fdbg_cnt_:
68d070ac
ML
2069 /* Deferred. */
2070 break;
2071
0a090f42 2072 case OPT_fdbg_cnt_list:
299404a1 2073 /* Deferred. */
68d070ac 2074 opts->x_exit_after_options = true;
0a090f42 2075 break;
058de654 2076
c8aea42c 2077 case OPT_fdebug_prefix_map_:
299404a1 2078 /* Deferred. */
c8aea42c
PB
2079 break;
2080
de32c0cb 2081 case OPT_fdiagnostics_show_location_:
e6d4b984 2082 diagnostic_prefixing_rule (dc) = (diagnostic_prefixing_rule_t) value;
de32c0cb 2083 break;
9fec0042
MLI
2084
2085 case OPT_fdiagnostics_show_caret:
2086 dc->show_caret = value;
2087 break;
de32c0cb 2088
4b84d650 2089 case OPT_fdiagnostics_color_:
97aa8bb6 2090 diagnostic_color_init (dc, value);
4b84d650
JJ
2091 break;
2092
a93eac6a
DM
2093 case OPT_fdiagnostics_parseable_fixits:
2094 dc->parseable_fixits_p = value;
2095 break;
2096
2098fe9e 2097 case OPT_fdiagnostics_show_option:
d5478783 2098 dc->show_option_requested = value;
2098fe9e
DD
2099 break;
2100
6de9cd9a 2101 case OPT_fdump_:
21bf1558 2102 /* Deferred. */
6de9cd9a
DN
2103 break;
2104
058de654 2105 case OPT_ffast_math:
d5478783 2106 set_fast_math_flags (opts, value);
058de654
NB
2107 break;
2108
a1a82611 2109 case OPT_funsafe_math_optimizations:
d5478783 2110 set_unsafe_math_optimizations_flags (opts, value);
a1a82611
RE
2111 break;
2112
058de654 2113 case OPT_ffixed_:
21bf1558 2114 /* Deferred. */
058de654
NB
2115 break;
2116
d302c9d6 2117 case OPT_finline_limit_:
48476d13
JM
2118 set_param_value ("max-inline-insns-single", value / 2,
2119 opts->x_param_values, opts_set->x_param_values);
2120 set_param_value ("max-inline-insns-auto", value / 2,
2121 opts->x_param_values, opts_set->x_param_values);
d302c9d6
NB
2122 break;
2123
8d5a7d1f 2124 case OPT_finstrument_functions_exclude_function_list_:
1ebc7e68 2125 add_comma_separated_to_vector
6a1f6c9c 2126 (&opts->x_flag_instrument_functions_exclude_functions, arg);
8d5a7d1f
ILT
2127 break;
2128
2129 case OPT_finstrument_functions_exclude_file_list_:
1ebc7e68 2130 add_comma_separated_to_vector
6a1f6c9c 2131 (&opts->x_flag_instrument_functions_exclude_files, arg);
8d5a7d1f
ILT
2132 break;
2133
de32c0cb 2134 case OPT_fmessage_length_:
d5478783 2135 pp_set_line_maximum_length (dc->printer, value);
9fec0042 2136 diagnostic_set_caret_max_width (dc, value);
de32c0cb
NB
2137 break;
2138
78c60e3d
SS
2139 case OPT_fopt_info:
2140 case OPT_fopt_info_:
2141 /* Deferred. */
2142 break;
2143
c713ddc0 2144 case OPT_foffload_:
b2b40051
MJ
2145 {
2146 const char *p = arg;
2147 opts->x_flag_disable_hsa = true;
2148 while (*p != 0)
2149 {
2150 const char *comma = strchr (p, ',');
2151
2152 if ((strncmp (p, "disable", 7) == 0)
2153 && (p[7] == ',' || p[7] == '\0'))
2154 {
2155 opts->x_flag_disable_hsa = true;
2156 break;
2157 }
2158
2159 if ((strncmp (p, "hsa", 3) == 0)
2160 && (p[3] == ',' || p[3] == '\0'))
2161 {
2162#ifdef ENABLE_HSA
2163 opts->x_flag_disable_hsa = false;
2164#else
2165 sorry ("HSA has not been enabled during configuration");
2166#endif
2167 }
2168 if (!comma)
2169 break;
2170 p = comma + 1;
2171 }
2172 break;
2173 }
c713ddc0
BS
2174
2175#ifndef ACCEL_COMPILER
2176 case OPT_foffload_abi_:
4f4b35a0 2177 error_at (loc, "%<-foffload-abi%> option can be specified only for "
c713ddc0
BS
2178 "offload compiler");
2179 break;
2180#endif
2181
467cecf3
JB
2182 case OPT_fpack_struct_:
2183 if (value <= 0 || (value & (value - 1)) || value > 16)
299404a1
JM
2184 error_at (loc,
2185 "structure alignment must be a small power of two, not %d",
2186 value);
467cecf3 2187 else
299404a1 2188 opts->x_initial_max_fld_align = value;
467cecf3
JB
2189 break;
2190
68a607d8 2191 case OPT_fplugin_:
68a607d8 2192 case OPT_fplugin_arg_:
21bf1558 2193 /* Deferred. */
68a607d8
DN
2194 break;
2195
2f908293 2196 case OPT_fprofile_use_:
0576d21f 2197 opts->x_profile_data_prefix = xstrdup (arg);
d5478783 2198 opts->x_flag_profile_use = true;
2f908293
SP
2199 value = true;
2200 /* No break here - do -fprofile-use processing. */
191816a3 2201 /* FALLTHRU */
a8a5f53a 2202 case OPT_fprofile_use:
be3c16c4 2203 enable_fdo_optimizations (opts, opts_set, value);
9cec31f4 2204 if (!opts_set->x_flag_profile_reorder_functions)
be3c16c4
DC
2205 opts->x_flag_profile_reorder_functions = value;
2206 /* Indirect call profiling should do all useful transformations
2207 speculative devirtualization does. */
bbc9396b
JH
2208 if (!opts_set->x_flag_devirtualize_speculatively
2209 && opts->x_flag_value_profile_transformations)
2210 opts->x_flag_devirtualize_speculatively = false;
a8a5f53a
JH
2211 break;
2212
be3c16c4
DC
2213 case OPT_fauto_profile_:
2214 opts->x_auto_profile_file = xstrdup (arg);
2215 opts->x_flag_auto_profile = true;
2216 value = true;
2217 /* No break here - do -fauto-profile processing. */
191816a3 2218 /* FALLTHRU */
be3c16c4
DC
2219 case OPT_fauto_profile:
2220 enable_fdo_optimizations (opts, opts_set, value);
2221 if (!opts_set->x_flag_profile_correction)
2222 opts->x_flag_profile_correction = value;
2223 maybe_set_param_value (
2224 PARAM_EARLY_INLINER_MAX_ITERATIONS, 10,
2225 opts->x_param_values, opts_set->x_param_values);
2226 break;
2227
2f908293 2228 case OPT_fprofile_generate_:
0576d21f 2229 opts->x_profile_data_prefix = xstrdup (arg);
2f908293
SP
2230 value = true;
2231 /* No break here - do -fprofile-generate processing. */
191816a3 2232 /* FALLTHRU */
a8a5f53a 2233 case OPT_fprofile_generate:
d4d24ba4 2234 if (!opts_set->x_profile_arc_flag)
d5478783 2235 opts->x_profile_arc_flag = value;
d4d24ba4 2236 if (!opts_set->x_flag_profile_values)
d5478783 2237 opts->x_flag_profile_values = value;
d4d24ba4 2238 if (!opts_set->x_flag_inline_functions)
d5478783 2239 opts->x_flag_inline_functions = value;
37731134
ML
2240 if (!opts_set->x_flag_ipa_bit_cp)
2241 opts->x_flag_ipa_bit_cp = value;
b0223c3e
JH
2242 /* FIXME: Instrumentation we insert makes ipa-reference bitmaps
2243 quadratic. Disable the pass until better memory representation
2244 is done. */
1c58fe29 2245 if (!opts_set->x_flag_ipa_reference)
b0223c3e 2246 opts->x_flag_ipa_reference = false;
a8a5f53a
JH
2247 break;
2248
417ca011
TD
2249 case OPT_fpatchable_function_entry_:
2250 {
2251 char *patch_area_arg = xstrdup (arg);
2252 char *comma = strchr (patch_area_arg, ',');
2253 if (comma)
2254 {
2255 *comma = '\0';
2256 function_entry_patch_area_size =
2257 integral_argument (patch_area_arg);
2258 function_entry_patch_area_start =
2259 integral_argument (comma + 1);
2260 }
2261 else
2262 {
2263 function_entry_patch_area_size =
2264 integral_argument (patch_area_arg);
2265 function_entry_patch_area_start = 0;
2266 }
2267 if (function_entry_patch_area_size < 0
2268 || function_entry_patch_area_start < 0
2269 || function_entry_patch_area_size
2270 < function_entry_patch_area_start)
2271 error ("invalid arguments for %<-fpatchable_function_entry%>");
2272 free (patch_area_arg);
2273 }
2274 break;
2275
ea0f3e87 2276 case OPT_ftree_vectorize:
26d476cd
JG
2277 /* Automatically sets -ftree-loop-vectorize and
2278 -ftree-slp-vectorize. Nothing more to do here. */
ea0f3e87 2279 break;
5f0f4a3b 2280 case OPT_fshow_column:
d5478783 2281 dc->show_column = value;
5f0f4a3b
JM
2282 break;
2283
de32c0cb
NB
2284 case OPT_frandom_seed:
2285 /* The real switch is -fno-random-seed. */
2286 if (value)
5f20c657 2287 return false;
299404a1 2288 /* Deferred. */
de32c0cb
NB
2289 break;
2290
2291 case OPT_frandom_seed_:
299404a1 2292 /* Deferred. */
de32c0cb
NB
2293 break;
2294
de32c0cb
NB
2295 case OPT_fsched_verbose_:
2296#ifdef INSN_SCHEDULING
299404a1 2297 /* Handled with Var in common.opt. */
de32c0cb
NB
2298 break;
2299#else
5f20c657 2300 return false;
de32c0cb
NB
2301#endif
2302
569fa502 2303 case OPT_fsched_stalled_insns_:
d5478783
JM
2304 opts->x_flag_sched_stalled_insns = value;
2305 if (opts->x_flag_sched_stalled_insns == 0)
2306 opts->x_flag_sched_stalled_insns = -1;
569fa502
DN
2307 break;
2308
569fa502 2309 case OPT_fsched_stalled_insns_dep_:
d5478783 2310 opts->x_flag_sched_stalled_insns_dep = value;
569fa502 2311 break;
6ff3a151 2312
b38f3813
EB
2313 case OPT_fstack_check_:
2314 if (!strcmp (arg, "no"))
5e471ea6 2315 opts->x_flag_stack_check = NO_STACK_CHECK;
b38f3813
EB
2316 else if (!strcmp (arg, "generic"))
2317 /* This is the old stack checking method. */
5e471ea6 2318 opts->x_flag_stack_check = STACK_CHECK_BUILTIN
b38f3813
EB
2319 ? FULL_BUILTIN_STACK_CHECK
2320 : GENERIC_STACK_CHECK;
2321 else if (!strcmp (arg, "specific"))
2322 /* This is the new stack checking method. */
5e471ea6 2323 opts->x_flag_stack_check = STACK_CHECK_BUILTIN
b38f3813
EB
2324 ? FULL_BUILTIN_STACK_CHECK
2325 : STACK_CHECK_STATIC_BUILTIN
2326 ? STATIC_BUILTIN_STACK_CHECK
2327 : GENERIC_STACK_CHECK;
2328 else
778e02fd 2329 warning_at (loc, 0, "unknown stack check parameter %qs", arg);
b38f3813
EB
2330 break;
2331
de32c0cb
NB
2332 case OPT_fstack_limit:
2333 /* The real switch is -fno-stack-limit. */
2334 if (value)
5f20c657 2335 return false;
21bf1558 2336 /* Deferred. */
de32c0cb
NB
2337 break;
2338
058de654 2339 case OPT_fstack_limit_register_:
058de654 2340 case OPT_fstack_limit_symbol_:
21bf1558 2341 /* Deferred. */
058de654
NB
2342 break;
2343
a11e0df4
EB
2344 case OPT_fstack_usage:
2345 opts->x_flag_stack_usage = value;
2346 opts->x_flag_stack_usage_info = value != 0;
2347 break;
2348
e01cc6dc 2349 case OPT_g:
bc91b0e0
CC
2350 set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, arg, opts, opts_set,
2351 loc);
df38ffef
NB
2352 break;
2353
6782438d 2354 case OPT_gdwarf:
f0defe58 2355 if (arg && strlen (arg) != 0)
6782438d
SKS
2356 {
2357 error_at (loc, "%<-gdwarf%s%> is ambiguous; "
2358 "use %<-gdwarf-%s%> for DWARF version "
2359 "or %<-gdwarf -g%s%> for debug level", arg, arg, arg);
2360 break;
2361 }
2362 else
f0defe58
SKS
2363 value = opts->x_dwarf_version;
2364
2365 /* FALLTHRU */
53b2323e 2366 case OPT_gdwarf_:
5d45c9c0 2367 if (value < 2 || value > 5)
299404a1 2368 error_at (loc, "dwarf version %d is not supported", value);
53b2323e 2369 else
a7d0d30f 2370 opts->x_dwarf_version = value;
299404a1 2371 set_debug_level (DWARF2_DEBUG, false, "", opts, opts_set, loc);
df38ffef
NB
2372 break;
2373
99ea153e
SA
2374 case OPT_gsplit_dwarf:
2375 set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, "", opts, opts_set,
2376 loc);
2377 break;
2378
df38ffef 2379 case OPT_ggdb:
299404a1 2380 set_debug_level (NO_DEBUG, 2, arg, opts, opts_set, loc);
df38ffef
NB
2381 break;
2382
2383 case OPT_gstabs:
2384 case OPT_gstabs_:
299404a1
JM
2385 set_debug_level (DBX_DEBUG, code == OPT_gstabs_, arg, opts, opts_set,
2386 loc);
df38ffef
NB
2387 break;
2388
2389 case OPT_gvms:
299404a1 2390 set_debug_level (VMS_DEBUG, false, arg, opts, opts_set, loc);
df38ffef
NB
2391 break;
2392
2393 case OPT_gxcoff:
2394 case OPT_gxcoff_:
299404a1
JM
2395 set_debug_level (XCOFF_DEBUG, code == OPT_gxcoff_, arg, opts, opts_set,
2396 loc);
e01cc6dc
NB
2397 break;
2398
29d7cbd1
RO
2399 case OPT_gz:
2400 case OPT_gz_:
2401 /* Handled completely via specs. */
2402 break;
2403
d185d268 2404 case OPT_pedantic_errors:
d5478783 2405 dc->pedantic_errors = 1;
63bbf46d 2406 control_warning_option (OPT_Wpedantic, DK_ERROR, NULL, value,
9b095bf1
MLI
2407 loc, lang_mask,
2408 handlers, opts, opts_set,
2409 dc);
c04b6b38
RG
2410 break;
2411
014d92e1 2412 case OPT_flto:
595c8dfa 2413 opts->x_flag_lto = value ? "" : NULL;
e10909ce
AK
2414 break;
2415
5f0f4a3b 2416 case OPT_w:
d5478783 2417 dc->dc_inhibit_warnings = true;
5f0f4a3b
JM
2418 break;
2419
3a789837
NF
2420 case OPT_fmax_errors_:
2421 dc->max_errors = value;
2422 break;
2423
b352afba
NC
2424 case OPT_fuse_ld_bfd:
2425 case OPT_fuse_ld_gold:
da18ea94
RAE
2426 case OPT_fuse_linker_plugin:
2427 /* No-op. Used by the driver and passed to us because it starts with f.*/
2428 break;
2429
955f5a07
JJ
2430 case OPT_fwrapv:
2431 if (value)
2432 opts->x_flag_trapv = 0;
2433 break;
2434
2435 case OPT_ftrapv:
2436 if (value)
2437 opts->x_flag_wrapv = 0;
2438 break;
2439
b84d4347 2440 case OPT_fipa_icf:
9d4ded75
ML
2441 opts->x_flag_ipa_icf_functions = value;
2442 opts->x_flag_ipa_icf_variables = value;
b84d4347
ML
2443 break;
2444
50431bc4
ZD
2445 default:
2446 /* If the flag was handled in a standard way, assume the lack of
2447 processing here is intentional. */
46625112 2448 gcc_assert (option_flag_var (scode, opts));
0e61db61 2449 break;
d7b42618
NB
2450 }
2451
7d5a5747
MLI
2452 common_handle_option_auto (opts, opts_set, decoded, lang_mask, kind,
2453 loc, handlers, dc);
5f20c657 2454 return true;
d7b42618 2455}
903caebf
NB
2456
2457/* Handle --param NAME=VALUE. */
2458static void
48476d13 2459handle_param (struct gcc_options *opts, struct gcc_options *opts_set,
299404a1 2460 location_t loc, const char *carg)
903caebf
NB
2461{
2462 char *equal, *arg;
2463 int value;
2464
2465 arg = xstrdup (carg);
2466 equal = strchr (arg, '=');
2467 if (!equal)
299404a1
JM
2468 error_at (loc, "%s: --param arguments should be of the form NAME=VALUE",
2469 arg);
903caebf
NB
2470 else
2471 {
d78182cc
TV
2472 *equal = '\0';
2473
2474 enum compiler_param index;
2475 if (!find_param (arg, &index))
f4452176
DM
2476 {
2477 const char *suggestion = find_param_fuzzy (arg);
2478 if (suggestion)
2479 error_at (loc, "invalid --param name %qs; did you mean %qs?",
2480 arg, suggestion);
2481 else
2482 error_at (loc, "invalid --param name %qs", arg);
2483 }
903caebf
NB
2484 else
2485 {
d78182cc
TV
2486 if (!param_string_value_p (index, equal + 1, &value))
2487 value = integral_argument (equal + 1);
2488
2489 if (value == -1)
2490 error_at (loc, "invalid --param value %qs", equal + 1);
2491 else
2492 set_param_value (arg, value,
2493 opts->x_param_values, opts_set->x_param_values);
903caebf
NB
2494 }
2495 }
2496
2497 free (arg);
2498}
2499
d5478783 2500/* Used to set the level of strict aliasing warnings in OPTS,
79bedddc
SR
2501 when no level is specified (i.e., when -Wstrict-aliasing, and not
2502 -Wstrict-aliasing=level was given).
2503 ONOFF is assumed to take value 1 when -Wstrict-aliasing is specified,
2504 and 0 otherwise. After calling this function, wstrict_aliasing will be
2505 set to the default value of -Wstrict_aliasing=level, currently 3. */
65d4f2cd 2506static void
d5478783 2507set_Wstrict_aliasing (struct gcc_options *opts, int onoff)
79bedddc
SR
2508{
2509 gcc_assert (onoff == 0 || onoff == 1);
2510 if (onoff != 0)
d5478783 2511 opts->x_warn_strict_aliasing = 3;
621b5ed6 2512 else
d5478783 2513 opts->x_warn_strict_aliasing = 0;
79bedddc
SR
2514}
2515
058de654
NB
2516/* The following routines are useful in setting all the flags that
2517 -ffast-math and -fno-fast-math imply. */
7bb3487f 2518static void
d5478783 2519set_fast_math_flags (struct gcc_options *opts, int set)
058de654 2520{
5e46b0c6
ILT
2521 if (!opts->frontend_set_flag_unsafe_math_optimizations)
2522 {
2523 opts->x_flag_unsafe_math_optimizations = set;
2524 set_unsafe_math_optimizations_flags (opts, set);
2525 }
2526 if (!opts->frontend_set_flag_finite_math_only)
2527 opts->x_flag_finite_math_only = set;
2528 if (!opts->frontend_set_flag_errno_math)
2529 opts->x_flag_errno_math = !set;
058de654 2530 if (set)
039c3d42 2531 {
314e1b47
JG
2532 if (opts->frontend_set_flag_excess_precision_cmdline
2533 == EXCESS_PRECISION_DEFAULT)
2534 opts->x_flag_excess_precision_cmdline
2535 = set ? EXCESS_PRECISION_FAST : EXCESS_PRECISION_DEFAULT;
5e46b0c6
ILT
2536 if (!opts->frontend_set_flag_signaling_nans)
2537 opts->x_flag_signaling_nans = 0;
2538 if (!opts->frontend_set_flag_rounding_math)
2539 opts->x_flag_rounding_math = 0;
2540 if (!opts->frontend_set_flag_cx_limited_range)
2541 opts->x_flag_cx_limited_range = 1;
039c3d42 2542 }
058de654
NB
2543}
2544
b8698a0f
L
2545/* When -funsafe-math-optimizations is set the following
2546 flags are set as well. */
7bb3487f 2547static void
d5478783 2548set_unsafe_math_optimizations_flags (struct gcc_options *opts, int set)
a1a82611 2549{
5e46b0c6
ILT
2550 if (!opts->frontend_set_flag_trapping_math)
2551 opts->x_flag_trapping_math = !set;
2552 if (!opts->frontend_set_flag_signed_zeros)
2553 opts->x_flag_signed_zeros = !set;
2554 if (!opts->frontend_set_flag_associative_math)
2555 opts->x_flag_associative_math = set;
2556 if (!opts->frontend_set_flag_reciprocal_math)
2557 opts->x_flag_reciprocal_math = set;
a1a82611
RE
2558}
2559
0576d21f 2560/* Return true iff flags in OPTS are set as if -ffast-math. */
058de654 2561bool
0576d21f 2562fast_math_flags_set_p (const struct gcc_options *opts)
058de654 2563{
0576d21f
JM
2564 return (!opts->x_flag_trapping_math
2565 && opts->x_flag_unsafe_math_optimizations
2566 && opts->x_flag_finite_math_only
2567 && !opts->x_flag_signed_zeros
314e1b47
JG
2568 && !opts->x_flag_errno_math
2569 && opts->x_flag_excess_precision_cmdline
2570 == EXCESS_PRECISION_FAST);
058de654 2571}
cf03fd63 2572
ab442df7
MM
2573/* Return true iff flags are set as if -ffast-math but using the flags stored
2574 in the struct cl_optimization structure. */
2575bool
2576fast_math_flags_struct_set_p (struct cl_optimization *opt)
2577{
e3339d0f
JM
2578 return (!opt->x_flag_trapping_math
2579 && opt->x_flag_unsafe_math_optimizations
2580 && opt->x_flag_finite_math_only
2581 && !opt->x_flag_signed_zeros
2582 && !opt->x_flag_errno_math);
ab442df7
MM
2583}
2584
0576d21f
JM
2585/* Handle a debug output -g switch for options OPTS
2586 (OPTS_SET->x_write_symbols storing whether a debug type was passed
299404a1
JM
2587 explicitly), location LOC. EXTENDED is true or false to support
2588 extended output (2 is special and means "-ggdb" was given). */
df38ffef 2589static void
0576d21f 2590set_debug_level (enum debug_info_type type, int extended, const char *arg,
299404a1
JM
2591 struct gcc_options *opts, struct gcc_options *opts_set,
2592 location_t loc)
df38ffef 2593{
0576d21f 2594 opts->x_use_gnu_debug_info_extensions = extended;
df38ffef
NB
2595
2596 if (type == NO_DEBUG)
2597 {
0576d21f 2598 if (opts->x_write_symbols == NO_DEBUG)
df38ffef 2599 {
0576d21f 2600 opts->x_write_symbols = PREFERRED_DEBUGGING_TYPE;
df38ffef
NB
2601
2602 if (extended == 2)
2603 {
c9665100 2604#if defined DWARF2_DEBUGGING_INFO || defined DWARF2_LINENO_DEBUGGING_INFO
0576d21f 2605 opts->x_write_symbols = DWARF2_DEBUG;
df38ffef 2606#elif defined DBX_DEBUGGING_INFO
0576d21f 2607 opts->x_write_symbols = DBX_DEBUG;
df38ffef
NB
2608#endif
2609 }
2610
0576d21f 2611 if (opts->x_write_symbols == NO_DEBUG)
299404a1 2612 warning_at (loc, 0, "target system does not support debug output");
df38ffef
NB
2613 }
2614 }
2615 else
2616 {
2617 /* Does it conflict with an already selected type? */
0576d21f
JM
2618 if (opts_set->x_write_symbols != NO_DEBUG
2619 && opts->x_write_symbols != NO_DEBUG
2620 && type != opts->x_write_symbols)
778e02fd 2621 error_at (loc, "debug format %qs conflicts with prior selection",
299404a1 2622 debug_type_names[type]);
0576d21f
JM
2623 opts->x_write_symbols = type;
2624 opts_set->x_write_symbols = type;
df38ffef
NB
2625 }
2626
bc91b0e0
CC
2627 /* A debug flag without a level defaults to level 2.
2628 If off or at level 1, set it to level 2, but if already
2629 at level 3, don't lower it. */
df38ffef
NB
2630 if (*arg == '\0')
2631 {
bc91b0e0 2632 if (opts->x_debug_info_level < DINFO_LEVEL_NORMAL)
0576d21f 2633 opts->x_debug_info_level = DINFO_LEVEL_NORMAL;
df38ffef
NB
2634 }
2635 else
2636 {
32e8bb8e
ILT
2637 int argval = integral_argument (arg);
2638 if (argval == -1)
bd2c6270 2639 error_at (loc, "unrecognized debug output level %qs", arg);
32e8bb8e 2640 else if (argval > 3)
778e02fd 2641 error_at (loc, "debug output level %qs is too high", arg);
32e8bb8e 2642 else
0576d21f 2643 opts->x_debug_info_level = (enum debug_info_levels) argval;
df38ffef
NB
2644 }
2645}
2646
299404a1
JM
2647/* Arrange to dump core on error for diagnostic context DC. (The
2648 regular error message is still printed first, except in the case of
2649 abort ().) */
75685792 2650
c98cd5bf 2651static void
299404a1 2652setup_core_dumping (diagnostic_context *dc)
75685792 2653{
c98cd5bf
JM
2654#ifdef SIGABRT
2655 signal (SIGABRT, SIG_DFL);
2656#endif
2657#if defined(HAVE_SETRLIMIT)
2658 {
2659 struct rlimit rlim;
2660 if (getrlimit (RLIMIT_CORE, &rlim) != 0)
40fecdd6 2661 fatal_error (input_location, "getting core file size maximum limit: %m");
c98cd5bf
JM
2662 rlim.rlim_cur = rlim.rlim_max;
2663 if (setrlimit (RLIMIT_CORE, &rlim) != 0)
40fecdd6
JM
2664 fatal_error (input_location,
2665 "setting core file size limit to maximum: %m");
c98cd5bf
JM
2666 }
2667#endif
299404a1 2668 diagnostic_abort_on_error (dc);
75685792 2669}
5c60a017 2670
299404a1
JM
2671/* Parse a -d<ARG> command line switch for OPTS, location LOC,
2672 diagnostic context DC. */
5c60a017 2673
c98cd5bf 2674static void
299404a1
JM
2675decode_d_option (const char *arg, struct gcc_options *opts,
2676 location_t loc, diagnostic_context *dc)
5c60a017 2677{
c98cd5bf 2678 int c;
5c60a017 2679
c98cd5bf
JM
2680 while (*arg)
2681 switch (c = *arg++)
2682 {
2683 case 'A':
299404a1 2684 opts->x_flag_debug_asm = 1;
c98cd5bf
JM
2685 break;
2686 case 'p':
299404a1 2687 opts->x_flag_print_asm_name = 1;
c98cd5bf
JM
2688 break;
2689 case 'P':
299404a1
JM
2690 opts->x_flag_dump_rtl_in_asm = 1;
2691 opts->x_flag_print_asm_name = 1;
c98cd5bf 2692 break;
c98cd5bf 2693 case 'x':
299404a1 2694 opts->x_rtl_dump_and_exit = 1;
c98cd5bf
JM
2695 break;
2696 case 'D': /* These are handled by the preprocessor. */
2697 case 'I':
2698 case 'M':
2699 case 'N':
2700 case 'U':
2701 break;
2702 case 'H':
299404a1 2703 setup_core_dumping (dc);
c98cd5bf
JM
2704 break;
2705 case 'a':
299404a1 2706 opts->x_flag_dump_all_passed = true;
c98cd5bf 2707 break;
21bf1558 2708
c98cd5bf 2709 default:
299404a1 2710 warning_at (loc, 0, "unrecognized gcc debugging option: %c", c);
c98cd5bf
JM
2711 break;
2712 }
5c60a017 2713}
dc90f45b 2714
1ebe4b4f 2715/* Enable (or disable if VALUE is 0) a warning option ARG (language
c5fa0890
JM
2716 mask LANG_MASK, option handlers HANDLERS) as an error for option
2717 structures OPTS and OPTS_SET, diagnostic context DC (possibly
2718 NULL), location LOC. This is used by -Werror=. */
dc90f45b 2719
a4d8c676 2720static void
5f20c657 2721enable_warning_as_error (const char *arg, int value, unsigned int lang_mask,
1ebe4b4f 2722 const struct cl_option_handlers *handlers,
c5fa0890
JM
2723 struct gcc_options *opts,
2724 struct gcc_options *opts_set,
a4d8c676 2725 location_t loc, diagnostic_context *dc)
dc90f45b
MLI
2726{
2727 char *new_option;
2728 int option_index;
2729
2730 new_option = XNEWVEC (char, strlen (arg) + 2);
2731 new_option[0] = 'W';
2732 strcpy (new_option + 1, arg);
2733 option_index = find_opt (new_option, lang_mask);
6e2f1956 2734 if (option_index == OPT_SPECIAL_unknown)
35632122
MLI
2735 error_at (loc, "-Werror=%s: no option -%s", arg, new_option);
2736 else if (!(cl_options[option_index].flags & CL_WARNING))
2737 error_at (loc, "-Werror=%s: -%s is not an option that controls warnings",
2738 arg, new_option);
dc90f45b
MLI
2739 else
2740 {
87cf0651 2741 const diagnostic_t kind = value ? DK_ERROR : DK_WARNING;
63bbf46d 2742 const char *arg = NULL;
87cf0651 2743
63bbf46d
JJ
2744 if (cl_options[option_index].flags & CL_JOINED)
2745 arg = new_option + cl_options[option_index].opt_len;
2746 control_warning_option (option_index, (int) kind, arg, value,
c5fa0890
JM
2747 loc, lang_mask,
2748 handlers, opts, opts_set, dc);
dc90f45b
MLI
2749 }
2750 free (new_option);
2751}
5f0f4a3b
JM
2752
2753/* Return malloced memory for the name of the option OPTION_INDEX
2754 which enabled a diagnostic (context CONTEXT), originally of type
2755 ORIG_DIAG_KIND but possibly converted to DIAG_KIND by options such
2756 as -Werror. */
2757
2758char *
2759option_name (diagnostic_context *context, int option_index,
2760 diagnostic_t orig_diag_kind, diagnostic_t diag_kind)
2761{
2762 if (option_index)
2763 {
2764 /* A warning classified as an error. */
2765 if ((orig_diag_kind == DK_WARNING || orig_diag_kind == DK_PEDWARN)
2766 && diag_kind == DK_ERROR)
2767 return concat (cl_options[OPT_Werror_].opt_text,
2768 /* Skip over "-W". */
2769 cl_options[option_index].opt_text + 2,
2770 NULL);
2771 /* A warning with option. */
2772 else
2773 return xstrdup (cl_options[option_index].opt_text);
2774 }
2775 /* A warning without option classified as an error. */
9f8da907
RS
2776 else if ((orig_diag_kind == DK_WARNING || orig_diag_kind == DK_PEDWARN
2777 || diag_kind == DK_WARNING)
2778 && context->warning_as_error_requested)
2779 return xstrdup (cl_options[OPT_Werror].opt_text);
5f0f4a3b
JM
2780 else
2781 return NULL;
2782}