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