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