OSDN Git Service

2007-02-15 Manuel Lopez-Ibanez <manu@gcc.gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / opts.c
1 /* Command line option handling.
2    Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
3    Free Software Foundation, Inc.
4    Contributed by Neil Booth.
5
6 This file is part of GCC.
7
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
11 version.
12
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16 for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING.  If not, write to the Free
20 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
21 02110-1301, USA.  */
22
23 #include "config.h"
24 #include "system.h"
25 #include "intl.h"
26 #include "coretypes.h"
27 #include "tm.h"
28 #include "tree.h"
29 #include "rtl.h"
30 #include "ggc.h"
31 #include "output.h"
32 #include "langhooks.h"
33 #include "opts.h"
34 #include "options.h"
35 #include "flags.h"
36 #include "toplev.h"
37 #include "params.h"
38 #include "diagnostic.h"
39 #include "tm_p.h"               /* For OPTIMIZATION_OPTIONS.  */
40 #include "insn-attr.h"          /* For INSN_SCHEDULING.  */
41 #include "target.h"
42 #include "tree-pass.h"
43
44 /* Value of the -G xx switch, and whether it was passed or not.  */
45 unsigned HOST_WIDE_INT g_switch_value;
46 bool g_switch_set;
47
48 /* True if we should exit after parsing options.  */
49 bool exit_after_options;
50
51 /* Print various extra warnings.  -W/-Wextra.  */
52 bool extra_warnings;
53
54 /* True to warn about any objects definitions whose size is larger
55    than N bytes.  Also want about function definitions whose returned
56    values are larger than N bytes, where N is `larger_than_size'.  */
57 bool warn_larger_than;
58 HOST_WIDE_INT larger_than_size;
59
60 /* Nonzero means warn about constructs which might not be
61    strict-aliasing safe.  */
62 int warn_strict_aliasing;
63
64 /* Nonzero means warn about optimizations which rely on undefined
65    signed overflow.  */
66 int warn_strict_overflow;
67
68 /* Hack for cooperation between set_Wunused and set_Wextra.  */
69 static bool maybe_warn_unused_parameter;
70
71 /* Type(s) of debugging information we are producing (if any).  See
72    flags.h for the definitions of the different possible types of
73    debugging information.  */
74 enum debug_info_type write_symbols = NO_DEBUG;
75
76 /* Level of debugging information we are producing.  See flags.h for
77    the definitions of the different possible levels.  */
78 enum debug_info_level debug_info_level = DINFO_LEVEL_NONE;
79
80 /* Nonzero means use GNU-only extensions in the generated symbolic
81    debugging information.  Currently, this only has an effect when
82    write_symbols is set to DBX_DEBUG, XCOFF_DEBUG, or DWARF_DEBUG.  */
83 bool use_gnu_debug_info_extensions;
84
85 /* The default visibility for all symbols (unless overridden) */
86 enum symbol_visibility default_visibility = VISIBILITY_DEFAULT;
87
88 /* Disable unit-at-a-time for frontends that might be still broken in this
89    respect.  */
90
91 bool no_unit_at_a_time_default;
92
93 /* Global visibility options.  */
94 struct visibility_flags visibility_options;
95
96 /* What to print when a switch has no documentation.  */
97 static const char undocumented_msg[] = N_("This switch lacks documentation");
98
99 /* Used for bookkeeping on whether user set these flags so
100    -fprofile-use/-fprofile-generate does not use them.  */
101 static bool profile_arc_flag_set, flag_profile_values_set;
102 static bool flag_unroll_loops_set, flag_tracer_set;
103 static bool flag_value_profile_transformations_set;
104 static bool flag_peel_loops_set, flag_branch_probabilities_set;
105
106 /* Input file names.  */
107 const char **in_fnames;
108 unsigned num_in_fnames;
109
110 static int common_handle_option (size_t scode, const char *arg, int value,
111                                  unsigned int lang_mask);
112 static void handle_param (const char *);
113 static void set_Wextra (int);
114 static unsigned int handle_option (const char **argv, unsigned int lang_mask);
115 static char *write_langs (unsigned int lang_mask);
116 static void complain_wrong_lang (const char *, const struct cl_option *,
117                                  unsigned int lang_mask);
118 static void handle_options (unsigned int, const char **, unsigned int);
119 static void set_debug_level (enum debug_info_type type, int extended,
120                              const char *arg);
121
122 /* If ARG is a non-negative integer made up solely of digits, return its
123    value, otherwise return -1.  */
124 static int
125 integral_argument (const char *arg)
126 {
127   const char *p = arg;
128
129   while (*p && ISDIGIT (*p))
130     p++;
131
132   if (*p == '\0')
133     return atoi (arg);
134
135   return -1;
136 }
137
138 /* Return a malloced slash-separated list of languages in MASK.  */
139 static char *
140 write_langs (unsigned int mask)
141 {
142   unsigned int n = 0, len = 0;
143   const char *lang_name;
144   char *result;
145
146   for (n = 0; (lang_name = lang_names[n]) != 0; n++)
147     if (mask & (1U << n))
148       len += strlen (lang_name) + 1;
149
150   result = XNEWVEC (char, len);
151   len = 0;
152   for (n = 0; (lang_name = lang_names[n]) != 0; n++)
153     if (mask & (1U << n))
154       {
155         if (len)
156           result[len++] = '/';
157         strcpy (result + len, lang_name);
158         len += strlen (lang_name);
159       }
160
161   result[len] = 0;
162
163   return result;
164 }
165
166 /* Complain that switch OPT_INDEX does not apply to this front end.  */
167 static void
168 complain_wrong_lang (const char *text, const struct cl_option *option,
169                      unsigned int lang_mask)
170 {
171   char *ok_langs, *bad_lang;
172
173   ok_langs = write_langs (option->flags);
174   bad_lang = write_langs (lang_mask);
175
176   /* Eventually this should become a hard error IMO.  */
177   warning (0, "command line option \"%s\" is valid for %s but not for %s",
178            text, ok_langs, bad_lang);
179
180   free (ok_langs);
181   free (bad_lang);
182 }
183
184 /* Handle the switch beginning at ARGV for the language indicated by
185    LANG_MASK.  Returns the number of switches consumed.  */
186 static unsigned int
187 handle_option (const char **argv, unsigned int lang_mask)
188 {
189   size_t opt_index;
190   const char *opt, *arg = 0;
191   char *dup = 0;
192   int value = 1;
193   unsigned int result = 0;
194   const struct cl_option *option;
195
196   opt = argv[0];
197
198   opt_index = find_opt (opt + 1, lang_mask | CL_COMMON | CL_TARGET);
199   if (opt_index == cl_options_count
200       && (opt[1] == 'W' || opt[1] == 'f' || opt[1] == 'm')
201       && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-')
202     {
203       /* Drop the "no-" from negative switches.  */
204       size_t len = strlen (opt) - 3;
205
206       dup = XNEWVEC (char, len + 1);
207       dup[0] = '-';
208       dup[1] = opt[1];
209       memcpy (dup + 2, opt + 5, len - 2 + 1);
210       opt = dup;
211       value = 0;
212       opt_index = find_opt (opt + 1, lang_mask | CL_COMMON | CL_TARGET);
213     }
214
215   if (opt_index == cl_options_count)
216     goto done;
217
218   option = &cl_options[opt_index];
219
220   /* Reject negative form of switches that don't take negatives as
221      unrecognized.  */
222   if (!value && (option->flags & CL_REJECT_NEGATIVE))
223     goto done;
224
225   /* We've recognized this switch.  */
226   result = 1;
227
228   /* Check to see if the option is disabled for this configuration.  */
229   if (option->flags & CL_DISABLED)
230     {
231       error ("command line option %qs"
232              " is not supported by this configuration", opt);
233       goto done;
234     }
235
236   /* Sort out any argument the switch takes.  */
237   if (option->flags & CL_JOINED)
238     {
239       /* Have arg point to the original switch.  This is because
240          some code, such as disable_builtin_function, expects its
241          argument to be persistent until the program exits.  */
242       arg = argv[0] + cl_options[opt_index].opt_len + 1;
243       if (!value)
244         arg += strlen ("no-");
245
246       if (*arg == '\0' && !(option->flags & CL_MISSING_OK))
247         {
248           if (option->flags & CL_SEPARATE)
249             {
250               arg = argv[1];
251               result = 2;
252             }
253           else
254             /* Missing argument.  */
255             arg = NULL;
256         }
257     }
258   else if (option->flags & CL_SEPARATE)
259     {
260       arg = argv[1];
261       result = 2;
262     }
263
264   /* Now we've swallowed any potential argument, complain if this
265      is a switch for a different front end.  */
266   if (!(option->flags & (lang_mask | CL_COMMON | CL_TARGET)))
267     {
268       complain_wrong_lang (argv[0], option, lang_mask);
269       goto done;
270     }
271
272   if (arg == NULL && (option->flags & (CL_JOINED | CL_SEPARATE)))
273     {
274       if (!lang_hooks.missing_argument (opt, opt_index))
275         error ("missing argument to \"%s\"", opt);
276       goto done;
277     }
278
279   /* If the switch takes an integer, convert it.  */
280   if (arg && (option->flags & CL_UINTEGER))
281     {
282       value = integral_argument (arg);
283       if (value == -1)
284         {
285           error ("argument to \"%s\" should be a non-negative integer",
286                  option->opt_text);
287           goto done;
288         }
289     }
290
291   if (option->flag_var)
292     switch (option->var_type)
293       {
294       case CLVC_BOOLEAN:
295         *(int *) option->flag_var = value;
296         break;
297
298       case CLVC_EQUAL:
299         *(int *) option->flag_var = (value
300                                      ? option->var_value
301                                      : !option->var_value);
302         break;
303
304       case CLVC_BIT_CLEAR:
305       case CLVC_BIT_SET:
306         if ((value != 0) == (option->var_type == CLVC_BIT_SET))
307           *(int *) option->flag_var |= option->var_value;
308         else
309           *(int *) option->flag_var &= ~option->var_value;
310         if (option->flag_var == &target_flags)
311           target_flags_explicit |= option->var_value;
312         break;
313
314       case CLVC_STRING:
315         *(const char **) option->flag_var = arg;
316         break;
317       }
318
319   if (option->flags & lang_mask)
320     if (lang_hooks.handle_option (opt_index, arg, value) == 0)
321       result = 0;
322
323   if (result && (option->flags & CL_COMMON))
324     if (common_handle_option (opt_index, arg, value, lang_mask) == 0)
325       result = 0;
326
327   if (result && (option->flags & CL_TARGET))
328     if (!targetm.handle_option (opt_index, arg, value))
329       result = 0;
330
331  done:
332   if (dup)
333     free (dup);
334   return result;
335 }
336
337 /* Handle FILENAME from the command line.  */
338 static void
339 add_input_filename (const char *filename)
340 {
341   num_in_fnames++;
342   in_fnames = xrealloc (in_fnames, num_in_fnames * sizeof (in_fnames[0]));
343   in_fnames[num_in_fnames - 1] = filename;
344 }
345
346 /* Decode and handle the vector of command line options.  LANG_MASK
347    contains has a single bit set representing the current
348    language.  */
349 static void
350 handle_options (unsigned int argc, const char **argv, unsigned int lang_mask)
351 {
352   unsigned int n, i;
353
354   for (i = 1; i < argc; i += n)
355     {
356       const char *opt = argv[i];
357
358       /* Interpret "-" or a non-switch as a file name.  */
359       if (opt[0] != '-' || opt[1] == '\0')
360         {
361           if (main_input_filename == NULL)
362             main_input_filename = opt;
363           add_input_filename (opt);
364           n = 1;
365           continue;
366         }
367
368       n = handle_option (argv + i, lang_mask);
369
370       if (!n)
371         {
372           n = 1;
373           error ("unrecognized command line option \"%s\"", opt);
374         }
375     }
376 }
377
378 /* Parse command line options and set default flag values.  Do minimal
379    options processing.  */
380 void
381 decode_options (unsigned int argc, const char **argv)
382 {
383   unsigned int i, lang_mask;
384
385   /* Perform language-specific options initialization.  */
386   lang_mask = lang_hooks.init_options (argc, argv);
387
388   lang_hooks.initialize_diagnostics (global_dc);
389
390   /* Scan to see what optimization level has been specified.  That will
391      determine the default value of many flags.  */
392   for (i = 1; i < argc; i++)
393     {
394       if (!strcmp (argv[i], "-O"))
395         {
396           optimize = 1;
397           optimize_size = 0;
398         }
399       else if (argv[i][0] == '-' && argv[i][1] == 'O')
400         {
401           /* Handle -Os, -O2, -O3, -O69, ...  */
402           const char *p = &argv[i][2];
403
404           if ((p[0] == 's') && (p[1] == 0))
405             {
406               optimize_size = 1;
407
408               /* Optimizing for size forces optimize to be 2.  */
409               optimize = 2;
410             }
411           else
412             {
413               const int optimize_val = read_integral_parameter (p, p - 2, -1);
414               if (optimize_val != -1)
415                 {
416                   optimize = optimize_val;
417                   optimize_size = 0;
418                 }
419             }
420         }
421     }
422
423   if (!optimize)
424     {
425       flag_merge_constants = 0;
426     }
427
428   if (optimize >= 1)
429     {
430       flag_defer_pop = 1;
431 #ifdef DELAY_SLOTS
432       flag_delayed_branch = 1;
433 #endif
434 #ifdef CAN_DEBUG_WITHOUT_FP
435       flag_omit_frame_pointer = 1;
436 #endif
437       flag_guess_branch_prob = 1;
438       flag_cprop_registers = 1;
439       flag_if_conversion = 1;
440       flag_if_conversion2 = 1;
441       flag_ipa_pure_const = 1;
442       flag_ipa_reference = 1;
443       flag_split_wide_types = 1;
444       flag_tree_ccp = 1;
445       flag_tree_dce = 1;
446       flag_tree_dom = 1;
447       flag_tree_dse = 1;
448       flag_tree_ter = 1;
449       flag_tree_sra = 1;
450       flag_tree_copyrename = 1;
451       flag_tree_fre = 1;
452       flag_tree_copy_prop = 1;
453       flag_tree_sink = 1;
454       flag_tree_salias = 1;
455       if (!no_unit_at_a_time_default)
456         flag_unit_at_a_time = 1;
457
458       if (!optimize_size)
459         {
460           /* Loop header copying usually increases size of the code.  This used
461              not to be true, since quite often it is possible to verify that
462              the condition is satisfied in the first iteration and therefore
463              to eliminate it.  Jump threading handles these cases now.  */
464           flag_tree_ch = 1;
465         }
466     }
467
468   if (optimize >= 2)
469     {
470       flag_thread_jumps = 1;
471       flag_crossjumping = 1;
472       flag_optimize_sibling_calls = 1;
473       flag_forward_propagate = 1;
474       flag_cse_follow_jumps = 1;
475       flag_gcse = 1;
476       flag_expensive_optimizations = 1;
477       flag_ipa_type_escape = 1;
478       flag_rerun_cse_after_loop = 1;
479       flag_caller_saves = 1;
480       flag_peephole2 = 1;
481 #ifdef INSN_SCHEDULING
482       flag_schedule_insns = 1;
483       flag_schedule_insns_after_reload = 1;
484 #endif
485       flag_regmove = 1;
486       flag_strict_aliasing = 1;
487       flag_strict_overflow = 1;
488       flag_delete_null_pointer_checks = 1;
489       flag_reorder_blocks = 1;
490       flag_reorder_functions = 1;
491       flag_tree_store_ccp = 1;
492       flag_tree_store_copy_prop = 1;
493       flag_tree_vrp = 1;
494
495       if (!optimize_size)
496         {
497           /* PRE tends to generate bigger code.  */
498           flag_tree_pre = 1;
499         }
500     }
501
502   if (optimize >= 3)
503     {
504       flag_inline_functions = 1;
505       flag_unswitch_loops = 1;
506       flag_gcse_after_reload = 1;
507     }
508
509   if (optimize < 2 || optimize_size)
510     {
511       align_loops = 1;
512       align_jumps = 1;
513       align_labels = 1;
514       align_functions = 1;
515
516       /* Don't reorder blocks when optimizing for size because extra
517          jump insns may be created; also barrier may create extra padding.
518
519          More correctly we should have a block reordering mode that tried
520          to minimize the combined size of all the jumps.  This would more
521          or less automatically remove extra jumps, but would also try to
522          use more short jumps instead of long jumps.  */
523       flag_reorder_blocks = 0;
524       flag_reorder_blocks_and_partition = 0;
525     }
526
527   if (optimize_size)
528     {
529       /* Inlining of very small functions usually reduces total size.  */
530       set_param_value ("max-inline-insns-single", 5);
531       set_param_value ("max-inline-insns-auto", 5);
532       flag_inline_functions = 1;
533
534       /* We want to crossjump as much as possible.  */
535       set_param_value ("min-crossjump-insns", 1);
536     }
537
538   /* Initialize whether `char' is signed.  */
539   flag_signed_char = DEFAULT_SIGNED_CHAR;
540   /* Set this to a special "uninitialized" value.  The actual default is set
541      after target options have been processed.  */
542   flag_short_enums = 2;
543
544   /* Initialize target_flags before OPTIMIZATION_OPTIONS so the latter can
545      modify it.  */
546   target_flags = targetm.default_target_flags;
547
548   /* Some tagets have ABI-specified unwind tables.  */
549   flag_unwind_tables = targetm.unwind_tables_default;
550
551 #ifdef OPTIMIZATION_OPTIONS
552   /* Allow default optimizations to be specified on a per-machine basis.  */
553   OPTIMIZATION_OPTIONS (optimize, optimize_size);
554 #endif
555
556   handle_options (argc, argv, lang_mask);
557
558   if (flag_pie)
559     flag_pic = flag_pie;
560   if (flag_pic && !flag_pie)
561     flag_shlib = 1;
562
563   if (flag_no_inline == 2)
564     flag_no_inline = 0;
565   else
566     flag_really_no_inline = flag_no_inline;
567
568   /* Set flag_no_inline before the post_options () hook.  The C front
569      ends use it to determine tree inlining defaults.  FIXME: such
570      code should be lang-independent when all front ends use tree
571      inlining, in which case it, and this condition, should be moved
572      to the top of process_options() instead.  */
573   if (optimize == 0)
574     {
575       /* Inlining does not work if not optimizing,
576          so force it not to be done.  */
577       flag_no_inline = 1;
578       warn_inline = 0;
579
580       /* The c_decode_option function and decode_option hook set
581          this to `2' if -Wall is used, so we can avoid giving out
582          lots of errors for people who don't realize what -Wall does.  */
583       if (warn_uninitialized == 1)
584         warning (OPT_Wuninitialized,
585                  "-Wuninitialized is not supported without -O");
586     }
587
588   if (flag_really_no_inline == 2)
589     flag_really_no_inline = flag_no_inline;
590
591   /* The optimization to partition hot and cold basic blocks into separate
592      sections of the .o and executable files does not work (currently)
593      with exception handling.  This is because there is no support for
594      generating unwind info.  If flag_exceptions is turned on we need to
595      turn off the partitioning optimization.  */
596
597   if (flag_exceptions && flag_reorder_blocks_and_partition)
598     {
599       inform
600             ("-freorder-blocks-and-partition does not work with exceptions");
601       flag_reorder_blocks_and_partition = 0;
602       flag_reorder_blocks = 1;
603     }
604
605   /* If user requested unwind info, then turn off the partitioning
606      optimization.  */
607
608   if (flag_unwind_tables && ! targetm.unwind_tables_default
609       && flag_reorder_blocks_and_partition)
610     {
611       inform ("-freorder-blocks-and-partition does not support unwind info");
612       flag_reorder_blocks_and_partition = 0;
613       flag_reorder_blocks = 1;
614     }
615
616   /* If the target requested unwind info, then turn off the partitioning
617      optimization with a different message.  Likewise, if the target does not
618      support named sections.  */
619
620   if (flag_reorder_blocks_and_partition
621       && (!targetm.have_named_sections
622           || (flag_unwind_tables && targetm.unwind_tables_default)))
623     {
624       inform
625        ("-freorder-blocks-and-partition does not work on this architecture");
626       flag_reorder_blocks_and_partition = 0;
627       flag_reorder_blocks = 1;
628     }
629 }
630
631 #define LEFT_COLUMN     27
632
633 /* Output ITEM, of length ITEM_WIDTH, in the left column,
634    followed by word-wrapped HELP in a second column.  */
635 static void
636 wrap_help (const char *help,
637            const char *item,
638            unsigned int item_width,
639            unsigned int columns)
640 {
641   unsigned int col_width = LEFT_COLUMN;
642   unsigned int remaining, room, len;
643
644   remaining = strlen (help);
645
646   do
647     {
648       room = columns - 3 - MAX (col_width, item_width);
649       if (room > columns)
650         room = 0;
651       len = remaining;
652
653       if (room < len)
654         {
655           unsigned int i;
656
657           for (i = 0; help[i]; i++)
658             {
659               if (i >= room && len != remaining)
660                 break;
661               if (help[i] == ' ')
662                 len = i;
663               else if ((help[i] == '-' || help[i] == '/')
664                        && help[i + 1] != ' '
665                        && i > 0 && ISALPHA (help[i - 1]))
666                 len = i + 1;
667             }
668         }
669
670       printf( "  %-*.*s %.*s\n", col_width, item_width, item, len, help);
671       item_width = 0;
672       while (help[len] == ' ')
673         len++;
674       help += len;
675       remaining -= len;
676     }
677   while (remaining);
678 }
679
680 /* Print help for a specific front-end, etc.  */
681 static void
682 print_filtered_help (unsigned int include_flags,
683                      unsigned int exclude_flags,
684                      unsigned int any_flags,
685                      unsigned int columns)
686 {
687   unsigned int i;
688   const char *help;
689   static char *printed = NULL;
690   bool found = false;
691   bool displayed = false;
692
693   if (include_flags == CL_PARAMS)
694     {
695       for (i = 0; i < LAST_PARAM; i++)
696         {
697           const char *param = compiler_params[i].option;
698
699           help = compiler_params[i].help;
700           if (help == NULL || *help == '\0')
701             {
702               if (exclude_flags & CL_UNDOCUMENTED)
703                 continue;
704               help = undocumented_msg;
705             }
706
707           /* Get the translation.  */
708           help = _(help);
709
710           wrap_help (help, param, strlen (param), columns);
711         }
712       putchar ('\n');
713       return;
714     }
715
716   if (!printed)
717     printed = xcalloc (1, cl_options_count);
718
719   for (i = 0; i < cl_options_count; i++)
720     {
721       static char new_help[128];
722       const struct cl_option *option = cl_options + i;
723       unsigned int len;
724       const char *opt;
725       const char *tab;
726
727       if (include_flags == 0
728           || ((option->flags & include_flags) != include_flags))
729         {
730           if ((option->flags & any_flags) == 0)
731             continue;
732         }
733
734       /* Skip unwanted switches.  */
735       if ((option->flags & exclude_flags) != 0)
736         continue;
737
738       found = true;
739       /* Skip switches that have already been printed.  */
740       if (printed[i])
741         continue;
742
743       printed[i] = true;
744
745       help = option->help;
746       if (help == NULL)
747         {
748           if (exclude_flags & CL_UNDOCUMENTED)
749             continue;
750           help = undocumented_msg;
751         }
752
753       /* Get the translation.  */
754       help = _(help);
755
756       /* Find the gap between the name of the
757          option and its descriptive text.  */
758       tab = strchr (help, '\t');
759       if (tab)
760         {
761           len = tab - help;
762           opt = help;
763           help = tab + 1;
764         }
765       else
766         {
767           opt = option->opt_text;
768           len = strlen (opt);
769         }
770
771       /* With the -Q option enabled we change the descriptive text associated
772          with an option to be an indication of its current setting.  */
773       if (!quiet_flag)
774         {
775           if (len < (LEFT_COLUMN + 2))
776             strcpy (new_help, "\t\t");
777           else
778             strcpy (new_help, "\t");
779
780           if (option->flag_var != NULL)
781             {
782               if (option->flags & CL_JOINED)
783                 {
784                   if (option->var_type == CLVC_STRING)
785                     {
786                       if (* (const char **) option->flag_var != NULL)
787                         snprintf (new_help + strlen (new_help),
788                                   sizeof (new_help) - strlen (new_help),
789                                   * (const char **) option->flag_var);
790                     }
791                   else
792                     sprintf (new_help + strlen (new_help),
793                              "%#x", * (int *) option->flag_var);
794                 }
795               else
796                 strcat (new_help, option_enabled (i)
797                         ? _("[enabled]") : _("[disabled]"));
798             }
799
800           help = new_help;
801         }
802
803       wrap_help (help, opt, len, columns);
804       displayed = true;
805     }
806
807   if (! found)
808     printf (_(" No options with the desired characteristics were found\n"));
809   else if (! displayed)
810     printf (_(" All options with the desired characteristics have already been displayed\n"));
811
812   putchar ('\n');
813 }
814
815 /* Display help for a specified type of option.
816    The options must have ALL of the INCLUDE_FLAGS set
817    ANY of the flags in the ANY_FLAGS set
818    and NONE of the EXCLUDE_FLAGS set.  */
819 static void
820 print_specific_help (unsigned int include_flags,
821                      unsigned int exclude_flags,
822                      unsigned int any_flags)
823 {
824   unsigned int all_langs_mask = (1U << cl_lang_count) - 1;
825   const char * description = NULL;
826   const char * descrip_extra = "";
827   size_t i;
828   unsigned int flag;
829   static unsigned int columns = 0;
830
831   /* Sanity check: Make sure that we do not have more
832      languages than we have bits available to enumerate them.  */
833   gcc_assert ((1U << cl_lang_count) < CL_MIN_OPTION_CLASS);
834
835   /* If we have not done so already, obtain
836      the desired maximum width of the output.  */
837   if (columns == 0)
838     {
839       const char *p;
840
841       GET_ENVIRONMENT (p, "COLUMNS");
842       if (p != NULL)
843         {
844           int value = atoi (p);
845
846           if (value > 0)
847             columns = value;
848         }
849
850       if (columns == 0)
851         /* Use a reasonable default.  */
852         columns = 80;
853     }
854
855   /* Decide upon the title for the options that we are going to display.  */
856   for (i = 0, flag = 1; flag <= CL_MAX_OPTION_CLASS; flag <<= 1, i ++)
857     {
858       switch (flag & include_flags)
859         {
860         case 0:
861           break;
862
863         case CL_TARGET:
864           description = _("The following options are target specific");
865           break;
866         case CL_WARNING:
867           description = _("The following options control compiler warning messages");
868           break;
869         case CL_OPTIMIZATION:
870           description = _("The following options control optimizations");
871           break;
872         case CL_COMMON:
873           description = _("The following options are language-independent");
874           break;
875         case CL_PARAMS:
876           description = _("The --param option recognizes the following as parameters");
877           break;
878         default:
879           if (i >= cl_lang_count)
880             break;
881           if ((exclude_flags & ((1U << cl_lang_count) - 1)) != 0)
882             {
883               description = _("The following options are specific to the language ");
884               descrip_extra = lang_names [i];
885             }
886           else
887             description = _("The following options are supported by, amoung others, the language ");
888           break;
889         }
890     }
891
892   if (description == NULL)
893     {
894       if (any_flags == 0)
895         {
896           if (include_flags == CL_UNDOCUMENTED)
897             description = _("The following options are not documented");
898           else
899             {
900               internal_error ("unrecognized include_flags 0x%x passed to print_specific_help",
901                               include_flags);
902               return;
903             }
904         }
905       else
906         {
907           if (any_flags & all_langs_mask)
908             description = _("The following options are language-related");
909           else
910             description = _("The following options are language-independent");
911         }
912     }
913
914   printf ("%s%s:\n", description, descrip_extra);
915   print_filtered_help (include_flags, exclude_flags, any_flags, columns);
916 }
917
918 /* Handle target- and language-independent options.  Return zero to
919    generate an "unknown option" message.  Only options that need
920    extra handling need to be listed here; if you simply want
921    VALUE assigned to a variable, it happens automatically.  */
922
923 static int
924 common_handle_option (size_t scode, const char *arg, int value,
925                       unsigned int lang_mask)
926 {
927   enum opt_code code = (enum opt_code) scode;
928
929   switch (code)
930     {
931     case OPT__param:
932       handle_param (arg);
933       break;
934
935     case OPT_fhelp:
936     case OPT__help:
937       {
938         unsigned int all_langs_mask = (1U << cl_lang_count) - 1;
939         unsigned int undoc_mask;
940         unsigned int i;
941
942         undoc_mask = extra_warnings ? 0 : CL_UNDOCUMENTED;
943         /* First display any single language specific options.  */
944         for (i = 0; i < cl_lang_count; i++)
945           print_specific_help
946             (1U << i, (all_langs_mask & (~ (1U << i))) | undoc_mask, 0);
947         /* Next display any multi language specific options.  */
948         print_specific_help (0, undoc_mask, all_langs_mask);
949         /* Then display any remaining, non-language options.  */
950         for (i = CL_MIN_OPTION_CLASS; i <= CL_MAX_OPTION_CLASS; i <<= 1)
951           print_specific_help (i, undoc_mask, 0);
952         exit_after_options = true;
953         break;
954       }
955
956     case OPT_ftarget_help:
957     case OPT__target_help:
958       print_specific_help (CL_TARGET, CL_UNDOCUMENTED, 0);
959       exit_after_options = true;
960       break;
961
962     case OPT_fhelp_:
963     case OPT__help_:
964       {
965         const char * a = arg;
966         unsigned int include_flags = 0;
967         /* Note - by default we include undocumented options when listing
968            specific classes.  If you only want to see documented options
969            then add ",^undocumented" to the --help= option.  e.g.:
970
971            --help=target,^undocumented  */
972         unsigned int exclude_flags = 0;
973
974         /* Walk along the argument string, parsing each word in turn.
975            The format is:
976            arg = [^]{word}[,{arg}]
977            word = {optimizers|target|warnings|undocumented|params}  */
978         while (* a != 0)
979           {
980             static struct
981             {
982               const char * string;
983               unsigned int flag;
984             }
985             specifics[] =
986             {
987               { "optimizers", CL_OPTIMIZATION },
988               { "target", CL_TARGET },
989               { "warnings", CL_WARNING },
990               { "undocumented", CL_UNDOCUMENTED },
991               { "params", CL_PARAMS },
992               { "joined", CL_JOINED },
993               { "separate", CL_SEPARATE },
994               { NULL, 0 }
995             };
996             unsigned int * pflags;
997             char * comma;
998             unsigned int len;
999             unsigned int i;
1000
1001             if (* a == '^')
1002               {
1003                 ++ a;
1004                 pflags = & exclude_flags;
1005               }
1006             else
1007               pflags = & include_flags;
1008
1009             comma = strchr (a, ',');
1010             if (comma == NULL)
1011               len = strlen (a);
1012             else
1013               len = comma - a;
1014
1015             for (i = 0; specifics[i].string != NULL; i++)
1016               if (strncasecmp (a, specifics[i].string, len) == 0)
1017                 {
1018                   * pflags |= specifics[i].flag;
1019                   break;
1020                 }
1021
1022             if (specifics[i].string == NULL)
1023               {
1024                 /* Check to see if the string matches a language name.  */
1025                 for (i = 0; i < cl_lang_count; i++)
1026                   if (strncasecmp (a, lang_names[i], len) == 0)
1027                     {
1028                       * pflags |= 1U << i;
1029                       break;
1030                     }
1031
1032                 if (i == cl_lang_count)
1033                   fnotice (stderr,
1034                            "warning: unrecognized argument to --help= switch: %.*s\n",
1035                            len, a);
1036               }
1037
1038             if (comma == NULL)
1039               break;
1040             a = comma + 1;
1041           }
1042
1043         if (include_flags)
1044           print_specific_help (include_flags, exclude_flags, 0);
1045         exit_after_options = true;
1046         break;
1047       }
1048
1049     case OPT__version:
1050       print_version (stderr, "");
1051       exit_after_options = true;
1052       break;
1053
1054     case OPT_G:
1055       g_switch_value = value;
1056       g_switch_set = true;
1057       break;
1058
1059     case OPT_O:
1060     case OPT_Os:
1061       /* Currently handled in a prescan.  */
1062       break;
1063
1064     case OPT_W:
1065       /* For backward compatibility, -W is the same as -Wextra.  */
1066       set_Wextra (value);
1067       break;
1068
1069     case OPT_Werror_:
1070       enable_warning_as_error (arg, value, lang_mask);
1071       break;
1072
1073     case OPT_Wextra:
1074       set_Wextra (value);
1075       break;
1076
1077     case OPT_Wlarger_than_:
1078       larger_than_size = value;
1079       warn_larger_than = value != -1;
1080       break;
1081
1082     case OPT_Wstrict_aliasing:
1083     case OPT_Wstrict_aliasing_:
1084       warn_strict_aliasing = value;
1085       break;
1086
1087     case OPT_Wstrict_overflow:
1088     case OPT_Wstrict_overflow_:
1089       warn_strict_overflow = value;
1090       break;
1091
1092     case OPT_Wunused:
1093       set_Wunused (value);
1094       break;
1095
1096     case OPT_aux_info:
1097     case OPT_aux_info_:
1098       aux_info_file_name = arg;
1099       flag_gen_aux_info = 1;
1100       break;
1101
1102     case OPT_auxbase:
1103       aux_base_name = arg;
1104       break;
1105
1106     case OPT_auxbase_strip:
1107       {
1108         char *tmp = xstrdup (arg);
1109         strip_off_ending (tmp, strlen (tmp));
1110         if (tmp[0])
1111           aux_base_name = tmp;
1112       }
1113       break;
1114
1115     case OPT_d:
1116       decode_d_option (arg);
1117       break;
1118
1119     case OPT_dumpbase:
1120       dump_base_name = arg;
1121       break;
1122
1123     case OPT_falign_functions_:
1124       align_functions = value;
1125       break;
1126
1127     case OPT_falign_jumps_:
1128       align_jumps = value;
1129       break;
1130
1131     case OPT_falign_labels_:
1132       align_labels = value;
1133       break;
1134
1135     case OPT_falign_loops_:
1136       align_loops = value;
1137       break;
1138
1139     case OPT_fbranch_probabilities:
1140       flag_branch_probabilities_set = true;
1141       break;
1142
1143     case OPT_fcall_used_:
1144       fix_register (arg, 0, 1);
1145       break;
1146
1147     case OPT_fcall_saved_:
1148       fix_register (arg, 0, 0);
1149       break;
1150
1151     case OPT_fdiagnostics_show_location_:
1152       if (!strcmp (arg, "once"))
1153         diagnostic_prefixing_rule (global_dc) = DIAGNOSTICS_SHOW_PREFIX_ONCE;
1154       else if (!strcmp (arg, "every-line"))
1155         diagnostic_prefixing_rule (global_dc)
1156           = DIAGNOSTICS_SHOW_PREFIX_EVERY_LINE;
1157       else
1158         return 0;
1159       break;
1160
1161     case OPT_fdiagnostics_show_option:
1162       global_dc->show_option_requested = true;
1163       break;
1164
1165     case OPT_fdump_:
1166       if (!dump_switch_p (arg))
1167         return 0;
1168       break;
1169
1170     case OPT_ffast_math:
1171       set_fast_math_flags (value);
1172       break;
1173
1174     case OPT_ffixed_:
1175       fix_register (arg, 1, 1);
1176       break;
1177
1178     case OPT_finline_limit_:
1179     case OPT_finline_limit_eq:
1180       set_param_value ("max-inline-insns-single", value / 2);
1181       set_param_value ("max-inline-insns-auto", value / 2);
1182       break;
1183
1184     case OPT_fmessage_length_:
1185       pp_set_line_maximum_length (global_dc->printer, value);
1186       break;
1187
1188     case OPT_fpack_struct_:
1189       if (value <= 0 || (value & (value - 1)) || value > 16)
1190         error ("structure alignment must be a small power of two, not %d", value);
1191       else
1192         {
1193           initial_max_fld_align = value;
1194           maximum_field_alignment = value * BITS_PER_UNIT;
1195         }
1196       break;
1197
1198     case OPT_fpeel_loops:
1199       flag_peel_loops_set = true;
1200       break;
1201
1202     case OPT_fprofile_arcs:
1203       profile_arc_flag_set = true;
1204       break;
1205
1206     case OPT_fprofile_use:
1207       if (!flag_branch_probabilities_set)
1208         flag_branch_probabilities = value;
1209       if (!flag_profile_values_set)
1210         flag_profile_values = value;
1211       if (!flag_unroll_loops_set)
1212         flag_unroll_loops = value;
1213       if (!flag_peel_loops_set)
1214         flag_peel_loops = value;
1215       if (!flag_tracer_set)
1216         flag_tracer = value;
1217       if (!flag_value_profile_transformations_set)
1218         flag_value_profile_transformations = value;
1219       break;
1220
1221     case OPT_fprofile_generate:
1222       if (!profile_arc_flag_set)
1223         profile_arc_flag = value;
1224       if (!flag_profile_values_set)
1225         flag_profile_values = value;
1226       if (!flag_value_profile_transformations_set)
1227         flag_value_profile_transformations = value;
1228       break;
1229
1230     case OPT_fprofile_values:
1231       flag_profile_values_set = true;
1232       break;
1233
1234     case OPT_fvisibility_:
1235       {
1236         if (!strcmp(arg, "default"))
1237           default_visibility = VISIBILITY_DEFAULT;
1238         else if (!strcmp(arg, "internal"))
1239           default_visibility = VISIBILITY_INTERNAL;
1240         else if (!strcmp(arg, "hidden"))
1241           default_visibility = VISIBILITY_HIDDEN;
1242         else if (!strcmp(arg, "protected"))
1243           default_visibility = VISIBILITY_PROTECTED;
1244         else
1245           error ("unrecognized visibility value \"%s\"", arg);
1246       }
1247       break;
1248
1249     case OPT_fvpt:
1250       flag_value_profile_transformations_set = true;
1251       break;
1252
1253     case OPT_frandom_seed:
1254       /* The real switch is -fno-random-seed.  */
1255       if (value)
1256         return 0;
1257       flag_random_seed = NULL;
1258       break;
1259
1260     case OPT_frandom_seed_:
1261       flag_random_seed = arg;
1262       break;
1263
1264     case OPT_fsched_verbose_:
1265 #ifdef INSN_SCHEDULING
1266       fix_sched_param ("verbose", arg);
1267       break;
1268 #else
1269       return 0;
1270 #endif
1271
1272     case OPT_fsched_stalled_insns_:
1273       flag_sched_stalled_insns = value;
1274       if (flag_sched_stalled_insns == 0)
1275         flag_sched_stalled_insns = -1;
1276       break;
1277
1278     case OPT_fsched_stalled_insns_dep_:
1279       flag_sched_stalled_insns_dep = value;
1280       break;
1281
1282     case OPT_fstack_limit:
1283       /* The real switch is -fno-stack-limit.  */
1284       if (value)
1285         return 0;
1286       stack_limit_rtx = NULL_RTX;
1287       break;
1288
1289     case OPT_fstack_limit_register_:
1290       {
1291         int reg = decode_reg_name (arg);
1292         if (reg < 0)
1293           error ("unrecognized register name \"%s\"", arg);
1294         else
1295           stack_limit_rtx = gen_rtx_REG (Pmode, reg);
1296       }
1297       break;
1298
1299     case OPT_fstack_limit_symbol_:
1300       stack_limit_rtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (arg));
1301       break;
1302
1303     case OPT_ftree_vectorizer_verbose_:
1304       vect_set_verbosity_level (arg);
1305       break;
1306
1307     case OPT_ftls_model_:
1308       if (!strcmp (arg, "global-dynamic"))
1309         flag_tls_default = TLS_MODEL_GLOBAL_DYNAMIC;
1310       else if (!strcmp (arg, "local-dynamic"))
1311         flag_tls_default = TLS_MODEL_LOCAL_DYNAMIC;
1312       else if (!strcmp (arg, "initial-exec"))
1313         flag_tls_default = TLS_MODEL_INITIAL_EXEC;
1314       else if (!strcmp (arg, "local-exec"))
1315         flag_tls_default = TLS_MODEL_LOCAL_EXEC;
1316       else
1317         warning (0, "unknown tls-model \"%s\"", arg);
1318       break;
1319
1320     case OPT_ftracer:
1321       flag_tracer_set = true;
1322       break;
1323
1324     case OPT_funroll_loops:
1325       flag_unroll_loops_set = true;
1326       break;
1327
1328     case OPT_g:
1329       set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, arg);
1330       break;
1331
1332     case OPT_gcoff:
1333       set_debug_level (SDB_DEBUG, false, arg);
1334       break;
1335
1336     case OPT_gdwarf_2:
1337       set_debug_level (DWARF2_DEBUG, false, arg);
1338       break;
1339
1340     case OPT_ggdb:
1341       set_debug_level (NO_DEBUG, 2, arg);
1342       break;
1343
1344     case OPT_gstabs:
1345     case OPT_gstabs_:
1346       set_debug_level (DBX_DEBUG, code == OPT_gstabs_, arg);
1347       break;
1348
1349     case OPT_gvms:
1350       set_debug_level (VMS_DEBUG, false, arg);
1351       break;
1352
1353     case OPT_gxcoff:
1354     case OPT_gxcoff_:
1355       set_debug_level (XCOFF_DEBUG, code == OPT_gxcoff_, arg);
1356       break;
1357
1358     case OPT_o:
1359       asm_file_name = arg;
1360       break;
1361
1362     case OPT_pedantic_errors:
1363       flag_pedantic_errors = pedantic = 1;
1364       break;
1365
1366     case OPT_floop_optimize:
1367     case OPT_frerun_loop_opt:
1368     case OPT_fstrength_reduce:
1369       /* These are no-ops, preserved for backward compatibility.  */
1370       break;
1371
1372     default:
1373       /* If the flag was handled in a standard way, assume the lack of
1374          processing here is intentional.  */
1375       gcc_assert (cl_options[scode].flag_var);
1376       break;
1377     }
1378
1379   return 1;
1380 }
1381
1382 /* Handle --param NAME=VALUE.  */
1383 static void
1384 handle_param (const char *carg)
1385 {
1386   char *equal, *arg;
1387   int value;
1388
1389   arg = xstrdup (carg);
1390   equal = strchr (arg, '=');
1391   if (!equal)
1392     error ("%s: --param arguments should be of the form NAME=VALUE", arg);
1393   else
1394     {
1395       value = integral_argument (equal + 1);
1396       if (value == -1)
1397         error ("invalid --param value %qs", equal + 1);
1398       else
1399         {
1400           *equal = '\0';
1401           set_param_value (arg, value);
1402         }
1403     }
1404
1405   free (arg);
1406 }
1407
1408 /* Handle -W and -Wextra.  */
1409 static void
1410 set_Wextra (int setting)
1411 {
1412   extra_warnings = setting;
1413   warn_unused_parameter = (setting && maybe_warn_unused_parameter);
1414
1415   /* We save the value of warn_uninitialized, since if they put
1416      -Wuninitialized on the command line, we need to generate a
1417      warning about not using it without also specifying -O.  */
1418   if (setting == 0)
1419     warn_uninitialized = 0;
1420   else if (warn_uninitialized != 1)
1421     warn_uninitialized = 2;
1422 }
1423
1424 /* Initialize unused warning flags.  */
1425 void
1426 set_Wunused (int setting)
1427 {
1428   warn_unused_function = setting;
1429   warn_unused_label = setting;
1430   /* Unused function parameter warnings are reported when either
1431      ``-Wextra -Wunused'' or ``-Wunused-parameter'' is specified.
1432      Thus, if -Wextra has already been seen, set warn_unused_parameter;
1433      otherwise set maybe_warn_extra_parameter, which will be picked up
1434      by set_Wextra.  */
1435   maybe_warn_unused_parameter = setting;
1436   warn_unused_parameter = (setting && extra_warnings);
1437   warn_unused_variable = setting;
1438   warn_unused_value = setting;
1439 }
1440
1441 /* The following routines are useful in setting all the flags that
1442    -ffast-math and -fno-fast-math imply.  */
1443 void
1444 set_fast_math_flags (int set)
1445 {
1446   flag_trapping_math = !set;
1447   flag_unsafe_math_optimizations = set;
1448   flag_finite_math_only = set;
1449   flag_signed_zeros = !set;
1450   flag_errno_math = !set;
1451   if (set)
1452     {
1453       flag_signaling_nans = 0;
1454       flag_rounding_math = 0;
1455       flag_cx_limited_range = 1;
1456     }
1457 }
1458
1459 /* Return true iff flags are set as if -ffast-math.  */
1460 bool
1461 fast_math_flags_set_p (void)
1462 {
1463   return (!flag_trapping_math
1464           && flag_unsafe_math_optimizations
1465           && flag_finite_math_only
1466           && !flag_signed_zeros
1467           && !flag_errno_math);
1468 }
1469
1470 /* Handle a debug output -g switch.  EXTENDED is true or false to support
1471    extended output (2 is special and means "-ggdb" was given).  */
1472 static void
1473 set_debug_level (enum debug_info_type type, int extended, const char *arg)
1474 {
1475   static bool type_explicit;
1476
1477   use_gnu_debug_info_extensions = extended;
1478
1479   if (type == NO_DEBUG)
1480     {
1481       if (write_symbols == NO_DEBUG)
1482         {
1483           write_symbols = PREFERRED_DEBUGGING_TYPE;
1484
1485           if (extended == 2)
1486             {
1487 #ifdef DWARF2_DEBUGGING_INFO
1488               write_symbols = DWARF2_DEBUG;
1489 #elif defined DBX_DEBUGGING_INFO
1490               write_symbols = DBX_DEBUG;
1491 #endif
1492             }
1493
1494           if (write_symbols == NO_DEBUG)
1495             warning (0, "target system does not support debug output");
1496         }
1497     }
1498   else
1499     {
1500       /* Does it conflict with an already selected type?  */
1501       if (type_explicit && write_symbols != NO_DEBUG && type != write_symbols)
1502         error ("debug format \"%s\" conflicts with prior selection",
1503                debug_type_names[type]);
1504       write_symbols = type;
1505       type_explicit = true;
1506     }
1507
1508   /* A debug flag without a level defaults to level 2.  */
1509   if (*arg == '\0')
1510     {
1511       if (!debug_info_level)
1512         debug_info_level = 2;
1513     }
1514   else
1515     {
1516       debug_info_level = integral_argument (arg);
1517       if (debug_info_level == (unsigned int) -1)
1518         error ("unrecognised debug output level \"%s\"", arg);
1519       else if (debug_info_level > 3)
1520         error ("debug output level %s is too high", arg);
1521     }
1522 }
1523
1524 /* Return 1 if OPTION is enabled, 0 if it is disabled, or -1 if it isn't
1525    a simple on-off switch.  */
1526
1527 int
1528 option_enabled (int opt_idx)
1529 {
1530   const struct cl_option *option = &(cl_options[opt_idx]);
1531
1532   if (option->flag_var)
1533     switch (option->var_type)
1534       {
1535       case CLVC_BOOLEAN:
1536         return *(int *) option->flag_var != 0;
1537
1538       case CLVC_EQUAL:
1539         return *(int *) option->flag_var == option->var_value;
1540
1541       case CLVC_BIT_CLEAR:
1542         return (*(int *) option->flag_var & option->var_value) == 0;
1543
1544       case CLVC_BIT_SET:
1545         return (*(int *) option->flag_var & option->var_value) != 0;
1546
1547       case CLVC_STRING:
1548         break;
1549       }
1550   return -1;
1551 }
1552
1553 /* Fill STATE with the current state of option OPTION.  Return true if
1554    there is some state to store.  */
1555
1556 bool
1557 get_option_state (int option, struct cl_option_state *state)
1558 {
1559   if (cl_options[option].flag_var == 0)
1560     return false;
1561
1562   switch (cl_options[option].var_type)
1563     {
1564     case CLVC_BOOLEAN:
1565     case CLVC_EQUAL:
1566       state->data = cl_options[option].flag_var;
1567       state->size = sizeof (int);
1568       break;
1569
1570     case CLVC_BIT_CLEAR:
1571     case CLVC_BIT_SET:
1572       state->ch = option_enabled (option);
1573       state->data = &state->ch;
1574       state->size = 1;
1575       break;
1576
1577     case CLVC_STRING:
1578       state->data = *(const char **) cl_options[option].flag_var;
1579       if (state->data == 0)
1580         state->data = "";
1581       state->size = strlen (state->data) + 1;
1582       break;
1583     }
1584   return true;
1585 }
1586
1587 /* Enable a warning option as an error.  This is used by -Werror= and
1588    also by legacy Werror-implicit-function-declaration.  */
1589
1590 void
1591 enable_warning_as_error (const char *arg, int value, unsigned int lang_mask)
1592 {
1593   char *new_option;
1594   int option_index;
1595
1596   new_option = XNEWVEC (char, strlen (arg) + 2);
1597   new_option[0] = 'W';
1598   strcpy (new_option + 1, arg);
1599   option_index = find_opt (new_option, lang_mask);
1600   if (option_index == N_OPTS)
1601     {
1602       error ("-Werror=%s: No option -%s", arg, new_option);
1603     }
1604   else
1605     {
1606       int kind = value ? DK_ERROR : DK_WARNING;
1607       diagnostic_classify_diagnostic (global_dc, option_index, kind);
1608       
1609       /* -Werror=foo implies -Wfoo.  */
1610       if (cl_options[option_index].var_type == CLVC_BOOLEAN
1611           && cl_options[option_index].flag_var
1612           && kind == DK_ERROR)
1613         *(int *) cl_options[option_index].flag_var = 1;
1614     }
1615   free (new_option);
1616 }