Line data Source code
1 : /* Command line option handling. Code involving global state that
2 : should not be shared with the driver.
3 : Copyright (C) 2002-2026 Free Software Foundation, Inc.
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
9 : Software Foundation; either version 3, or (at your option) any later
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
18 : along with GCC; see the file COPYING3. If not see
19 : <http://www.gnu.org/licenses/>. */
20 :
21 : #include "config.h"
22 : #include "system.h"
23 : #include "coretypes.h"
24 : #include "backend.h"
25 : #include "rtl.h"
26 : #include "tree.h"
27 : #include "tree-pass.h"
28 : #include "diagnostic.h"
29 : #include "opts.h"
30 : #include "flags.h"
31 : #include "langhooks.h"
32 : #include "dbgcnt.h"
33 : #include "debug.h"
34 : #include "output.h"
35 : #include "plugin.h"
36 : #include "toplev.h"
37 : #include "context.h"
38 : #include "stringpool.h"
39 : #include "attribs.h"
40 : #include "asan.h"
41 : #include "file-prefix-map.h" /* add_*_prefix_map() */
42 :
43 : typedef const char *const_char_p; /* For DEF_VEC_P. */
44 :
45 : static vec<const_char_p> ignored_options;
46 :
47 : /* Input file names. */
48 : const char **in_fnames;
49 : unsigned num_in_fnames;
50 :
51 : /* Return a malloced slash-separated list of languages in MASK. */
52 :
53 : char *
54 588 : write_langs (unsigned int mask)
55 : {
56 588 : unsigned int n = 0, len = 0;
57 588 : const char *lang_name;
58 588 : char *result;
59 :
60 9996 : for (n = 0; (lang_name = lang_names[n]) != 0; n++)
61 9408 : if (mask & (1U << n))
62 726 : len += strlen (lang_name) + 1;
63 :
64 : /* Allocate at least one character as we'll terminate the string
65 : at the very end of this function. */
66 588 : result = XNEWVEC (char, MAX (1, len));
67 588 : len = 0;
68 10584 : for (n = 0; (lang_name = lang_names[n]) != 0; n++)
69 9408 : if (mask & (1U << n))
70 : {
71 726 : if (len)
72 139 : result[len++] = '/';
73 726 : strcpy (result + len, lang_name);
74 726 : len += strlen (lang_name);
75 : }
76 :
77 588 : result[len] = 0;
78 :
79 588 : return result;
80 : }
81 :
82 : /* Complain that switch DECODED does not apply to this front end (mask
83 : LANG_MASK). */
84 :
85 : static void
86 492 : complain_wrong_lang (const struct cl_decoded_option *decoded,
87 : unsigned int lang_mask)
88 : {
89 492 : const struct cl_option *option = &cl_options[decoded->opt_index];
90 492 : const char *text = decoded->orig_option_with_args_text;
91 492 : char *ok_langs = NULL, *bad_lang = NULL;
92 492 : unsigned int opt_flags = option->flags;
93 :
94 492 : if (!warn_complain_wrong_lang)
95 : return;
96 :
97 299 : if (!lang_hooks.complain_wrong_lang_p (option))
98 : return;
99 :
100 293 : opt_flags &= ((1U << cl_lang_count) - 1) | CL_DRIVER;
101 293 : if (opt_flags != CL_DRIVER)
102 293 : ok_langs = write_langs (opt_flags);
103 293 : if (lang_mask != CL_DRIVER)
104 293 : bad_lang = write_langs (lang_mask);
105 :
106 293 : if (opt_flags == CL_DRIVER)
107 0 : error ("command-line option %qs is valid for the driver but not for %s",
108 : text, bad_lang);
109 293 : else if (lang_mask == CL_DRIVER)
110 0 : gcc_unreachable ();
111 293 : else if (ok_langs[0] != '\0')
112 : /* Eventually this should become a hard error IMO. */
113 292 : warning (0, "command-line option %qs is valid for %s but not for %s",
114 : text, ok_langs, bad_lang);
115 : else
116 : /* Happens for -Werror=warning_name. */
117 1 : warning (0, "%<-Werror=%> argument %qs is not valid for %s",
118 : text, bad_lang);
119 :
120 293 : free (ok_langs);
121 293 : free (bad_lang);
122 : }
123 :
124 : /* Buffer the unknown option described by the string OPT. Currently,
125 : we only complain about unknown -Wno-* options if they may have
126 : prevented a diagnostic. Otherwise, we just ignore them. Note that
127 : if we do complain, it is only as a warning, not an error; passing
128 : the compiler an unrecognized -Wno-* option should never change
129 : whether the compilation succeeds or fails. */
130 :
131 : static void
132 91 : postpone_unknown_option_warning (const char *opt)
133 : {
134 0 : ignored_options.safe_push (opt);
135 0 : }
136 :
137 : /* Produce a warning for each option previously buffered. */
138 :
139 : void
140 39899 : print_ignored_options (void)
141 : {
142 39922 : while (!ignored_options.is_empty ())
143 : {
144 23 : const char *opt;
145 :
146 23 : opt = ignored_options.pop ();
147 : /* Use inform, not warning_at, to avoid promoting these to errors. */
148 23 : inform (UNKNOWN_LOCATION,
149 : "unrecognized command-line option %qs may have been intended "
150 : "to silence earlier diagnostics", opt);
151 : }
152 39899 : }
153 :
154 : /* Handle an unknown option DECODED, returning true if an error should
155 : be given. */
156 :
157 : static bool
158 91 : unknown_option_callback (const struct cl_decoded_option *decoded)
159 : {
160 91 : const char *opt = decoded->arg;
161 :
162 91 : if (opt[1] == 'W' && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-'
163 91 : && !(decoded->errors & CL_ERR_NEGATIVE))
164 : {
165 : /* We don't generate warnings for unknown -Wno-* options unless
166 : we issue diagnostics. */
167 91 : postpone_unknown_option_warning (opt);
168 91 : return false;
169 : }
170 : else
171 : return true;
172 : }
173 :
174 : /* Handle a front-end option; arguments and return value as for
175 : handle_option. */
176 :
177 : static bool
178 4205359 : lang_handle_option (struct gcc_options *opts,
179 : struct gcc_options *opts_set,
180 : const struct cl_decoded_option *decoded,
181 : unsigned int lang_mask ATTRIBUTE_UNUSED, int kind,
182 : location_t loc,
183 : const struct cl_option_handlers *handlers,
184 : diagnostics::context *dc,
185 : void (*) (void))
186 : {
187 4205359 : gcc_assert (opts == &global_options);
188 4205359 : gcc_assert (opts_set == &global_options_set);
189 4205359 : gcc_assert (dc == global_dc);
190 4205359 : gcc_assert (decoded->canonical_option_num_elements <= 2);
191 4205359 : return lang_hooks.handle_option (decoded->opt_index, decoded->arg,
192 4205359 : decoded->value, kind, loc, handlers);
193 : }
194 :
195 : /* Handle FILENAME from the command line. */
196 :
197 : static void
198 296521 : add_input_filename (const char *filename)
199 : {
200 296521 : num_in_fnames++;
201 296521 : in_fnames = XRESIZEVEC (const char *, in_fnames, num_in_fnames);
202 296521 : in_fnames[num_in_fnames - 1] = filename;
203 296521 : }
204 :
205 : /* Handle the vector of command line options (located at LOC), storing
206 : the results of processing DECODED_OPTIONS and DECODED_OPTIONS_COUNT
207 : in OPTS and OPTS_SET and using DC for diagnostic state. LANG_MASK
208 : contains has a single bit set representing the current language.
209 : HANDLERS describes what functions to call for the options. */
210 :
211 : static void
212 629766 : read_cmdline_options (struct gcc_options *opts, struct gcc_options *opts_set,
213 : struct cl_decoded_option *decoded_options,
214 : unsigned int decoded_options_count,
215 : location_t loc,
216 : unsigned int lang_mask,
217 : const struct cl_option_handlers *handlers,
218 : diagnostics::context *dc)
219 : {
220 629766 : unsigned int i;
221 :
222 10646069 : for (i = 1; i < decoded_options_count; i++)
223 : {
224 10016303 : if (decoded_options[i].opt_index == OPT_SPECIAL_input_file)
225 : {
226 : /* Input files should only ever appear on the main command
227 : line. */
228 296521 : gcc_assert (opts == &global_options);
229 296521 : gcc_assert (opts_set == &global_options_set);
230 :
231 296521 : if (opts->x_main_input_filename == NULL)
232 : {
233 285722 : opts->x_main_input_filename = decoded_options[i].arg;
234 285722 : opts->x_main_input_baselength
235 285722 : = base_of_path (opts->x_main_input_filename,
236 : &opts->x_main_input_basename);
237 : }
238 296521 : add_input_filename (decoded_options[i].arg);
239 296521 : continue;
240 : }
241 :
242 9719782 : read_cmdline_option (opts, opts_set,
243 : decoded_options + i, loc, lang_mask, handlers,
244 : dc);
245 : }
246 629766 : }
247 :
248 : /* Language mask determined at initialization. */
249 : static unsigned int initial_lang_mask;
250 :
251 : /* Initialize global options-related settings at start-up. */
252 :
253 : void
254 285722 : init_options_once (void)
255 : {
256 : /* Perform language-specific options initialization. */
257 285722 : initial_lang_mask = lang_hooks.option_lang_mask ();
258 :
259 285722 : const bool show_highlight_colors
260 285722 : = pp_show_highlight_colors (global_dc->get_reference_printer ());
261 :
262 285722 : lang_hooks.initialize_diagnostics (global_dc);
263 : /* ??? Ideally, we should do this earlier and the FEs will override
264 : it if desired (none do it so far). However, the way the FEs
265 : construct their pretty-printers means that all previous settings
266 : are overriden. */
267 285722 : global_dc->set_show_highlight_colors (show_highlight_colors);
268 :
269 285722 : diagnostic_color_init (global_dc);
270 285722 : diagnostic_urls_init (global_dc);
271 285722 : global_dc->refresh_output_sinks ();
272 285722 : }
273 :
274 : /* Decode command-line options to an array, like
275 : decode_cmdline_options_to_array and with the same arguments but
276 : using the default lang_mask. */
277 :
278 : void
279 629766 : decode_cmdline_options_to_array_default_mask (unsigned int argc,
280 : const char **argv,
281 : struct cl_decoded_option **decoded_options,
282 : unsigned int *decoded_options_count)
283 : {
284 629766 : decode_cmdline_options_to_array (argc, argv,
285 : initial_lang_mask | CL_COMMON | CL_TARGET,
286 : decoded_options, decoded_options_count);
287 629766 : }
288 :
289 : /* Set *HANDLERS to the default set of option handlers for use in the
290 : compilers proper (not the driver). */
291 : void
292 4586433 : set_default_handlers (struct cl_option_handlers *handlers,
293 : void (*target_option_override_hook) (void))
294 : {
295 4586433 : handlers->unknown_option_callback = unknown_option_callback;
296 4586433 : handlers->wrong_lang_callback = complain_wrong_lang;
297 4586433 : handlers->target_option_override_hook = target_option_override_hook;
298 4586433 : handlers->num_handlers = 3;
299 4586433 : handlers->handlers[0].handler = lang_handle_option;
300 4586433 : handlers->handlers[0].mask = initial_lang_mask;
301 4586433 : handlers->handlers[1].handler = common_handle_option;
302 4586433 : handlers->handlers[1].mask = CL_COMMON;
303 4586433 : handlers->handlers[2].handler = target_handle_option;
304 4586433 : handlers->handlers[2].mask = CL_TARGET;
305 4586433 : }
306 :
307 : /* Parse command line options and set default flag values. Do minimal
308 : options processing. The decoded options are in *DECODED_OPTIONS
309 : and *DECODED_OPTIONS_COUNT; settings go in OPTS, OPTS_SET and DC;
310 : the options are located at LOC. */
311 : void
312 629766 : decode_options (struct gcc_options *opts, struct gcc_options *opts_set,
313 : struct cl_decoded_option *decoded_options,
314 : unsigned int decoded_options_count,
315 : location_t loc, diagnostics::context *dc,
316 : void (*target_option_override_hook) (void))
317 : {
318 629766 : struct cl_option_handlers handlers;
319 :
320 629766 : unsigned int lang_mask;
321 :
322 629766 : lang_mask = initial_lang_mask;
323 :
324 629766 : set_default_handlers (&handlers, target_option_override_hook);
325 :
326 629766 : default_options_optimization (opts, opts_set,
327 : decoded_options, decoded_options_count,
328 : loc, lang_mask, &handlers, dc);
329 :
330 629766 : read_cmdline_options (opts, opts_set,
331 : decoded_options, decoded_options_count,
332 : loc, lang_mask,
333 : &handlers, dc);
334 :
335 629766 : finish_options (opts, opts_set, loc);
336 :
337 : /* Print --help=* if used. */
338 629766 : unsigned i;
339 629766 : const char *arg;
340 :
341 629766 : if (!help_option_arguments.is_empty ())
342 : {
343 : /* Make sure --help=* sees the overridden values. */
344 71 : target_option_override_hook ();
345 :
346 215 : FOR_EACH_VEC_ELT (help_option_arguments, i, arg)
347 73 : print_help (opts, lang_mask, arg);
348 : }
349 629766 : }
350 :
351 : /* Hold command-line options associated with stack limitation. */
352 : const char *opt_fstack_limit_symbol_arg = NULL;
353 : int opt_fstack_limit_register_no = -1;
354 :
355 : /* Process common options that have been deferred until after the
356 : handlers have been called for all options. */
357 :
358 : void
359 285722 : handle_common_deferred_options (void)
360 : {
361 285722 : unsigned int i;
362 285722 : cl_deferred_option *opt;
363 285722 : vec<cl_deferred_option> v;
364 :
365 285722 : if (common_deferred_options)
366 23413 : v = *((vec<cl_deferred_option> *) common_deferred_options);
367 : else
368 : v = vNULL;
369 :
370 285722 : if (flag_dump_all_passed)
371 4 : enable_rtl_dump_file ();
372 :
373 285722 : if (flag_opt_info)
374 1 : opt_info_switch_p (NULL);
375 :
376 285722 : flag_canon_prefix_map = false;
377 311930 : FOR_EACH_VEC_ELT (v, i, opt)
378 : {
379 26212 : switch (opt->opt_index)
380 : {
381 0 : case OPT_fcall_used_:
382 0 : fix_register (opt->arg, 0, 1);
383 0 : break;
384 :
385 0 : case OPT_fcall_saved_:
386 0 : fix_register (opt->arg, 0, 0);
387 0 : break;
388 :
389 3 : case OPT_fdbg_cnt_:
390 3 : dbg_cnt_process_opt (opt->arg);
391 3 : break;
392 :
393 552 : case OPT_fdebug_prefix_map_:
394 552 : add_debug_prefix_map (opt->arg);
395 552 : break;
396 :
397 220 : case OPT_ffile_prefix_map_:
398 220 : add_file_prefix_map (opt->arg);
399 220 : break;
400 :
401 0 : case OPT_fprofile_prefix_map_:
402 0 : add_profile_prefix_map (opt->arg);
403 0 : break;
404 :
405 0 : case OPT_fcanon_prefix_map:
406 0 : flag_canon_prefix_map = opt->value;
407 0 : break;
408 :
409 : case OPT_fdump_:
410 : /* Deferred until plugins initialized. */
411 : break;
412 :
413 674 : case OPT_fopt_info_:
414 674 : if (!opt_info_switch_p (opt->arg))
415 0 : error ("unrecognized command-line option %<-fopt-info-%s%>",
416 : opt->arg);
417 : break;
418 :
419 209 : case OPT_fenable_:
420 209 : case OPT_fdisable_:
421 209 : if (opt->opt_index == OPT_fenable_)
422 4 : enable_pass (opt->arg);
423 : else
424 205 : disable_pass (opt->arg);
425 : break;
426 :
427 93 : case OPT_ffixed_:
428 : /* Deferred. */
429 93 : fix_register (opt->arg, 1, 1);
430 93 : break;
431 :
432 257 : case OPT_fplugin_:
433 : #ifdef ENABLE_PLUGIN
434 257 : add_new_plugin (opt->arg);
435 : #else
436 : error ("plugin support is disabled; configure with "
437 : "%<--enable-plugin%>");
438 : #endif
439 257 : break;
440 :
441 17 : case OPT_fplugin_arg_:
442 : #ifdef ENABLE_PLUGIN
443 17 : parse_plugin_arg_opt (opt->arg);
444 : #else
445 : error ("plugin support is disabled; configure with "
446 : "%<--enable-plugin%>");
447 : #endif
448 17 : break;
449 :
450 0 : case OPT_frandom_seed:
451 : /* The real switch is -fno-random-seed. */
452 0 : if (!opt->value)
453 0 : set_random_seed (NULL);
454 : break;
455 :
456 1794 : case OPT_frandom_seed_:
457 1794 : set_random_seed (opt->arg);
458 1794 : break;
459 :
460 1 : case OPT_fstack_limit:
461 : /* The real switch is -fno-stack-limit. */
462 1 : if (!opt->value)
463 0 : stack_limit_rtx = NULL_RTX;
464 : break;
465 :
466 0 : case OPT_fstack_limit_register_:
467 0 : {
468 0 : int reg = decode_reg_name (opt->arg);
469 0 : if (reg < 0)
470 0 : error ("unrecognized register name %qs", opt->arg);
471 : else
472 : {
473 : /* Deactivate previous OPT_fstack_limit_symbol_ options. */
474 0 : opt_fstack_limit_symbol_arg = NULL;
475 0 : opt_fstack_limit_register_no = reg;
476 : }
477 : }
478 : break;
479 :
480 0 : case OPT_fstack_limit_symbol_:
481 : /* Deactivate previous OPT_fstack_limit_register_ options. */
482 0 : opt_fstack_limit_register_no = -1;
483 0 : opt_fstack_limit_symbol_arg = opt->arg;
484 0 : break;
485 :
486 11 : case OPT_fasan_shadow_offset_:
487 11 : if (!(flag_sanitize & SANITIZE_KERNEL_ADDRESS))
488 0 : error ("%<-fasan-shadow-offset%> should only be used "
489 : "with %<-fsanitize=kernel-address%>");
490 11 : if (!set_asan_shadow_offset (opt->arg))
491 0 : error ("unrecognized shadow offset %qs", opt->arg);
492 : break;
493 :
494 40 : case OPT_fsanitize_sections_:
495 40 : set_sanitized_sections (opt->arg);
496 40 : break;
497 :
498 0 : default:
499 0 : gcc_unreachable ();
500 : }
501 : }
502 285718 : }
503 :
504 : /* Handle deferred dump options. */
505 :
506 : void
507 285718 : handle_deferred_dump_options (void)
508 : {
509 285718 : unsigned int i;
510 285718 : cl_deferred_option *opt;
511 285718 : vec<cl_deferred_option> v;
512 :
513 285718 : if (common_deferred_options)
514 23409 : v = *((vec<cl_deferred_option> *) common_deferred_options);
515 : else
516 : v = vNULL;
517 311926 : FOR_EACH_VEC_ELT (v, i, opt)
518 26208 : if (opt->opt_index == OPT_fdump_)
519 22341 : g->get_dumps ()->dump_switch_p (opt->arg);
520 285718 : }
|