]>
Commit | Line | Data |
---|---|---|
5457b645 | 1 | /* Command line option handling. |
aad93da1 | 2 | Copyright (C) 2002-2017 Free Software Foundation, Inc. |
5457b645 | 3 | Contributed by Neil Booth. |
4 | ||
5 | This file is part of GCC. | |
6 | ||
7 | GCC is free software; you can redistribute it and/or modify it under | |
8 | the terms of the GNU General Public License as published by the Free | |
8c4c00c1 | 9 | Software Foundation; either version 3, or (at your option) any later |
5457b645 | 10 | version. |
11 | ||
12 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
13 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 | for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
8c4c00c1 | 18 | along 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 | 35 | static void set_Wstrict_aliasing (struct gcc_options *opts, int onoff); |
36 | ||
90336809 | 37 | /* Indexed by enum debug_info_type. */ |
38 | const 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 | ||
50 | void | |
9faf44d6 | 51 | set_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 | |
144 | void | |
145 | strip_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 | 160 | int |
0e4744ac | 161 | base_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 | 185 | static const char undocumented_msg[] = N_("This option lacks documentation."); |
186 | static const char use_diagnosed_msg[] = N_("Uses of this option are diagnosed."); | |
344c9292 | 187 | |
a95c0776 | 188 | typedef char *char_p; /* For DEF_VEC_P. */ |
a95c0776 | 189 | |
56f280c4 | 190 | static void handle_param (struct gcc_options *opts, |
9faf44d6 | 191 | struct gcc_options *opts_set, location_t loc, |
192 | const char *carg); | |
b0e56fb1 | 193 | static 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 | 197 | static void set_fast_math_flags (struct gcc_options *opts, int set); |
9faf44d6 | 198 | static void decode_d_option (const char *arg, struct gcc_options *opts, |
199 | location_t loc, diagnostic_context *dc); | |
6bd9d862 | 200 | static void set_unsafe_math_optimizations_flags (struct gcc_options *opts, |
201 | int set); | |
3c6c0e40 | 202 | static 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 | 213 | bool |
2c5d2e39 | 214 | target_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 | |
229 | static void | |
470a0ecd | 230 | add_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 | |
272 | void | |
273 | init_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 | ||
280 | void | |
281 | init_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 | ||
320 | void | |
321 | finalize_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 | |
331 | static void | |
332 | maybe_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 | |
420 | static void | |
421 | maybe_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 | ||
440 | static 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 | 555 | void |
f3f006ad | 556 | default_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 | 695 | void |
9faf44d6 | 696 | finish_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. */ | |
1037 | static void | |
1038 | wrap_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. */ | |
1083 | static void | |
1084 | print_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 | 1365 | static void |
1366 | print_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 | ||
1461 | static void | |
1462 | enable_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 | 1507 | const 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. */ |
1548 | const 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 | ||
1560 | struct 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 | ||
1572 | template <> | |
1573 | struct 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 | ||
1594 | static const char * | |
1595 | get_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 | ||
1624 | unsigned int | |
1625 | parse_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 | |
1723 | unsigned int | |
93e9d560 | 1724 | parse_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 | 1756 | bool |
2c5d2e39 | 1757 | common_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. */ | |
2475 | static void | |
56f280c4 | 2476 | handle_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 | 2523 | static void |
6bd9d862 | 2524 | set_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 | 2535 | static void |
6bd9d862 | 2536 | set_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 | 2564 | static void |
6bd9d862 | 2565 | set_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 | 2578 | bool |
cc4fa57a | 2579 | fast_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. */ | |
2592 | bool | |
2593 | fast_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 | 2606 | static void |
cc4fa57a | 2607 | set_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 | 2668 | static void |
9faf44d6 | 2669 | setup_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 | 2691 | static void |
9faf44d6 | 2692 | decode_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 | 2737 | static void |
b78351e5 | 2738 | enable_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 | ||
2775 | char * | |
2776 | option_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 | } |