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