Line data Source code
1 : /* Command line option handling.
2 : Copyright (C) 2006-2026 Free Software Foundation, Inc.
3 :
4 : This file is part of GCC.
5 :
6 : GCC is free software; you can redistribute it and/or modify it under
7 : the terms of the GNU General Public License as published by the Free
8 : Software Foundation; either version 3, or (at your option) any later
9 : version.
10 :
11 : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 : WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 : for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with GCC; see the file COPYING3. If not see
18 : <http://www.gnu.org/licenses/>. */
19 :
20 : #define INCLUDE_STRING
21 : #define INCLUDE_VECTOR
22 : #include "config.h"
23 : #include "system.h"
24 : #include "intl.h"
25 : #include "coretypes.h"
26 : #include "opts.h"
27 : #include "options.h"
28 : #include "diagnostic.h"
29 : #include "opts-diagnostic.h"
30 : #include "spellcheck.h"
31 : #include "opts-jobserver.h"
32 :
33 : static void prune_options (struct cl_decoded_option **, unsigned int *);
34 :
35 : /* An option that is undocumented, that takes a joined argument, and
36 : that doesn't fit any of the classes of uses (language/common,
37 : driver, target) is assumed to be a prefix used to catch
38 : e.g. negated options, and stop them from being further shortened to
39 : a prefix that could use the negated option as an argument. For
40 : example, we want -gno-statement-frontiers to be taken as a negation
41 : of -gstatement-frontiers, but without catching the gno- prefix and
42 : signaling it's to be used for option remapping, it would end up
43 : backtracked to g with no-statement-frontiers as the debug level. */
44 :
45 : static bool
46 6738353 : remapping_prefix_p (const struct cl_option *opt)
47 : {
48 6738353 : return opt->flags & CL_UNDOCUMENTED
49 144616 : && opt->flags & CL_JOINED
50 6759734 : && !(opt->flags & (CL_DRIVER | CL_TARGET | CL_COMMON | CL_LANG_ALL));
51 : }
52 :
53 : /* Perform a binary search to find which option the command-line INPUT
54 : matches. Returns its index in the option array, and
55 : OPT_SPECIAL_unknown on failure.
56 :
57 : This routine is quite subtle. A normal binary search is not good
58 : enough because some options can be suffixed with an argument, and
59 : multiple sub-matches can occur, e.g. input of "-pedantic" matching
60 : the initial substring of "-pedantic-errors".
61 :
62 : A more complicated example is -gstabs. It should match "-g" with
63 : an argument of "stabs". Suppose, however, that the number and list
64 : of switches are such that the binary search tests "-gen-decls"
65 : before having tested "-g". This doesn't match, and as "-gen-decls"
66 : is less than "-gstabs", it will become the lower bound of the
67 : binary search range, and "-g" will never be seen. To resolve this
68 : issue, 'optc-gen.awk' makes "-gen-decls" point, via the back_chain member,
69 : to "-g" so that failed searches that end between "-gen-decls" and
70 : the lexicographically subsequent switch know to go back and see if
71 : "-g" causes a match (which it does in this example).
72 :
73 : This search is done in such a way that the longest match for the
74 : front end in question wins. If there is no match for the current
75 : front end, the longest match for a different front end is returned
76 : (or N_OPTS if none) and the caller emits an error message. */
77 : size_t
78 23664392 : find_opt (const char *input, unsigned int lang_mask)
79 : {
80 23664392 : size_t mn, mn_orig, mx, md, opt_len;
81 23664392 : size_t match_wrong_lang;
82 23664392 : int comp;
83 :
84 23664392 : mn = 0;
85 23664392 : mx = cl_options_count;
86 :
87 : /* Find mn such this lexicographical inequality holds:
88 : cl_options[mn] <= input < cl_options[mn + 1]. */
89 317012821 : while (mx - mn > 1)
90 : {
91 269684037 : md = (mn + mx) / 2;
92 269684037 : opt_len = cl_options[md].opt_len;
93 269684037 : comp = strncmp (input, cl_options[md].opt_text + 1, opt_len);
94 :
95 269684037 : if (comp < 0)
96 : mx = md;
97 : else
98 161572139 : mn = md;
99 : }
100 :
101 : mn_orig = mn;
102 :
103 : /* This is the switch that is the best match but for a different
104 : front end, or OPT_SPECIAL_unknown if there is no match at all. */
105 : match_wrong_lang = OPT_SPECIAL_unknown;
106 :
107 : /* Backtrace the chain of possible matches, returning the longest
108 : one, if any, that fits best. With current GCC switches, this
109 : loop executes at most twice. */
110 23826571 : do
111 : {
112 23826571 : const struct cl_option *opt = &cl_options[mn];
113 :
114 : /* Is the input either an exact match or a prefix that takes a
115 : joined argument? */
116 23826571 : if (!strncmp (input, opt->opt_text + 1, opt->opt_len)
117 20348757 : && (input[opt->opt_len] == '\0' || (opt->flags & CL_JOINED)))
118 : {
119 : /* If language is OK, return it. */
120 20348500 : if (opt->flags & lang_mask)
121 : return mn;
122 :
123 4944113 : if (remapping_prefix_p (opt))
124 : return OPT_SPECIAL_unknown;
125 :
126 : /* If we haven't remembered a prior match, remember this
127 : one. Any prior match is necessarily better. */
128 4942623 : if (match_wrong_lang == OPT_SPECIAL_unknown)
129 8420694 : match_wrong_lang = mn;
130 : }
131 :
132 : /* Try the next possibility. This is cl_options_count if there
133 : are no more. */
134 8420694 : mn = opt->back_chain;
135 : }
136 8420694 : while (mn != cl_options_count);
137 :
138 8258515 : if (match_wrong_lang == OPT_SPECIAL_unknown && input[0] == '-')
139 : {
140 : /* Long options, starting "--", may be abbreviated if the
141 : abbreviation is unambiguous. This only applies to options
142 : not taking a joined argument, and abbreviations of "--option"
143 : are permitted even if there is a variant "--option=". */
144 32 : size_t mnc = mn_orig + 1;
145 32 : size_t cmp_len = strlen (input);
146 32 : while (mnc < cl_options_count
147 34 : && strncmp (input, cl_options[mnc].opt_text + 1, cmp_len) == 0)
148 : {
149 : /* Option matching this abbreviation. OK if it is the first
150 : match and that does not take a joined argument, or the
151 : second match, taking a joined argument and with only '='
152 : added to the first match; otherwise considered
153 : ambiguous. */
154 2 : if (mnc == mn_orig + 1
155 2 : && !(cl_options[mnc].flags & CL_JOINED))
156 : match_wrong_lang = mnc;
157 0 : else if (mnc == mn_orig + 2
158 0 : && match_wrong_lang == mn_orig + 1
159 0 : && (cl_options[mnc].flags & CL_JOINED)
160 0 : && (cl_options[mnc].opt_len
161 0 : == cl_options[mn_orig + 1].opt_len + 1)
162 0 : && strncmp (cl_options[mnc].opt_text + 1,
163 0 : cl_options[mn_orig + 1].opt_text + 1,
164 : cl_options[mn_orig + 1].opt_len) == 0)
165 : ; /* OK, as long as there are no more matches. */
166 : else
167 : return OPT_SPECIAL_unknown;
168 2 : mnc++;
169 : }
170 : }
171 :
172 : /* Return the best wrong match, or OPT_SPECIAL_unknown if none. */
173 : return match_wrong_lang;
174 : }
175 :
176 : /* If ARG is a non-negative decimal or hexadecimal integer representable
177 : in HOST_WIDE_INT return its value, otherwise return -1. If ERR is not
178 : null set *ERR to zero on success or to EINVAL or to the value of errno
179 : otherwise. */
180 :
181 : HOST_WIDE_INT
182 823106 : integral_argument (const char *arg, int *err, bool byte_size_suffix)
183 : {
184 823106 : if (!err)
185 557893 : err = &errno;
186 :
187 823106 : if (!ISDIGIT (*arg))
188 : {
189 0 : *err = EINVAL;
190 0 : return -1;
191 : }
192 :
193 823106 : *err = 0;
194 823106 : errno = 0;
195 :
196 823106 : char *end = NULL;
197 823106 : unsigned HOST_WIDE_INT unit = 1;
198 823106 : unsigned HOST_WIDE_INT value = strtoull (arg, &end, 10);
199 :
200 : /* If the value is too large to be represented use the maximum
201 : representable value that strtoull sets VALUE to (setting
202 : errno to ERANGE). */
203 :
204 823106 : if (end && *end)
205 : {
206 50 : if (!byte_size_suffix)
207 : {
208 4 : errno = 0;
209 4 : value = strtoull (arg, &end, 0);
210 4 : if (*end)
211 : {
212 2 : if (errno)
213 0 : *err = errno;
214 : else
215 2 : *err = EINVAL;
216 2 : return -1;
217 : }
218 :
219 2 : return value;
220 : }
221 :
222 : /* Numeric option arguments are at most INT_MAX. Make it
223 : possible to specify a larger value by accepting common
224 : suffixes. */
225 46 : if (!strcmp (end, "kB"))
226 : unit = 1000;
227 44 : else if (!strcasecmp (end, "KiB") || !strcmp (end, "KB"))
228 : unit = 1024;
229 38 : else if (!strcmp (end, "MB"))
230 : unit = HOST_WIDE_INT_UC (1000) * 1000;
231 36 : else if (!strcasecmp (end, "MiB"))
232 : unit = HOST_WIDE_INT_UC (1024) * 1024;
233 32 : else if (!strcasecmp (end, "GB"))
234 : unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000;
235 28 : else if (!strcasecmp (end, "GiB"))
236 : unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024;
237 26 : else if (!strcasecmp (end, "TB"))
238 : unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000;
239 24 : else if (!strcasecmp (end, "TiB"))
240 : unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024;
241 22 : else if (!strcasecmp (end, "PB"))
242 : unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000 * 1000;
243 20 : else if (!strcasecmp (end, "PiB"))
244 : unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024 * 1024;
245 18 : else if (!strcasecmp (end, "EB"))
246 : unit = HOST_WIDE_INT_UC (1000) * 1000 * 1000 * 1000 * 1000
247 : * 1000;
248 16 : else if (!strcasecmp (end, "EiB"))
249 : unit = HOST_WIDE_INT_UC (1024) * 1024 * 1024 * 1024 * 1024
250 : * 1024;
251 : else
252 : {
253 : /* This could mean an unknown suffix or a bad prefix, like
254 : "+-1". */
255 3 : *err = EINVAL;
256 3 : return -1;
257 : }
258 : }
259 :
260 : if (unit)
261 : {
262 823099 : unsigned HOST_WIDE_INT prod = value * unit;
263 823099 : value = prod < value ? HOST_WIDE_INT_M1U : prod;
264 : }
265 :
266 823099 : return value;
267 : }
268 :
269 : /* Return whether OPTION is OK for the language given by
270 : LANG_MASK. */
271 : static bool
272 158640540 : option_ok_for_language (const struct cl_option *option,
273 : unsigned int lang_mask)
274 : {
275 158640540 : if (!(option->flags & lang_mask))
276 : return false;
277 78648110 : else if ((option->flags & CL_TARGET)
278 66965305 : && (option->flags & (CL_LANG_ALL | CL_DRIVER))
279 0 : && !(option->flags & (lang_mask & ~CL_COMMON & ~CL_TARGET)))
280 : /* Complain for target flag language mismatches if any languages
281 : are specified. */
282 0 : return false;
283 : return true;
284 : }
285 :
286 : /* Return whether ENUM_ARG is OK for the language given by
287 : LANG_MASK. */
288 :
289 : static bool
290 5016948 : enum_arg_ok_for_language (const struct cl_enum_arg *enum_arg,
291 : unsigned int lang_mask)
292 : {
293 2367103 : return (lang_mask & CL_DRIVER) || !(enum_arg->flags & CL_ENUM_DRIVER_ONLY);
294 : }
295 :
296 : /* Look up ARG in ENUM_ARGS for language LANG_MASK, returning the cl_enum_arg
297 : index and storing the value in *VALUE if found, and returning -1 without
298 : modifying *VALUE if not found. */
299 :
300 : static int
301 2557145 : enum_arg_to_value (const struct cl_enum_arg *enum_args,
302 : const char *arg, size_t len, HOST_WIDE_INT *value,
303 : unsigned int lang_mask)
304 : {
305 2557145 : unsigned int i;
306 :
307 7754308 : for (i = 0; enum_args[i].arg != NULL; i++)
308 7754303 : if ((len
309 7754303 : ? (strncmp (arg, enum_args[i].arg, len) == 0
310 274 : && enum_args[i].arg[len] == '\0')
311 7753601 : : strcmp (arg, enum_args[i].arg) == 0)
312 15508178 : && enum_arg_ok_for_language (&enum_args[i], lang_mask))
313 : {
314 2557140 : *value = enum_args[i].value;
315 2557140 : return i;
316 : }
317 :
318 : return -1;
319 : }
320 :
321 : /* Look up ARG in the enum used by option OPT_INDEX for language
322 : LANG_MASK, returning true and storing the value in *VALUE if found,
323 : and returning false without modifying *VALUE if not found. */
324 :
325 : bool
326 187 : opt_enum_arg_to_value (size_t opt_index, const char *arg,
327 : int *value, unsigned int lang_mask)
328 : {
329 187 : const struct cl_option *option = &cl_options[opt_index];
330 :
331 187 : gcc_assert (option->var_type == CLVC_ENUM);
332 :
333 187 : HOST_WIDE_INT wideval;
334 187 : if (enum_arg_to_value (cl_enums[option->var_enum].values, arg, 0,
335 : &wideval, lang_mask) >= 0)
336 : {
337 187 : *value = wideval;
338 187 : return true;
339 : }
340 :
341 : return false;
342 : }
343 :
344 : /* Look of VALUE in ENUM_ARGS for language LANG_MASK and store the
345 : corresponding string in *ARGP, returning true if the found string
346 : was marked as canonical, false otherwise. If VALUE is not found
347 : (which may be the case for uninitialized values if the relevant
348 : option has not been passed), set *ARGP to NULL and return
349 : false. */
350 :
351 : bool
352 2459810 : enum_value_to_arg (const struct cl_enum_arg *enum_args,
353 : const char **argp, int value, unsigned int lang_mask)
354 : {
355 2459810 : unsigned int i;
356 :
357 10640008 : for (i = 0; enum_args[i].arg != NULL; i++)
358 8180198 : if (enum_args[i].value == value
359 2460488 : && (enum_args[i].flags & CL_ENUM_CANONICAL)
360 10640686 : && enum_arg_ok_for_language (&enum_args[i], lang_mask))
361 : {
362 0 : *argp = enum_args[i].arg;
363 0 : return true;
364 : }
365 :
366 7408026 : for (i = 0; enum_args[i].arg != NULL; i++)
367 7408016 : if (enum_args[i].value == value
368 7408016 : && enum_arg_ok_for_language (&enum_args[i], lang_mask))
369 : {
370 2459800 : *argp = enum_args[i].arg;
371 2459800 : return false;
372 : }
373 :
374 10 : *argp = NULL;
375 10 : return false;
376 : }
377 :
378 : /* Fill in the canonical option part of *DECODED with an option
379 : described by OPT_INDEX, ARG and VALUE. */
380 :
381 : static void
382 158634557 : generate_canonical_option (size_t opt_index, const char *arg,
383 : HOST_WIDE_INT value,
384 : struct cl_decoded_option *decoded)
385 : {
386 158634557 : const struct cl_option *option = &cl_options[opt_index];
387 158634557 : const char *opt_text = option->opt_text;
388 :
389 158634557 : if (value == 0
390 28683195 : && !option->cl_reject_negative
391 26592956 : && (opt_text[1] == 'W' || opt_text[1] == 'f'
392 : || opt_text[1] == 'g' || opt_text[1] == 'm'))
393 : {
394 26585396 : char *t = XOBNEWVEC (&opts_obstack, char, option->opt_len + 5);
395 26585396 : t[0] = '-';
396 26585396 : t[1] = opt_text[1];
397 26585396 : t[2] = 'n';
398 26585396 : t[3] = 'o';
399 26585396 : t[4] = '-';
400 26585396 : memcpy (t + 5, opt_text + 2, option->opt_len);
401 26585396 : opt_text = t;
402 : }
403 :
404 158634557 : decoded->canonical_option[2] = NULL;
405 158634557 : decoded->canonical_option[3] = NULL;
406 :
407 158634557 : if (arg)
408 : {
409 10385025 : if ((option->flags & CL_SEPARATE)
410 4803978 : && !option->cl_separate_alias)
411 : {
412 4803978 : decoded->canonical_option[0] = opt_text;
413 4803978 : decoded->canonical_option[1] = arg;
414 4803978 : decoded->canonical_option_num_elements = 2;
415 : }
416 : else
417 : {
418 5581047 : gcc_assert (option->flags & CL_JOINED);
419 5581047 : decoded->canonical_option[0] = opts_concat (opt_text, arg, NULL);
420 5581047 : decoded->canonical_option[1] = NULL;
421 5581047 : decoded->canonical_option_num_elements = 1;
422 : }
423 : }
424 : else
425 : {
426 148249532 : decoded->canonical_option[0] = opt_text;
427 148249532 : decoded->canonical_option[1] = NULL;
428 148249532 : decoded->canonical_option_num_elements = 1;
429 : }
430 158634557 : }
431 :
432 : /* Structure describing mappings from options on the command line to
433 : options to look up with find_opt. */
434 : struct option_map
435 : {
436 : /* Prefix of the option on the command line. */
437 : const char *opt0;
438 : /* If two argv elements are considered to be merged into one option,
439 : prefix for the second element, otherwise NULL. */
440 : const char *opt1;
441 : /* The new prefix to map to. */
442 : const char *new_prefix;
443 : /* Whether at least one character is needed following opt1 or opt0
444 : for this mapping to be used. (--optimize= is valid for -O, but
445 : --warn- is not valid for -W.) */
446 : bool another_char_needed;
447 : /* Whether the original option is a negated form of the option
448 : resulting from this map. */
449 : bool negated;
450 : };
451 : static const struct option_map option_map[] =
452 : {
453 : { "-Wno-", NULL, "-W", false, true },
454 : { "-fno-", NULL, "-f", false, true },
455 : { "-gno-", NULL, "-g", false, true },
456 : { "-mno-", NULL, "-m", false, true },
457 : { "--debug=", NULL, "-g", false, false },
458 : { "--machine-", NULL, "-m", true, false },
459 : { "--machine-no-", NULL, "-m", false, true },
460 : { "--machine=", NULL, "-m", false, false },
461 : { "--machine=no-", NULL, "-m", false, true },
462 : { "--machine", "", "-m", false, false },
463 : { "--machine", "no-", "-m", false, true },
464 : { "--optimize=", NULL, "-O", false, false },
465 : { "--std=", NULL, "-std=", false, false },
466 : { "--std", "", "-std=", false, false },
467 : { "--warn-", NULL, "-W", true, false },
468 : { "--warn-no-", NULL, "-W", false, true },
469 : { "--", NULL, "-f", true, false },
470 : { "--no-", NULL, "-f", false, true }
471 : };
472 :
473 : /* Given buffer P of size SZ, look for a prefix within OPTION_MAP;
474 : if found, return the prefix and write the new prefix to *OUT_NEW_PREFIX.
475 : Otherwise return nullptr. */
476 :
477 : const char *
478 29087 : get_option_prefix_remapping (const char *p, size_t sz,
479 : const char **out_new_prefix)
480 : {
481 386551 : for (unsigned i = 0; i < ARRAY_SIZE (option_map); i++)
482 : {
483 367372 : const char * const old_prefix = option_map[i].opt0;
484 367372 : const size_t old_prefix_len = strlen (old_prefix);
485 367372 : if (old_prefix_len <= sz
486 294699 : && !memcmp (p, old_prefix, old_prefix_len))
487 : {
488 9908 : *out_new_prefix = option_map[i].new_prefix;
489 9908 : return old_prefix;
490 : }
491 : }
492 : return nullptr;
493 : }
494 :
495 : /* Helper function for gcc.cc's driver::suggest_option, for populating the
496 : vec of suggestions for misspelled options.
497 :
498 : option_map above provides various prefixes for spelling command-line
499 : options, which decode_cmdline_option uses to map spellings of options
500 : to specific options. We want to do the reverse: to find all the ways
501 : that a user could validly spell an option.
502 :
503 : Given valid OPT_TEXT (with a leading dash) for OPTION, add it and all
504 : of its valid variant spellings to CANDIDATES, each without a leading
505 : dash.
506 :
507 : For example, given "-Wabi-tag", the following are added to CANDIDATES:
508 : "Wabi-tag"
509 : "Wno-abi-tag"
510 : "-warn-abi-tag"
511 : "-warn-no-abi-tag".
512 :
513 : The added strings must be freed using free. */
514 :
515 : void
516 1794240 : add_misspelling_candidates (auto_vec<char *> *candidates,
517 : const struct cl_option *option,
518 : const char *opt_text)
519 : {
520 1794240 : gcc_assert (candidates);
521 1794240 : gcc_assert (option);
522 1794240 : gcc_assert (opt_text);
523 1794240 : if (remapping_prefix_p (option))
524 : return;
525 1793664 : candidates->safe_push (xstrdup (opt_text + 1));
526 34079616 : for (unsigned i = 0; i < ARRAY_SIZE (option_map); i++)
527 : {
528 32285952 : const char *opt0 = option_map[i].opt0;
529 32285952 : const char *opt1 = option_map[i].opt1;
530 32285952 : const char *new_prefix = option_map[i].new_prefix;
531 32285952 : size_t new_prefix_len = strlen (new_prefix);
532 :
533 32285952 : if (option->cl_reject_negative && option_map[i].negated)
534 4639680 : continue;
535 :
536 27646272 : if (strncmp (opt_text, new_prefix, new_prefix_len) == 0)
537 : {
538 3961152 : char *alternative
539 7501824 : = concat (opt0 + 1, opt1 ? " " : "", opt1 ? opt1 : "",
540 3961152 : opt_text + new_prefix_len, NULL);
541 3961152 : candidates->safe_push (alternative);
542 : }
543 : }
544 :
545 : /* For all params (e.g. --param=key=value),
546 : include also '--param key=value'. */
547 1793664 : const char *prefix = "--param=";
548 1793664 : if (strstr (opt_text, prefix) == opt_text)
549 : {
550 193536 : char *param = xstrdup (opt_text + 1);
551 193536 : gcc_assert (param[6] == '=');
552 193536 : param[6] = ' ';
553 193536 : candidates->safe_push (param);
554 : }
555 : }
556 :
557 : /* Decode the switch beginning at ARGV for the language indicated by
558 : LANG_MASK (including CL_COMMON and CL_TARGET if applicable), into
559 : the structure *DECODED. Returns the number of switches
560 : consumed. */
561 :
562 : static unsigned int
563 15514762 : decode_cmdline_option (const char *const *argv, unsigned int lang_mask,
564 : struct cl_decoded_option *decoded)
565 : {
566 15514762 : size_t opt_index;
567 15514762 : const char *arg = 0;
568 15514762 : HOST_WIDE_INT value = 1, mask = 0;
569 15514762 : unsigned int result = 1, i, extra_args, separate_args = 0;
570 15514762 : int adjust_len = 0;
571 15514762 : size_t total_len;
572 15514762 : char *p;
573 15514762 : const struct cl_option *option;
574 15514762 : int errors = 0;
575 15514762 : const char *warn_message = NULL;
576 15514762 : bool separate_arg_flag;
577 15514762 : bool joined_arg_flag;
578 15514762 : bool have_separate_arg = false;
579 :
580 15514762 : extra_args = 0;
581 :
582 15514762 : const char *opt_value = argv[0] + 1;
583 15514762 : opt_index = find_opt (opt_value, lang_mask);
584 15514762 : i = 0;
585 15514762 : while (opt_index == OPT_SPECIAL_unknown
586 22057369 : && i < ARRAY_SIZE (option_map))
587 : {
588 6542607 : const char *opt0 = option_map[i].opt0;
589 6542607 : const char *opt1 = option_map[i].opt1;
590 6542607 : const char *new_prefix = option_map[i].new_prefix;
591 6542607 : bool another_char_needed = option_map[i].another_char_needed;
592 6542607 : size_t opt0_len = strlen (opt0);
593 6542607 : size_t opt1_len = (opt1 == NULL ? 0 : strlen (opt1));
594 2373 : size_t optn_len = (opt1 == NULL ? opt0_len : opt1_len);
595 6542607 : size_t new_prefix_len = strlen (new_prefix);
596 :
597 6542607 : extra_args = (opt1 == NULL ? 0 : 1);
598 6542607 : value = !option_map[i].negated;
599 :
600 6542607 : if (strncmp (argv[0], opt0, opt0_len) == 0
601 3329502 : && (opt1 == NULL
602 0 : || (argv[1] != NULL && strncmp (argv[1], opt1, opt1_len) == 0))
603 3329502 : && (!another_char_needed
604 24 : || argv[extra_args][optn_len] != 0))
605 : {
606 3329502 : size_t arglen = strlen (argv[extra_args]);
607 3329502 : char *dup;
608 :
609 3329502 : adjust_len = (int) optn_len - (int) new_prefix_len;
610 3329502 : dup = XNEWVEC (char, arglen + 1 - adjust_len);
611 3329502 : memcpy (dup, new_prefix, new_prefix_len);
612 3329502 : memcpy (dup + new_prefix_len, argv[extra_args] + optn_len,
613 3329502 : arglen - optn_len + 1);
614 3329502 : opt_index = find_opt (dup + 1, lang_mask);
615 3329502 : free (dup);
616 : }
617 6542607 : i++;
618 : }
619 :
620 15514762 : if (opt_index == OPT_SPECIAL_unknown)
621 : {
622 767 : arg = argv[0];
623 767 : extra_args = 0;
624 767 : value = 1;
625 767 : goto done;
626 : }
627 :
628 15513995 : option = &cl_options[opt_index];
629 :
630 : /* Reject negative form of switches that don't take negatives as
631 : unrecognized. */
632 15513995 : if (!value && option->cl_reject_negative)
633 : {
634 7 : opt_index = OPT_SPECIAL_unknown;
635 7 : errors |= CL_ERR_NEGATIVE;
636 7 : arg = argv[0];
637 7 : goto done;
638 : }
639 :
640 : /* Clear the initial value for size options (it will be overwritten
641 : later based on the Init(value) specification in the opt file. */
642 15513988 : if (option->var_type == CLVC_SIZE)
643 191 : value = 0;
644 :
645 15513988 : result = extra_args + 1;
646 15513988 : warn_message = option->warn_message;
647 :
648 : /* Check to see if the option is disabled for this configuration. */
649 15513988 : if (option->cl_disabled)
650 0 : errors |= CL_ERR_DISABLED;
651 :
652 : /* Determine whether there may be a separate argument based on
653 : whether this option is being processed for the driver, and, if
654 : so, how many such arguments. */
655 35653440 : separate_arg_flag = ((option->flags & CL_SEPARATE)
656 15513988 : && !(option->cl_no_driver_arg
657 11784 : && (lang_mask & CL_DRIVER)));
658 4625464 : separate_args = (separate_arg_flag
659 4625464 : ? option->cl_separate_nargs + 1
660 : : 0);
661 15513988 : joined_arg_flag = (option->flags & CL_JOINED) != 0;
662 :
663 : /* Sort out any argument the switch takes. */
664 15513988 : if (joined_arg_flag)
665 : {
666 : /* Have arg point to the original switch. This is because
667 : some code, such as disable_builtin_function, expects its
668 : argument to be persistent until the program exits. */
669 9185316 : arg = argv[extra_args] + cl_options[opt_index].opt_len + 1 + adjust_len;
670 :
671 9185316 : if (*arg == '\0' && !option->cl_missing_ok)
672 : {
673 2132203 : if (separate_arg_flag)
674 : {
675 2132202 : arg = argv[extra_args + 1];
676 2132202 : result = extra_args + 2;
677 2132202 : if (arg == NULL)
678 : result = extra_args + 1;
679 : else
680 : have_separate_arg = true;
681 : }
682 : else
683 : /* Missing argument. */
684 : arg = NULL;
685 : }
686 : }
687 6328672 : else if (separate_arg_flag)
688 : {
689 752529 : arg = argv[extra_args + 1];
690 1505058 : for (i = 0; i < separate_args; i++)
691 752529 : if (argv[extra_args + 1 + i] == NULL)
692 : {
693 0 : errors |= CL_ERR_MISSING_ARG;
694 0 : break;
695 : }
696 752529 : result = extra_args + 1 + i;
697 752529 : if (arg != NULL)
698 : have_separate_arg = true;
699 : }
700 :
701 5576144 : if (arg == NULL && (separate_arg_flag || joined_arg_flag))
702 1 : errors |= CL_ERR_MISSING_ARG;
703 :
704 : /* Is this option an alias (or an ignored option, marked as an alias
705 : of OPT_SPECIAL_ignore)? */
706 15513988 : if (option->alias_target != N_OPTS
707 43817 : && (!option->cl_separate_alias || have_separate_arg))
708 : {
709 43817 : size_t new_opt_index = option->alias_target;
710 :
711 43817 : if (new_opt_index == OPT_SPECIAL_ignore
712 43817 : || new_opt_index == OPT_SPECIAL_warn_removed)
713 : {
714 35 : gcc_assert (option->alias_arg == NULL);
715 35 : gcc_assert (option->neg_alias_arg == NULL);
716 : opt_index = new_opt_index;
717 : arg = NULL;
718 : }
719 : else
720 : {
721 43782 : const struct cl_option *new_option = &cl_options[new_opt_index];
722 :
723 : /* The new option must not be an alias itself. */
724 43782 : gcc_assert (new_option->alias_target == N_OPTS
725 : || new_option->cl_separate_alias);
726 :
727 43782 : if (option->neg_alias_arg)
728 : {
729 9820 : gcc_assert (option->alias_arg != NULL);
730 9820 : gcc_assert (arg == NULL);
731 9820 : gcc_assert (!option->cl_negative_alias);
732 9820 : if (value)
733 : arg = option->alias_arg;
734 : else
735 5906 : arg = option->neg_alias_arg;
736 9820 : value = 1;
737 : }
738 33962 : else if (option->alias_arg)
739 : {
740 21028 : gcc_assert (value == 1);
741 21028 : gcc_assert (arg == NULL);
742 21028 : gcc_assert (!option->cl_negative_alias);
743 : arg = option->alias_arg;
744 : }
745 :
746 43782 : if (option->cl_negative_alias)
747 0 : value = !value;
748 :
749 43782 : opt_index = new_opt_index;
750 43782 : option = new_option;
751 :
752 43782 : if (value == 0)
753 32 : gcc_assert (!option->cl_reject_negative);
754 :
755 : /* Recompute what arguments are allowed. */
756 87564 : separate_arg_flag = ((option->flags & CL_SEPARATE)
757 43782 : && !(option->cl_no_driver_arg
758 0 : && (lang_mask & CL_DRIVER)));
759 43782 : joined_arg_flag = (option->flags & CL_JOINED) != 0;
760 :
761 43782 : if (separate_args > 1 || option->cl_separate_nargs)
762 0 : gcc_assert (separate_args
763 : == (unsigned int) option->cl_separate_nargs + 1);
764 :
765 43782 : if (!(errors & CL_ERR_MISSING_ARG))
766 : {
767 43782 : if (separate_arg_flag || joined_arg_flag)
768 : {
769 31026 : if (option->cl_missing_ok && arg == NULL)
770 : arg = "";
771 31000 : gcc_assert (arg != NULL);
772 : }
773 : else
774 12756 : gcc_assert (arg == NULL);
775 : }
776 :
777 : /* Recheck for warnings and disabled options. */
778 43782 : if (option->warn_message)
779 : {
780 0 : gcc_assert (warn_message == NULL);
781 : warn_message = option->warn_message;
782 : }
783 43782 : if (option->cl_disabled)
784 0 : errors |= CL_ERR_DISABLED;
785 : }
786 : }
787 :
788 : /* Check if this is a switch for a different front end. */
789 15513988 : if (!option_ok_for_language (option, lang_mask))
790 4923193 : errors |= CL_ERR_WRONG_LANG;
791 10590795 : else if (strcmp (option->opt_text, "-Werror=") == 0
792 7058 : && strchr (opt_value, ',') == NULL)
793 : {
794 : /* Verify that -Werror argument is a valid warning
795 : for a language. */
796 7056 : char *werror_arg = xstrdup (opt_value + 6);
797 7056 : werror_arg[0] = 'W';
798 :
799 7056 : size_t warning_index = find_opt (werror_arg, lang_mask);
800 7056 : free (werror_arg);
801 7056 : if (warning_index != OPT_SPECIAL_unknown)
802 : {
803 5948 : const struct cl_option *warning_option
804 : = &cl_options[warning_index];
805 5948 : if (!option_ok_for_language (warning_option, lang_mask))
806 1 : errors |= CL_ERR_WRONG_LANG;
807 : }
808 : }
809 :
810 : /* Convert the argument to lowercase if appropriate. */
811 15513988 : if (arg && option->cl_tolower)
812 : {
813 74 : size_t j;
814 74 : size_t len = strlen (arg);
815 74 : char *arg_lower = XOBNEWVEC (&opts_obstack, char, len + 1);
816 :
817 320 : for (j = 0; j < len; j++)
818 246 : arg_lower[j] = TOLOWER ((unsigned char) arg[j]);
819 74 : arg_lower[len] = 0;
820 74 : arg = arg_lower;
821 : }
822 :
823 : /* If the switch takes an integer argument, convert it. */
824 9968692 : if (arg && (option->cl_uinteger || option->cl_host_wide_int))
825 : {
826 265180 : int error = 0;
827 265180 : value = *arg ? integral_argument (arg, &error, option->cl_byte_size) : 0;
828 265180 : if (error)
829 5 : errors |= CL_ERR_UINT_ARG;
830 :
831 : /* Reject value out of a range. */
832 265180 : if (option->range_max != -1
833 10003 : && (value < option->range_min || value > option->range_max))
834 5 : errors |= CL_ERR_INT_RANGE_ARG;
835 : }
836 :
837 : /* If the switch takes an enumerated argument, convert it. */
838 9968692 : if (arg && (option->var_type == CLVC_ENUM))
839 : {
840 2556675 : const struct cl_enum *e = &cl_enums[option->var_enum];
841 :
842 2556675 : gcc_assert (option->var_value != CLEV_NORMAL || value == 1);
843 2556675 : if (option->var_value != CLEV_NORMAL)
844 : {
845 : const char *p = arg;
846 : HOST_WIDE_INT sum_value = 0;
847 : unsigned HOST_WIDE_INT used_sets = 0;
848 97466 : do
849 : {
850 97193 : const char *q = strchr (p, ',');
851 97193 : HOST_WIDE_INT this_value = 0;
852 97193 : if (q && q == p)
853 : {
854 0 : errors |= CL_ERR_ENUM_SET_ARG;
855 0 : break;
856 : }
857 97193 : int idx = enum_arg_to_value (e->values, p, q ? q - p : 0,
858 : &this_value, lang_mask);
859 97193 : if (idx < 0)
860 : {
861 2 : errors |= CL_ERR_ENUM_SET_ARG;
862 2 : break;
863 : }
864 :
865 97191 : HOST_WIDE_INT this_mask = 0;
866 97191 : if (option->var_value == CLEV_SET)
867 : {
868 96802 : unsigned set = e->values[idx].flags >> CL_ENUM_SET_SHIFT;
869 96802 : gcc_checking_assert (set >= 1
870 : && set <= HOST_BITS_PER_WIDE_INT);
871 96802 : if ((used_sets & (HOST_WIDE_INT_1U << (set - 1))) != 0)
872 : {
873 0 : errors |= CL_ERR_ENUM_SET_ARG;
874 0 : break;
875 : }
876 96802 : used_sets |= HOST_WIDE_INT_1U << (set - 1);
877 :
878 580623 : for (int i = 0; e->values[i].arg != NULL; i++)
879 483821 : if (set == (e->values[i].flags >> CL_ENUM_SET_SHIFT))
880 193425 : this_mask |= e->values[i].value;
881 : }
882 : else
883 : {
884 389 : gcc_assert (option->var_value == CLEV_BITSET
885 : && ((e->values[idx].flags >> CL_ENUM_SET_SHIFT)
886 : == 0));
887 389 : this_mask = this_value;
888 : }
889 :
890 97191 : sum_value |= this_value;
891 97191 : mask |= this_mask;
892 97191 : if (q == NULL)
893 : break;
894 273 : p = q + 1;
895 273 : }
896 : while (1);
897 96920 : if (value == 1)
898 96884 : value = sum_value;
899 : else
900 36 : gcc_checking_assert (value == 0);
901 : }
902 2459755 : else if (enum_arg_to_value (e->values, arg, 0, &value, lang_mask) >= 0)
903 : {
904 2459754 : const char *carg = NULL;
905 :
906 2459754 : if (enum_value_to_arg (e->values, &carg, value, lang_mask))
907 0 : arg = carg;
908 2459754 : gcc_assert (carg != NULL);
909 : }
910 : else
911 1 : errors |= CL_ERR_ENUM_ARG;
912 : }
913 :
914 7412017 : done:
915 15514762 : decoded->opt_index = opt_index;
916 15514762 : decoded->arg = arg;
917 15514762 : decoded->value = value;
918 15514762 : decoded->mask = mask;
919 15514762 : decoded->errors = errors;
920 15514762 : decoded->warn_message = warn_message;
921 :
922 15514762 : if (opt_index == OPT_SPECIAL_unknown)
923 774 : gcc_assert (result == 1);
924 :
925 15513988 : gcc_assert (result >= 1 && result <= ARRAY_SIZE (decoded->canonical_option));
926 15514762 : decoded->canonical_option_num_elements = result;
927 15514762 : total_len = 0;
928 77573810 : for (i = 0; i < ARRAY_SIZE (decoded->canonical_option); i++)
929 : {
930 62059048 : if (i < result)
931 : {
932 18399493 : size_t len;
933 18399493 : if (opt_index == OPT_SPECIAL_unknown)
934 774 : decoded->canonical_option[i] = argv[i];
935 : else
936 18398719 : decoded->canonical_option[i] = NULL;
937 18399493 : len = strlen (argv[i]);
938 : /* If the argument is an empty string, we will print it as "" in
939 : orig_option_with_args_text. */
940 18399493 : total_len += (len != 0 ? len : 2) + 1;
941 : }
942 : else
943 43659555 : decoded->canonical_option[i] = NULL;
944 : }
945 15514762 : if (opt_index != OPT_SPECIAL_unknown && opt_index != OPT_SPECIAL_ignore
946 15514762 : && opt_index != OPT_SPECIAL_warn_removed)
947 : {
948 15513953 : generate_canonical_option (opt_index, arg, value, decoded);
949 15513953 : if (separate_args > 1)
950 : {
951 0 : for (i = 0; i < separate_args; i++)
952 : {
953 0 : if (argv[extra_args + 1 + i] == NULL)
954 : break;
955 : else
956 0 : decoded->canonical_option[1 + i] = argv[extra_args + 1 + i];
957 : }
958 0 : gcc_assert (result == 1 + i);
959 0 : decoded->canonical_option_num_elements = result;
960 : }
961 : }
962 15514762 : decoded->orig_option_with_args_text
963 15514762 : = p = XOBNEWVEC (&opts_obstack, char, total_len);
964 33914255 : for (i = 0; i < result; i++)
965 : {
966 18399493 : size_t len = strlen (argv[i]);
967 :
968 : /* Print the empty string verbally. */
969 18399493 : if (len == 0)
970 : {
971 1470 : *p++ = '"';
972 1470 : *p++ = '"';
973 : }
974 : else
975 18398023 : memcpy (p, argv[i], len);
976 18399493 : p += len;
977 18399493 : if (i == result - 1)
978 15514762 : *p++ = 0;
979 : else
980 2884731 : *p++ = ' ';
981 : }
982 :
983 15514762 : return result;
984 : }
985 :
986 : /* Obstack for option strings. */
987 :
988 : struct obstack opts_obstack;
989 :
990 : /* Like libiberty concat, but allocate using opts_obstack. */
991 :
992 : char *
993 5868234 : opts_concat (const char *first, ...)
994 : {
995 5868234 : char *newstr, *end;
996 5868234 : size_t length = 0;
997 5868234 : const char *arg;
998 5868234 : va_list ap;
999 :
1000 : /* First compute the size of the result and get sufficient memory. */
1001 5868234 : va_start (ap, first);
1002 17785993 : for (arg = first; arg; arg = va_arg (ap, const char *))
1003 11917759 : length += strlen (arg);
1004 5868234 : newstr = XOBNEWVEC (&opts_obstack, char, length + 1);
1005 5868234 : va_end (ap);
1006 :
1007 : /* Now copy the individual pieces to the result string. */
1008 5868234 : va_start (ap, first);
1009 17785993 : for (arg = first, end = newstr; arg; arg = va_arg (ap, const char *))
1010 : {
1011 11917759 : length = strlen (arg);
1012 11917759 : memcpy (end, arg, length);
1013 11917759 : end += length;
1014 : }
1015 5868234 : *end = '\0';
1016 5868234 : va_end (ap);
1017 5868234 : return newstr;
1018 : }
1019 :
1020 : /* Decode command-line options (ARGC and ARGV being the arguments of
1021 : main) into an array, setting *DECODED_OPTIONS to a pointer to that
1022 : array and *DECODED_OPTIONS_COUNT to the number of entries in the
1023 : array. The first entry in the array is always one for the program
1024 : name (OPT_SPECIAL_program_name). LANG_MASK indicates the language
1025 : flags applicable for decoding (including CL_COMMON and CL_TARGET if
1026 : those options should be considered applicable). Do not produce any
1027 : diagnostics or set state outside of these variables. */
1028 :
1029 : void
1030 1507212 : decode_cmdline_options_to_array (unsigned int argc, const char **argv,
1031 : unsigned int lang_mask,
1032 : struct cl_decoded_option **decoded_options,
1033 : unsigned int *decoded_options_count)
1034 : {
1035 1507212 : unsigned int n, i;
1036 1507212 : struct cl_decoded_option *opt_array;
1037 1507212 : unsigned int num_decoded_options;
1038 :
1039 1507212 : int opt_array_len = argc;
1040 1507212 : opt_array = XNEWVEC (struct cl_decoded_option, opt_array_len);
1041 :
1042 1507212 : opt_array[0].opt_index = OPT_SPECIAL_program_name;
1043 1507212 : opt_array[0].warn_message = NULL;
1044 1507212 : opt_array[0].arg = argv[0];
1045 1507212 : opt_array[0].orig_option_with_args_text = argv[0];
1046 1507212 : opt_array[0].canonical_option_num_elements = 1;
1047 1507212 : opt_array[0].canonical_option[0] = argv[0];
1048 1507212 : opt_array[0].canonical_option[1] = NULL;
1049 1507212 : opt_array[0].canonical_option[2] = NULL;
1050 1507212 : opt_array[0].canonical_option[3] = NULL;
1051 1507212 : opt_array[0].value = 1;
1052 1507212 : opt_array[0].mask = 0;
1053 1507212 : opt_array[0].errors = 0;
1054 1507212 : num_decoded_options = 1;
1055 :
1056 15752688 : for (i = 1; i < argc; i += n)
1057 : {
1058 14245476 : const char *opt = argv[i];
1059 :
1060 : /* Interpret "-" or a non-switch as a file name. */
1061 14245476 : if (opt[0] != '-' || opt[1] == '\0')
1062 : {
1063 614806 : generate_option_input_file (opt, &opt_array[num_decoded_options]);
1064 614806 : num_decoded_options++;
1065 614806 : n = 1;
1066 614806 : continue;
1067 : }
1068 :
1069 : /* Interpret "--param" "key=name" as "--param=key=name". */
1070 13630670 : const char *needle = "--param";
1071 13630670 : if (i + 1 < argc && strcmp (opt, needle) == 0)
1072 : {
1073 2743 : const char *replacement
1074 2743 : = opts_concat (needle, "=", argv[i + 1], NULL);
1075 2743 : argv[++i] = replacement;
1076 : }
1077 :
1078 : /* Expand -fdiagnostics-plain-output to its constituents. This needs
1079 : to happen here so that prune_options can handle -fdiagnostics-color
1080 : specially. */
1081 13630670 : if (opt[0] == '-'
1082 13630670 : && (opt[1] == '-' || opt[1] == 'f')
1083 5301988 : && !strcmp (opt + 2, "diagnostics-plain-output"))
1084 : {
1085 : /* If you have changed the default diagnostics output, and this new
1086 : output is not appropriately "plain" (e.g., the change needs to be
1087 : undone in order for the testsuite to work properly), then please do
1088 : the following:
1089 : 1. Add the necessary option to undo the new behavior to
1090 : the array below.
1091 : 2. Update the documentation for -fdiagnostics-plain-output
1092 : in invoke.texi. */
1093 269156 : const char *const expanded_args[] = {
1094 : "-fno-diagnostics-show-caret",
1095 : "-fno-diagnostics-show-line-numbers",
1096 : "-fdiagnostics-color=never",
1097 : "-fdiagnostics-urls=never",
1098 : "-fdiagnostics-path-format=separate-events",
1099 : "-fdiagnostics-text-art-charset=none",
1100 : "-fno-diagnostics-show-event-links",
1101 : "-fno-diagnostics-show-nesting"
1102 : /* We don't put "-fno-diagnostics-show-highlight-colors" here
1103 : as -fdiagnostics-color=never makes it redundant. */
1104 : };
1105 269156 : const int num_expanded = ARRAY_SIZE (expanded_args);
1106 269156 : opt_array_len += num_expanded - 1;
1107 269156 : opt_array = XRESIZEVEC (struct cl_decoded_option,
1108 : opt_array, opt_array_len);
1109 2422404 : for (int j = 0, nj; j < num_expanded; j += nj)
1110 : {
1111 4306496 : nj = decode_cmdline_option (expanded_args + j, lang_mask,
1112 2153248 : &opt_array[num_decoded_options]);
1113 2153248 : num_decoded_options++;
1114 : }
1115 :
1116 269156 : n = 1;
1117 269156 : continue;
1118 269156 : }
1119 :
1120 26723028 : n = decode_cmdline_option (argv + i, lang_mask,
1121 13361514 : &opt_array[num_decoded_options]);
1122 13361514 : num_decoded_options++;
1123 : }
1124 :
1125 1507212 : *decoded_options = opt_array;
1126 1507212 : *decoded_options_count = num_decoded_options;
1127 1507212 : prune_options (decoded_options, decoded_options_count);
1128 1507212 : }
1129 :
1130 : /* Return true if NEXT_OPT_IDX cancels OPT_IDX. Return false if the
1131 : next one is the same as ORIG_NEXT_OPT_IDX. */
1132 :
1133 : static bool
1134 0 : cancel_option (int opt_idx, int next_opt_idx, int orig_next_opt_idx)
1135 : {
1136 : /* An option can be canceled by the same option or an option with
1137 : Negative. */
1138 17600000 : if (cl_options [next_opt_idx].neg_index == opt_idx)
1139 : return true;
1140 :
1141 17323523 : if (cl_options [next_opt_idx].neg_index != orig_next_opt_idx)
1142 : return cancel_option (opt_idx, cl_options [next_opt_idx].neg_index,
1143 : orig_next_opt_idx);
1144 :
1145 : return false;
1146 : }
1147 :
1148 : /* Filter out options canceled by the ones after them, and related
1149 : rearrangement. */
1150 :
1151 : static void
1152 1507212 : prune_options (struct cl_decoded_option **decoded_options,
1153 : unsigned int *decoded_options_count)
1154 : {
1155 1507212 : unsigned int old_decoded_options_count = *decoded_options_count;
1156 1507212 : struct cl_decoded_option *old_decoded_options = *decoded_options;
1157 1507212 : unsigned int new_decoded_options_count;
1158 1507212 : struct cl_decoded_option *new_decoded_options
1159 1507212 : = XNEWVEC (struct cl_decoded_option, old_decoded_options_count);
1160 1507212 : unsigned int i;
1161 1507212 : const struct cl_option *option;
1162 1507212 : unsigned int options_to_prepend = 0;
1163 1507212 : unsigned int Wcomplain_wrong_lang_idx = 0;
1164 1507212 : unsigned int fdiagnostics_color_idx = 0;
1165 1507212 : unsigned int fdiagnostics_urls_idx = 0;
1166 :
1167 : /* Remove arguments which are negated by others after them. */
1168 1507212 : new_decoded_options_count = 0;
1169 19143992 : for (i = 0; i < old_decoded_options_count; i++)
1170 : {
1171 17636780 : unsigned int j, opt_idx, next_opt_idx;
1172 :
1173 17636780 : if (old_decoded_options[i].errors & ~CL_ERR_WRONG_LANG)
1174 20 : goto keep;
1175 :
1176 17636760 : opt_idx = old_decoded_options[i].opt_index;
1177 17636760 : switch (opt_idx)
1178 : {
1179 2122820 : case OPT_SPECIAL_unknown:
1180 2122820 : case OPT_SPECIAL_ignore:
1181 2122820 : case OPT_SPECIAL_warn_removed:
1182 2122820 : case OPT_SPECIAL_program_name:
1183 2122820 : case OPT_SPECIAL_input_file:
1184 2122820 : goto keep;
1185 :
1186 : /* Do not handle the following yet, just remember the last one. */
1187 27535 : case OPT_Wcomplain_wrong_lang:
1188 27535 : gcc_checking_assert (i != 0);
1189 27535 : if (Wcomplain_wrong_lang_idx == 0)
1190 27534 : ++options_to_prepend;
1191 27535 : Wcomplain_wrong_lang_idx = i;
1192 27535 : continue;
1193 584995 : case OPT_fdiagnostics_color_:
1194 584995 : gcc_checking_assert (i != 0);
1195 584995 : if (fdiagnostics_color_idx == 0)
1196 542692 : ++options_to_prepend;
1197 584995 : fdiagnostics_color_idx = i;
1198 584995 : continue;
1199 565333 : case OPT_fdiagnostics_urls_:
1200 565333 : gcc_checking_assert (i != 0);
1201 565333 : if (fdiagnostics_urls_idx == 0)
1202 537476 : ++options_to_prepend;
1203 565333 : fdiagnostics_urls_idx = i;
1204 565333 : continue;
1205 :
1206 14336077 : default:
1207 14336077 : gcc_assert (opt_idx < cl_options_count);
1208 14336077 : option = &cl_options[opt_idx];
1209 14336077 : if (option->neg_index < 0)
1210 8459228 : goto keep;
1211 :
1212 : /* Skip joined switches. */
1213 5876849 : if ((option->flags & CL_JOINED)
1214 1818556 : && (!option->cl_reject_negative
1215 1248601 : || (unsigned int) option->neg_index != opt_idx))
1216 569955 : goto keep;
1217 :
1218 52814907 : for (j = i + 1; j < old_decoded_options_count; j++)
1219 : {
1220 47784490 : if (old_decoded_options[j].errors & ~CL_ERR_WRONG_LANG)
1221 81 : continue;
1222 47784409 : next_opt_idx = old_decoded_options[j].opt_index;
1223 47784409 : if (next_opt_idx >= cl_options_count)
1224 1151810 : continue;
1225 46632599 : if (cl_options[next_opt_idx].neg_index < 0)
1226 26328725 : continue;
1227 20303874 : if ((cl_options[next_opt_idx].flags & CL_JOINED)
1228 5055187 : && (!cl_options[next_opt_idx].cl_reject_negative
1229 1300877 : || ((unsigned int) cl_options[next_opt_idx].neg_index
1230 : != next_opt_idx)))
1231 3754310 : continue;
1232 33099128 : if (cancel_option (opt_idx, next_opt_idx, next_opt_idx))
1233 : break;
1234 : }
1235 5306894 : if (j == old_decoded_options_count)
1236 : {
1237 5030417 : keep:
1238 16182440 : new_decoded_options[new_decoded_options_count]
1239 16182440 : = old_decoded_options[i];
1240 16182440 : new_decoded_options_count++;
1241 : }
1242 : break;
1243 : }
1244 : }
1245 :
1246 : /* For those not yet handled, put (only) the last at a front position after
1247 : 'argv[0]', so they can take effect immediately. */
1248 1507212 : if (options_to_prepend)
1249 : {
1250 542739 : const unsigned int argv_0 = 1;
1251 542739 : memmove (new_decoded_options + argv_0 + options_to_prepend,
1252 542739 : new_decoded_options + argv_0,
1253 : sizeof (struct cl_decoded_option)
1254 542739 : * (new_decoded_options_count - argv_0));
1255 542739 : unsigned int options_prepended = 0;
1256 542739 : if (Wcomplain_wrong_lang_idx != 0)
1257 : {
1258 27534 : new_decoded_options[argv_0 + options_prepended++]
1259 27534 : = old_decoded_options[Wcomplain_wrong_lang_idx];
1260 27534 : new_decoded_options_count++;
1261 : }
1262 542739 : if (fdiagnostics_color_idx != 0)
1263 : {
1264 542692 : new_decoded_options[argv_0 + options_prepended++]
1265 542692 : = old_decoded_options[fdiagnostics_color_idx];
1266 542692 : new_decoded_options_count++;
1267 : }
1268 542739 : if (fdiagnostics_urls_idx != 0)
1269 : {
1270 537476 : new_decoded_options[argv_0 + options_prepended++]
1271 537476 : = old_decoded_options[fdiagnostics_urls_idx];
1272 537476 : new_decoded_options_count++;
1273 : }
1274 542739 : gcc_checking_assert (options_to_prepend == options_prepended);
1275 : }
1276 :
1277 1507212 : free (old_decoded_options);
1278 1507212 : new_decoded_options = XRESIZEVEC (struct cl_decoded_option,
1279 : new_decoded_options,
1280 : new_decoded_options_count);
1281 1507212 : *decoded_options = new_decoded_options;
1282 1507212 : *decoded_options_count = new_decoded_options_count;
1283 1507212 : }
1284 :
1285 : /* Handle option DECODED for the language indicated by LANG_MASK,
1286 : using the handlers in HANDLERS and setting fields in OPTS and
1287 : OPTS_SET. KIND is the enum diagnostics::kind if this is a diagnostics
1288 : option, diagnostics::kind::unspecified otherwise, and LOC is the location
1289 : of the option for options from the source file, UNKNOWN_LOCATION
1290 : otherwise. GENERATED_P is true for an option generated as part of
1291 : processing another option or otherwise generated internally, false
1292 : for one explicitly passed by the user. control_warning_option
1293 : generated options are considered explicitly passed by the user.
1294 : Returns false if the switch was invalid. DC is the diagnostic
1295 : context for options affecting diagnostics state, or NULL. */
1296 :
1297 : static bool
1298 88583840 : handle_option (struct gcc_options *opts,
1299 : struct gcc_options *opts_set,
1300 : const struct cl_decoded_option *decoded,
1301 : unsigned int lang_mask, int kind, location_t loc,
1302 : const struct cl_option_handlers *handlers,
1303 : bool generated_p, diagnostics::context *dc)
1304 : {
1305 88583840 : size_t opt_index = decoded->opt_index;
1306 88583840 : const char *arg = decoded->arg;
1307 88583840 : HOST_WIDE_INT value = decoded->value;
1308 88583840 : HOST_WIDE_INT mask = decoded->mask;
1309 88583840 : const struct cl_option *option = &cl_options[opt_index];
1310 88583840 : void *flag_var = option_flag_var (opt_index, opts);
1311 88583840 : size_t i;
1312 :
1313 88583840 : if (flag_var)
1314 91193419 : set_option (opts, (generated_p ? NULL : opts_set),
1315 : opt_index, value, arg, kind, loc, dc, mask);
1316 :
1317 354334512 : for (i = 0; i < handlers->num_handlers; i++)
1318 265750955 : if (option->flags & handlers->handlers[i].mask)
1319 : {
1320 90226516 : if (!handlers->handlers[i].handler (opts, opts_set, decoded,
1321 : lang_mask, kind, loc,
1322 : handlers, dc,
1323 90226797 : handlers->target_option_override_hook))
1324 : return false;
1325 : }
1326 :
1327 : return true;
1328 : }
1329 :
1330 : /* Like handle_option, but OPT_INDEX, ARG and VALUE describe the
1331 : option instead of DECODED. This is used for callbacks when one
1332 : option implies another instead of an option being decoded from the
1333 : command line. */
1334 :
1335 : bool
1336 76185764 : handle_generated_option (struct gcc_options *opts,
1337 : struct gcc_options *opts_set,
1338 : size_t opt_index, const char *arg, HOST_WIDE_INT value,
1339 : unsigned int lang_mask, int kind, location_t loc,
1340 : const struct cl_option_handlers *handlers,
1341 : bool generated_p, diagnostics::context *dc)
1342 : {
1343 76185764 : struct cl_decoded_option decoded;
1344 :
1345 76185764 : generate_option (opt_index, arg, value, lang_mask, &decoded);
1346 76185764 : return handle_option (opts, opts_set, &decoded, lang_mask, kind, loc,
1347 76185764 : handlers, generated_p, dc);
1348 : }
1349 :
1350 : /* Fill in *DECODED with an option described by OPT_INDEX, ARG and
1351 : VALUE for a front end using LANG_MASK. This is used when the
1352 : compiler generates options internally. */
1353 :
1354 : void
1355 143120604 : generate_option (size_t opt_index, const char *arg, HOST_WIDE_INT value,
1356 : unsigned int lang_mask, struct cl_decoded_option *decoded)
1357 : {
1358 143120604 : const struct cl_option *option = &cl_options[opt_index];
1359 :
1360 143120604 : decoded->opt_index = opt_index;
1361 143120604 : decoded->warn_message = NULL;
1362 143120604 : decoded->arg = arg;
1363 143120604 : decoded->value = value;
1364 143120604 : decoded->mask = 0;
1365 286241208 : decoded->errors = (option_ok_for_language (option, lang_mask)
1366 143120604 : ? 0
1367 : : CL_ERR_WRONG_LANG);
1368 :
1369 143120604 : generate_canonical_option (opt_index, arg, value, decoded);
1370 143120604 : switch (decoded->canonical_option_num_elements)
1371 : {
1372 142942056 : case 1:
1373 142942056 : decoded->orig_option_with_args_text = decoded->canonical_option[0];
1374 142942056 : break;
1375 :
1376 178548 : case 2:
1377 178548 : decoded->orig_option_with_args_text
1378 178548 : = opts_concat (decoded->canonical_option[0], " ",
1379 : decoded->canonical_option[1], NULL);
1380 178548 : break;
1381 :
1382 0 : default:
1383 0 : gcc_unreachable ();
1384 : }
1385 143120604 : }
1386 :
1387 : /* Fill in *DECODED with an option for input file FILE. */
1388 :
1389 : void
1390 614809 : generate_option_input_file (const char *file,
1391 : struct cl_decoded_option *decoded)
1392 : {
1393 614809 : decoded->opt_index = OPT_SPECIAL_input_file;
1394 614809 : decoded->warn_message = NULL;
1395 614809 : decoded->arg = file;
1396 614809 : decoded->orig_option_with_args_text = file;
1397 614809 : decoded->canonical_option_num_elements = 1;
1398 614809 : decoded->canonical_option[0] = file;
1399 614809 : decoded->canonical_option[1] = NULL;
1400 614809 : decoded->canonical_option[2] = NULL;
1401 614809 : decoded->canonical_option[3] = NULL;
1402 614809 : decoded->value = 1;
1403 614809 : decoded->mask = 0;
1404 614809 : decoded->errors = 0;
1405 614809 : }
1406 :
1407 : /* Helper function for listing valid choices and hint for misspelled
1408 : value. CANDIDATES is a vector containing all valid strings,
1409 : STR is set to a heap allocated string that contains all those
1410 : strings concatenated, separated by spaces, and the return value
1411 : is the closest string from those to ARG, or NULL if nothing is
1412 : close enough. Callers should XDELETEVEC (STR) after using it
1413 : to avoid memory leaks. */
1414 :
1415 : const char *
1416 178 : candidates_list_and_hint (const char *arg, char *&str,
1417 : const auto_vec <const char *> &candidates)
1418 : {
1419 178 : size_t len = 0;
1420 178 : int i;
1421 178 : const char *candidate;
1422 178 : char *p;
1423 :
1424 178 : gcc_assert (!candidates.is_empty ());
1425 :
1426 6098 : FOR_EACH_VEC_ELT (candidates, i, candidate)
1427 5920 : len += strlen (candidate) + 1;
1428 :
1429 178 : str = p = XNEWVEC (char, len);
1430 6098 : FOR_EACH_VEC_ELT (candidates, i, candidate)
1431 : {
1432 5920 : len = strlen (candidate);
1433 5920 : memcpy (p, candidate, len);
1434 5920 : p[len] = ' ';
1435 5920 : p += len + 1;
1436 : }
1437 178 : p[-1] = '\0';
1438 178 : return find_closest_string (arg, &candidates);
1439 : }
1440 :
1441 : /* Perform diagnostics for read_cmdline_option and control_warning_option
1442 : functions. Returns true if an error has been diagnosed.
1443 : LOC and LANG_MASK arguments like in read_cmdline_option.
1444 : OPTION is the option to report diagnostics for, OPT the name
1445 : of the option as text, ARG the argument of the option (for joined
1446 : options), ERRORS is bitmask of CL_ERR_* values. */
1447 :
1448 : static bool
1449 4291111 : cmdline_handle_error (location_t loc, const struct cl_option *option,
1450 : const char *opt, const char *arg, int errors,
1451 : unsigned int lang_mask)
1452 : {
1453 4291111 : if (errors & CL_ERR_DISABLED)
1454 : {
1455 0 : error_at (loc, "command-line option %qs"
1456 : " is not supported by this configuration", opt);
1457 0 : return true;
1458 : }
1459 :
1460 4291111 : if (errors & CL_ERR_MISSING_ARG)
1461 : {
1462 1 : if (option->missing_argument_error)
1463 0 : error_at (loc, option->missing_argument_error, opt);
1464 : else
1465 1 : error_at (loc, "missing argument to %qs", opt);
1466 1 : return true;
1467 : }
1468 :
1469 4291110 : if (errors & CL_ERR_UINT_ARG)
1470 : {
1471 5 : if (option->cl_byte_size)
1472 3 : error_at (loc, "argument to %qs should be a non-negative integer "
1473 : "optionally followed by a size unit",
1474 3 : option->opt_text);
1475 : else
1476 2 : error_at (loc, "argument to %qs should be a non-negative integer",
1477 2 : option->opt_text);
1478 5 : return true;
1479 : }
1480 :
1481 4291105 : if (errors & CL_ERR_INT_RANGE_ARG)
1482 : {
1483 4 : error_at (loc, "argument to %qs is not between %d and %d",
1484 4 : option->opt_text, option->range_min, option->range_max);
1485 4 : return true;
1486 : }
1487 :
1488 4291101 : if (errors & CL_ERR_ENUM_SET_ARG)
1489 : {
1490 2 : const struct cl_enum *e = &cl_enums[option->var_enum];
1491 2 : const char *p = arg;
1492 2 : unsigned HOST_WIDE_INT used_sets = 0;
1493 2 : const char *second_opt = NULL;
1494 2 : size_t second_opt_len = 0;
1495 2 : errors = 0;
1496 3 : do
1497 : {
1498 3 : const char *q = strchr (p, ',');
1499 3 : HOST_WIDE_INT this_value = 0;
1500 3 : if (q && q == p)
1501 : {
1502 : arg = "";
1503 : errors = CL_ERR_ENUM_ARG;
1504 0 : break;
1505 : }
1506 3 : int idx = enum_arg_to_value (e->values, p, q ? q - p : 0,
1507 : &this_value, lang_mask);
1508 3 : if (idx < 0)
1509 : {
1510 2 : if (q == NULL)
1511 2 : q = strchr (p, '\0');
1512 2 : char *narg = XALLOCAVEC (char, (q - p) + 1);
1513 2 : memcpy (narg, p, q - p);
1514 2 : narg[q - p] = '\0';
1515 2 : arg = narg;
1516 2 : errors = CL_ERR_ENUM_ARG;
1517 2 : break;
1518 : }
1519 :
1520 1 : if (option->var_value == CLEV_BITSET)
1521 : {
1522 1 : if (q == NULL)
1523 : break;
1524 1 : p = q + 1;
1525 1 : continue;
1526 : }
1527 :
1528 0 : unsigned set = e->values[idx].flags >> CL_ENUM_SET_SHIFT;
1529 0 : gcc_checking_assert (set >= 1 && set <= HOST_BITS_PER_WIDE_INT);
1530 0 : if ((used_sets & (HOST_WIDE_INT_1U << (set - 1))) != 0)
1531 : {
1532 0 : if (q == NULL)
1533 0 : q = strchr (p, '\0');
1534 0 : if (second_opt == NULL)
1535 : {
1536 0 : used_sets = HOST_WIDE_INT_1U << (set - 1);
1537 0 : second_opt = p;
1538 0 : second_opt_len = q - p;
1539 0 : p = arg;
1540 0 : continue;
1541 : }
1542 0 : char *args = XALLOCAVEC (char, (q - p) + 1 + second_opt_len + 1);
1543 0 : memcpy (args, p, q - p);
1544 0 : args[q - p] = '\0';
1545 0 : memcpy (args + (q - p) + 1, second_opt, second_opt_len);
1546 0 : args[(q - p) + 1 + second_opt_len] = '\0';
1547 0 : error_at (loc, "invalid argument in option %qs", opt);
1548 0 : if (strcmp (args, args + (q - p) + 1) == 0)
1549 0 : inform (loc, "%qs specified multiple times in the same option",
1550 : args);
1551 : else
1552 0 : inform (loc, "%qs is mutually exclusive with %qs and cannot be"
1553 : " specified together", args, args + (q - p) + 1);
1554 0 : return true;
1555 : }
1556 0 : used_sets |= HOST_WIDE_INT_1U << (set - 1);
1557 0 : if (q == NULL)
1558 : break;
1559 0 : p = q + 1;
1560 : }
1561 : while (1);
1562 : }
1563 :
1564 4291101 : if (errors & CL_ERR_ENUM_ARG)
1565 : {
1566 3 : const struct cl_enum *e = &cl_enums[option->var_enum];
1567 3 : unsigned int i;
1568 3 : char *s;
1569 :
1570 3 : auto_diagnostic_group d;
1571 3 : if (e->unknown_error)
1572 1 : error_at (loc, e->unknown_error, arg);
1573 : else
1574 2 : error_at (loc, "unrecognized argument in option %qs", opt);
1575 :
1576 3 : auto_vec <const char *> candidates;
1577 11 : for (i = 0; e->values[i].arg != NULL; i++)
1578 : {
1579 8 : if (!enum_arg_ok_for_language (&e->values[i], lang_mask))
1580 0 : continue;
1581 8 : candidates.safe_push (e->values[i].arg);
1582 : }
1583 3 : const char *hint = candidates_list_and_hint (arg, s, candidates);
1584 3 : if (hint)
1585 3 : inform (loc, "valid arguments to %qs are: %s; did you mean %qs?",
1586 3 : option->opt_text, s, hint);
1587 : else
1588 0 : inform (loc, "valid arguments to %qs are: %s", option->opt_text, s);
1589 3 : XDELETEVEC (s);
1590 :
1591 3 : return true;
1592 3 : }
1593 :
1594 : return false;
1595 : }
1596 :
1597 : /* Handle the switch DECODED (location LOC) for the language indicated
1598 : by LANG_MASK, using the handlers in *HANDLERS and setting fields in
1599 : OPTS and OPTS_SET and using diagnostic context DC (if not NULL) for
1600 : diagnostic options. */
1601 :
1602 : void
1603 16689996 : read_cmdline_option (struct gcc_options *opts,
1604 : struct gcc_options *opts_set,
1605 : struct cl_decoded_option *decoded,
1606 : location_t loc,
1607 : unsigned int lang_mask,
1608 : const struct cl_option_handlers *handlers,
1609 : diagnostics::context *dc)
1610 : {
1611 16689996 : const struct cl_option *option;
1612 16689996 : const char *opt = decoded->orig_option_with_args_text;
1613 :
1614 16689996 : if (decoded->warn_message)
1615 121 : warning_at (loc, 0, decoded->warn_message, opt);
1616 :
1617 16689996 : if (decoded->opt_index == OPT_SPECIAL_unknown)
1618 : {
1619 774 : if (handlers->unknown_option_callback (decoded))
1620 0 : error_at (loc, "unrecognized command-line option %qs", decoded->arg);
1621 774 : return;
1622 : }
1623 :
1624 16689222 : if (decoded->opt_index == OPT_SPECIAL_ignore)
1625 : return;
1626 :
1627 16689194 : if (decoded->opt_index == OPT_SPECIAL_warn_removed)
1628 : {
1629 : /* Warn only about positive ignored options. */
1630 7 : if (decoded->value)
1631 7 : warning_at (loc, 0, "switch %qs is no longer supported", opt);
1632 7 : return;
1633 : }
1634 :
1635 16689187 : option = &cl_options[decoded->opt_index];
1636 :
1637 16689187 : if (decoded->errors
1638 16689187 : && cmdline_handle_error (loc, option, opt, decoded->arg,
1639 : decoded->errors, lang_mask))
1640 : return;
1641 :
1642 16689174 : if (decoded->errors & CL_ERR_WRONG_LANG)
1643 : {
1644 4291098 : handlers->wrong_lang_callback (decoded, lang_mask);
1645 4291098 : return;
1646 : }
1647 :
1648 12398076 : gcc_assert (!decoded->errors);
1649 :
1650 12398076 : if (!handle_option (opts, opts_set, decoded, lang_mask,
1651 : static_cast<int> (diagnostics::kind::unspecified),
1652 : loc, handlers, false, dc))
1653 2 : error_at (loc, "unrecognized command-line option %qs", opt);
1654 : }
1655 :
1656 : /* Set any field in OPTS, and OPTS_SET if not NULL, for option
1657 : OPT_INDEX according to VALUE and ARG, diagnostic kind KIND,
1658 : location LOC, using diagnostic context DC if not NULL for
1659 : diagnostic classification. */
1660 :
1661 : void
1662 83339467 : set_option (struct gcc_options *opts, struct gcc_options *opts_set,
1663 : size_t opt_index, HOST_WIDE_INT value, const char *arg,
1664 : int kind, location_t loc, diagnostics::context *dc,
1665 : HOST_WIDE_INT mask /* = 0 */)
1666 : {
1667 83339467 : const struct cl_option *option = &cl_options[opt_index];
1668 83339467 : void *flag_var = option_flag_var (opt_index, opts);
1669 83339467 : void *set_flag_var = NULL;
1670 :
1671 83339467 : if (!flag_var)
1672 : return;
1673 :
1674 83339467 : if ((enum diagnostics::kind) kind != diagnostics::kind::unspecified
1675 83339467 : && dc != nullptr)
1676 407823 : diagnostic_classify_diagnostic (dc, opt_index,
1677 : (enum diagnostics::kind) kind, loc);
1678 :
1679 83339467 : if (opts_set != NULL)
1680 7854326 : set_flag_var = option_flag_var (opt_index, opts_set);
1681 :
1682 83339467 : switch (option->var_type)
1683 : {
1684 75761151 : case CLVC_INTEGER:
1685 75761151 : if (option->cl_host_wide_int)
1686 : {
1687 3 : *(HOST_WIDE_INT *) flag_var = value;
1688 3 : if (set_flag_var)
1689 3 : *(HOST_WIDE_INT *) set_flag_var = 1;
1690 : }
1691 : else
1692 : {
1693 75761148 : if (value > INT_MAX)
1694 3 : error_at (loc, "argument to %qs is bigger than %d",
1695 3 : option->opt_text, INT_MAX);
1696 : else
1697 : {
1698 75761145 : *(int *) flag_var = value;
1699 75761145 : if (set_flag_var)
1700 3498070 : *(int *) set_flag_var = 1;
1701 : }
1702 : }
1703 :
1704 : break;
1705 :
1706 117 : case CLVC_SIZE:
1707 117 : if (option->cl_host_wide_int)
1708 : {
1709 117 : *(HOST_WIDE_INT *) flag_var = value;
1710 117 : if (set_flag_var)
1711 117 : *(HOST_WIDE_INT *) set_flag_var = value;
1712 : }
1713 : else
1714 : {
1715 0 : *(int *) flag_var = value;
1716 0 : if (set_flag_var)
1717 0 : *(int *) set_flag_var = value;
1718 : }
1719 :
1720 : break;
1721 :
1722 1311630 : case CLVC_EQUAL:
1723 1311630 : if (option->cl_host_wide_int)
1724 : {
1725 0 : *(HOST_WIDE_INT *) flag_var = (value
1726 0 : ? option->var_value
1727 0 : : !option->var_value);
1728 0 : if (set_flag_var)
1729 0 : *(HOST_WIDE_INT *) set_flag_var = 1;
1730 : }
1731 : else
1732 : {
1733 1311630 : *(int *) flag_var = (value
1734 1021239 : ? option->var_value
1735 290391 : : !option->var_value);
1736 1311630 : if (set_flag_var)
1737 52098 : *(int *) set_flag_var = 1;
1738 : }
1739 : break;
1740 :
1741 57095 : case CLVC_BIT_CLEAR:
1742 57095 : case CLVC_BIT_SET:
1743 57095 : if ((value != 0) == (option->var_type == CLVC_BIT_SET))
1744 : {
1745 45245 : if (option->cl_host_wide_int)
1746 43331 : *(HOST_WIDE_INT *) flag_var |= option->var_value;
1747 : else
1748 1914 : *(int *) flag_var |= option->var_value;
1749 : }
1750 : else
1751 : {
1752 11850 : if (option->cl_host_wide_int)
1753 10675 : *(HOST_WIDE_INT *) flag_var &= ~option->var_value;
1754 : else
1755 1175 : *(int *) flag_var &= ~option->var_value;
1756 : }
1757 57095 : if (set_flag_var)
1758 : {
1759 57095 : if (option->cl_host_wide_int)
1760 54006 : *(HOST_WIDE_INT *) set_flag_var |= option->var_value;
1761 : else
1762 3089 : *(int *) set_flag_var |= option->var_value;
1763 : }
1764 : break;
1765 :
1766 1871186 : case CLVC_STRING:
1767 1871186 : *(const char **) flag_var = arg;
1768 1871186 : if (set_flag_var)
1769 1871186 : *(const char **) set_flag_var = "";
1770 : break;
1771 :
1772 4312076 : case CLVC_ENUM:
1773 4312076 : {
1774 4312076 : const struct cl_enum *e = &cl_enums[option->var_enum];
1775 :
1776 4312076 : if (mask)
1777 41811 : e->set (flag_var, value | (e->get (flag_var) & ~mask));
1778 : else
1779 4270265 : e->set (flag_var, value);
1780 4312076 : if (set_flag_var)
1781 2349542 : e->set (set_flag_var, 1);
1782 : }
1783 : break;
1784 :
1785 26212 : case CLVC_DEFER:
1786 26212 : {
1787 26212 : vec<cl_deferred_option> *v
1788 : = (vec<cl_deferred_option> *) *(void **) flag_var;
1789 26212 : cl_deferred_option p = {opt_index, arg, value};
1790 26212 : if (!v)
1791 23413 : v = XCNEW (vec<cl_deferred_option>);
1792 26212 : v->safe_push (p);
1793 26212 : *(void **) flag_var = v;
1794 26212 : if (set_flag_var)
1795 26212 : *(void **) set_flag_var = v;
1796 : }
1797 26212 : break;
1798 : }
1799 : }
1800 :
1801 : /* Return the address of the flag variable for option OPT_INDEX in
1802 : options structure OPTS, or NULL if there is no flag variable. */
1803 :
1804 : void *
1805 370903692 : option_flag_var (int opt_index, struct gcc_options *opts)
1806 : {
1807 370903692 : const struct cl_option *option = &cl_options[opt_index];
1808 :
1809 370903692 : if (option->flag_var_offset == (unsigned short) -1)
1810 : return NULL;
1811 365503987 : return (void *)(((char *) opts) + option->flag_var_offset);
1812 : }
1813 :
1814 : /* Return 1 if option OPT_IDX is enabled in OPTS, 0 if it is disabled,
1815 : or -1 if it isn't a simple on-off switch
1816 : (or if the value is unknown, typically set later in target). */
1817 :
1818 : int
1819 106256295 : option_enabled (int opt_idx, unsigned lang_mask, void *opts)
1820 : {
1821 106256295 : const struct cl_option *option = &(cl_options[opt_idx]);
1822 :
1823 : /* A language-specific option can only be considered enabled when it's
1824 : valid for the current language. */
1825 106256295 : if (!(option->flags & CL_COMMON)
1826 99899871 : && (option->flags & CL_LANG_ALL)
1827 97537521 : && !(option->flags & lang_mask))
1828 : return 0;
1829 :
1830 104412230 : struct gcc_options *optsg = (struct gcc_options *) opts;
1831 104412230 : void *flag_var = option_flag_var (opt_idx, optsg);
1832 :
1833 104412230 : if (flag_var)
1834 104412119 : switch (option->var_type)
1835 : {
1836 102047359 : case CLVC_INTEGER:
1837 102047359 : if (option->cl_host_wide_int)
1838 : {
1839 0 : HOST_WIDE_INT v = *(HOST_WIDE_INT *) flag_var;
1840 0 : return v != 0 ? (v < 0 ? -1 : 1) : 0;
1841 : }
1842 : else
1843 : {
1844 102047359 : int v = *(int *) flag_var;
1845 105296497 : return v != 0 ? (v < 0 ? -1 : 1) : 0;
1846 : }
1847 :
1848 49 : case CLVC_EQUAL:
1849 49 : if (option->cl_host_wide_int)
1850 0 : return *(HOST_WIDE_INT *) flag_var == option->var_value;
1851 : else
1852 49 : return *(int *) flag_var == option->var_value;
1853 :
1854 134526 : case CLVC_BIT_CLEAR:
1855 134526 : if (option->cl_host_wide_int)
1856 19044 : return (*(HOST_WIDE_INT *) flag_var & option->var_value) == 0;
1857 : else
1858 115482 : return (*(int *) flag_var & option->var_value) == 0;
1859 :
1860 2227818 : case CLVC_BIT_SET:
1861 2227818 : if (option->cl_host_wide_int)
1862 1687278 : return (*(HOST_WIDE_INT *) flag_var & option->var_value) != 0;
1863 : else
1864 540540 : return (*(int *) flag_var & option->var_value) != 0;
1865 :
1866 270 : case CLVC_SIZE:
1867 270 : if (option->cl_host_wide_int)
1868 270 : return *(HOST_WIDE_INT *) flag_var != -1;
1869 : else
1870 0 : return *(int *) flag_var != -1;
1871 :
1872 : case CLVC_STRING:
1873 : case CLVC_ENUM:
1874 : case CLVC_DEFER:
1875 : break;
1876 : }
1877 : return -1;
1878 : }
1879 :
1880 : int
1881 102638363 : compiler_diagnostic_option_id_manager::
1882 : option_enabled_p (diagnostics::option_id opt_id) const
1883 : {
1884 102638363 : return option_enabled (opt_id.m_idx, m_lang_mask, m_opts);
1885 : }
1886 :
1887 : /* Fill STATE with the current state of option OPTION in OPTS. Return
1888 : true if there is some state to store. */
1889 :
1890 : bool
1891 3676824 : get_option_state (struct gcc_options *opts, int option,
1892 : struct cl_option_state *state)
1893 : {
1894 3676824 : void *flag_var = option_flag_var (option, opts);
1895 :
1896 3676824 : if (flag_var == 0)
1897 : return false;
1898 :
1899 3599430 : switch (cl_options[option].var_type)
1900 : {
1901 844026 : case CLVC_INTEGER:
1902 844026 : case CLVC_EQUAL:
1903 844026 : case CLVC_SIZE:
1904 844026 : state->data = flag_var;
1905 1688052 : state->size = (cl_options[option].cl_host_wide_int
1906 844026 : ? sizeof (HOST_WIDE_INT)
1907 : : sizeof (int));
1908 844026 : break;
1909 :
1910 2362344 : case CLVC_BIT_CLEAR:
1911 2362344 : case CLVC_BIT_SET:
1912 2362344 : state->ch = option_enabled (option, -1, opts);
1913 2362344 : state->data = &state->ch;
1914 2362344 : state->size = 1;
1915 2362344 : break;
1916 :
1917 120354 : case CLVC_STRING:
1918 120354 : state->data = *(const char **) flag_var;
1919 120354 : if (state->data == 0)
1920 100092 : state->data = "";
1921 120354 : state->size = strlen ((const char *) state->data) + 1;
1922 120354 : break;
1923 :
1924 272706 : case CLVC_ENUM:
1925 272706 : state->data = flag_var;
1926 272706 : state->size = cl_enums[cl_options[option].var_enum].var_size;
1927 272706 : break;
1928 :
1929 : case CLVC_DEFER:
1930 : return false;
1931 : }
1932 : return true;
1933 : }
1934 :
1935 : /* Set a warning option OPT_INDEX (language mask LANG_MASK, option
1936 : handlers HANDLERS) to have diagnostic kind KIND for option
1937 : structures OPTS and OPTS_SET and diagnostic context DC (possibly
1938 : NULL), at location LOC (UNKNOWN_LOCATION for -Werror=). ARG is the
1939 : argument of the option for joined options, or NULL otherwise. If IMPLY,
1940 : the warning option in question is implied at this point. This is
1941 : used by -Werror= and #pragma GCC diagnostic. */
1942 :
1943 : void
1944 4028556 : control_warning_option (unsigned int opt_index, int kind, const char *arg,
1945 : bool imply, location_t loc, unsigned int lang_mask,
1946 : const struct cl_option_handlers *handlers,
1947 : struct gcc_options *opts,
1948 : struct gcc_options *opts_set,
1949 : diagnostics::context *dc)
1950 : {
1951 4028556 : if (cl_options[opt_index].alias_target != N_OPTS)
1952 : {
1953 33205 : gcc_assert (!cl_options[opt_index].cl_separate_alias
1954 : && !cl_options[opt_index].cl_negative_alias);
1955 33205 : if (cl_options[opt_index].alias_arg)
1956 33189 : arg = cl_options[opt_index].alias_arg;
1957 33205 : opt_index = cl_options[opt_index].alias_target;
1958 : }
1959 4028556 : if (opt_index == OPT_SPECIAL_ignore || opt_index == OPT_SPECIAL_warn_removed)
1960 : return;
1961 4028553 : if (dc)
1962 4028553 : diagnostic_classify_diagnostic (dc, opt_index,
1963 : static_cast<enum diagnostics::kind> (kind),
1964 : loc);
1965 4028553 : if (imply)
1966 : {
1967 : /* -Werror=foo implies -Wfoo. */
1968 70857 : const struct cl_option *option = &cl_options[opt_index];
1969 70857 : HOST_WIDE_INT value = 1;
1970 :
1971 70857 : if (option->var_type == CLVC_INTEGER
1972 : || option->var_type == CLVC_ENUM
1973 : || option->var_type == CLVC_SIZE)
1974 : {
1975 :
1976 70854 : if (arg && *arg == '\0' && !option->cl_missing_ok)
1977 70854 : arg = NULL;
1978 :
1979 70854 : if ((option->flags & CL_JOINED) && arg == NULL)
1980 : {
1981 0 : cmdline_handle_error (loc, option, option->opt_text, arg,
1982 : CL_ERR_MISSING_ARG, lang_mask);
1983 0 : return;
1984 : }
1985 :
1986 : /* If the switch takes an integer argument, convert it. */
1987 70854 : if (arg && (option->cl_uinteger || option->cl_host_wide_int))
1988 : {
1989 35 : int error = 0;
1990 35 : value = *arg ? integral_argument (arg, &error,
1991 : option->cl_byte_size) : 0;
1992 35 : if (error)
1993 : {
1994 0 : cmdline_handle_error (loc, option, option->opt_text, arg,
1995 : CL_ERR_UINT_ARG, lang_mask);
1996 0 : return;
1997 : }
1998 : }
1999 :
2000 : /* If the switch takes an enumerated argument, convert it. */
2001 42 : if (arg && option->var_type == CLVC_ENUM)
2002 : {
2003 7 : const struct cl_enum *e = &cl_enums[option->var_enum];
2004 :
2005 7 : if (enum_arg_to_value (e->values, arg, 0, &value,
2006 : lang_mask) >= 0)
2007 : {
2008 7 : const char *carg = NULL;
2009 :
2010 7 : if (enum_value_to_arg (e->values, &carg, value, lang_mask))
2011 0 : arg = carg;
2012 7 : gcc_assert (carg != NULL);
2013 : }
2014 : else
2015 : {
2016 0 : cmdline_handle_error (loc, option, option->opt_text, arg,
2017 : CL_ERR_ENUM_ARG, lang_mask);
2018 0 : return;
2019 : }
2020 : }
2021 : }
2022 :
2023 70857 : handle_generated_option (opts, opts_set,
2024 : opt_index, arg, value, lang_mask,
2025 : kind, loc, handlers, false, dc);
2026 : }
2027 : }
2028 :
2029 : /* Parse options in COLLECT_GCC_OPTIONS and push them on ARGV_OBSTACK.
2030 : Store number of arguments into ARGC_P. */
2031 :
2032 : void
2033 25462 : parse_options_from_collect_gcc_options (const char *collect_gcc_options,
2034 : obstack *argv_obstack,
2035 : int *argc_p)
2036 : {
2037 25462 : char *argv_storage = xstrdup (collect_gcc_options);
2038 25462 : int j, k;
2039 :
2040 1050580 : for (j = 0, k = 0; argv_storage[j] != '\0'; ++j)
2041 : {
2042 1025118 : if (argv_storage[j] == '\'')
2043 : {
2044 525207 : obstack_ptr_grow (argv_obstack, &argv_storage[k]);
2045 525207 : ++j;
2046 12006195 : do
2047 : {
2048 12006195 : if (argv_storage[j] == '\0')
2049 0 : fatal_error (input_location,
2050 : "malformed %<COLLECT_GCC_OPTIONS%>");
2051 12006195 : else if (startswith (&argv_storage[j], "'\\''"))
2052 : {
2053 0 : argv_storage[k++] = '\'';
2054 0 : j += 4;
2055 : }
2056 12006195 : else if (argv_storage[j] == '\'')
2057 : break;
2058 : else
2059 11480988 : argv_storage[k++] = argv_storage[j++];
2060 : }
2061 : while (1);
2062 525207 : argv_storage[k++] = '\0';
2063 : }
2064 : }
2065 :
2066 25462 : obstack_ptr_grow (argv_obstack, NULL);
2067 25462 : *argc_p = obstack_object_size (argv_obstack) / sizeof (void *) - 1;
2068 25462 : }
2069 :
2070 : /* Prepend -Xassembler for each option in COLLECT_AS_OPTIONS,
2071 : and push on O. */
2072 :
2073 3 : void prepend_xassembler_to_collect_as_options (const char *collect_as_options,
2074 : obstack *o)
2075 : {
2076 3 : obstack opts_obstack;
2077 3 : int opts_count;
2078 :
2079 3 : obstack_init (&opts_obstack);
2080 3 : parse_options_from_collect_gcc_options (collect_as_options,
2081 : &opts_obstack, &opts_count);
2082 3 : const char **assembler_opts = XOBFINISH (&opts_obstack, const char **);
2083 :
2084 67 : for (int i = 0; i < opts_count; i++)
2085 : {
2086 64 : obstack_grow (o, " '-Xassembler' ",
2087 : strlen (" '-Xassembler' "));
2088 64 : const char *opt = assembler_opts[i];
2089 64 : obstack_1grow (o, '\'');
2090 64 : obstack_grow (o, opt, strlen (opt));
2091 64 : obstack_1grow (o, '\'');
2092 : }
2093 3 : }
2094 :
2095 267027 : jobserver_info::jobserver_info ()
2096 : {
2097 : /* Traditionally, GNU make uses opened pipes for jobserver-auth,
2098 : e.g. --jobserver-auth=3,4.
2099 : Starting with GNU make 4.4, one can use --jobserver-style=fifo
2100 : and then named pipe is used: --jobserver-auth=fifo:/tmp/hcsparta. */
2101 :
2102 : /* Detect jobserver and drop it if it's not working. */
2103 267027 : string js_needle = "--jobserver-auth=";
2104 267027 : string fifo_prefix = "fifo:";
2105 :
2106 267027 : const char *envval = getenv ("MAKEFLAGS");
2107 267027 : if (envval != NULL)
2108 : {
2109 264709 : string makeflags = envval;
2110 264709 : size_t n = makeflags.rfind (js_needle);
2111 264709 : if (n != string::npos)
2112 : {
2113 260592 : string ending = makeflags.substr (n + js_needle.size ());
2114 260592 : bool is_named_pipe = ending.find (fifo_prefix) == 0;
2115 260592 : if (is_named_pipe)
2116 : {
2117 260592 : ending = ending.substr (fifo_prefix.size ());
2118 260592 : pipe_path = ending.substr (0, ending.find (' '));
2119 260592 : is_active = true;
2120 : }
2121 0 : else if (sscanf (makeflags.c_str () + n + js_needle.size (),
2122 : "%d,%d", &rfd, &wfd) == 2
2123 0 : && rfd > 0
2124 0 : && wfd > 0
2125 0 : && is_valid_fd (rfd)
2126 0 : && is_valid_fd (wfd))
2127 0 : is_active = true;
2128 : else
2129 : {
2130 0 : bool negative_fds = !is_named_pipe && rfd < 0 && wfd < 0;
2131 0 : if (!negative_fds)
2132 : {
2133 0 : string dup = makeflags.substr (0, n);
2134 0 : size_t pos = makeflags.find (' ', n);
2135 0 : if (pos != string::npos)
2136 0 : dup += makeflags.substr (pos);
2137 0 : skipped_makeflags = "MAKEFLAGS=" + dup;
2138 0 : }
2139 0 : error_msg
2140 0 : = "cannot access %<" + js_needle + "%> file descriptors";
2141 : }
2142 260592 : }
2143 529418 : error_msg = "%<" + js_needle + "%> is not present in %<MAKEFLAGS%>";
2144 264709 : }
2145 : else
2146 2318 : error_msg = "%<MAKEFLAGS%> environment variable is unset";
2147 :
2148 267027 : if (!error_msg.empty ())
2149 267027 : error_msg = "jobserver is not available: " + error_msg;
2150 267027 : }
2151 :
2152 : void
2153 7739 : jobserver_info::connect ()
2154 : {
2155 7739 : if (!pipe_path.empty ())
2156 : {
2157 : #if HOST_HAS_O_NONBLOCK
2158 7739 : pipefd = open (pipe_path.c_str (), O_RDWR | O_NONBLOCK);
2159 7739 : is_connected = true;
2160 : #else
2161 : is_connected = false;
2162 : #endif
2163 : }
2164 : else
2165 0 : is_connected = true;
2166 7739 : }
2167 :
2168 : void
2169 201 : jobserver_info::disconnect ()
2170 : {
2171 201 : if (!pipe_path.empty ())
2172 : {
2173 201 : int res = close (pipefd);
2174 201 : gcc_assert (res == 0);
2175 201 : pipefd = -1;
2176 : }
2177 201 : }
2178 :
2179 : bool
2180 357 : jobserver_info::get_token ()
2181 : {
2182 357 : int fd = pipe_path.empty () ? rfd : pipefd;
2183 357 : char c;
2184 357 : unsigned n = read (fd, &c, 1);
2185 357 : if (n != 1)
2186 : {
2187 357 : gcc_assert (errno == EAGAIN);
2188 : return false;
2189 : }
2190 : else
2191 : return true;
2192 : }
2193 :
2194 : void
2195 0 : jobserver_info::return_token ()
2196 : {
2197 0 : int fd = pipe_path.empty () ? wfd : pipefd;
2198 0 : char c = 'G';
2199 0 : int res = write (fd, &c, 1);
2200 0 : gcc_assert (res == 1);
2201 0 : }
|