OSDN Git Service

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