]>
Commit | Line | Data |
---|---|---|
5457b645 | 1 | /* Command line option handling. |
3aea1f79 | 2 | Copyright (C) 2002-2014 Free Software Foundation, Inc. |
5457b645 | 3 | Contributed by Neil Booth. |
4 | ||
5 | This file is part of GCC. | |
6 | ||
7 | GCC is free software; you can redistribute it and/or modify it under | |
8 | the terms of the GNU General Public License as published by the Free | |
8c4c00c1 | 9 | Software Foundation; either version 3, or (at your option) any later |
5457b645 | 10 | version. |
11 | ||
12 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY | |
13 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 | for more details. | |
16 | ||
17 | You should have received a copy of the GNU General Public License | |
8c4c00c1 | 18 | along with GCC; see the file COPYING3. If not see |
19 | <http://www.gnu.org/licenses/>. */ | |
5457b645 | 20 | |
21 | #include "config.h" | |
22 | #include "system.h" | |
53b8e5c1 | 23 | #include "intl.h" |
5457b645 | 24 | #include "coretypes.h" |
fbb6fbd8 | 25 | #include "opts.h" |
26 | #include "options.h" | |
808674b1 | 27 | #include "tm.h" /* For STACK_CHECK_BUILTIN, |
068c688e | 28 | STACK_CHECK_STATIC_BUILTIN, DEFAULT_GDB_EXTENSIONS, |
29 | DWARF2_DEBUGGING_INFO and DBX_DEBUGGING_INFO. */ | |
3272db82 | 30 | #include "flags.h" |
da3b1bab | 31 | #include "params.h" |
1e06725a | 32 | #include "diagnostic.h" |
41609f8b | 33 | #include "diagnostic-color.h" |
3c6a9715 | 34 | #include "opts-diagnostic.h" |
808674b1 | 35 | #include "insn-attr-common.h" |
218e3e4e | 36 | #include "common/common-target.h" |
5457b645 | 37 | |
77b27208 | 38 | static void set_Wstrict_aliasing (struct gcc_options *opts, int onoff); |
39 | ||
90336809 | 40 | /* Indexed by enum debug_info_type. */ |
41 | const char *const debug_type_names[] = | |
42 | { | |
43 | "none", "stabs", "coff", "dwarf-2", "xcoff", "vms" | |
44 | }; | |
45 | ||
0e4744ac | 46 | /* Parse the -femit-struct-debug-detailed option value |
47 | and set the flag variables. */ | |
48 | ||
49 | #define MATCH( prefix, string ) \ | |
50 | ((strncmp (prefix, string, sizeof prefix - 1) == 0) \ | |
51 | ? ((string += sizeof prefix - 1), 1) : 0) | |
52 | ||
53 | void | |
9faf44d6 | 54 | set_struct_debug_option (struct gcc_options *opts, location_t loc, |
55 | const char *spec) | |
0e4744ac | 56 | { |
57 | /* various labels for comparison */ | |
cc4fa57a | 58 | static const char dfn_lbl[] = "dfn:", dir_lbl[] = "dir:", ind_lbl[] = "ind:"; |
59 | static const char ord_lbl[] = "ord:", gen_lbl[] = "gen:"; | |
60 | static const char none_lbl[] = "none", any_lbl[] = "any"; | |
61 | static const char base_lbl[] = "base", sys_lbl[] = "sys"; | |
0e4744ac | 62 | |
63 | enum debug_struct_file files = DINFO_STRUCT_FILE_ANY; | |
64 | /* Default is to apply to as much as possible. */ | |
65 | enum debug_info_usage usage = DINFO_USAGE_NUM_ENUMS; | |
66 | int ord = 1, gen = 1; | |
67 | ||
68 | /* What usage? */ | |
69 | if (MATCH (dfn_lbl, spec)) | |
70 | usage = DINFO_USAGE_DFN; | |
71 | else if (MATCH (dir_lbl, spec)) | |
72 | usage = DINFO_USAGE_DIR_USE; | |
73 | else if (MATCH (ind_lbl, spec)) | |
74 | usage = DINFO_USAGE_IND_USE; | |
75 | ||
76 | /* Generics or not? */ | |
77 | if (MATCH (ord_lbl, spec)) | |
78 | gen = 0; | |
79 | else if (MATCH (gen_lbl, spec)) | |
80 | ord = 0; | |
81 | ||
82 | /* What allowable environment? */ | |
83 | if (MATCH (none_lbl, spec)) | |
84 | files = DINFO_STRUCT_FILE_NONE; | |
85 | else if (MATCH (any_lbl, spec)) | |
86 | files = DINFO_STRUCT_FILE_ANY; | |
87 | else if (MATCH (sys_lbl, spec)) | |
88 | files = DINFO_STRUCT_FILE_SYS; | |
89 | else if (MATCH (base_lbl, spec)) | |
90 | files = DINFO_STRUCT_FILE_BASE; | |
91 | else | |
9faf44d6 | 92 | error_at (loc, |
93 | "argument %qs to %<-femit-struct-debug-detailed%> " | |
94 | "not recognized", | |
95 | spec); | |
0e4744ac | 96 | |
97 | /* Effect the specification. */ | |
98 | if (usage == DINFO_USAGE_NUM_ENUMS) | |
99 | { | |
100 | if (ord) | |
101 | { | |
d7175aef | 102 | opts->x_debug_struct_ordinary[DINFO_USAGE_DFN] = files; |
103 | opts->x_debug_struct_ordinary[DINFO_USAGE_DIR_USE] = files; | |
104 | opts->x_debug_struct_ordinary[DINFO_USAGE_IND_USE] = files; | |
0e4744ac | 105 | } |
106 | if (gen) | |
107 | { | |
d7175aef | 108 | opts->x_debug_struct_generic[DINFO_USAGE_DFN] = files; |
109 | opts->x_debug_struct_generic[DINFO_USAGE_DIR_USE] = files; | |
110 | opts->x_debug_struct_generic[DINFO_USAGE_IND_USE] = files; | |
0e4744ac | 111 | } |
112 | } | |
113 | else | |
114 | { | |
115 | if (ord) | |
d7175aef | 116 | opts->x_debug_struct_ordinary[usage] = files; |
0e4744ac | 117 | if (gen) |
d7175aef | 118 | opts->x_debug_struct_generic[usage] = files; |
0e4744ac | 119 | } |
120 | ||
121 | if (*spec == ',') | |
9faf44d6 | 122 | set_struct_debug_option (opts, loc, spec+1); |
0e4744ac | 123 | else |
124 | { | |
125 | /* No more -femit-struct-debug-detailed specifications. | |
126 | Do final checks. */ | |
127 | if (*spec != '\0') | |
9faf44d6 | 128 | error_at (loc, |
129 | "argument %qs to %<-femit-struct-debug-detailed%> unknown", | |
130 | spec); | |
d7175aef | 131 | if (opts->x_debug_struct_ordinary[DINFO_USAGE_DIR_USE] |
132 | < opts->x_debug_struct_ordinary[DINFO_USAGE_IND_USE] | |
133 | || opts->x_debug_struct_generic[DINFO_USAGE_DIR_USE] | |
134 | < opts->x_debug_struct_generic[DINFO_USAGE_IND_USE]) | |
9faf44d6 | 135 | error_at (loc, |
136 | "%<-femit-struct-debug-detailed=dir:...%> must allow " | |
137 | "at least as much as " | |
138 | "%<-femit-struct-debug-detailed=ind:...%>"); | |
0e4744ac | 139 | } |
140 | } | |
141 | ||
79396169 | 142 | /* Strip off a legitimate source ending from the input string NAME of |
143 | length LEN. Rather than having to know the names used by all of | |
144 | our front ends, we strip off an ending of a period followed by | |
145 | up to five characters. (Java uses ".class".) */ | |
146 | ||
147 | void | |
148 | strip_off_ending (char *name, int len) | |
149 | { | |
150 | int i; | |
151 | for (i = 2; i < 6 && len > i; i++) | |
152 | { | |
153 | if (name[len - i] == '.') | |
154 | { | |
155 | name[len - i] = '\0'; | |
156 | break; | |
157 | } | |
158 | } | |
159 | } | |
160 | ||
0e4744ac | 161 | /* Find the base name of a path, stripping off both directories and |
162 | a single final extension. */ | |
d7175aef | 163 | int |
0e4744ac | 164 | base_of_path (const char *path, const char **base_out) |
165 | { | |
166 | const char *base = path; | |
167 | const char *dot = 0; | |
168 | const char *p = path; | |
169 | char c = *p; | |
170 | while (c) | |
171 | { | |
9af5ce0c | 172 | if (IS_DIR_SEPARATOR (c)) |
0e4744ac | 173 | { |
174 | base = p + 1; | |
175 | dot = 0; | |
176 | } | |
177 | else if (c == '.') | |
178 | dot = p; | |
179 | c = *++p; | |
180 | } | |
181 | if (!dot) | |
182 | dot = p; | |
183 | *base_out = base; | |
184 | return dot - base; | |
185 | } | |
186 | ||
344c9292 | 187 | /* What to print when a switch has no documentation. */ |
188 | static const char undocumented_msg[] = N_("This switch lacks documentation"); | |
189 | ||
a95c0776 | 190 | typedef char *char_p; /* For DEF_VEC_P. */ |
a95c0776 | 191 | |
56f280c4 | 192 | static void handle_param (struct gcc_options *opts, |
9faf44d6 | 193 | struct gcc_options *opts_set, location_t loc, |
194 | const char *carg); | |
b0e56fb1 | 195 | static void set_debug_level (enum debug_info_type type, int extended, |
cc4fa57a | 196 | const char *arg, struct gcc_options *opts, |
9faf44d6 | 197 | struct gcc_options *opts_set, |
198 | location_t loc); | |
6bd9d862 | 199 | static void set_fast_math_flags (struct gcc_options *opts, int set); |
9faf44d6 | 200 | static void decode_d_option (const char *arg, struct gcc_options *opts, |
201 | location_t loc, diagnostic_context *dc); | |
6bd9d862 | 202 | static void set_unsafe_math_optimizations_flags (struct gcc_options *opts, |
203 | int set); | |
3c6c0e40 | 204 | static void enable_warning_as_error (const char *arg, int value, |
205 | unsigned int lang_mask, | |
206 | const struct cl_option_handlers *handlers, | |
c123f04d | 207 | struct gcc_options *opts, |
208 | struct gcc_options *opts_set, | |
3c6c0e40 | 209 | location_t loc, |
210 | diagnostic_context *dc); | |
5457b645 | 211 | |
b78351e5 | 212 | /* Handle a back-end option; arguments and return value as for |
213 | handle_option. */ | |
5457b645 | 214 | |
79396169 | 215 | bool |
2c5d2e39 | 216 | target_handle_option (struct gcc_options *opts, |
f83b64ca | 217 | struct gcc_options *opts_set, |
2c5d2e39 | 218 | const struct cl_decoded_option *decoded, |
666f4bf0 | 219 | unsigned int lang_mask ATTRIBUTE_UNUSED, int kind, |
fba5dd52 | 220 | location_t loc, |
6bd9d862 | 221 | const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED, |
222 | diagnostic_context *dc) | |
b78351e5 | 223 | { |
6bd9d862 | 224 | gcc_assert (dc == global_dc); |
b78351e5 | 225 | gcc_assert (kind == DK_UNSPECIFIED); |
218e3e4e | 226 | return targetm_common.handle_option (opts, opts_set, decoded, loc); |
5457b645 | 227 | } |
3272db82 | 228 | |
b5f30e7c | 229 | /* Add comma-separated strings to a char_p vector. */ |
a95c0776 | 230 | |
231 | static void | |
470a0ecd | 232 | add_comma_separated_to_vector (void **pvec, const char *arg) |
a95c0776 | 233 | { |
234 | char *tmp; | |
235 | char *r; | |
236 | char *w; | |
237 | char *token_start; | |
f1f41a6c | 238 | vec<char_p> *v = (vec<char_p> *) *pvec; |
239 | ||
240 | vec_check_alloc (v, 1); | |
a95c0776 | 241 | |
242 | /* We never free this string. */ | |
243 | tmp = xstrdup (arg); | |
244 | ||
245 | r = tmp; | |
246 | w = tmp; | |
247 | token_start = tmp; | |
248 | ||
249 | while (*r != '\0') | |
250 | { | |
251 | if (*r == ',') | |
252 | { | |
253 | *w++ = '\0'; | |
254 | ++r; | |
f1f41a6c | 255 | v->safe_push (token_start); |
a95c0776 | 256 | token_start = w; |
257 | } | |
258 | if (*r == '\\' && r[1] == ',') | |
259 | { | |
260 | *w++ = ','; | |
261 | r += 2; | |
262 | } | |
263 | else | |
264 | *w++ = *r++; | |
265 | } | |
266 | if (*token_start != '\0') | |
f1f41a6c | 267 | v->safe_push (token_start); |
a95c0776 | 268 | |
f1f41a6c | 269 | *pvec = v; |
a95c0776 | 270 | } |
271 | ||
f3f006ad | 272 | /* Initialize OPTS and OPTS_SET before using them in parsing options. */ |
273 | ||
274 | void | |
275 | init_options_struct (struct gcc_options *opts, struct gcc_options *opts_set) | |
276 | { | |
56f280c4 | 277 | size_t num_params = get_num_compiler_params (); |
278 | ||
ba30d337 | 279 | gcc_obstack_init (&opts_obstack); |
280 | ||
f3f006ad | 281 | *opts = global_options_init; |
55310327 | 282 | |
283 | if (opts_set) | |
284 | memset (opts_set, 0, sizeof (*opts_set)); | |
f3f006ad | 285 | |
56f280c4 | 286 | opts->x_param_values = XNEWVEC (int, num_params); |
55310327 | 287 | |
288 | if (opts_set) | |
289 | opts_set->x_param_values = XCNEWVEC (int, num_params); | |
290 | ||
56f280c4 | 291 | init_param_values (opts->x_param_values); |
292 | ||
f3f006ad | 293 | /* Initialize whether `char' is signed. */ |
294 | opts->x_flag_signed_char = DEFAULT_SIGNED_CHAR; | |
295 | /* Set this to a special "uninitialized" value. The actual default | |
296 | is set after target options have been processed. */ | |
297 | opts->x_flag_short_enums = 2; | |
298 | ||
218e3e4e | 299 | /* Initialize target_flags before default_options_optimization |
f3f006ad | 300 | so the latter can modify it. */ |
218e3e4e | 301 | opts->x_target_flags = targetm_common.default_target_flags; |
f3f006ad | 302 | |
303 | /* Some targets have ABI-specified unwind tables. */ | |
218e3e4e | 304 | opts->x_flag_unwind_tables = targetm_common.unwind_tables_default; |
cc07c468 | 305 | |
306 | /* Some targets have other target-specific initialization. */ | |
218e3e4e | 307 | targetm_common.option_init_struct (opts); |
f3f006ad | 308 | } |
309 | ||
c17f64cc | 310 | /* If indicated by the optimization level LEVEL (-Os if SIZE is set, |
9b0d2865 | 311 | -Ofast if FAST is set, -Og if DEBUG is set), apply the option DEFAULT_OPT |
312 | to OPTS and OPTS_SET, diagnostic context DC, location LOC, with language | |
313 | mask LANG_MASK and option handlers HANDLERS. */ | |
c17f64cc | 314 | |
315 | static void | |
316 | maybe_default_option (struct gcc_options *opts, | |
317 | struct gcc_options *opts_set, | |
318 | const struct default_options *default_opt, | |
9b0d2865 | 319 | int level, bool size, bool fast, bool debug, |
c17f64cc | 320 | unsigned int lang_mask, |
321 | const struct cl_option_handlers *handlers, | |
3c6c0e40 | 322 | location_t loc, |
c17f64cc | 323 | diagnostic_context *dc) |
324 | { | |
325 | const struct cl_option *option = &cl_options[default_opt->opt_index]; | |
326 | bool enabled; | |
327 | ||
328 | if (size) | |
329 | gcc_assert (level == 2); | |
330 | if (fast) | |
331 | gcc_assert (level == 3); | |
9b0d2865 | 332 | if (debug) |
333 | gcc_assert (level == 1); | |
c17f64cc | 334 | |
335 | switch (default_opt->levels) | |
336 | { | |
337 | case OPT_LEVELS_ALL: | |
338 | enabled = true; | |
339 | break; | |
340 | ||
341 | case OPT_LEVELS_0_ONLY: | |
342 | enabled = (level == 0); | |
343 | break; | |
344 | ||
345 | case OPT_LEVELS_1_PLUS: | |
346 | enabled = (level >= 1); | |
347 | break; | |
348 | ||
349 | case OPT_LEVELS_1_PLUS_SPEED_ONLY: | |
9b0d2865 | 350 | enabled = (level >= 1 && !size && !debug); |
351 | break; | |
352 | ||
353 | case OPT_LEVELS_1_PLUS_NOT_DEBUG: | |
354 | enabled = (level >= 1 && !debug); | |
c17f64cc | 355 | break; |
356 | ||
357 | case OPT_LEVELS_2_PLUS: | |
358 | enabled = (level >= 2); | |
359 | break; | |
360 | ||
361 | case OPT_LEVELS_2_PLUS_SPEED_ONLY: | |
9b0d2865 | 362 | enabled = (level >= 2 && !size && !debug); |
c17f64cc | 363 | break; |
364 | ||
365 | case OPT_LEVELS_3_PLUS: | |
366 | enabled = (level >= 3); | |
367 | break; | |
368 | ||
369 | case OPT_LEVELS_3_PLUS_AND_SIZE: | |
370 | enabled = (level >= 3 || size); | |
371 | break; | |
372 | ||
373 | case OPT_LEVELS_SIZE: | |
374 | enabled = size; | |
375 | break; | |
376 | ||
377 | case OPT_LEVELS_FAST: | |
378 | enabled = fast; | |
379 | break; | |
380 | ||
381 | case OPT_LEVELS_NONE: | |
382 | default: | |
383 | gcc_unreachable (); | |
384 | } | |
385 | ||
386 | if (enabled) | |
387 | handle_generated_option (opts, opts_set, default_opt->opt_index, | |
388 | default_opt->arg, default_opt->value, | |
3c6c0e40 | 389 | lang_mask, DK_UNSPECIFIED, loc, |
390 | handlers, dc); | |
c17f64cc | 391 | else if (default_opt->arg == NULL |
ec840af4 | 392 | && !option->cl_reject_negative) |
c17f64cc | 393 | handle_generated_option (opts, opts_set, default_opt->opt_index, |
394 | default_opt->arg, !default_opt->value, | |
3c6c0e40 | 395 | lang_mask, DK_UNSPECIFIED, loc, |
396 | handlers, dc); | |
c17f64cc | 397 | } |
398 | ||
399 | /* As indicated by the optimization level LEVEL (-Os if SIZE is set, | |
400 | -Ofast if FAST is set), apply the options in array DEFAULT_OPTS to | |
3c6c0e40 | 401 | OPTS and OPTS_SET, diagnostic context DC, location LOC, with |
402 | language mask LANG_MASK and option handlers HANDLERS. */ | |
c17f64cc | 403 | |
404 | static void | |
405 | maybe_default_options (struct gcc_options *opts, | |
406 | struct gcc_options *opts_set, | |
407 | const struct default_options *default_opts, | |
9b0d2865 | 408 | int level, bool size, bool fast, bool debug, |
c17f64cc | 409 | unsigned int lang_mask, |
410 | const struct cl_option_handlers *handlers, | |
3c6c0e40 | 411 | location_t loc, |
c17f64cc | 412 | diagnostic_context *dc) |
413 | { | |
414 | size_t i; | |
415 | ||
416 | for (i = 0; default_opts[i].levels != OPT_LEVELS_NONE; i++) | |
417 | maybe_default_option (opts, opts_set, &default_opts[i], | |
9b0d2865 | 418 | level, size, fast, debug, |
419 | lang_mask, handlers, loc, dc); | |
c17f64cc | 420 | } |
421 | ||
422 | /* Table of options enabled by default at different levels. */ | |
423 | ||
424 | static const struct default_options default_options_table[] = | |
425 | { | |
426 | /* -O1 optimizations. */ | |
427 | { OPT_LEVELS_1_PLUS, OPT_fdefer_pop, NULL, 1 }, | |
428 | #ifdef DELAY_SLOTS | |
429 | { OPT_LEVELS_1_PLUS, OPT_fdelayed_branch, NULL, 1 }, | |
430 | #endif | |
431 | { OPT_LEVELS_1_PLUS, OPT_fguess_branch_probability, NULL, 1 }, | |
432 | { OPT_LEVELS_1_PLUS, OPT_fcprop_registers, NULL, 1 }, | |
433 | { OPT_LEVELS_1_PLUS, OPT_fforward_propagate, NULL, 1 }, | |
e87649a3 | 434 | { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fif_conversion, NULL, 1 }, |
435 | { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fif_conversion2, NULL, 1 }, | |
c17f64cc | 436 | { OPT_LEVELS_1_PLUS, OPT_fipa_pure_const, NULL, 1 }, |
437 | { OPT_LEVELS_1_PLUS, OPT_fipa_reference, NULL, 1 }, | |
438 | { OPT_LEVELS_1_PLUS, OPT_fipa_profile, NULL, 1 }, | |
439 | { OPT_LEVELS_1_PLUS, OPT_fmerge_constants, NULL, 1 }, | |
1f021f97 | 440 | { OPT_LEVELS_1_PLUS, OPT_fshrink_wrap, NULL, 1 }, |
c17f64cc | 441 | { OPT_LEVELS_1_PLUS, OPT_fsplit_wide_types, NULL, 1 }, |
442 | { OPT_LEVELS_1_PLUS, OPT_ftree_ccp, NULL, 1 }, | |
443 | { OPT_LEVELS_1_PLUS, OPT_ftree_bit_ccp, NULL, 1 }, | |
444 | { OPT_LEVELS_1_PLUS, OPT_ftree_dce, NULL, 1 }, | |
445 | { OPT_LEVELS_1_PLUS, OPT_ftree_dominator_opts, NULL, 1 }, | |
446 | { OPT_LEVELS_1_PLUS, OPT_ftree_dse, NULL, 1 }, | |
447 | { OPT_LEVELS_1_PLUS, OPT_ftree_ter, NULL, 1 }, | |
9b0d2865 | 448 | { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_sra, NULL, 1 }, |
c17f64cc | 449 | { OPT_LEVELS_1_PLUS, OPT_ftree_copyrename, NULL, 1 }, |
450 | { OPT_LEVELS_1_PLUS, OPT_ftree_fre, NULL, 1 }, | |
451 | { OPT_LEVELS_1_PLUS, OPT_ftree_copy_prop, NULL, 1 }, | |
452 | { OPT_LEVELS_1_PLUS, OPT_ftree_sink, NULL, 1 }, | |
453 | { OPT_LEVELS_1_PLUS, OPT_ftree_ch, NULL, 1 }, | |
454 | { OPT_LEVELS_1_PLUS, OPT_fcombine_stack_adjustments, NULL, 1 }, | |
a50372fe | 455 | { OPT_LEVELS_1_PLUS, OPT_fcompare_elim, NULL, 1 }, |
6de100ef | 456 | { OPT_LEVELS_1_PLUS, OPT_ftree_slsr, NULL, 1 }, |
1941e89d | 457 | { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fbranch_count_reg, NULL, 1 }, |
458 | { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fmove_loop_invariants, NULL, 1 }, | |
459 | { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_pta, NULL, 1 }, | |
c17f64cc | 460 | |
461 | /* -O2 optimizations. */ | |
462 | { OPT_LEVELS_2_PLUS, OPT_finline_small_functions, NULL, 1 }, | |
463 | { OPT_LEVELS_2_PLUS, OPT_findirect_inlining, NULL, 1 }, | |
464 | { OPT_LEVELS_2_PLUS, OPT_fpartial_inlining, NULL, 1 }, | |
465 | { OPT_LEVELS_2_PLUS, OPT_fthread_jumps, NULL, 1 }, | |
466 | { OPT_LEVELS_2_PLUS, OPT_fcrossjumping, NULL, 1 }, | |
467 | { OPT_LEVELS_2_PLUS, OPT_foptimize_sibling_calls, NULL, 1 }, | |
468 | { OPT_LEVELS_2_PLUS, OPT_fcse_follow_jumps, NULL, 1 }, | |
469 | { OPT_LEVELS_2_PLUS, OPT_fgcse, NULL, 1 }, | |
470 | { OPT_LEVELS_2_PLUS, OPT_fexpensive_optimizations, NULL, 1 }, | |
471 | { OPT_LEVELS_2_PLUS, OPT_frerun_cse_after_loop, NULL, 1 }, | |
472 | { OPT_LEVELS_2_PLUS, OPT_fcaller_saves, NULL, 1 }, | |
473 | { OPT_LEVELS_2_PLUS, OPT_fpeephole2, NULL, 1 }, | |
474 | #ifdef INSN_SCHEDULING | |
475 | /* Only run the pre-regalloc scheduling pass if optimizing for speed. */ | |
476 | { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_fschedule_insns, NULL, 1 }, | |
477 | { OPT_LEVELS_2_PLUS, OPT_fschedule_insns2, NULL, 1 }, | |
478 | #endif | |
c17f64cc | 479 | { OPT_LEVELS_2_PLUS, OPT_fstrict_aliasing, NULL, 1 }, |
480 | { OPT_LEVELS_2_PLUS, OPT_fstrict_overflow, NULL, 1 }, | |
481 | { OPT_LEVELS_2_PLUS, OPT_freorder_blocks, NULL, 1 }, | |
482 | { OPT_LEVELS_2_PLUS, OPT_freorder_functions, NULL, 1 }, | |
483 | { OPT_LEVELS_2_PLUS, OPT_ftree_vrp, NULL, 1 }, | |
484 | { OPT_LEVELS_2_PLUS, OPT_ftree_builtin_call_dce, NULL, 1 }, | |
485 | { OPT_LEVELS_2_PLUS, OPT_ftree_pre, NULL, 1 }, | |
486 | { OPT_LEVELS_2_PLUS, OPT_ftree_switch_conversion, NULL, 1 }, | |
487 | { OPT_LEVELS_2_PLUS, OPT_fipa_cp, NULL, 1 }, | |
16358a63 | 488 | { OPT_LEVELS_2_PLUS, OPT_fdevirtualize, NULL, 1 }, |
84f6cc40 | 489 | { OPT_LEVELS_2_PLUS, OPT_fdevirtualize_speculatively, NULL, 1 }, |
c17f64cc | 490 | { OPT_LEVELS_2_PLUS, OPT_fipa_sra, NULL, 1 }, |
491 | { OPT_LEVELS_2_PLUS, OPT_falign_loops, NULL, 1 }, | |
492 | { OPT_LEVELS_2_PLUS, OPT_falign_jumps, NULL, 1 }, | |
493 | { OPT_LEVELS_2_PLUS, OPT_falign_labels, NULL, 1 }, | |
494 | { OPT_LEVELS_2_PLUS, OPT_falign_functions, NULL, 1 }, | |
51385f30 | 495 | { OPT_LEVELS_2_PLUS, OPT_ftree_tail_merge, NULL, 1 }, |
1dbf9bd1 | 496 | { OPT_LEVELS_2_PLUS, OPT_fvect_cost_model_, NULL, VECT_COST_MODEL_CHEAP }, |
0210d998 | 497 | { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_foptimize_strlen, NULL, 1 }, |
239e9670 | 498 | { OPT_LEVELS_2_PLUS, OPT_fhoist_adjacent_loads, NULL, 1 }, |
30b10261 | 499 | { OPT_LEVELS_2_PLUS, OPT_fisolate_erroneous_paths_dereference, NULL, 1 }, |
c17f64cc | 500 | |
501 | /* -O3 optimizations. */ | |
502 | { OPT_LEVELS_3_PLUS, OPT_ftree_loop_distribute_patterns, NULL, 1 }, | |
503 | { OPT_LEVELS_3_PLUS, OPT_fpredictive_commoning, NULL, 1 }, | |
504 | /* Inlining of functions reducing size is a good idea with -Os | |
505 | regardless of them being declared inline. */ | |
506 | { OPT_LEVELS_3_PLUS_AND_SIZE, OPT_finline_functions, NULL, 1 }, | |
9b0d2865 | 507 | { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_finline_functions_called_once, NULL, 1 }, |
c17f64cc | 508 | { OPT_LEVELS_3_PLUS, OPT_funswitch_loops, NULL, 1 }, |
509 | { OPT_LEVELS_3_PLUS, OPT_fgcse_after_reload, NULL, 1 }, | |
043115ec | 510 | { OPT_LEVELS_3_PLUS, OPT_ftree_loop_vectorize, NULL, 1 }, |
511 | { OPT_LEVELS_3_PLUS, OPT_ftree_slp_vectorize, NULL, 1 }, | |
1dbf9bd1 | 512 | { OPT_LEVELS_3_PLUS, OPT_fvect_cost_model_, NULL, VECT_COST_MODEL_DYNAMIC }, |
c17f64cc | 513 | { OPT_LEVELS_3_PLUS, OPT_fipa_cp_clone, NULL, 1 }, |
0f9b384d | 514 | { OPT_LEVELS_3_PLUS, OPT_ftree_partial_pre, NULL, 1 }, |
c17f64cc | 515 | |
516 | /* -Ofast adds optimizations to -O3. */ | |
517 | { OPT_LEVELS_FAST, OPT_ffast_math, NULL, 1 }, | |
518 | ||
519 | { OPT_LEVELS_NONE, 0, NULL, 0 } | |
520 | }; | |
521 | ||
f3f006ad | 522 | /* Default the options in OPTS and OPTS_SET based on the optimization |
523 | settings in DECODED_OPTIONS and DECODED_OPTIONS_COUNT. */ | |
79396169 | 524 | void |
f3f006ad | 525 | default_options_optimization (struct gcc_options *opts, |
526 | struct gcc_options *opts_set, | |
527 | struct cl_decoded_option *decoded_options, | |
c17f64cc | 528 | unsigned int decoded_options_count, |
3c6c0e40 | 529 | location_t loc, |
c17f64cc | 530 | unsigned int lang_mask, |
531 | const struct cl_option_handlers *handlers, | |
532 | diagnostic_context *dc) | |
f3f006ad | 533 | { |
534 | unsigned int i; | |
46f8e3b0 | 535 | int opt2; |
f5d971c5 | 536 | |
537 | /* Scan to see what optimization level has been specified. That will | |
538 | determine the default value of many flags. */ | |
f3f006ad | 539 | for (i = 1; i < decoded_options_count; i++) |
f5d971c5 | 540 | { |
f3f006ad | 541 | struct cl_decoded_option *opt = &decoded_options[i]; |
615ef0bb | 542 | switch (opt->opt_index) |
f5d971c5 | 543 | { |
615ef0bb | 544 | case OPT_O: |
545 | if (*opt->arg == '\0') | |
1ebc0b9f | 546 | { |
c17f64cc | 547 | opts->x_optimize = 1; |
548 | opts->x_optimize_size = 0; | |
d2807aa3 | 549 | opts->x_optimize_fast = 0; |
9b0d2865 | 550 | opts->x_optimize_debug = 0; |
f5d971c5 | 551 | } |
552 | else | |
553 | { | |
615ef0bb | 554 | const int optimize_val = integral_argument (opt->arg); |
555 | if (optimize_val == -1) | |
9448cf4a | 556 | error_at (loc, "argument to %<-O%> should be a non-negative " |
557 | "integer, %<g%>, %<s%> or %<fast%>"); | |
615ef0bb | 558 | else |
f5d971c5 | 559 | { |
c17f64cc | 560 | opts->x_optimize = optimize_val; |
561 | if ((unsigned int) opts->x_optimize > 255) | |
562 | opts->x_optimize = 255; | |
563 | opts->x_optimize_size = 0; | |
d2807aa3 | 564 | opts->x_optimize_fast = 0; |
9b0d2865 | 565 | opts->x_optimize_debug = 0; |
f5d971c5 | 566 | } |
567 | } | |
615ef0bb | 568 | break; |
569 | ||
570 | case OPT_Os: | |
c17f64cc | 571 | opts->x_optimize_size = 1; |
615ef0bb | 572 | |
573 | /* Optimizing for size forces optimize to be 2. */ | |
c17f64cc | 574 | opts->x_optimize = 2; |
d2807aa3 | 575 | opts->x_optimize_fast = 0; |
9b0d2865 | 576 | opts->x_optimize_debug = 0; |
615ef0bb | 577 | break; |
578 | ||
579 | case OPT_Ofast: | |
580 | /* -Ofast only adds flags to -O3. */ | |
c17f64cc | 581 | opts->x_optimize_size = 0; |
582 | opts->x_optimize = 3; | |
d2807aa3 | 583 | opts->x_optimize_fast = 1; |
9b0d2865 | 584 | opts->x_optimize_debug = 0; |
585 | break; | |
586 | ||
587 | case OPT_Og: | |
588 | /* -Og selects optimization level 1. */ | |
589 | opts->x_optimize_size = 0; | |
590 | opts->x_optimize = 1; | |
591 | opts->x_optimize_fast = 0; | |
592 | opts->x_optimize_debug = 1; | |
615ef0bb | 593 | break; |
594 | ||
595 | default: | |
596 | /* Ignore other options in this prescan. */ | |
597 | break; | |
f5d971c5 | 598 | } |
599 | } | |
48e1416a | 600 | |
c17f64cc | 601 | maybe_default_options (opts, opts_set, default_options_table, |
602 | opts->x_optimize, opts->x_optimize_size, | |
9b0d2865 | 603 | opts->x_optimize_fast, opts->x_optimize_debug, |
604 | lang_mask, handlers, loc, dc); | |
c17f64cc | 605 | |
606 | /* -O2 param settings. */ | |
607 | opt2 = (opts->x_optimize >= 2); | |
523a88b0 | 608 | |
46f8e3b0 | 609 | /* Track fields in field-sensitive alias analysis. */ |
56f280c4 | 610 | maybe_set_param_value |
611 | (PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE, | |
612 | opt2 ? 100 : default_param_value (PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE), | |
613 | opts->x_param_values, opts_set->x_param_values); | |
c227f8de | 614 | |
86482d6b | 615 | /* For -O1 only do loop invariant motion for very small loops. */ |
56f280c4 | 616 | maybe_set_param_value |
617 | (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP, | |
618 | opt2 ? default_param_value (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP) : 1000, | |
619 | opts->x_param_values, opts_set->x_param_values); | |
86482d6b | 620 | |
c17f64cc | 621 | if (opts->x_optimize_size) |
622 | /* We want to crossjump as much as possible. */ | |
623 | maybe_set_param_value (PARAM_MIN_CROSSJUMP_INSNS, 1, | |
624 | opts->x_param_values, opts_set->x_param_values); | |
46f8e3b0 | 625 | else |
686e2769 | 626 | maybe_set_param_value (PARAM_MIN_CROSSJUMP_INSNS, |
56f280c4 | 627 | default_param_value (PARAM_MIN_CROSSJUMP_INSNS), |
628 | opts->x_param_values, opts_set->x_param_values); | |
8ba44f35 | 629 | |
f3f006ad | 630 | /* Allow default optimizations to be specified on a per-machine basis. */ |
c17f64cc | 631 | maybe_default_options (opts, opts_set, |
218e3e4e | 632 | targetm_common.option_optimization_table, |
c17f64cc | 633 | opts->x_optimize, opts->x_optimize_size, |
9b0d2865 | 634 | opts->x_optimize_fast, opts->x_optimize_debug, |
635 | lang_mask, handlers, loc, dc); | |
f3f006ad | 636 | } |
637 | ||
9faf44d6 | 638 | /* After all options at LOC have been read into OPTS and OPTS_SET, |
639 | finalize settings of those options and diagnose incompatible | |
f3f006ad | 640 | combinations. */ |
79396169 | 641 | void |
9faf44d6 | 642 | finish_options (struct gcc_options *opts, struct gcc_options *opts_set, |
643 | location_t loc) | |
f3f006ad | 644 | { |
f3f006ad | 645 | enum unwind_info_type ui_except; |
646 | ||
6aaca0b4 | 647 | if (opts->x_dump_base_name |
648 | && ! IS_ABSOLUTE_PATH (opts->x_dump_base_name) | |
649 | && ! opts->x_dump_base_name_prefixed) | |
b2d31ed6 | 650 | { |
6bd9d862 | 651 | /* First try to make OPTS->X_DUMP_BASE_NAME relative to the |
652 | OPTS->X_DUMP_DIR_NAME directory. Then try to make | |
653 | OPTS->X_DUMP_BASE_NAME relative to the OPTS->X_AUX_BASE_NAME | |
654 | directory, typically the directory to contain the object | |
655 | file. */ | |
656 | if (opts->x_dump_dir_name) | |
ba30d337 | 657 | opts->x_dump_base_name = opts_concat (opts->x_dump_dir_name, |
658 | opts->x_dump_base_name, NULL); | |
ad905e43 | 659 | else if (opts->x_aux_base_name |
660 | && strcmp (opts->x_aux_base_name, HOST_BIT_BUCKET) != 0) | |
b2d31ed6 | 661 | { |
50ca7c37 | 662 | const char *aux_base; |
663 | ||
6bd9d862 | 664 | base_of_path (opts->x_aux_base_name, &aux_base); |
665 | if (opts->x_aux_base_name != aux_base) | |
50ca7c37 | 666 | { |
6bd9d862 | 667 | int dir_len = aux_base - opts->x_aux_base_name; |
ba30d337 | 668 | char *new_dump_base_name |
669 | = XOBNEWVEC (&opts_obstack, char, | |
670 | strlen (opts->x_dump_base_name) + dir_len + 1); | |
50ca7c37 | 671 | |
6bd9d862 | 672 | /* Copy directory component from OPTS->X_AUX_BASE_NAME. */ |
673 | memcpy (new_dump_base_name, opts->x_aux_base_name, dir_len); | |
674 | /* Append existing OPTS->X_DUMP_BASE_NAME. */ | |
675 | strcpy (new_dump_base_name + dir_len, opts->x_dump_base_name); | |
676 | opts->x_dump_base_name = new_dump_base_name; | |
50ca7c37 | 677 | } |
b2d31ed6 | 678 | } |
6aaca0b4 | 679 | opts->x_dump_base_name_prefixed = true; |
b2d31ed6 | 680 | } |
681 | ||
91bfa5c6 | 682 | /* Handle related options for unit-at-a-time, toplevel-reorder, and |
683 | section-anchors. */ | |
6bd9d862 | 684 | if (!opts->x_flag_unit_at_a_time) |
cd8171dd | 685 | { |
6bd9d862 | 686 | if (opts->x_flag_section_anchors && opts_set->x_flag_section_anchors) |
9faf44d6 | 687 | error_at (loc, "section anchors must be disabled when unit-at-a-time " |
688 | "is disabled"); | |
6bd9d862 | 689 | opts->x_flag_section_anchors = 0; |
690 | if (opts->x_flag_toplevel_reorder == 1) | |
9faf44d6 | 691 | error_at (loc, "toplevel reorder must be disabled when unit-at-a-time " |
692 | "is disabled"); | |
6bd9d862 | 693 | opts->x_flag_toplevel_reorder = 0; |
cd8171dd | 694 | } |
43d60d64 | 695 | |
4ca5a717 | 696 | if (opts->x_flag_tm && opts->x_flag_non_call_exceptions) |
697 | sorry ("transactional memory is not supported with non-call exceptions"); | |
698 | ||
a227c9ef | 699 | /* Unless the user has asked for section anchors, we disable toplevel |
700 | reordering at -O0 to disable transformations that might be surprising | |
701 | to end users and to get -fno-toplevel-reorder tested. */ | |
9faf44d6 | 702 | if (!opts->x_optimize |
6bd9d862 | 703 | && opts->x_flag_toplevel_reorder == 2 |
704 | && !(opts->x_flag_section_anchors && opts_set->x_flag_section_anchors)) | |
91bfa5c6 | 705 | { |
6bd9d862 | 706 | opts->x_flag_toplevel_reorder = 0; |
707 | opts->x_flag_section_anchors = 0; | |
91bfa5c6 | 708 | } |
6bd9d862 | 709 | if (!opts->x_flag_toplevel_reorder) |
cd8171dd | 710 | { |
6bd9d862 | 711 | if (opts->x_flag_section_anchors && opts_set->x_flag_section_anchors) |
9faf44d6 | 712 | error_at (loc, "section anchors must be disabled when toplevel reorder" |
713 | " is disabled"); | |
6bd9d862 | 714 | opts->x_flag_section_anchors = 0; |
cd8171dd | 715 | } |
716 | ||
9faf44d6 | 717 | if (!opts->x_flag_opts_finished) |
46f8e3b0 | 718 | { |
6bd9d862 | 719 | if (opts->x_flag_pie) |
720 | opts->x_flag_pic = opts->x_flag_pie; | |
721 | if (opts->x_flag_pic && !opts->x_flag_pie) | |
722 | opts->x_flag_shlib = 1; | |
ae6f03e2 | 723 | opts->x_flag_opts_finished = true; |
46f8e3b0 | 724 | } |
f5d971c5 | 725 | |
9faf44d6 | 726 | if (opts->x_optimize == 0) |
f5d971c5 | 727 | { |
728 | /* Inlining does not work if not optimizing, | |
729 | so force it not to be done. */ | |
6bd9d862 | 730 | opts->x_warn_inline = 0; |
731 | opts->x_flag_no_inline = 1; | |
f5d971c5 | 732 | } |
733 | ||
4f18499c | 734 | /* The optimization to partition hot and cold basic blocks into separate |
735 | sections of the .o and executable files does not work (currently) | |
8de492c3 | 736 | with exception handling. This is because there is no support for |
6bd9d862 | 737 | generating unwind info. If opts->x_flag_exceptions is turned on |
738 | we need to turn off the partitioning optimization. */ | |
4f18499c | 739 | |
218e3e4e | 740 | ui_except = targetm_common.except_unwind_info (opts); |
cc7d6aed | 741 | |
6bd9d862 | 742 | if (opts->x_flag_exceptions |
743 | && opts->x_flag_reorder_blocks_and_partition | |
8ad0b530 | 744 | && (ui_except == UI_SJLJ || ui_except >= UI_TARGET)) |
4f18499c | 745 | { |
e4bb2b6e | 746 | if (opts_set->x_flag_reorder_blocks_and_partition) |
747 | inform (loc, | |
748 | "-freorder-blocks-and-partition does not work " | |
749 | "with exceptions on this architecture"); | |
6bd9d862 | 750 | opts->x_flag_reorder_blocks_and_partition = 0; |
751 | opts->x_flag_reorder_blocks = 1; | |
4f18499c | 752 | } |
4d0e931f | 753 | |
8de492c3 | 754 | /* If user requested unwind info, then turn off the partitioning |
755 | optimization. */ | |
756 | ||
6bd9d862 | 757 | if (opts->x_flag_unwind_tables |
218e3e4e | 758 | && !targetm_common.unwind_tables_default |
6bd9d862 | 759 | && opts->x_flag_reorder_blocks_and_partition |
8ad0b530 | 760 | && (ui_except == UI_SJLJ || ui_except >= UI_TARGET)) |
8de492c3 | 761 | { |
e4bb2b6e | 762 | if (opts_set->x_flag_reorder_blocks_and_partition) |
763 | inform (loc, | |
764 | "-freorder-blocks-and-partition does not support " | |
765 | "unwind info on this architecture"); | |
6bd9d862 | 766 | opts->x_flag_reorder_blocks_and_partition = 0; |
767 | opts->x_flag_reorder_blocks = 1; | |
8de492c3 | 768 | } |
769 | ||
770 | /* If the target requested unwind info, then turn off the partitioning | |
771 | optimization with a different message. Likewise, if the target does not | |
772 | support named sections. */ | |
773 | ||
6bd9d862 | 774 | if (opts->x_flag_reorder_blocks_and_partition |
218e3e4e | 775 | && (!targetm_common.have_named_sections |
6bd9d862 | 776 | || (opts->x_flag_unwind_tables |
218e3e4e | 777 | && targetm_common.unwind_tables_default |
8ad0b530 | 778 | && (ui_except == UI_SJLJ || ui_except >= UI_TARGET)))) |
4d0e931f | 779 | { |
e4bb2b6e | 780 | if (opts_set->x_flag_reorder_blocks_and_partition) |
781 | inform (loc, | |
782 | "-freorder-blocks-and-partition does not work " | |
783 | "on this architecture"); | |
6bd9d862 | 784 | opts->x_flag_reorder_blocks_and_partition = 0; |
785 | opts->x_flag_reorder_blocks = 1; | |
4d0e931f | 786 | } |
46f8e3b0 | 787 | |
5525a5c1 | 788 | if (opts->x_flag_reorder_blocks_and_partition |
789 | && !opts_set->x_flag_reorder_functions) | |
790 | opts->x_flag_reorder_functions = 1; | |
791 | ||
e1ab7874 | 792 | /* Pipelining of outer loops is only possible when general pipelining |
793 | capabilities are requested. */ | |
6bd9d862 | 794 | if (!opts->x_flag_sel_sched_pipelining) |
795 | opts->x_flag_sel_sched_pipelining_outer_loops = 0; | |
e1ab7874 | 796 | |
6bd9d862 | 797 | if (opts->x_flag_conserve_stack) |
c231842d | 798 | { |
56f280c4 | 799 | maybe_set_param_value (PARAM_LARGE_STACK_FRAME, 100, |
800 | opts->x_param_values, opts_set->x_param_values); | |
801 | maybe_set_param_value (PARAM_STACK_FRAME_GROWTH, 40, | |
802 | opts->x_param_values, opts_set->x_param_values); | |
c231842d | 803 | } |
804 | ||
cbcf2791 | 805 | if (opts->x_flag_lto) |
6756f4d2 | 806 | { |
807 | #ifdef ENABLE_LTO | |
6bd9d862 | 808 | opts->x_flag_generate_lto = 1; |
6756f4d2 | 809 | |
810 | /* When generating IL, do not operate in whole-program mode. | |
811 | Otherwise, symbols will be privatized too early, causing link | |
812 | errors later. */ | |
6bd9d862 | 813 | opts->x_flag_whole_program = 0; |
6756f4d2 | 814 | #else |
9faf44d6 | 815 | error_at (loc, "LTO support has not been enabled in this configuration"); |
6756f4d2 | 816 | #endif |
cef15d47 | 817 | if (!opts->x_flag_fat_lto_objects |
818 | && (!HAVE_LTO_PLUGIN | |
819 | || (opts_set->x_flag_use_linker_plugin | |
820 | && !opts->x_flag_use_linker_plugin))) | |
76eca1df | 821 | { |
822 | if (opts_set->x_flag_fat_lto_objects) | |
cef15d47 | 823 | error_at (loc, "-fno-fat-lto-objects are supported only with linker plugin"); |
76eca1df | 824 | opts->x_flag_fat_lto_objects = 1; |
825 | } | |
826 | } | |
6756f4d2 | 827 | |
6bd9d862 | 828 | /* We initialize opts->x_flag_split_stack to -1 so that targets can set a |
48b14f50 | 829 | default value if they choose based on other options. */ |
6bd9d862 | 830 | if (opts->x_flag_split_stack == -1) |
831 | opts->x_flag_split_stack = 0; | |
832 | else if (opts->x_flag_split_stack) | |
48b14f50 | 833 | { |
218e3e4e | 834 | if (!targetm_common.supports_split_stack (true, opts)) |
48b14f50 | 835 | { |
9faf44d6 | 836 | error_at (loc, "%<-fsplit-stack%> is not supported by " |
837 | "this compiler configuration"); | |
6bd9d862 | 838 | opts->x_flag_split_stack = 0; |
48b14f50 | 839 | } |
840 | } | |
ec611e12 | 841 | |
1dbf9bd1 | 842 | /* Tune vectorization related parametees according to cost model. */ |
843 | if (opts->x_flag_vect_cost_model == VECT_COST_MODEL_CHEAP) | |
844 | { | |
845 | maybe_set_param_value (PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS, | |
846 | 6, opts->x_param_values, opts_set->x_param_values); | |
847 | maybe_set_param_value (PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS, | |
848 | 0, opts->x_param_values, opts_set->x_param_values); | |
849 | maybe_set_param_value (PARAM_VECT_MAX_PEELING_FOR_ALIGNMENT, | |
850 | 0, opts->x_param_values, opts_set->x_param_values); | |
851 | } | |
852 | ||
ec611e12 | 853 | /* Set PARAM_MAX_STORES_TO_SINK to 0 if either vectorization or if-conversion |
854 | is disabled. */ | |
043115ec | 855 | if ((!opts->x_flag_tree_loop_vectorize && !opts->x_flag_tree_slp_vectorize) |
856 | || !opts->x_flag_tree_loop_if_convert) | |
ec611e12 | 857 | maybe_set_param_value (PARAM_MAX_STORES_TO_SINK, 0, |
858 | opts->x_param_values, opts_set->x_param_values); | |
20c2121a | 859 | |
b35329c7 | 860 | /* The -gsplit-dwarf option requires -gpubnames. */ |
861 | if (opts->x_dwarf_split_debug_info) | |
862 | opts->x_debug_generate_pub_sections = 1; | |
f5d971c5 | 863 | } |
864 | ||
87c75316 | 865 | #define LEFT_COLUMN 27 |
866 | ||
867 | /* Output ITEM, of length ITEM_WIDTH, in the left column, | |
868 | followed by word-wrapped HELP in a second column. */ | |
869 | static void | |
870 | wrap_help (const char *help, | |
871 | const char *item, | |
872 | unsigned int item_width, | |
873 | unsigned int columns) | |
874 | { | |
875 | unsigned int col_width = LEFT_COLUMN; | |
876 | unsigned int remaining, room, len; | |
877 | ||
878 | remaining = strlen (help); | |
879 | ||
880 | do | |
881 | { | |
882 | room = columns - 3 - MAX (col_width, item_width); | |
883 | if (room > columns) | |
884 | room = 0; | |
885 | len = remaining; | |
886 | ||
887 | if (room < len) | |
888 | { | |
889 | unsigned int i; | |
890 | ||
891 | for (i = 0; help[i]; i++) | |
892 | { | |
893 | if (i >= room && len != remaining) | |
894 | break; | |
895 | if (help[i] == ' ') | |
896 | len = i; | |
897 | else if ((help[i] == '-' || help[i] == '/') | |
898 | && help[i + 1] != ' ' | |
899 | && i > 0 && ISALPHA (help[i - 1])) | |
900 | len = i + 1; | |
901 | } | |
902 | } | |
903 | ||
9af5ce0c | 904 | printf (" %-*.*s %.*s\n", col_width, item_width, item, len, help); |
87c75316 | 905 | item_width = 0; |
906 | while (help[len] == ' ') | |
907 | len++; | |
908 | help += len; | |
909 | remaining -= len; | |
910 | } | |
911 | while (remaining); | |
912 | } | |
913 | ||
914 | /* Print help for a specific front-end, etc. */ | |
915 | static void | |
916 | print_filtered_help (unsigned int include_flags, | |
917 | unsigned int exclude_flags, | |
918 | unsigned int any_flags, | |
cc4fa57a | 919 | unsigned int columns, |
d62a5950 | 920 | struct gcc_options *opts, |
921 | unsigned int lang_mask) | |
87c75316 | 922 | { |
923 | unsigned int i; | |
924 | const char *help; | |
87c75316 | 925 | bool found = false; |
926 | bool displayed = false; | |
927 | ||
928 | if (include_flags == CL_PARAMS) | |
929 | { | |
930 | for (i = 0; i < LAST_PARAM; i++) | |
931 | { | |
932 | const char *param = compiler_params[i].option; | |
933 | ||
934 | help = compiler_params[i].help; | |
935 | if (help == NULL || *help == '\0') | |
936 | { | |
937 | if (exclude_flags & CL_UNDOCUMENTED) | |
938 | continue; | |
939 | help = undocumented_msg; | |
940 | } | |
941 | ||
942 | /* Get the translation. */ | |
943 | help = _(help); | |
944 | ||
945 | wrap_help (help, param, strlen (param), columns); | |
946 | } | |
947 | putchar ('\n'); | |
948 | return; | |
949 | } | |
950 | ||
9faf44d6 | 951 | if (!opts->x_help_printed) |
952 | opts->x_help_printed = XCNEWVAR (char, cl_options_count); | |
87c75316 | 953 | |
d62a5950 | 954 | if (!opts->x_help_enum_printed) |
955 | opts->x_help_enum_printed = XCNEWVAR (char, cl_enums_count); | |
956 | ||
87c75316 | 957 | for (i = 0; i < cl_options_count; i++) |
958 | { | |
cc4fa57a | 959 | char new_help[128]; |
87c75316 | 960 | const struct cl_option *option = cl_options + i; |
961 | unsigned int len; | |
962 | const char *opt; | |
963 | const char *tab; | |
964 | ||
965 | if (include_flags == 0 | |
966 | || ((option->flags & include_flags) != include_flags)) | |
967 | { | |
968 | if ((option->flags & any_flags) == 0) | |
969 | continue; | |
970 | } | |
971 | ||
972 | /* Skip unwanted switches. */ | |
973 | if ((option->flags & exclude_flags) != 0) | |
974 | continue; | |
975 | ||
e28aa114 | 976 | /* The driver currently prints its own help text. */ |
977 | if ((option->flags & CL_DRIVER) != 0 | |
978 | && (option->flags & (((1U << cl_lang_count) - 1) | |
979 | | CL_COMMON | CL_TARGET)) == 0) | |
980 | continue; | |
981 | ||
87c75316 | 982 | found = true; |
983 | /* Skip switches that have already been printed. */ | |
9faf44d6 | 984 | if (opts->x_help_printed[i]) |
87c75316 | 985 | continue; |
986 | ||
9faf44d6 | 987 | opts->x_help_printed[i] = true; |
87c75316 | 988 | |
989 | help = option->help; | |
990 | if (help == NULL) | |
991 | { | |
992 | if (exclude_flags & CL_UNDOCUMENTED) | |
993 | continue; | |
994 | help = undocumented_msg; | |
995 | } | |
996 | ||
997 | /* Get the translation. */ | |
998 | help = _(help); | |
999 | ||
1000 | /* Find the gap between the name of the | |
1001 | option and its descriptive text. */ | |
1002 | tab = strchr (help, '\t'); | |
1003 | if (tab) | |
1004 | { | |
1005 | len = tab - help; | |
1006 | opt = help; | |
1007 | help = tab + 1; | |
1008 | } | |
1009 | else | |
1010 | { | |
1011 | opt = option->opt_text; | |
1012 | len = strlen (opt); | |
1013 | } | |
1014 | ||
1015 | /* With the -Q option enabled we change the descriptive text associated | |
1016 | with an option to be an indication of its current setting. */ | |
90336809 | 1017 | if (!opts->x_quiet_flag) |
87c75316 | 1018 | { |
cc4fa57a | 1019 | void *flag_var = option_flag_var (i, opts); |
2c5d2e39 | 1020 | |
87c75316 | 1021 | if (len < (LEFT_COLUMN + 2)) |
1022 | strcpy (new_help, "\t\t"); | |
1023 | else | |
1024 | strcpy (new_help, "\t"); | |
1025 | ||
f0da0668 | 1026 | if (flag_var != NULL |
1027 | && option->var_type != CLVC_DEFER) | |
87c75316 | 1028 | { |
1029 | if (option->flags & CL_JOINED) | |
1030 | { | |
1031 | if (option->var_type == CLVC_STRING) | |
1032 | { | |
2c5d2e39 | 1033 | if (* (const char **) flag_var != NULL) |
87c75316 | 1034 | snprintf (new_help + strlen (new_help), |
1035 | sizeof (new_help) - strlen (new_help), | |
2c5d2e39 | 1036 | * (const char **) flag_var); |
87c75316 | 1037 | } |
d62a5950 | 1038 | else if (option->var_type == CLVC_ENUM) |
1039 | { | |
1040 | const struct cl_enum *e = &cl_enums[option->var_enum]; | |
1041 | int value; | |
1042 | const char *arg = NULL; | |
1043 | ||
1044 | value = e->get (flag_var); | |
1045 | enum_value_to_arg (e->values, &arg, value, lang_mask); | |
1046 | if (arg == NULL) | |
1047 | arg = _("[default]"); | |
1048 | snprintf (new_help + strlen (new_help), | |
1049 | sizeof (new_help) - strlen (new_help), | |
1050 | arg); | |
1051 | } | |
87c75316 | 1052 | else |
1053 | sprintf (new_help + strlen (new_help), | |
2c5d2e39 | 1054 | "%#x", * (int *) flag_var); |
87c75316 | 1055 | } |
1056 | else | |
cc4fa57a | 1057 | strcat (new_help, option_enabled (i, opts) |
87c75316 | 1058 | ? _("[enabled]") : _("[disabled]")); |
1059 | } | |
1060 | ||
1061 | help = new_help; | |
1062 | } | |
1063 | ||
1064 | wrap_help (help, opt, len, columns); | |
1065 | displayed = true; | |
d62a5950 | 1066 | |
1067 | if (option->var_type == CLVC_ENUM | |
1068 | && opts->x_help_enum_printed[option->var_enum] != 2) | |
1069 | opts->x_help_enum_printed[option->var_enum] = 1; | |
87c75316 | 1070 | } |
1071 | ||
1072 | if (! found) | |
86895a67 | 1073 | { |
1074 | unsigned int langs = include_flags & CL_LANG_ALL; | |
1075 | ||
1076 | if (langs == 0) | |
1077 | printf (_(" No options with the desired characteristics were found\n")); | |
1078 | else | |
1079 | { | |
1080 | unsigned int i; | |
1081 | ||
1082 | /* PR 31349: Tell the user how to see all of the | |
1083 | options supported by a specific front end. */ | |
1084 | for (i = 0; (1U << i) < CL_LANG_ALL; i ++) | |
1085 | if ((1U << i) & langs) | |
1086 | printf (_(" None found. Use --help=%s to show *all* the options supported by the %s front-end\n"), | |
1087 | lang_names[i], lang_names[i]); | |
1088 | } | |
48e1416a | 1089 | |
86895a67 | 1090 | } |
87c75316 | 1091 | else if (! displayed) |
1092 | printf (_(" All options with the desired characteristics have already been displayed\n")); | |
1093 | ||
1094 | putchar ('\n'); | |
d62a5950 | 1095 | |
1096 | /* Print details of enumerated option arguments, if those | |
1097 | enumerations have help text headings provided. If no help text | |
1098 | is provided, presume that the possible values are listed in the | |
1099 | help text for the relevant options. */ | |
1100 | for (i = 0; i < cl_enums_count; i++) | |
1101 | { | |
1102 | unsigned int j, pos; | |
1103 | ||
1104 | if (opts->x_help_enum_printed[i] != 1) | |
1105 | continue; | |
1106 | if (cl_enums[i].help == NULL) | |
1107 | continue; | |
1108 | printf (" %s\n ", _(cl_enums[i].help)); | |
1109 | pos = 4; | |
1110 | for (j = 0; cl_enums[i].values[j].arg != NULL; j++) | |
1111 | { | |
1112 | unsigned int len = strlen (cl_enums[i].values[j].arg); | |
1113 | ||
1114 | if (pos > 4 && pos + 1 + len <= columns) | |
1115 | { | |
1116 | printf (" %s", cl_enums[i].values[j].arg); | |
1117 | pos += 1 + len; | |
1118 | } | |
1119 | else | |
1120 | { | |
1121 | if (pos > 4) | |
1122 | { | |
1123 | printf ("\n "); | |
1124 | pos = 4; | |
1125 | } | |
1126 | printf ("%s", cl_enums[i].values[j].arg); | |
1127 | pos += len; | |
1128 | } | |
1129 | } | |
1130 | printf ("\n\n"); | |
1131 | opts->x_help_enum_printed[i] = 2; | |
1132 | } | |
87c75316 | 1133 | } |
1134 | ||
1135 | /* Display help for a specified type of option. | |
1136 | The options must have ALL of the INCLUDE_FLAGS set | |
1137 | ANY of the flags in the ANY_FLAGS set | |
cc4fa57a | 1138 | and NONE of the EXCLUDE_FLAGS set. The current option state is in |
d62a5950 | 1139 | OPTS; LANG_MASK is used for interpreting enumerated option state. */ |
87c75316 | 1140 | static void |
1141 | print_specific_help (unsigned int include_flags, | |
1142 | unsigned int exclude_flags, | |
cc4fa57a | 1143 | unsigned int any_flags, |
d62a5950 | 1144 | struct gcc_options *opts, |
1145 | unsigned int lang_mask) | |
87c75316 | 1146 | { |
1147 | unsigned int all_langs_mask = (1U << cl_lang_count) - 1; | |
1148 | const char * description = NULL; | |
1149 | const char * descrip_extra = ""; | |
1150 | size_t i; | |
1151 | unsigned int flag; | |
87c75316 | 1152 | |
1153 | /* Sanity check: Make sure that we do not have more | |
1154 | languages than we have bits available to enumerate them. */ | |
634b1f85 | 1155 | gcc_assert ((1U << cl_lang_count) <= CL_MIN_OPTION_CLASS); |
87c75316 | 1156 | |
1157 | /* If we have not done so already, obtain | |
1158 | the desired maximum width of the output. */ | |
9faf44d6 | 1159 | if (opts->x_help_columns == 0) |
87c75316 | 1160 | { |
1161 | const char *p; | |
1162 | ||
967958e4 | 1163 | p = getenv ("COLUMNS"); |
87c75316 | 1164 | if (p != NULL) |
1165 | { | |
1166 | int value = atoi (p); | |
1167 | ||
1168 | if (value > 0) | |
9faf44d6 | 1169 | opts->x_help_columns = value; |
87c75316 | 1170 | } |
1171 | ||
9faf44d6 | 1172 | if (opts->x_help_columns == 0) |
87c75316 | 1173 | /* Use a reasonable default. */ |
9faf44d6 | 1174 | opts->x_help_columns = 80; |
87c75316 | 1175 | } |
1176 | ||
1177 | /* Decide upon the title for the options that we are going to display. */ | |
1178 | for (i = 0, flag = 1; flag <= CL_MAX_OPTION_CLASS; flag <<= 1, i ++) | |
1179 | { | |
1180 | switch (flag & include_flags) | |
1181 | { | |
1182 | case 0: | |
e28aa114 | 1183 | case CL_DRIVER: |
87c75316 | 1184 | break; |
1185 | ||
1186 | case CL_TARGET: | |
1187 | description = _("The following options are target specific"); | |
1188 | break; | |
1189 | case CL_WARNING: | |
1190 | description = _("The following options control compiler warning messages"); | |
1191 | break; | |
1192 | case CL_OPTIMIZATION: | |
1193 | description = _("The following options control optimizations"); | |
1194 | break; | |
1195 | case CL_COMMON: | |
1196 | description = _("The following options are language-independent"); | |
1197 | break; | |
1198 | case CL_PARAMS: | |
1199 | description = _("The --param option recognizes the following as parameters"); | |
1200 | break; | |
1201 | default: | |
1202 | if (i >= cl_lang_count) | |
1203 | break; | |
fad6b6bb | 1204 | if (exclude_flags & all_langs_mask) |
d06cb02d | 1205 | description = _("The following options are specific to just the language "); |
87c75316 | 1206 | else |
7fbbfa9f | 1207 | description = _("The following options are supported by the language "); |
86895a67 | 1208 | descrip_extra = lang_names [i]; |
87c75316 | 1209 | break; |
1210 | } | |
1211 | } | |
1212 | ||
1213 | if (description == NULL) | |
1214 | { | |
1215 | if (any_flags == 0) | |
1216 | { | |
fad6b6bb | 1217 | if (include_flags & CL_UNDOCUMENTED) |
87c75316 | 1218 | description = _("The following options are not documented"); |
fad6b6bb | 1219 | else if (include_flags & CL_SEPARATE) |
1220 | description = _("The following options take separate arguments"); | |
1221 | else if (include_flags & CL_JOINED) | |
1222 | description = _("The following options take joined arguments"); | |
87c75316 | 1223 | else |
1224 | { | |
1225 | internal_error ("unrecognized include_flags 0x%x passed to print_specific_help", | |
1226 | include_flags); | |
1227 | return; | |
1228 | } | |
1229 | } | |
1230 | else | |
1231 | { | |
1232 | if (any_flags & all_langs_mask) | |
1233 | description = _("The following options are language-related"); | |
1234 | else | |
1235 | description = _("The following options are language-independent"); | |
1236 | } | |
1237 | } | |
1238 | ||
1239 | printf ("%s%s:\n", description, descrip_extra); | |
9faf44d6 | 1240 | print_filtered_help (include_flags, exclude_flags, any_flags, |
d62a5950 | 1241 | opts->x_help_columns, opts, lang_mask); |
87c75316 | 1242 | } |
1243 | ||
3272db82 | 1244 | /* Handle target- and language-independent options. Return zero to |
2e9da478 | 1245 | generate an "unknown option" message. Only options that need |
1246 | extra handling need to be listed here; if you simply want | |
666f4bf0 | 1247 | DECODED->value assigned to a variable, it happens automatically. */ |
2e9da478 | 1248 | |
79396169 | 1249 | bool |
2c5d2e39 | 1250 | common_handle_option (struct gcc_options *opts, |
f83b64ca | 1251 | struct gcc_options *opts_set, |
2c5d2e39 | 1252 | const struct cl_decoded_option *decoded, |
b78351e5 | 1253 | unsigned int lang_mask, int kind ATTRIBUTE_UNUSED, |
3c6c0e40 | 1254 | location_t loc, |
6bd9d862 | 1255 | const struct cl_option_handlers *handlers, |
1256 | diagnostic_context *dc) | |
3272db82 | 1257 | { |
666f4bf0 | 1258 | size_t scode = decoded->opt_index; |
1259 | const char *arg = decoded->arg; | |
1260 | int value = decoded->value; | |
3272db82 | 1261 | enum opt_code code = (enum opt_code) scode; |
1262 | ||
666f4bf0 | 1263 | gcc_assert (decoded->canonical_option_num_elements <= 2); |
1264 | ||
3272db82 | 1265 | switch (code) |
1266 | { | |
da3b1bab | 1267 | case OPT__param: |
9faf44d6 | 1268 | handle_param (opts, opts_set, loc, arg); |
da3b1bab | 1269 | break; |
1270 | ||
87c75316 | 1271 | case OPT__help: |
1272 | { | |
1273 | unsigned int all_langs_mask = (1U << cl_lang_count) - 1; | |
1274 | unsigned int undoc_mask; | |
1275 | unsigned int i; | |
1276 | ||
90336809 | 1277 | if (lang_mask == CL_DRIVER) |
1278 | break;; | |
1279 | ||
6bd9d862 | 1280 | undoc_mask = ((opts->x_verbose_flag | opts->x_extra_warnings) |
1281 | ? 0 | |
1282 | : CL_UNDOCUMENTED); | |
87c75316 | 1283 | /* First display any single language specific options. */ |
1284 | for (i = 0; i < cl_lang_count; i++) | |
1285 | print_specific_help | |
d62a5950 | 1286 | (1U << i, (all_langs_mask & (~ (1U << i))) | undoc_mask, 0, opts, |
1287 | lang_mask); | |
87c75316 | 1288 | /* Next display any multi language specific options. */ |
d62a5950 | 1289 | print_specific_help (0, undoc_mask, all_langs_mask, opts, lang_mask); |
87c75316 | 1290 | /* Then display any remaining, non-language options. */ |
1291 | for (i = CL_MIN_OPTION_CLASS; i <= CL_MAX_OPTION_CLASS; i <<= 1) | |
e28aa114 | 1292 | if (i != CL_DRIVER) |
d62a5950 | 1293 | print_specific_help (i, undoc_mask, 0, opts, lang_mask); |
cc4fa57a | 1294 | opts->x_exit_after_options = true; |
87c75316 | 1295 | break; |
1296 | } | |
1297 | ||
e690b385 | 1298 | case OPT__target_help: |
90336809 | 1299 | if (lang_mask == CL_DRIVER) |
1300 | break; | |
1301 | ||
d62a5950 | 1302 | print_specific_help (CL_TARGET, CL_UNDOCUMENTED, 0, opts, lang_mask); |
cc4fa57a | 1303 | opts->x_exit_after_options = true; |
e690b385 | 1304 | break; |
1305 | ||
87c75316 | 1306 | case OPT__help_: |
1307 | { | |
1308 | const char * a = arg; | |
1309 | unsigned int include_flags = 0; | |
1310 | /* Note - by default we include undocumented options when listing | |
1311 | specific classes. If you only want to see documented options | |
f0b5f617 | 1312 | then add ",^undocumented" to the --help= option. E.g.: |
87c75316 | 1313 | |
1314 | --help=target,^undocumented */ | |
1315 | unsigned int exclude_flags = 0; | |
1316 | ||
90336809 | 1317 | if (lang_mask == CL_DRIVER) |
1318 | break; | |
1319 | ||
87c75316 | 1320 | /* Walk along the argument string, parsing each word in turn. |
1321 | The format is: | |
1322 | arg = [^]{word}[,{arg}] | |
7fbbfa9f | 1323 | word = {optimizers|target|warnings|undocumented| |
1324 | params|common|<language>} */ | |
87c75316 | 1325 | while (* a != 0) |
1326 | { | |
cc4fa57a | 1327 | static const struct |
87c75316 | 1328 | { |
1329 | const char * string; | |
1330 | unsigned int flag; | |
1331 | } | |
1332 | specifics[] = | |
1333 | { | |
1334 | { "optimizers", CL_OPTIMIZATION }, | |
1335 | { "target", CL_TARGET }, | |
1336 | { "warnings", CL_WARNING }, | |
1337 | { "undocumented", CL_UNDOCUMENTED }, | |
1338 | { "params", CL_PARAMS }, | |
b8048da5 | 1339 | { "joined", CL_JOINED }, |
1340 | { "separate", CL_SEPARATE }, | |
7fbbfa9f | 1341 | { "common", CL_COMMON }, |
87c75316 | 1342 | { NULL, 0 } |
1343 | }; | |
1344 | unsigned int * pflags; | |
3f24af9b | 1345 | const char * comma; |
86895a67 | 1346 | unsigned int lang_flag, specific_flag; |
87c75316 | 1347 | unsigned int len; |
1348 | unsigned int i; | |
1349 | ||
1350 | if (* a == '^') | |
1351 | { | |
1352 | ++ a; | |
1353 | pflags = & exclude_flags; | |
1354 | } | |
1355 | else | |
1356 | pflags = & include_flags; | |
1357 | ||
1358 | comma = strchr (a, ','); | |
1359 | if (comma == NULL) | |
1360 | len = strlen (a); | |
1361 | else | |
1362 | len = comma - a; | |
fad6b6bb | 1363 | if (len == 0) |
1364 | { | |
1365 | a = comma + 1; | |
1366 | continue; | |
1367 | } | |
87c75316 | 1368 | |
86895a67 | 1369 | /* Check to see if the string matches an option class name. */ |
1370 | for (i = 0, specific_flag = 0; specifics[i].string != NULL; i++) | |
87c75316 | 1371 | if (strncasecmp (a, specifics[i].string, len) == 0) |
1372 | { | |
86895a67 | 1373 | specific_flag = specifics[i].flag; |
1374 | break; | |
1375 | } | |
fad6b6bb | 1376 | |
86895a67 | 1377 | /* Check to see if the string matches a language name. |
1378 | Note - we rely upon the alpha-sorted nature of the entries in | |
1379 | the lang_names array, specifically that shorter names appear | |
f0b5f617 | 1380 | before their longer variants. (i.e. C before C++). That way |
86895a67 | 1381 | when we are attempting to match --help=c for example we will |
1382 | match with C first and not C++. */ | |
1383 | for (i = 0, lang_flag = 0; i < cl_lang_count; i++) | |
1384 | if (strncasecmp (a, lang_names[i], len) == 0) | |
1385 | { | |
1386 | lang_flag = 1U << i; | |
87c75316 | 1387 | break; |
1388 | } | |
1389 | ||
86895a67 | 1390 | if (specific_flag != 0) |
87c75316 | 1391 | { |
86895a67 | 1392 | if (lang_flag == 0) |
1393 | * pflags |= specific_flag; | |
1394 | else | |
1395 | { | |
1396 | /* The option's argument matches both the start of a | |
1397 | language name and the start of an option class name. | |
1398 | We have a special case for when the user has | |
1399 | specified "--help=c", but otherwise we have to issue | |
1400 | a warning. */ | |
1401 | if (strncasecmp (a, "c", len) == 0) | |
1402 | * pflags |= lang_flag; | |
1403 | else | |
9faf44d6 | 1404 | warning_at (loc, 0, |
1405 | "--help argument %q.*s is ambiguous, " | |
1406 | "please be more specific", | |
1407 | len, a); | |
86895a67 | 1408 | } |
87c75316 | 1409 | } |
86895a67 | 1410 | else if (lang_flag != 0) |
1411 | * pflags |= lang_flag; | |
1412 | else | |
9faf44d6 | 1413 | warning_at (loc, 0, |
1414 | "unrecognized argument to --help= option: %q.*s", | |
1415 | len, a); | |
87c75316 | 1416 | |
1417 | if (comma == NULL) | |
1418 | break; | |
1419 | a = comma + 1; | |
1420 | } | |
1421 | ||
1422 | if (include_flags) | |
d62a5950 | 1423 | print_specific_help (include_flags, exclude_flags, 0, opts, |
1424 | lang_mask); | |
cc4fa57a | 1425 | opts->x_exit_after_options = true; |
87c75316 | 1426 | break; |
1427 | } | |
1428 | ||
e690b385 | 1429 | case OPT__version: |
90336809 | 1430 | if (lang_mask == CL_DRIVER) |
1431 | break; | |
1432 | ||
cc4fa57a | 1433 | opts->x_exit_after_options = true; |
e690b385 | 1434 | break; |
1435 | ||
9e46467d | 1436 | case OPT_fsanitize_: |
1437 | { | |
1438 | const char *p = arg; | |
1439 | while (*p != 0) | |
1440 | { | |
1441 | static const struct | |
1442 | { | |
1443 | const char *const name; | |
1444 | unsigned int flag; | |
1445 | size_t len; | |
1446 | } spec[] = | |
1447 | { | |
1448 | { "address", SANITIZE_ADDRESS, sizeof "address" - 1 }, | |
1449 | { "thread", SANITIZE_THREAD, sizeof "thread" - 1 }, | |
f8ff4a27 | 1450 | { "leak", SANITIZE_LEAK, sizeof "leak" - 1 }, |
9e46467d | 1451 | { "shift", SANITIZE_SHIFT, sizeof "shift" - 1 }, |
1452 | { "integer-divide-by-zero", SANITIZE_DIVIDE, | |
1453 | sizeof "integer-divide-by-zero" - 1 }, | |
1454 | { "undefined", SANITIZE_UNDEFINED, sizeof "undefined" - 1 }, | |
1455 | { "unreachable", SANITIZE_UNREACHABLE, | |
1456 | sizeof "unreachable" - 1 }, | |
2c4c3477 | 1457 | { "vla-bound", SANITIZE_VLA, sizeof "vla-bound" - 1 }, |
020bc656 | 1458 | { "return", SANITIZE_RETURN, sizeof "return" - 1 }, |
19b928d9 | 1459 | { "null", SANITIZE_NULL, sizeof "null" - 1 }, |
137559b2 | 1460 | { "signed-integer-overflow", SANITIZE_SI_OVERFLOW, |
1461 | sizeof "signed-integer-overflow" -1 }, | |
ec08f7b0 | 1462 | { "bool", SANITIZE_BOOL, sizeof "bool" - 1 }, |
1463 | { "enum", SANITIZE_ENUM, sizeof "enum" - 1 }, | |
52cc0072 | 1464 | { "float-divide-by-zero", SANITIZE_FLOAT_DIVIDE, |
1465 | sizeof "float-divide-by-zero" - 1 }, | |
9e46467d | 1466 | { NULL, 0, 0 } |
1467 | }; | |
1468 | const char *comma; | |
1469 | size_t len, i; | |
1470 | bool found = false; | |
1471 | ||
1472 | comma = strchr (p, ','); | |
1473 | if (comma == NULL) | |
1474 | len = strlen (p); | |
1475 | else | |
1476 | len = comma - p; | |
1477 | if (len == 0) | |
1478 | { | |
1479 | p = comma + 1; | |
1480 | continue; | |
1481 | } | |
1482 | ||
1483 | /* Check to see if the string matches an option class name. */ | |
1484 | for (i = 0; spec[i].name != NULL; ++i) | |
1485 | if (len == spec[i].len | |
1486 | && memcmp (p, spec[i].name, len) == 0) | |
1487 | { | |
1488 | /* Handle both -fsanitize and -fno-sanitize cases. */ | |
1489 | if (value) | |
1490 | flag_sanitize |= spec[i].flag; | |
1491 | else | |
1492 | flag_sanitize &= ~spec[i].flag; | |
1493 | found = true; | |
1494 | break; | |
1495 | } | |
1496 | ||
1497 | if (! found) | |
1498 | warning_at (loc, 0, | |
1499 | "unrecognized argument to -fsanitize= option: %q.*s", | |
1500 | (int) len, p); | |
1501 | ||
1502 | if (comma == NULL) | |
1503 | break; | |
1504 | p = comma + 1; | |
1505 | } | |
1506 | ||
19b928d9 | 1507 | /* When instrumenting the pointers, we don't want to remove |
1508 | the null pointer checks. */ | |
1509 | if (flag_sanitize & SANITIZE_NULL) | |
1510 | opts->x_flag_delete_null_pointer_checks = 0; | |
9e46467d | 1511 | break; |
1512 | } | |
1513 | ||
da3b1bab | 1514 | case OPT_O: |
1515 | case OPT_Os: | |
e00798c7 | 1516 | case OPT_Ofast: |
9b0d2865 | 1517 | case OPT_Og: |
da3b1bab | 1518 | /* Currently handled in a prescan. */ |
1519 | break; | |
1520 | ||
90e2341f | 1521 | case OPT_Werror: |
1522 | dc->warning_as_error_requested = value; | |
1523 | break; | |
1524 | ||
76f02516 | 1525 | case OPT_Werror_: |
90336809 | 1526 | if (lang_mask == CL_DRIVER) |
1527 | break; | |
1528 | ||
c123f04d | 1529 | enable_warning_as_error (arg, value, lang_mask, handlers, |
1530 | opts, opts_set, loc, dc); | |
76f02516 | 1531 | break; |
1532 | ||
6f2f567f | 1533 | case OPT_Wlarger_than_: |
6bd9d862 | 1534 | opts->x_larger_than_size = value; |
1535 | opts->x_warn_larger_than = value != -1; | |
6f2f567f | 1536 | break; |
1537 | ||
3c6a9715 | 1538 | case OPT_Wfatal_errors: |
6bd9d862 | 1539 | dc->fatal_errors = value; |
3c6a9715 | 1540 | break; |
1541 | ||
6fdade09 | 1542 | case OPT_Wframe_larger_than_: |
6bd9d862 | 1543 | opts->x_frame_larger_than_size = value; |
1544 | opts->x_warn_frame_larger_than = value != -1; | |
6fdade09 | 1545 | break; |
1546 | ||
8c0dd614 | 1547 | case OPT_Wstack_usage_: |
1548 | opts->x_warn_stack_usage = value; | |
1549 | opts->x_flag_stack_usage_info = value != -1; | |
1550 | break; | |
1551 | ||
6f2f567f | 1552 | case OPT_Wstrict_aliasing: |
6bd9d862 | 1553 | set_Wstrict_aliasing (opts, value); |
6f2f567f | 1554 | break; |
1555 | ||
add6ee5e | 1556 | case OPT_Wstrict_overflow: |
6bd9d862 | 1557 | opts->x_warn_strict_overflow = (value |
1558 | ? (int) WARN_STRICT_OVERFLOW_CONDITIONAL | |
1559 | : 0); | |
add6ee5e | 1560 | break; |
1561 | ||
3c6a9715 | 1562 | case OPT_Wsystem_headers: |
6bd9d862 | 1563 | dc->dc_warn_system_headers = value; |
da3b1bab | 1564 | break; |
1565 | ||
e690b385 | 1566 | case OPT_aux_info: |
6bd9d862 | 1567 | opts->x_flag_gen_aux_info = 1; |
e690b385 | 1568 | break; |
1569 | ||
1570 | case OPT_auxbase_strip: | |
1571 | { | |
1572 | char *tmp = xstrdup (arg); | |
1573 | strip_off_ending (tmp, strlen (tmp)); | |
1574 | if (tmp[0]) | |
6bd9d862 | 1575 | opts->x_aux_base_name = tmp; |
ce0fdb91 | 1576 | else |
1577 | free (tmp); | |
e690b385 | 1578 | } |
1579 | break; | |
1580 | ||
1581 | case OPT_d: | |
9faf44d6 | 1582 | decode_d_option (arg, opts, loc, dc); |
e690b385 | 1583 | break; |
1584 | ||
941a4893 | 1585 | case OPT_fcall_used_: |
941a4893 | 1586 | case OPT_fcall_saved_: |
f0da0668 | 1587 | /* Deferred. */ |
941a4893 | 1588 | break; |
3072d30e | 1589 | |
1590 | case OPT_fdbg_cnt_: | |
d2153a46 | 1591 | case OPT_fdbg_cnt_list: |
9faf44d6 | 1592 | /* Deferred. */ |
d2153a46 | 1593 | break; |
941a4893 | 1594 | |
5f1f2de5 | 1595 | case OPT_fdebug_prefix_map_: |
9faf44d6 | 1596 | /* Deferred. */ |
5f1f2de5 | 1597 | break; |
1598 | ||
1e06725a | 1599 | case OPT_fdiagnostics_show_location_: |
d62a5950 | 1600 | diagnostic_prefixing_rule (dc) = (diagnostic_prefixing_rule_t) value; |
1e06725a | 1601 | break; |
5a983084 | 1602 | |
1603 | case OPT_fdiagnostics_show_caret: | |
1604 | dc->show_caret = value; | |
1605 | break; | |
1e06725a | 1606 | |
41609f8b | 1607 | case OPT_fdiagnostics_color_: |
1608 | pp_show_color (dc->printer) | |
1609 | = colorize_init ((diagnostic_color_rule_t) value); | |
1610 | break; | |
1611 | ||
b0932b2f | 1612 | case OPT_fdiagnostics_show_option: |
6bd9d862 | 1613 | dc->show_option_requested = value; |
b0932b2f | 1614 | break; |
1615 | ||
4ee9c684 | 1616 | case OPT_fdump_: |
f0da0668 | 1617 | /* Deferred. */ |
4ee9c684 | 1618 | break; |
1619 | ||
941a4893 | 1620 | case OPT_ffast_math: |
6bd9d862 | 1621 | set_fast_math_flags (opts, value); |
941a4893 | 1622 | break; |
1623 | ||
49d060d7 | 1624 | case OPT_funsafe_math_optimizations: |
6bd9d862 | 1625 | set_unsafe_math_optimizations_flags (opts, value); |
49d060d7 | 1626 | break; |
1627 | ||
941a4893 | 1628 | case OPT_ffixed_: |
f0da0668 | 1629 | /* Deferred. */ |
941a4893 | 1630 | break; |
1631 | ||
39470ac3 | 1632 | case OPT_finline_limit_: |
56f280c4 | 1633 | set_param_value ("max-inline-insns-single", value / 2, |
1634 | opts->x_param_values, opts_set->x_param_values); | |
1635 | set_param_value ("max-inline-insns-auto", value / 2, | |
1636 | opts->x_param_values, opts_set->x_param_values); | |
39470ac3 | 1637 | break; |
1638 | ||
a95c0776 | 1639 | case OPT_finstrument_functions_exclude_function_list_: |
b5f30e7c | 1640 | add_comma_separated_to_vector |
470a0ecd | 1641 | (&opts->x_flag_instrument_functions_exclude_functions, arg); |
a95c0776 | 1642 | break; |
1643 | ||
1644 | case OPT_finstrument_functions_exclude_file_list_: | |
b5f30e7c | 1645 | add_comma_separated_to_vector |
470a0ecd | 1646 | (&opts->x_flag_instrument_functions_exclude_files, arg); |
a95c0776 | 1647 | break; |
1648 | ||
1e06725a | 1649 | case OPT_fmessage_length_: |
6bd9d862 | 1650 | pp_set_line_maximum_length (dc->printer, value); |
5a983084 | 1651 | diagnostic_set_caret_max_width (dc, value); |
1e06725a | 1652 | break; |
1653 | ||
7bd765d4 | 1654 | case OPT_fopt_info: |
1655 | case OPT_fopt_info_: | |
1656 | /* Deferred. */ | |
1657 | break; | |
1658 | ||
6b5553e5 | 1659 | case OPT_fpack_struct_: |
1660 | if (value <= 0 || (value & (value - 1)) || value > 16) | |
9faf44d6 | 1661 | error_at (loc, |
1662 | "structure alignment must be a small power of two, not %d", | |
1663 | value); | |
6b5553e5 | 1664 | else |
9faf44d6 | 1665 | opts->x_initial_max_fld_align = value; |
6b5553e5 | 1666 | break; |
1667 | ||
9227b6fc | 1668 | case OPT_fplugin_: |
9227b6fc | 1669 | case OPT_fplugin_arg_: |
f0da0668 | 1670 | /* Deferred. */ |
9227b6fc | 1671 | break; |
1672 | ||
3e3a0e9c | 1673 | case OPT_fprofile_use_: |
cc4fa57a | 1674 | opts->x_profile_data_prefix = xstrdup (arg); |
6bd9d862 | 1675 | opts->x_flag_profile_use = true; |
3e3a0e9c | 1676 | value = true; |
1677 | /* No break here - do -fprofile-use processing. */ | |
7dea76ba | 1678 | case OPT_fprofile_use: |
f83b64ca | 1679 | if (!opts_set->x_flag_branch_probabilities) |
6bd9d862 | 1680 | opts->x_flag_branch_probabilities = value; |
f83b64ca | 1681 | if (!opts_set->x_flag_profile_values) |
6bd9d862 | 1682 | opts->x_flag_profile_values = value; |
f83b64ca | 1683 | if (!opts_set->x_flag_unroll_loops) |
6bd9d862 | 1684 | opts->x_flag_unroll_loops = value; |
f83b64ca | 1685 | if (!opts_set->x_flag_peel_loops) |
6bd9d862 | 1686 | opts->x_flag_peel_loops = value; |
f83b64ca | 1687 | if (!opts_set->x_flag_tracer) |
6bd9d862 | 1688 | opts->x_flag_tracer = value; |
f83b64ca | 1689 | if (!opts_set->x_flag_value_profile_transformations) |
6bd9d862 | 1690 | opts->x_flag_value_profile_transformations = value; |
f83b64ca | 1691 | if (!opts_set->x_flag_inline_functions) |
6bd9d862 | 1692 | opts->x_flag_inline_functions = value; |
f83b64ca | 1693 | if (!opts_set->x_flag_ipa_cp) |
6bd9d862 | 1694 | opts->x_flag_ipa_cp = value; |
f83b64ca | 1695 | if (!opts_set->x_flag_ipa_cp_clone |
6bd9d862 | 1696 | && value && opts->x_flag_ipa_cp) |
1697 | opts->x_flag_ipa_cp_clone = value; | |
f83b64ca | 1698 | if (!opts_set->x_flag_predictive_commoning) |
6bd9d862 | 1699 | opts->x_flag_predictive_commoning = value; |
f83b64ca | 1700 | if (!opts_set->x_flag_unswitch_loops) |
6bd9d862 | 1701 | opts->x_flag_unswitch_loops = value; |
f83b64ca | 1702 | if (!opts_set->x_flag_gcse_after_reload) |
6bd9d862 | 1703 | opts->x_flag_gcse_after_reload = value; |
043115ec | 1704 | if (!opts_set->x_flag_tree_loop_vectorize |
1705 | && !opts_set->x_flag_tree_vectorize) | |
1706 | opts->x_flag_tree_loop_vectorize = value; | |
1707 | if (!opts_set->x_flag_tree_slp_vectorize | |
1708 | && !opts_set->x_flag_tree_vectorize) | |
1709 | opts->x_flag_tree_slp_vectorize = value; | |
5f38d9ef | 1710 | if (!opts_set->x_flag_vect_cost_model) |
1dbf9bd1 | 1711 | opts->x_flag_vect_cost_model = VECT_COST_MODEL_DYNAMIC; |
5f38d9ef | 1712 | if (!opts_set->x_flag_tree_loop_distribute_patterns) |
1713 | opts->x_flag_tree_loop_distribute_patterns = value; | |
af48f0b1 | 1714 | if (!opts_set->x_flag_profile_reorder_functions) |
1715 | opts->x_flag_profile_reorder_functions = value; | |
84f6cc40 | 1716 | /* Indirect call profiling should do all useful transformations |
c7142344 | 1717 | speculative devirtualization does. */ |
84f6cc40 | 1718 | if (!opts_set->x_flag_devirtualize_speculatively |
1719 | && opts->x_flag_value_profile_transformations) | |
1720 | opts->x_flag_devirtualize_speculatively = false; | |
7dea76ba | 1721 | break; |
1722 | ||
3e3a0e9c | 1723 | case OPT_fprofile_generate_: |
cc4fa57a | 1724 | opts->x_profile_data_prefix = xstrdup (arg); |
3e3a0e9c | 1725 | value = true; |
1726 | /* No break here - do -fprofile-generate processing. */ | |
7dea76ba | 1727 | case OPT_fprofile_generate: |
f83b64ca | 1728 | if (!opts_set->x_profile_arc_flag) |
6bd9d862 | 1729 | opts->x_profile_arc_flag = value; |
f83b64ca | 1730 | if (!opts_set->x_flag_profile_values) |
6bd9d862 | 1731 | opts->x_flag_profile_values = value; |
f83b64ca | 1732 | if (!opts_set->x_flag_inline_functions) |
6bd9d862 | 1733 | opts->x_flag_inline_functions = value; |
02a5f2b9 | 1734 | /* FIXME: Instrumentation we insert makes ipa-reference bitmaps |
1735 | quadratic. Disable the pass until better memory representation | |
1736 | is done. */ | |
704db68e | 1737 | if (!opts_set->x_flag_ipa_reference) |
02a5f2b9 | 1738 | opts->x_flag_ipa_reference = false; |
7dea76ba | 1739 | break; |
1740 | ||
043115ec | 1741 | case OPT_ftree_vectorize: |
1742 | if (!opts_set->x_flag_tree_loop_vectorize) | |
1743 | opts->x_flag_tree_loop_vectorize = value; | |
1744 | if (!opts_set->x_flag_tree_slp_vectorize) | |
1745 | opts->x_flag_tree_slp_vectorize = value; | |
1746 | break; | |
3c6a9715 | 1747 | case OPT_fshow_column: |
6bd9d862 | 1748 | dc->show_column = value; |
3c6a9715 | 1749 | break; |
1750 | ||
1e06725a | 1751 | case OPT_frandom_seed: |
1752 | /* The real switch is -fno-random-seed. */ | |
1753 | if (value) | |
b78351e5 | 1754 | return false; |
9faf44d6 | 1755 | /* Deferred. */ |
1e06725a | 1756 | break; |
1757 | ||
1758 | case OPT_frandom_seed_: | |
9faf44d6 | 1759 | /* Deferred. */ |
1e06725a | 1760 | break; |
1761 | ||
1e06725a | 1762 | case OPT_fsched_verbose_: |
1763 | #ifdef INSN_SCHEDULING | |
9faf44d6 | 1764 | /* Handled with Var in common.opt. */ |
1e06725a | 1765 | break; |
1766 | #else | |
b78351e5 | 1767 | return false; |
1e06725a | 1768 | #endif |
1769 | ||
52c4b43f | 1770 | case OPT_fsched_stalled_insns_: |
6bd9d862 | 1771 | opts->x_flag_sched_stalled_insns = value; |
1772 | if (opts->x_flag_sched_stalled_insns == 0) | |
1773 | opts->x_flag_sched_stalled_insns = -1; | |
52c4b43f | 1774 | break; |
1775 | ||
52c4b43f | 1776 | case OPT_fsched_stalled_insns_dep_: |
6bd9d862 | 1777 | opts->x_flag_sched_stalled_insns_dep = value; |
52c4b43f | 1778 | break; |
ecdb6d1a | 1779 | |
4852b829 | 1780 | case OPT_fstack_check_: |
1781 | if (!strcmp (arg, "no")) | |
ab3728ee | 1782 | opts->x_flag_stack_check = NO_STACK_CHECK; |
4852b829 | 1783 | else if (!strcmp (arg, "generic")) |
1784 | /* This is the old stack checking method. */ | |
ab3728ee | 1785 | opts->x_flag_stack_check = STACK_CHECK_BUILTIN |
4852b829 | 1786 | ? FULL_BUILTIN_STACK_CHECK |
1787 | : GENERIC_STACK_CHECK; | |
1788 | else if (!strcmp (arg, "specific")) | |
1789 | /* This is the new stack checking method. */ | |
ab3728ee | 1790 | opts->x_flag_stack_check = STACK_CHECK_BUILTIN |
4852b829 | 1791 | ? FULL_BUILTIN_STACK_CHECK |
1792 | : STACK_CHECK_STATIC_BUILTIN | |
1793 | ? STATIC_BUILTIN_STACK_CHECK | |
1794 | : GENERIC_STACK_CHECK; | |
1795 | else | |
9faf44d6 | 1796 | warning_at (loc, 0, "unknown stack check parameter \"%s\"", arg); |
4852b829 | 1797 | break; |
1798 | ||
1e06725a | 1799 | case OPT_fstack_limit: |
1800 | /* The real switch is -fno-stack-limit. */ | |
1801 | if (value) | |
b78351e5 | 1802 | return false; |
f0da0668 | 1803 | /* Deferred. */ |
1e06725a | 1804 | break; |
1805 | ||
941a4893 | 1806 | case OPT_fstack_limit_register_: |
941a4893 | 1807 | case OPT_fstack_limit_symbol_: |
f0da0668 | 1808 | /* Deferred. */ |
941a4893 | 1809 | break; |
1810 | ||
8c0dd614 | 1811 | case OPT_fstack_usage: |
1812 | opts->x_flag_stack_usage = value; | |
1813 | opts->x_flag_stack_usage_info = value != 0; | |
1814 | break; | |
1815 | ||
6f2f567f | 1816 | case OPT_g: |
7fa9fa16 | 1817 | /* -g by itself should force -g2. */ |
1818 | if (*arg == '\0') | |
1819 | set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, "2", opts, opts_set, | |
1820 | loc); | |
1821 | else | |
1822 | set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, arg, opts, opts_set, | |
1823 | loc); | |
b0e56fb1 | 1824 | break; |
1825 | ||
1826 | case OPT_gcoff: | |
9faf44d6 | 1827 | set_debug_level (SDB_DEBUG, false, arg, opts, opts_set, loc); |
b0e56fb1 | 1828 | break; |
1829 | ||
8786b72c | 1830 | case OPT_gdwarf: |
6c1f6b49 | 1831 | if (arg && strlen (arg) != 0) |
8786b72c | 1832 | { |
1833 | error_at (loc, "%<-gdwarf%s%> is ambiguous; " | |
1834 | "use %<-gdwarf-%s%> for DWARF version " | |
1835 | "or %<-gdwarf -g%s%> for debug level", arg, arg, arg); | |
1836 | break; | |
1837 | } | |
1838 | else | |
6c1f6b49 | 1839 | value = opts->x_dwarf_version; |
1840 | ||
1841 | /* FALLTHRU */ | |
3d3b9d5b | 1842 | case OPT_gdwarf_: |
9845d120 | 1843 | if (value < 2 || value > 4) |
9faf44d6 | 1844 | error_at (loc, "dwarf version %d is not supported", value); |
3d3b9d5b | 1845 | else |
90336809 | 1846 | opts->x_dwarf_version = value; |
9faf44d6 | 1847 | set_debug_level (DWARF2_DEBUG, false, "", opts, opts_set, loc); |
b0e56fb1 | 1848 | break; |
1849 | ||
b35329c7 | 1850 | case OPT_gsplit_dwarf: |
1851 | set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, "", opts, opts_set, | |
1852 | loc); | |
1853 | break; | |
1854 | ||
b0e56fb1 | 1855 | case OPT_ggdb: |
9faf44d6 | 1856 | set_debug_level (NO_DEBUG, 2, arg, opts, opts_set, loc); |
b0e56fb1 | 1857 | break; |
1858 | ||
1859 | case OPT_gstabs: | |
1860 | case OPT_gstabs_: | |
9faf44d6 | 1861 | set_debug_level (DBX_DEBUG, code == OPT_gstabs_, arg, opts, opts_set, |
1862 | loc); | |
b0e56fb1 | 1863 | break; |
1864 | ||
1865 | case OPT_gvms: | |
9faf44d6 | 1866 | set_debug_level (VMS_DEBUG, false, arg, opts, opts_set, loc); |
b0e56fb1 | 1867 | break; |
1868 | ||
1869 | case OPT_gxcoff: | |
1870 | case OPT_gxcoff_: | |
9faf44d6 | 1871 | set_debug_level (XCOFF_DEBUG, code == OPT_gxcoff_, arg, opts, opts_set, |
1872 | loc); | |
6f2f567f | 1873 | break; |
1874 | ||
e690b385 | 1875 | case OPT_pedantic_errors: |
6bd9d862 | 1876 | dc->pedantic_errors = 1; |
db490cb6 | 1877 | control_warning_option (OPT_Wpedantic, DK_ERROR, value, |
1878 | loc, lang_mask, | |
1879 | handlers, opts, opts_set, | |
1880 | dc); | |
cba6710d | 1881 | break; |
1882 | ||
cbcf2791 | 1883 | case OPT_flto: |
489113a1 | 1884 | opts->x_flag_lto = value ? "" : NULL; |
e990a271 | 1885 | break; |
1886 | ||
3c6a9715 | 1887 | case OPT_w: |
6bd9d862 | 1888 | dc->dc_inhibit_warnings = true; |
3c6a9715 | 1889 | break; |
1890 | ||
566d7c74 | 1891 | case OPT_fmax_errors_: |
1892 | dc->max_errors = value; | |
1893 | break; | |
1894 | ||
99d5fe2d | 1895 | case OPT_fuse_ld_bfd: |
1896 | case OPT_fuse_ld_gold: | |
386fbe6a | 1897 | case OPT_fuse_linker_plugin: |
1898 | /* No-op. Used by the driver and passed to us because it starts with f.*/ | |
1899 | break; | |
1900 | ||
8365f6c8 | 1901 | case OPT_fwrapv: |
1902 | if (value) | |
1903 | opts->x_flag_trapv = 0; | |
1904 | break; | |
1905 | ||
1906 | case OPT_ftrapv: | |
1907 | if (value) | |
1908 | opts->x_flag_wrapv = 0; | |
1909 | break; | |
1910 | ||
2e9da478 | 1911 | default: |
1912 | /* If the flag was handled in a standard way, assume the lack of | |
1913 | processing here is intentional. */ | |
2c5d2e39 | 1914 | gcc_assert (option_flag_var (scode, opts)); |
1fa3a8f6 | 1915 | break; |
3272db82 | 1916 | } |
1917 | ||
fbb6fbd8 | 1918 | common_handle_option_auto (opts, opts_set, decoded, lang_mask, kind, |
1919 | loc, handlers, dc); | |
b78351e5 | 1920 | return true; |
3272db82 | 1921 | } |
da3b1bab | 1922 | |
1923 | /* Handle --param NAME=VALUE. */ | |
1924 | static void | |
56f280c4 | 1925 | handle_param (struct gcc_options *opts, struct gcc_options *opts_set, |
9faf44d6 | 1926 | location_t loc, const char *carg) |
da3b1bab | 1927 | { |
1928 | char *equal, *arg; | |
1929 | int value; | |
1930 | ||
1931 | arg = xstrdup (carg); | |
1932 | equal = strchr (arg, '='); | |
1933 | if (!equal) | |
9faf44d6 | 1934 | error_at (loc, "%s: --param arguments should be of the form NAME=VALUE", |
1935 | arg); | |
da3b1bab | 1936 | else |
1937 | { | |
1938 | value = integral_argument (equal + 1); | |
1939 | if (value == -1) | |
9faf44d6 | 1940 | error_at (loc, "invalid --param value %qs", equal + 1); |
da3b1bab | 1941 | else |
1942 | { | |
1943 | *equal = '\0'; | |
56f280c4 | 1944 | set_param_value (arg, value, |
1945 | opts->x_param_values, opts_set->x_param_values); | |
da3b1bab | 1946 | } |
1947 | } | |
1948 | ||
1949 | free (arg); | |
1950 | } | |
1951 | ||
6bd9d862 | 1952 | /* Used to set the level of strict aliasing warnings in OPTS, |
e6fa0ea6 | 1953 | when no level is specified (i.e., when -Wstrict-aliasing, and not |
1954 | -Wstrict-aliasing=level was given). | |
1955 | ONOFF is assumed to take value 1 when -Wstrict-aliasing is specified, | |
1956 | and 0 otherwise. After calling this function, wstrict_aliasing will be | |
1957 | set to the default value of -Wstrict_aliasing=level, currently 3. */ | |
77b27208 | 1958 | static void |
6bd9d862 | 1959 | set_Wstrict_aliasing (struct gcc_options *opts, int onoff) |
e6fa0ea6 | 1960 | { |
1961 | gcc_assert (onoff == 0 || onoff == 1); | |
1962 | if (onoff != 0) | |
6bd9d862 | 1963 | opts->x_warn_strict_aliasing = 3; |
e629070d | 1964 | else |
6bd9d862 | 1965 | opts->x_warn_strict_aliasing = 0; |
e6fa0ea6 | 1966 | } |
1967 | ||
941a4893 | 1968 | /* The following routines are useful in setting all the flags that |
1969 | -ffast-math and -fno-fast-math imply. */ | |
43c54942 | 1970 | static void |
6bd9d862 | 1971 | set_fast_math_flags (struct gcc_options *opts, int set) |
941a4893 | 1972 | { |
ecee1b29 | 1973 | if (!opts->frontend_set_flag_unsafe_math_optimizations) |
1974 | { | |
1975 | opts->x_flag_unsafe_math_optimizations = set; | |
1976 | set_unsafe_math_optimizations_flags (opts, set); | |
1977 | } | |
1978 | if (!opts->frontend_set_flag_finite_math_only) | |
1979 | opts->x_flag_finite_math_only = set; | |
1980 | if (!opts->frontend_set_flag_errno_math) | |
1981 | opts->x_flag_errno_math = !set; | |
941a4893 | 1982 | if (set) |
5466f589 | 1983 | { |
ecee1b29 | 1984 | if (!opts->frontend_set_flag_signaling_nans) |
1985 | opts->x_flag_signaling_nans = 0; | |
1986 | if (!opts->frontend_set_flag_rounding_math) | |
1987 | opts->x_flag_rounding_math = 0; | |
1988 | if (!opts->frontend_set_flag_cx_limited_range) | |
1989 | opts->x_flag_cx_limited_range = 1; | |
5466f589 | 1990 | } |
941a4893 | 1991 | } |
1992 | ||
48e1416a | 1993 | /* When -funsafe-math-optimizations is set the following |
1994 | flags are set as well. */ | |
43c54942 | 1995 | static void |
6bd9d862 | 1996 | set_unsafe_math_optimizations_flags (struct gcc_options *opts, int set) |
49d060d7 | 1997 | { |
ecee1b29 | 1998 | if (!opts->frontend_set_flag_trapping_math) |
1999 | opts->x_flag_trapping_math = !set; | |
2000 | if (!opts->frontend_set_flag_signed_zeros) | |
2001 | opts->x_flag_signed_zeros = !set; | |
2002 | if (!opts->frontend_set_flag_associative_math) | |
2003 | opts->x_flag_associative_math = set; | |
2004 | if (!opts->frontend_set_flag_reciprocal_math) | |
2005 | opts->x_flag_reciprocal_math = set; | |
49d060d7 | 2006 | } |
2007 | ||
cc4fa57a | 2008 | /* Return true iff flags in OPTS are set as if -ffast-math. */ |
941a4893 | 2009 | bool |
cc4fa57a | 2010 | fast_math_flags_set_p (const struct gcc_options *opts) |
941a4893 | 2011 | { |
cc4fa57a | 2012 | return (!opts->x_flag_trapping_math |
2013 | && opts->x_flag_unsafe_math_optimizations | |
2014 | && opts->x_flag_finite_math_only | |
2015 | && !opts->x_flag_signed_zeros | |
2016 | && !opts->x_flag_errno_math); | |
941a4893 | 2017 | } |
53b8e5c1 | 2018 | |
46f8e3b0 | 2019 | /* Return true iff flags are set as if -ffast-math but using the flags stored |
2020 | in the struct cl_optimization structure. */ | |
2021 | bool | |
2022 | fast_math_flags_struct_set_p (struct cl_optimization *opt) | |
2023 | { | |
5ae82d58 | 2024 | return (!opt->x_flag_trapping_math |
2025 | && opt->x_flag_unsafe_math_optimizations | |
2026 | && opt->x_flag_finite_math_only | |
2027 | && !opt->x_flag_signed_zeros | |
2028 | && !opt->x_flag_errno_math); | |
46f8e3b0 | 2029 | } |
2030 | ||
cc4fa57a | 2031 | /* Handle a debug output -g switch for options OPTS |
2032 | (OPTS_SET->x_write_symbols storing whether a debug type was passed | |
9faf44d6 | 2033 | explicitly), location LOC. EXTENDED is true or false to support |
2034 | extended output (2 is special and means "-ggdb" was given). */ | |
b0e56fb1 | 2035 | static void |
cc4fa57a | 2036 | set_debug_level (enum debug_info_type type, int extended, const char *arg, |
9faf44d6 | 2037 | struct gcc_options *opts, struct gcc_options *opts_set, |
2038 | location_t loc) | |
b0e56fb1 | 2039 | { |
cc4fa57a | 2040 | opts->x_use_gnu_debug_info_extensions = extended; |
b0e56fb1 | 2041 | |
2042 | if (type == NO_DEBUG) | |
2043 | { | |
cc4fa57a | 2044 | if (opts->x_write_symbols == NO_DEBUG) |
b0e56fb1 | 2045 | { |
cc4fa57a | 2046 | opts->x_write_symbols = PREFERRED_DEBUGGING_TYPE; |
b0e56fb1 | 2047 | |
2048 | if (extended == 2) | |
2049 | { | |
2050 | #ifdef DWARF2_DEBUGGING_INFO | |
cc4fa57a | 2051 | opts->x_write_symbols = DWARF2_DEBUG; |
b0e56fb1 | 2052 | #elif defined DBX_DEBUGGING_INFO |
cc4fa57a | 2053 | opts->x_write_symbols = DBX_DEBUG; |
b0e56fb1 | 2054 | #endif |
2055 | } | |
2056 | ||
cc4fa57a | 2057 | if (opts->x_write_symbols == NO_DEBUG) |
9faf44d6 | 2058 | warning_at (loc, 0, "target system does not support debug output"); |
b0e56fb1 | 2059 | } |
2060 | } | |
2061 | else | |
2062 | { | |
2063 | /* Does it conflict with an already selected type? */ | |
cc4fa57a | 2064 | if (opts_set->x_write_symbols != NO_DEBUG |
2065 | && opts->x_write_symbols != NO_DEBUG | |
2066 | && type != opts->x_write_symbols) | |
9faf44d6 | 2067 | error_at (loc, "debug format \"%s\" conflicts with prior selection", |
2068 | debug_type_names[type]); | |
cc4fa57a | 2069 | opts->x_write_symbols = type; |
2070 | opts_set->x_write_symbols = type; | |
b0e56fb1 | 2071 | } |
2072 | ||
2073 | /* A debug flag without a level defaults to level 2. */ | |
2074 | if (*arg == '\0') | |
2075 | { | |
cc4fa57a | 2076 | if (!opts->x_debug_info_level) |
2077 | opts->x_debug_info_level = DINFO_LEVEL_NORMAL; | |
b0e56fb1 | 2078 | } |
2079 | else | |
2080 | { | |
8458f4ca | 2081 | int argval = integral_argument (arg); |
2082 | if (argval == -1) | |
9faf44d6 | 2083 | error_at (loc, "unrecognised debug output level \"%s\"", arg); |
8458f4ca | 2084 | else if (argval > 3) |
9faf44d6 | 2085 | error_at (loc, "debug output level %s is too high", arg); |
8458f4ca | 2086 | else |
cc4fa57a | 2087 | opts->x_debug_info_level = (enum debug_info_levels) argval; |
b0e56fb1 | 2088 | } |
2089 | } | |
2090 | ||
9faf44d6 | 2091 | /* Arrange to dump core on error for diagnostic context DC. (The |
2092 | regular error message is still printed first, except in the case of | |
2093 | abort ().) */ | |
ff05e09e | 2094 | |
79396169 | 2095 | static void |
9faf44d6 | 2096 | setup_core_dumping (diagnostic_context *dc) |
ff05e09e | 2097 | { |
79396169 | 2098 | #ifdef SIGABRT |
2099 | signal (SIGABRT, SIG_DFL); | |
2100 | #endif | |
2101 | #if defined(HAVE_SETRLIMIT) | |
2102 | { | |
2103 | struct rlimit rlim; | |
2104 | if (getrlimit (RLIMIT_CORE, &rlim) != 0) | |
2105 | fatal_error ("getting core file size maximum limit: %m"); | |
2106 | rlim.rlim_cur = rlim.rlim_max; | |
2107 | if (setrlimit (RLIMIT_CORE, &rlim) != 0) | |
2108 | fatal_error ("setting core file size limit to maximum: %m"); | |
2109 | } | |
2110 | #endif | |
9faf44d6 | 2111 | diagnostic_abort_on_error (dc); |
ff05e09e | 2112 | } |
7abcc497 | 2113 | |
9faf44d6 | 2114 | /* Parse a -d<ARG> command line switch for OPTS, location LOC, |
2115 | diagnostic context DC. */ | |
7abcc497 | 2116 | |
79396169 | 2117 | static void |
9faf44d6 | 2118 | decode_d_option (const char *arg, struct gcc_options *opts, |
2119 | location_t loc, diagnostic_context *dc) | |
7abcc497 | 2120 | { |
79396169 | 2121 | int c; |
7abcc497 | 2122 | |
79396169 | 2123 | while (*arg) |
2124 | switch (c = *arg++) | |
2125 | { | |
2126 | case 'A': | |
9faf44d6 | 2127 | opts->x_flag_debug_asm = 1; |
79396169 | 2128 | break; |
2129 | case 'p': | |
9faf44d6 | 2130 | opts->x_flag_print_asm_name = 1; |
79396169 | 2131 | break; |
2132 | case 'P': | |
9faf44d6 | 2133 | opts->x_flag_dump_rtl_in_asm = 1; |
2134 | opts->x_flag_print_asm_name = 1; | |
79396169 | 2135 | break; |
79396169 | 2136 | case 'x': |
9faf44d6 | 2137 | opts->x_rtl_dump_and_exit = 1; |
79396169 | 2138 | break; |
2139 | case 'D': /* These are handled by the preprocessor. */ | |
2140 | case 'I': | |
2141 | case 'M': | |
2142 | case 'N': | |
2143 | case 'U': | |
2144 | break; | |
2145 | case 'H': | |
9faf44d6 | 2146 | setup_core_dumping (dc); |
79396169 | 2147 | break; |
2148 | case 'a': | |
9faf44d6 | 2149 | opts->x_flag_dump_all_passed = true; |
79396169 | 2150 | break; |
f0da0668 | 2151 | |
79396169 | 2152 | default: |
9faf44d6 | 2153 | warning_at (loc, 0, "unrecognized gcc debugging option: %c", c); |
79396169 | 2154 | break; |
2155 | } | |
7abcc497 | 2156 | } |
3ba510aa | 2157 | |
24ca3b4e | 2158 | /* Enable (or disable if VALUE is 0) a warning option ARG (language |
c123f04d | 2159 | mask LANG_MASK, option handlers HANDLERS) as an error for option |
2160 | structures OPTS and OPTS_SET, diagnostic context DC (possibly | |
2161 | NULL), location LOC. This is used by -Werror=. */ | |
3ba510aa | 2162 | |
3c6c0e40 | 2163 | static void |
b78351e5 | 2164 | enable_warning_as_error (const char *arg, int value, unsigned int lang_mask, |
24ca3b4e | 2165 | const struct cl_option_handlers *handlers, |
c123f04d | 2166 | struct gcc_options *opts, |
2167 | struct gcc_options *opts_set, | |
3c6c0e40 | 2168 | location_t loc, diagnostic_context *dc) |
3ba510aa | 2169 | { |
2170 | char *new_option; | |
2171 | int option_index; | |
2172 | ||
2173 | new_option = XNEWVEC (char, strlen (arg) + 2); | |
2174 | new_option[0] = 'W'; | |
2175 | strcpy (new_option + 1, arg); | |
2176 | option_index = find_opt (new_option, lang_mask); | |
615ef0bb | 2177 | if (option_index == OPT_SPECIAL_unknown) |
3ba510aa | 2178 | { |
9faf44d6 | 2179 | error_at (loc, "-Werror=%s: no option -%s", arg, new_option); |
3ba510aa | 2180 | } |
2181 | else | |
2182 | { | |
3a79f5da | 2183 | const diagnostic_t kind = value ? DK_ERROR : DK_WARNING; |
2184 | ||
c123f04d | 2185 | control_warning_option (option_index, (int) kind, value, |
2186 | loc, lang_mask, | |
2187 | handlers, opts, opts_set, dc); | |
3ba510aa | 2188 | } |
2189 | free (new_option); | |
2190 | } | |
3c6a9715 | 2191 | |
2192 | /* Return malloced memory for the name of the option OPTION_INDEX | |
2193 | which enabled a diagnostic (context CONTEXT), originally of type | |
2194 | ORIG_DIAG_KIND but possibly converted to DIAG_KIND by options such | |
2195 | as -Werror. */ | |
2196 | ||
2197 | char * | |
2198 | option_name (diagnostic_context *context, int option_index, | |
2199 | diagnostic_t orig_diag_kind, diagnostic_t diag_kind) | |
2200 | { | |
2201 | if (option_index) | |
2202 | { | |
2203 | /* A warning classified as an error. */ | |
2204 | if ((orig_diag_kind == DK_WARNING || orig_diag_kind == DK_PEDWARN) | |
2205 | && diag_kind == DK_ERROR) | |
2206 | return concat (cl_options[OPT_Werror_].opt_text, | |
2207 | /* Skip over "-W". */ | |
2208 | cl_options[option_index].opt_text + 2, | |
2209 | NULL); | |
2210 | /* A warning with option. */ | |
2211 | else | |
2212 | return xstrdup (cl_options[option_index].opt_text); | |
2213 | } | |
2214 | /* A warning without option classified as an error. */ | |
6f648625 | 2215 | else if ((orig_diag_kind == DK_WARNING || orig_diag_kind == DK_PEDWARN |
2216 | || diag_kind == DK_WARNING) | |
2217 | && context->warning_as_error_requested) | |
2218 | return xstrdup (cl_options[OPT_Werror].opt_text); | |
3c6a9715 | 2219 | else |
2220 | return NULL; | |
2221 | } |