1 /* Command line option handling.
2    Copyright (C) 2002-2016 Free Software Foundation, Inc.
3    Contributed by Neil Booth.
4 
5 This file is part of GCC.
6 
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
10 version.
11 
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.  */
20 
21 #include "config.h"
22 #include "system.h"
23 #include "intl.h"
24 #include "coretypes.h"
25 #include "opts.h"
26 #include "tm.h"
27 #include "flags.h"
28 #include "params.h"
29 #include "diagnostic.h"
30 #include "opts-diagnostic.h"
31 #include "insn-attr-common.h"
32 #include "common/common-target.h"
33 
34 static void set_Wstrict_aliasing (struct gcc_options *opts, int onoff);
35 
36 /* Indexed by enum debug_info_type.  */
37 const char *const debug_type_names[] =
38 {
39   "none", "stabs", "coff", "dwarf-2", "xcoff", "vms"
40 };
41 
42 /* Parse the -femit-struct-debug-detailed option value
43    and set the flag variables. */
44 
45 #define MATCH( prefix, string ) \
46   ((strncmp (prefix, string, sizeof prefix - 1) == 0) \
47    ? ((string += sizeof prefix - 1), 1) : 0)
48 
49 void
set_struct_debug_option(struct gcc_options * opts,location_t loc,const char * spec)50 set_struct_debug_option (struct gcc_options *opts, location_t loc,
51 			 const char *spec)
52 {
53   /* various labels for comparison */
54   static const char dfn_lbl[] = "dfn:", dir_lbl[] = "dir:", ind_lbl[] = "ind:";
55   static const char ord_lbl[] = "ord:", gen_lbl[] = "gen:";
56   static const char none_lbl[] = "none", any_lbl[] = "any";
57   static const char base_lbl[] = "base", sys_lbl[] = "sys";
58 
59   enum debug_struct_file files = DINFO_STRUCT_FILE_ANY;
60   /* Default is to apply to as much as possible. */
61   enum debug_info_usage usage = DINFO_USAGE_NUM_ENUMS;
62   int ord = 1, gen = 1;
63 
64   /* What usage? */
65   if (MATCH (dfn_lbl, spec))
66     usage = DINFO_USAGE_DFN;
67   else if (MATCH (dir_lbl, spec))
68     usage = DINFO_USAGE_DIR_USE;
69   else if (MATCH (ind_lbl, spec))
70     usage = DINFO_USAGE_IND_USE;
71 
72   /* Generics or not? */
73   if (MATCH (ord_lbl, spec))
74     gen = 0;
75   else if (MATCH (gen_lbl, spec))
76     ord = 0;
77 
78   /* What allowable environment? */
79   if (MATCH (none_lbl, spec))
80     files = DINFO_STRUCT_FILE_NONE;
81   else if (MATCH (any_lbl, spec))
82     files = DINFO_STRUCT_FILE_ANY;
83   else if (MATCH (sys_lbl, spec))
84     files = DINFO_STRUCT_FILE_SYS;
85   else if (MATCH (base_lbl, spec))
86     files = DINFO_STRUCT_FILE_BASE;
87   else
88     error_at (loc,
89 	      "argument %qs to %<-femit-struct-debug-detailed%> "
90 	      "not recognized",
91 	      spec);
92 
93   /* Effect the specification. */
94   if (usage == DINFO_USAGE_NUM_ENUMS)
95     {
96       if (ord)
97         {
98           opts->x_debug_struct_ordinary[DINFO_USAGE_DFN] = files;
99           opts->x_debug_struct_ordinary[DINFO_USAGE_DIR_USE] = files;
100           opts->x_debug_struct_ordinary[DINFO_USAGE_IND_USE] = files;
101         }
102       if (gen)
103         {
104           opts->x_debug_struct_generic[DINFO_USAGE_DFN] = files;
105           opts->x_debug_struct_generic[DINFO_USAGE_DIR_USE] = files;
106           opts->x_debug_struct_generic[DINFO_USAGE_IND_USE] = files;
107         }
108     }
109   else
110     {
111       if (ord)
112         opts->x_debug_struct_ordinary[usage] = files;
113       if (gen)
114         opts->x_debug_struct_generic[usage] = files;
115     }
116 
117   if (*spec == ',')
118     set_struct_debug_option (opts, loc, spec+1);
119   else
120     {
121       /* No more -femit-struct-debug-detailed specifications.
122          Do final checks. */
123       if (*spec != '\0')
124 	error_at (loc,
125 		  "argument %qs to %<-femit-struct-debug-detailed%> unknown",
126 		  spec);
127       if (opts->x_debug_struct_ordinary[DINFO_USAGE_DIR_USE]
128 		< opts->x_debug_struct_ordinary[DINFO_USAGE_IND_USE]
129 	  || opts->x_debug_struct_generic[DINFO_USAGE_DIR_USE]
130 		< opts->x_debug_struct_generic[DINFO_USAGE_IND_USE])
131 	error_at (loc,
132 		  "%<-femit-struct-debug-detailed=dir:...%> must allow "
133 		  "at least as much as "
134 		  "%<-femit-struct-debug-detailed=ind:...%>");
135     }
136 }
137 
138 /* Strip off a legitimate source ending from the input string NAME of
139    length LEN.  Rather than having to know the names used by all of
140    our front ends, we strip off an ending of a period followed by
141    up to five characters.  (Java uses ".class".)  */
142 
143 void
strip_off_ending(char * name,int len)144 strip_off_ending (char *name, int len)
145 {
146   int i;
147   for (i = 2; i < 6 && len > i; i++)
148     {
149       if (name[len - i] == '.')
150 	{
151 	  name[len - i] = '\0';
152 	  break;
153 	}
154     }
155 }
156 
157 /* Find the base name of a path, stripping off both directories and
158    a single final extension. */
159 int
base_of_path(const char * path,const char ** base_out)160 base_of_path (const char *path, const char **base_out)
161 {
162   const char *base = path;
163   const char *dot = 0;
164   const char *p = path;
165   char c = *p;
166   while (c)
167     {
168       if (IS_DIR_SEPARATOR (c))
169         {
170           base = p + 1;
171           dot = 0;
172         }
173       else if (c == '.')
174         dot = p;
175       c = *++p;
176     }
177   if (!dot)
178     dot = p;
179   *base_out = base;
180   return dot - base;
181 }
182 
183 /* What to print when a switch has no documentation.  */
184 static const char undocumented_msg[] = N_("This option lacks documentation.");
185 static const char use_diagnosed_msg[] = N_("Uses of this option are diagnosed.");
186 
187 typedef char *char_p; /* For DEF_VEC_P.  */
188 
189 static void handle_param (struct gcc_options *opts,
190 			  struct gcc_options *opts_set, location_t loc,
191 			  const char *carg);
192 static void set_debug_level (enum debug_info_type type, int extended,
193 			     const char *arg, struct gcc_options *opts,
194 			     struct gcc_options *opts_set,
195 			     location_t loc);
196 static void set_fast_math_flags (struct gcc_options *opts, int set);
197 static void decode_d_option (const char *arg, struct gcc_options *opts,
198 			     location_t loc, diagnostic_context *dc);
199 static void set_unsafe_math_optimizations_flags (struct gcc_options *opts,
200 						 int set);
201 static void enable_warning_as_error (const char *arg, int value,
202 				     unsigned int lang_mask,
203 				     const struct cl_option_handlers *handlers,
204 				     struct gcc_options *opts,
205 				     struct gcc_options *opts_set,
206 				     location_t loc,
207 				     diagnostic_context *dc);
208 
209 /* Handle a back-end option; arguments and return value as for
210    handle_option.  */
211 
212 bool
target_handle_option(struct gcc_options * opts,struct gcc_options * opts_set,const struct cl_decoded_option * decoded,unsigned int lang_mask ATTRIBUTE_UNUSED,int kind,location_t loc,const struct cl_option_handlers * handlers ATTRIBUTE_UNUSED,diagnostic_context * dc,void (*)(void))213 target_handle_option (struct gcc_options *opts,
214 		      struct gcc_options *opts_set,
215 		      const struct cl_decoded_option *decoded,
216 		      unsigned int lang_mask ATTRIBUTE_UNUSED, int kind,
217 		      location_t loc,
218 		      const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED,
219 		      diagnostic_context *dc, void (*) (void))
220 {
221   gcc_assert (dc == global_dc);
222   gcc_assert (kind == DK_UNSPECIFIED);
223   return targetm_common.handle_option (opts, opts_set, decoded, loc);
224 }
225 
226 /* Add comma-separated strings to a char_p vector.  */
227 
228 static void
add_comma_separated_to_vector(void ** pvec,const char * arg)229 add_comma_separated_to_vector (void **pvec, const char *arg)
230 {
231   char *tmp;
232   char *r;
233   char *w;
234   char *token_start;
235   vec<char_p> *v = (vec<char_p> *) *pvec;
236 
237   vec_check_alloc (v, 1);
238 
239   /* We never free this string.  */
240   tmp = xstrdup (arg);
241 
242   r = tmp;
243   w = tmp;
244   token_start = tmp;
245 
246   while (*r != '\0')
247     {
248       if (*r == ',')
249 	{
250 	  *w++ = '\0';
251 	  ++r;
252 	  v->safe_push (token_start);
253 	  token_start = w;
254 	}
255       if (*r == '\\' && r[1] == ',')
256 	{
257 	  *w++ = ',';
258 	  r += 2;
259 	}
260       else
261 	*w++ = *r++;
262     }
263   if (*token_start != '\0')
264     v->safe_push (token_start);
265 
266   *pvec = v;
267 }
268 
269 /* Initialize opts_obstack.  */
270 
271 void
init_opts_obstack(void)272 init_opts_obstack (void)
273 {
274   gcc_obstack_init (&opts_obstack);
275 }
276 
277 /* Initialize OPTS and OPTS_SET before using them in parsing options.  */
278 
279 void
init_options_struct(struct gcc_options * opts,struct gcc_options * opts_set)280 init_options_struct (struct gcc_options *opts, struct gcc_options *opts_set)
281 {
282   size_t num_params = get_num_compiler_params ();
283 
284   /* Ensure that opts_obstack has already been initialized by the time
285      that we initialize any gcc_options instances (PR jit/68446).  */
286   gcc_assert (opts_obstack.chunk_size > 0);
287 
288   *opts = global_options_init;
289 
290   if (opts_set)
291     memset (opts_set, 0, sizeof (*opts_set));
292 
293   opts->x_param_values = XNEWVEC (int, num_params);
294 
295   if (opts_set)
296     opts_set->x_param_values = XCNEWVEC (int, num_params);
297 
298   init_param_values (opts->x_param_values);
299 
300   /* Initialize whether `char' is signed.  */
301   opts->x_flag_signed_char = DEFAULT_SIGNED_CHAR;
302   /* Set this to a special "uninitialized" value.  The actual default
303      is set after target options have been processed.  */
304   opts->x_flag_short_enums = 2;
305 
306   /* Initialize target_flags before default_options_optimization
307      so the latter can modify it.  */
308   opts->x_target_flags = targetm_common.default_target_flags;
309 
310   /* Some targets have ABI-specified unwind tables.  */
311   opts->x_flag_unwind_tables = targetm_common.unwind_tables_default;
312 
313   /* Some targets have other target-specific initialization.  */
314   targetm_common.option_init_struct (opts);
315 }
316 
317 /* Release any allocations owned by OPTS.  */
318 
319 void
finalize_options_struct(struct gcc_options * opts)320 finalize_options_struct (struct gcc_options *opts)
321 {
322   XDELETEVEC (opts->x_param_values);
323 }
324 
325 /* If indicated by the optimization level LEVEL (-Os if SIZE is set,
326    -Ofast if FAST is set, -Og if DEBUG is set), apply the option DEFAULT_OPT
327    to OPTS and OPTS_SET, diagnostic context DC, location LOC, with language
328    mask LANG_MASK and option handlers HANDLERS.  */
329 
330 static void
maybe_default_option(struct gcc_options * opts,struct gcc_options * opts_set,const struct default_options * default_opt,int level,bool size,bool fast,bool debug,unsigned int lang_mask,const struct cl_option_handlers * handlers,location_t loc,diagnostic_context * dc)331 maybe_default_option (struct gcc_options *opts,
332 		      struct gcc_options *opts_set,
333 		      const struct default_options *default_opt,
334 		      int level, bool size, bool fast, bool debug,
335 		      unsigned int lang_mask,
336 		      const struct cl_option_handlers *handlers,
337 		      location_t loc,
338 		      diagnostic_context *dc)
339 {
340   const struct cl_option *option = &cl_options[default_opt->opt_index];
341   bool enabled;
342 
343   if (size)
344     gcc_assert (level == 2);
345   if (fast)
346     gcc_assert (level == 3);
347   if (debug)
348     gcc_assert (level == 1);
349 
350   switch (default_opt->levels)
351     {
352     case OPT_LEVELS_ALL:
353       enabled = true;
354       break;
355 
356     case OPT_LEVELS_0_ONLY:
357       enabled = (level == 0);
358       break;
359 
360     case OPT_LEVELS_1_PLUS:
361       enabled = (level >= 1);
362       break;
363 
364     case OPT_LEVELS_1_PLUS_SPEED_ONLY:
365       enabled = (level >= 1 && !size && !debug);
366       break;
367 
368     case OPT_LEVELS_1_PLUS_NOT_DEBUG:
369       enabled = (level >= 1 && !debug);
370       break;
371 
372     case OPT_LEVELS_2_PLUS:
373       enabled = (level >= 2);
374       break;
375 
376     case OPT_LEVELS_2_PLUS_SPEED_ONLY:
377       enabled = (level >= 2 && !size && !debug);
378       break;
379 
380     case OPT_LEVELS_3_PLUS:
381       enabled = (level >= 3);
382       break;
383 
384     case OPT_LEVELS_3_PLUS_AND_SIZE:
385       enabled = (level >= 3 || size);
386       break;
387 
388     case OPT_LEVELS_SIZE:
389       enabled = size;
390       break;
391 
392     case OPT_LEVELS_FAST:
393       enabled = fast;
394       break;
395 
396     case OPT_LEVELS_NONE:
397     default:
398       gcc_unreachable ();
399     }
400 
401   if (enabled)
402     handle_generated_option (opts, opts_set, default_opt->opt_index,
403 			     default_opt->arg, default_opt->value,
404 			     lang_mask, DK_UNSPECIFIED, loc,
405 			     handlers, dc);
406   else if (default_opt->arg == NULL
407 	   && !option->cl_reject_negative)
408     handle_generated_option (opts, opts_set, default_opt->opt_index,
409 			     default_opt->arg, !default_opt->value,
410 			     lang_mask, DK_UNSPECIFIED, loc,
411 			     handlers, dc);
412 }
413 
414 /* As indicated by the optimization level LEVEL (-Os if SIZE is set,
415    -Ofast if FAST is set), apply the options in array DEFAULT_OPTS to
416    OPTS and OPTS_SET, diagnostic context DC, location LOC, with
417    language mask LANG_MASK and option handlers HANDLERS.  */
418 
419 static void
maybe_default_options(struct gcc_options * opts,struct gcc_options * opts_set,const struct default_options * default_opts,int level,bool size,bool fast,bool debug,unsigned int lang_mask,const struct cl_option_handlers * handlers,location_t loc,diagnostic_context * dc)420 maybe_default_options (struct gcc_options *opts,
421 		       struct gcc_options *opts_set,
422 		       const struct default_options *default_opts,
423 		       int level, bool size, bool fast, bool debug,
424 		       unsigned int lang_mask,
425 		       const struct cl_option_handlers *handlers,
426 		       location_t loc,
427 		       diagnostic_context *dc)
428 {
429   size_t i;
430 
431   for (i = 0; default_opts[i].levels != OPT_LEVELS_NONE; i++)
432     maybe_default_option (opts, opts_set, &default_opts[i],
433 			  level, size, fast, debug,
434 			  lang_mask, handlers, loc, dc);
435 }
436 
437 /* Table of options enabled by default at different levels.  */
438 
439 static const struct default_options default_options_table[] =
440   {
441     /* -O1 optimizations.  */
442     { OPT_LEVELS_1_PLUS, OPT_fdefer_pop, NULL, 1 },
443 #if DELAY_SLOTS
444     { OPT_LEVELS_1_PLUS, OPT_fdelayed_branch, NULL, 1 },
445 #endif
446     { OPT_LEVELS_1_PLUS, OPT_fguess_branch_probability, NULL, 1 },
447     { OPT_LEVELS_1_PLUS, OPT_fcprop_registers, NULL, 1 },
448     { OPT_LEVELS_1_PLUS, OPT_fforward_propagate, NULL, 1 },
449     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fif_conversion, NULL, 1 },
450     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fif_conversion2, NULL, 1 },
451     { OPT_LEVELS_1_PLUS, OPT_fipa_pure_const, NULL, 1 },
452     { OPT_LEVELS_1_PLUS, OPT_fipa_reference, NULL, 1 },
453     { OPT_LEVELS_1_PLUS, OPT_fipa_profile, NULL, 1 },
454     { OPT_LEVELS_1_PLUS, OPT_fmerge_constants, NULL, 1 },
455     { OPT_LEVELS_1_PLUS, OPT_freorder_blocks, NULL, 1 },
456     { OPT_LEVELS_1_PLUS, OPT_fshrink_wrap, NULL, 1 },
457     { OPT_LEVELS_1_PLUS, OPT_fsplit_wide_types, NULL, 1 },
458     { OPT_LEVELS_1_PLUS, OPT_ftree_ccp, NULL, 1 },
459     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_bit_ccp, NULL, 1 },
460     { OPT_LEVELS_1_PLUS, OPT_ftree_coalesce_vars, NULL, 1 },
461     { OPT_LEVELS_1_PLUS, OPT_ftree_dce, NULL, 1 },
462     { OPT_LEVELS_1_PLUS, OPT_ftree_dominator_opts, NULL, 1 },
463     { OPT_LEVELS_1_PLUS, OPT_ftree_dse, NULL, 1 },
464     { OPT_LEVELS_1_PLUS, OPT_ftree_ter, NULL, 1 },
465     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_sra, NULL, 1 },
466     { OPT_LEVELS_1_PLUS, OPT_ftree_fre, NULL, 1 },
467     { OPT_LEVELS_1_PLUS, OPT_ftree_copy_prop, NULL, 1 },
468     { OPT_LEVELS_1_PLUS, OPT_ftree_sink, NULL, 1 },
469     { OPT_LEVELS_1_PLUS, OPT_ftree_ch, NULL, 1 },
470     { OPT_LEVELS_1_PLUS, OPT_fcombine_stack_adjustments, NULL, 1 },
471     { OPT_LEVELS_1_PLUS, OPT_fcompare_elim, NULL, 1 },
472     { OPT_LEVELS_1_PLUS, OPT_ftree_slsr, NULL, 1 },
473     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fbranch_count_reg, NULL, 1 },
474     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fmove_loop_invariants, NULL, 1 },
475     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_ftree_pta, NULL, 1 },
476     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_fssa_phiopt, NULL, 1 },
477     { OPT_LEVELS_1_PLUS, OPT_ftree_builtin_call_dce, NULL, 1 },
478 
479     /* -O2 optimizations.  */
480     { OPT_LEVELS_2_PLUS, OPT_finline_small_functions, NULL, 1 },
481     { OPT_LEVELS_2_PLUS, OPT_findirect_inlining, NULL, 1 },
482     { OPT_LEVELS_2_PLUS, OPT_fpartial_inlining, NULL, 1 },
483     { OPT_LEVELS_2_PLUS, OPT_fthread_jumps, NULL, 1 },
484     { OPT_LEVELS_2_PLUS, OPT_fcrossjumping, NULL, 1 },
485     { OPT_LEVELS_2_PLUS, OPT_foptimize_sibling_calls, NULL, 1 },
486     { OPT_LEVELS_2_PLUS, OPT_fcse_follow_jumps, NULL, 1 },
487     { OPT_LEVELS_2_PLUS, OPT_fgcse, NULL, 1 },
488     { OPT_LEVELS_2_PLUS, OPT_fexpensive_optimizations, NULL, 1 },
489     { OPT_LEVELS_2_PLUS, OPT_frerun_cse_after_loop, NULL, 1 },
490     { OPT_LEVELS_2_PLUS, OPT_fcaller_saves, NULL, 1 },
491     { OPT_LEVELS_2_PLUS, OPT_fpeephole2, NULL, 1 },
492 #ifdef INSN_SCHEDULING
493   /* Only run the pre-regalloc scheduling pass if optimizing for speed.  */
494     { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_fschedule_insns, NULL, 1 },
495     { OPT_LEVELS_2_PLUS, OPT_fschedule_insns2, NULL, 1 },
496 #endif
497     { OPT_LEVELS_2_PLUS, OPT_fstrict_aliasing, NULL, 1 },
498     { OPT_LEVELS_2_PLUS, OPT_fstrict_overflow, NULL, 1 },
499     { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_freorder_blocks_algorithm_, NULL,
500       REORDER_BLOCKS_ALGORITHM_STC },
501     { OPT_LEVELS_2_PLUS, OPT_freorder_functions, NULL, 1 },
502     { OPT_LEVELS_2_PLUS, OPT_ftree_vrp, NULL, 1 },
503     { OPT_LEVELS_2_PLUS, OPT_ftree_pre, NULL, 1 },
504     { OPT_LEVELS_2_PLUS, OPT_ftree_switch_conversion, NULL, 1 },
505     { OPT_LEVELS_2_PLUS, OPT_fipa_cp, NULL, 1 },
506     { OPT_LEVELS_2_PLUS, OPT_fipa_cp_alignment, NULL, 1 },
507     { OPT_LEVELS_2_PLUS, OPT_fdevirtualize, NULL, 1 },
508     { OPT_LEVELS_2_PLUS, OPT_fdevirtualize_speculatively, NULL, 1 },
509     { OPT_LEVELS_2_PLUS, OPT_fipa_sra, NULL, 1 },
510     { OPT_LEVELS_2_PLUS, OPT_falign_loops, NULL, 1 },
511     { OPT_LEVELS_2_PLUS, OPT_falign_jumps, NULL, 1 },
512     { OPT_LEVELS_2_PLUS, OPT_falign_labels, NULL, 1 },
513     { OPT_LEVELS_2_PLUS, OPT_falign_functions, NULL, 1 },
514     { OPT_LEVELS_2_PLUS, OPT_ftree_tail_merge, NULL, 1 },
515     { OPT_LEVELS_2_PLUS, OPT_fvect_cost_model_, NULL, VECT_COST_MODEL_CHEAP },
516     { OPT_LEVELS_2_PLUS_SPEED_ONLY, OPT_foptimize_strlen, NULL, 1 },
517     { OPT_LEVELS_2_PLUS, OPT_fhoist_adjacent_loads, NULL, 1 },
518     { OPT_LEVELS_2_PLUS, OPT_fipa_icf, NULL, 1 },
519     { OPT_LEVELS_2_PLUS, OPT_fisolate_erroneous_paths_dereference, NULL, 1 },
520     { OPT_LEVELS_2_PLUS, OPT_fipa_ra, NULL, 1 },
521     { OPT_LEVELS_2_PLUS, OPT_flra_remat, NULL, 1 },
522 
523     /* -O3 optimizations.  */
524     { OPT_LEVELS_3_PLUS, OPT_ftree_loop_distribute_patterns, NULL, 1 },
525     { OPT_LEVELS_3_PLUS, OPT_fpredictive_commoning, NULL, 1 },
526     { OPT_LEVELS_3_PLUS, OPT_fsplit_paths, NULL, 1 },
527     /* Inlining of functions reducing size is a good idea with -Os
528        regardless of them being declared inline.  */
529     { OPT_LEVELS_3_PLUS_AND_SIZE, OPT_finline_functions, NULL, 1 },
530     { OPT_LEVELS_1_PLUS_NOT_DEBUG, OPT_finline_functions_called_once, NULL, 1 },
531     { OPT_LEVELS_3_PLUS, OPT_funswitch_loops, NULL, 1 },
532     { OPT_LEVELS_3_PLUS, OPT_fgcse_after_reload, NULL, 1 },
533     { OPT_LEVELS_3_PLUS, OPT_ftree_loop_vectorize, NULL, 1 },
534     { OPT_LEVELS_3_PLUS, OPT_ftree_slp_vectorize, NULL, 1 },
535     { OPT_LEVELS_3_PLUS, OPT_fvect_cost_model_, NULL, VECT_COST_MODEL_DYNAMIC },
536     { OPT_LEVELS_3_PLUS, OPT_fipa_cp_clone, NULL, 1 },
537     { OPT_LEVELS_3_PLUS, OPT_ftree_partial_pre, NULL, 1 },
538 
539     /* -Ofast adds optimizations to -O3.  */
540     { OPT_LEVELS_FAST, OPT_ffast_math, NULL, 1 },
541 
542     { OPT_LEVELS_NONE, 0, NULL, 0 }
543   };
544 
545 /* Default the options in OPTS and OPTS_SET based on the optimization
546    settings in DECODED_OPTIONS and DECODED_OPTIONS_COUNT.  */
547 void
default_options_optimization(struct gcc_options * opts,struct gcc_options * opts_set,struct cl_decoded_option * decoded_options,unsigned int decoded_options_count,location_t loc,unsigned int lang_mask,const struct cl_option_handlers * handlers,diagnostic_context * dc)548 default_options_optimization (struct gcc_options *opts,
549 			      struct gcc_options *opts_set,
550 			      struct cl_decoded_option *decoded_options,
551 			      unsigned int decoded_options_count,
552 			      location_t loc,
553 			      unsigned int lang_mask,
554 			      const struct cl_option_handlers *handlers,
555 			      diagnostic_context *dc)
556 {
557   unsigned int i;
558   int opt2;
559   bool openacc_mode = false;
560 
561   /* Scan to see what optimization level has been specified.  That will
562      determine the default value of many flags.  */
563   for (i = 1; i < decoded_options_count; i++)
564     {
565       struct cl_decoded_option *opt = &decoded_options[i];
566       switch (opt->opt_index)
567 	{
568 	case OPT_O:
569 	  if (*opt->arg == '\0')
570 	    {
571 	      opts->x_optimize = 1;
572 	      opts->x_optimize_size = 0;
573 	      opts->x_optimize_fast = 0;
574 	      opts->x_optimize_debug = 0;
575 	    }
576 	  else
577 	    {
578 	      const int optimize_val = integral_argument (opt->arg);
579 	      if (optimize_val == -1)
580 		error_at (loc, "argument to %<-O%> should be a non-negative "
581 			       "integer, %<g%>, %<s%> or %<fast%>");
582 	      else
583 		{
584 		  opts->x_optimize = optimize_val;
585 		  if ((unsigned int) opts->x_optimize > 255)
586 		    opts->x_optimize = 255;
587 		  opts->x_optimize_size = 0;
588 		  opts->x_optimize_fast = 0;
589 		  opts->x_optimize_debug = 0;
590 		}
591 	    }
592 	  break;
593 
594 	case OPT_Os:
595 	  opts->x_optimize_size = 1;
596 
597 	  /* Optimizing for size forces optimize to be 2.  */
598 	  opts->x_optimize = 2;
599 	  opts->x_optimize_fast = 0;
600 	  opts->x_optimize_debug = 0;
601 	  break;
602 
603 	case OPT_Ofast:
604 	  /* -Ofast only adds flags to -O3.  */
605 	  opts->x_optimize_size = 0;
606 	  opts->x_optimize = 3;
607 	  opts->x_optimize_fast = 1;
608 	  opts->x_optimize_debug = 0;
609 	  break;
610 
611 	case OPT_Og:
612 	  /* -Og selects optimization level 1.  */
613 	  opts->x_optimize_size = 0;
614 	  opts->x_optimize = 1;
615 	  opts->x_optimize_fast = 0;
616 	  opts->x_optimize_debug = 1;
617 	  break;
618 
619 	case OPT_fopenacc:
620 	  if (opt->value)
621 	    openacc_mode = true;
622 	  break;
623 
624 	default:
625 	  /* Ignore other options in this prescan.  */
626 	  break;
627 	}
628     }
629 
630   maybe_default_options (opts, opts_set, default_options_table,
631 			 opts->x_optimize, opts->x_optimize_size,
632 			 opts->x_optimize_fast, opts->x_optimize_debug,
633 			 lang_mask, handlers, loc, dc);
634 
635   /* -O2 param settings.  */
636   opt2 = (opts->x_optimize >= 2);
637 
638   if (openacc_mode
639       && !opts_set->x_flag_ipa_pta)
640     opts->x_flag_ipa_pta = true;
641 
642   /* Track fields in field-sensitive alias analysis.  */
643   maybe_set_param_value
644     (PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE,
645      opt2 ? 100 : default_param_value (PARAM_MAX_FIELDS_FOR_FIELD_SENSITIVE),
646      opts->x_param_values, opts_set->x_param_values);
647 
648   /* For -O1 only do loop invariant motion for very small loops.  */
649   maybe_set_param_value
650     (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP,
651      opt2 ? default_param_value (PARAM_LOOP_INVARIANT_MAX_BBS_IN_LOOP) : 1000,
652      opts->x_param_values, opts_set->x_param_values);
653 
654   /* At -Ofast, allow store motion to introduce potential race conditions.  */
655   maybe_set_param_value
656     (PARAM_ALLOW_STORE_DATA_RACES,
657      opts->x_optimize_fast ? 1
658      : default_param_value (PARAM_ALLOW_STORE_DATA_RACES),
659      opts->x_param_values, opts_set->x_param_values);
660 
661   if (opts->x_optimize_size)
662     /* We want to crossjump as much as possible.  */
663     maybe_set_param_value (PARAM_MIN_CROSSJUMP_INSNS, 1,
664 			   opts->x_param_values, opts_set->x_param_values);
665   else
666     maybe_set_param_value (PARAM_MIN_CROSSJUMP_INSNS,
667 			   default_param_value (PARAM_MIN_CROSSJUMP_INSNS),
668 			   opts->x_param_values, opts_set->x_param_values);
669 
670   /* Restrict the amount of work combine does at -Og while retaining
671      most of its useful transforms.  */
672   if (opts->x_optimize_debug)
673     maybe_set_param_value (PARAM_MAX_COMBINE_INSNS, 2,
674 			   opts->x_param_values, opts_set->x_param_values);
675 
676   /* Allow default optimizations to be specified on a per-machine basis.  */
677   maybe_default_options (opts, opts_set,
678 			 targetm_common.option_optimization_table,
679 			 opts->x_optimize, opts->x_optimize_size,
680 			 opts->x_optimize_fast, opts->x_optimize_debug,
681 			 lang_mask, handlers, loc, dc);
682 }
683 
684 /* After all options at LOC have been read into OPTS and OPTS_SET,
685    finalize settings of those options and diagnose incompatible
686    combinations.  */
687 void
finish_options(struct gcc_options * opts,struct gcc_options * opts_set,location_t loc)688 finish_options (struct gcc_options *opts, struct gcc_options *opts_set,
689 		location_t loc)
690 {
691   enum unwind_info_type ui_except;
692 
693   if (opts->x_dump_base_name
694       && ! IS_ABSOLUTE_PATH (opts->x_dump_base_name)
695       && ! opts->x_dump_base_name_prefixed)
696     {
697       /* First try to make OPTS->X_DUMP_BASE_NAME relative to the
698 	 OPTS->X_DUMP_DIR_NAME directory.  Then try to make
699 	 OPTS->X_DUMP_BASE_NAME relative to the OPTS->X_AUX_BASE_NAME
700 	 directory, typically the directory to contain the object
701 	 file.  */
702       if (opts->x_dump_dir_name)
703 	opts->x_dump_base_name = opts_concat (opts->x_dump_dir_name,
704 					      opts->x_dump_base_name, NULL);
705       else if (opts->x_aux_base_name
706 	       && strcmp (opts->x_aux_base_name, HOST_BIT_BUCKET) != 0)
707 	{
708 	  const char *aux_base;
709 
710 	  base_of_path (opts->x_aux_base_name, &aux_base);
711 	  if (opts->x_aux_base_name != aux_base)
712 	    {
713 	      int dir_len = aux_base - opts->x_aux_base_name;
714 	      char *new_dump_base_name
715 		= XOBNEWVEC (&opts_obstack, char,
716 			     strlen (opts->x_dump_base_name) + dir_len + 1);
717 
718 	      /* Copy directory component from OPTS->X_AUX_BASE_NAME.  */
719 	      memcpy (new_dump_base_name, opts->x_aux_base_name, dir_len);
720 	      /* Append existing OPTS->X_DUMP_BASE_NAME.  */
721 	      strcpy (new_dump_base_name + dir_len, opts->x_dump_base_name);
722 	      opts->x_dump_base_name = new_dump_base_name;
723 	    }
724 	}
725 	opts->x_dump_base_name_prefixed = true;
726     }
727 
728   /* Handle related options for unit-at-a-time, toplevel-reorder, and
729      section-anchors.  */
730   if (!opts->x_flag_unit_at_a_time)
731     {
732       if (opts->x_flag_section_anchors && opts_set->x_flag_section_anchors)
733 	error_at (loc, "section anchors must be disabled when unit-at-a-time "
734 		  "is disabled");
735       opts->x_flag_section_anchors = 0;
736       if (opts->x_flag_toplevel_reorder == 1)
737 	error_at (loc, "toplevel reorder must be disabled when unit-at-a-time "
738 		  "is disabled");
739       opts->x_flag_toplevel_reorder = 0;
740     }
741 
742   if (opts->x_flag_tm && opts->x_flag_non_call_exceptions)
743     sorry ("transactional memory is not supported with non-call exceptions");
744 
745   /* Unless the user has asked for section anchors, we disable toplevel
746      reordering at -O0 to disable transformations that might be surprising
747      to end users and to get -fno-toplevel-reorder tested.  */
748   if (!opts->x_optimize
749       && opts->x_flag_toplevel_reorder == 2
750       && !(opts->x_flag_section_anchors && opts_set->x_flag_section_anchors))
751     {
752       opts->x_flag_toplevel_reorder = 0;
753       opts->x_flag_section_anchors = 0;
754     }
755   if (!opts->x_flag_toplevel_reorder)
756     {
757       if (opts->x_flag_section_anchors && opts_set->x_flag_section_anchors)
758 	error_at (loc, "section anchors must be disabled when toplevel reorder"
759 		  " is disabled");
760       opts->x_flag_section_anchors = 0;
761     }
762 
763   if (!opts->x_flag_opts_finished)
764     {
765       /* We initialize opts->x_flag_pie to -1 so that targets can set a
766 	 default value.  */
767       if (opts->x_flag_pie == -1)
768 	{
769 	  /* We initialize opts->x_flag_pic to -1 so that we can tell if
770 	     -fpic, -fPIC, -fno-pic or -fno-PIC is used.  */
771 	  if (opts->x_flag_pic == -1)
772 	    opts->x_flag_pie = DEFAULT_FLAG_PIE;
773 	  else
774 	    opts->x_flag_pie = 0;
775 	}
776       /* If -fPIE or -fpie is used, turn on PIC.  */
777       if (opts->x_flag_pie)
778 	opts->x_flag_pic = opts->x_flag_pie;
779       else if (opts->x_flag_pic == -1)
780 	opts->x_flag_pic = 0;
781       if (opts->x_flag_pic && !opts->x_flag_pie)
782 	opts->x_flag_shlib = 1;
783       opts->x_flag_opts_finished = true;
784     }
785 
786   /* We initialize opts->x_flag_stack_protect to -1 so that targets
787      can set a default value.  */
788   if (opts->x_flag_stack_protect == -1)
789     opts->x_flag_stack_protect = DEFAULT_FLAG_SSP;
790 
791   if (opts->x_optimize == 0)
792     {
793       /* Inlining does not work if not optimizing,
794 	 so force it not to be done.  */
795       opts->x_warn_inline = 0;
796       opts->x_flag_no_inline = 1;
797     }
798 
799   /* The optimization to partition hot and cold basic blocks into separate
800      sections of the .o and executable files does not work (currently)
801      with exception handling.  This is because there is no support for
802      generating unwind info.  If opts->x_flag_exceptions is turned on
803      we need to turn off the partitioning optimization.  */
804 
805   ui_except = targetm_common.except_unwind_info (opts);
806 
807   if (opts->x_flag_exceptions
808       && opts->x_flag_reorder_blocks_and_partition
809       && (ui_except == UI_SJLJ || ui_except >= UI_TARGET))
810     {
811       if (opts_set->x_flag_reorder_blocks_and_partition)
812         inform (loc,
813                 "-freorder-blocks-and-partition does not work "
814                 "with exceptions on this architecture");
815       opts->x_flag_reorder_blocks_and_partition = 0;
816       opts->x_flag_reorder_blocks = 1;
817     }
818 
819   /* If user requested unwind info, then turn off the partitioning
820      optimization.  */
821 
822   if (opts->x_flag_unwind_tables
823       && !targetm_common.unwind_tables_default
824       && opts->x_flag_reorder_blocks_and_partition
825       && (ui_except == UI_SJLJ || ui_except >= UI_TARGET))
826     {
827       if (opts_set->x_flag_reorder_blocks_and_partition)
828         inform (loc,
829                 "-freorder-blocks-and-partition does not support "
830                 "unwind info on this architecture");
831       opts->x_flag_reorder_blocks_and_partition = 0;
832       opts->x_flag_reorder_blocks = 1;
833     }
834 
835   /* If the target requested unwind info, then turn off the partitioning
836      optimization with a different message.  Likewise, if the target does not
837      support named sections.  */
838 
839   if (opts->x_flag_reorder_blocks_and_partition
840       && (!targetm_common.have_named_sections
841 	  || (opts->x_flag_unwind_tables
842 	      && targetm_common.unwind_tables_default
843 	      && (ui_except == UI_SJLJ || ui_except >= UI_TARGET))))
844     {
845       if (opts_set->x_flag_reorder_blocks_and_partition)
846         inform (loc,
847                 "-freorder-blocks-and-partition does not work "
848                 "on this architecture");
849       opts->x_flag_reorder_blocks_and_partition = 0;
850       opts->x_flag_reorder_blocks = 1;
851     }
852 
853   /* Disable -freorder-blocks-and-partition when -fprofile-use is not in
854      effect. Function splitting was not actually being performed in that case,
855      as probably_never_executed_bb_p does not distinguish any basic blocks as
856      being cold vs hot when there is no profile data. Leaving it enabled,
857      however, causes the assembly code generator to create (empty) cold
858      sections and labels, leading to unnecessary size overhead.  */
859   if (opts->x_flag_reorder_blocks_and_partition
860       && !opts_set->x_flag_profile_use)
861     opts->x_flag_reorder_blocks_and_partition = 0;
862 
863   if (opts->x_flag_reorder_blocks_and_partition
864       && !opts_set->x_flag_reorder_functions)
865     opts->x_flag_reorder_functions = 1;
866 
867   /* Pipelining of outer loops is only possible when general pipelining
868      capabilities are requested.  */
869   if (!opts->x_flag_sel_sched_pipelining)
870     opts->x_flag_sel_sched_pipelining_outer_loops = 0;
871 
872   if (opts->x_flag_conserve_stack)
873     {
874       maybe_set_param_value (PARAM_LARGE_STACK_FRAME, 100,
875 			     opts->x_param_values, opts_set->x_param_values);
876       maybe_set_param_value (PARAM_STACK_FRAME_GROWTH, 40,
877 			     opts->x_param_values, opts_set->x_param_values);
878     }
879 
880   if (opts->x_flag_lto)
881     {
882 #ifdef ENABLE_LTO
883       opts->x_flag_generate_lto = 1;
884 
885       /* When generating IL, do not operate in whole-program mode.
886 	 Otherwise, symbols will be privatized too early, causing link
887 	 errors later.  */
888       opts->x_flag_whole_program = 0;
889 #else
890       error_at (loc, "LTO support has not been enabled in this configuration");
891 #endif
892       if (!opts->x_flag_fat_lto_objects
893 	  && (!HAVE_LTO_PLUGIN
894 	      || (opts_set->x_flag_use_linker_plugin
895 		  && !opts->x_flag_use_linker_plugin)))
896 	{
897 	  if (opts_set->x_flag_fat_lto_objects)
898             error_at (loc, "-fno-fat-lto-objects are supported only with linker plugin");
899 	  opts->x_flag_fat_lto_objects = 1;
900 	}
901     }
902 
903   /* We initialize opts->x_flag_split_stack to -1 so that targets can set a
904      default value if they choose based on other options.  */
905   if (opts->x_flag_split_stack == -1)
906     opts->x_flag_split_stack = 0;
907   else if (opts->x_flag_split_stack)
908     {
909       if (!targetm_common.supports_split_stack (true, opts))
910 	{
911 	  error_at (loc, "%<-fsplit-stack%> is not supported by "
912 		    "this compiler configuration");
913 	  opts->x_flag_split_stack = 0;
914 	}
915     }
916 
917   /* Tune vectorization related parametees according to cost model.  */
918   if (opts->x_flag_vect_cost_model == VECT_COST_MODEL_CHEAP)
919     {
920       maybe_set_param_value (PARAM_VECT_MAX_VERSION_FOR_ALIAS_CHECKS,
921             6, opts->x_param_values, opts_set->x_param_values);
922       maybe_set_param_value (PARAM_VECT_MAX_VERSION_FOR_ALIGNMENT_CHECKS,
923             0, opts->x_param_values, opts_set->x_param_values);
924       maybe_set_param_value (PARAM_VECT_MAX_PEELING_FOR_ALIGNMENT,
925             0, opts->x_param_values, opts_set->x_param_values);
926     }
927 
928   /* Set PARAM_MAX_STORES_TO_SINK to 0 if either vectorization or if-conversion
929      is disabled.  */
930   if ((!opts->x_flag_tree_loop_vectorize && !opts->x_flag_tree_slp_vectorize)
931        || !opts->x_flag_tree_loop_if_convert)
932     maybe_set_param_value (PARAM_MAX_STORES_TO_SINK, 0,
933                            opts->x_param_values, opts_set->x_param_values);
934 
935   /* The -gsplit-dwarf option requires -ggnu-pubnames.  */
936   if (opts->x_dwarf_split_debug_info)
937     opts->x_debug_generate_pub_sections = 2;
938 
939   /* Userspace and kernel ASan conflict with each other.  */
940 
941   if ((opts->x_flag_sanitize & SANITIZE_USER_ADDRESS)
942       && (opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS))
943     error_at (loc,
944 	      "-fsanitize=address is incompatible with "
945 	      "-fsanitize=kernel-address");
946 
947   /* And with TSan.  */
948 
949   if ((opts->x_flag_sanitize & SANITIZE_ADDRESS)
950       && (opts->x_flag_sanitize & SANITIZE_THREAD))
951     error_at (loc,
952 	      "-fsanitize=address and -fsanitize=kernel-address "
953 	      "are incompatible with -fsanitize=thread");
954 
955   /* Error recovery is not allowed for LSan and TSan.  */
956 
957   if (opts->x_flag_sanitize_recover & SANITIZE_THREAD)
958     error_at (loc, "-fsanitize-recover=thread is not supported");
959 
960   if (opts->x_flag_sanitize_recover & SANITIZE_LEAK)
961     error_at (loc, "-fsanitize-recover=leak is not supported");
962 
963   /* When instrumenting the pointers, we don't want to remove
964      the null pointer checks.  */
965   if (opts->x_flag_sanitize & (SANITIZE_NULL | SANITIZE_NONNULL_ATTRIBUTE
966 				| SANITIZE_RETURNS_NONNULL_ATTRIBUTE))
967     opts->x_flag_delete_null_pointer_checks = 0;
968 
969   /* Aggressive compiler optimizations may cause false negatives.  */
970   if (opts->x_flag_sanitize)
971     {
972       opts->x_flag_aggressive_loop_optimizations = 0;
973       opts->x_flag_strict_overflow = 0;
974     }
975 
976   /* Comes from final.c -- no real reason to change it.  */
977 #define MAX_CODE_ALIGN 16
978 #define MAX_CODE_ALIGN_VALUE (1 << MAX_CODE_ALIGN)
979 
980   if (opts->x_align_loops > MAX_CODE_ALIGN_VALUE)
981     error_at (loc, "-falign-loops=%d is not between 0 and %d",
982 	      opts->x_align_loops, MAX_CODE_ALIGN_VALUE);
983 
984   if (opts->x_align_jumps > MAX_CODE_ALIGN_VALUE)
985     error_at (loc, "-falign-jumps=%d is not between 0 and %d",
986 	      opts->x_align_jumps, MAX_CODE_ALIGN_VALUE);
987 
988   if (opts->x_align_functions > MAX_CODE_ALIGN_VALUE)
989     error_at (loc, "-falign-functions=%d is not between 0 and %d",
990 	      opts->x_align_functions, MAX_CODE_ALIGN_VALUE);
991 
992   if (opts->x_align_labels > MAX_CODE_ALIGN_VALUE)
993     error_at (loc, "-falign-labels=%d is not between 0 and %d",
994 	      opts->x_align_labels, MAX_CODE_ALIGN_VALUE);
995 }
996 
997 #define LEFT_COLUMN	27
998 
999 /* Output ITEM, of length ITEM_WIDTH, in the left column,
1000    followed by word-wrapped HELP in a second column.  */
1001 static void
wrap_help(const char * help,const char * item,unsigned int item_width,unsigned int columns)1002 wrap_help (const char *help,
1003 	   const char *item,
1004 	   unsigned int item_width,
1005 	   unsigned int columns)
1006 {
1007   unsigned int col_width = LEFT_COLUMN;
1008   unsigned int remaining, room, len;
1009 
1010   remaining = strlen (help);
1011 
1012   do
1013     {
1014       room = columns - 3 - MAX (col_width, item_width);
1015       if (room > columns)
1016 	room = 0;
1017       len = remaining;
1018 
1019       if (room < len)
1020 	{
1021 	  unsigned int i;
1022 
1023 	  for (i = 0; help[i]; i++)
1024 	    {
1025 	      if (i >= room && len != remaining)
1026 		break;
1027 	      if (help[i] == ' ')
1028 		len = i;
1029 	      else if ((help[i] == '-' || help[i] == '/')
1030 		       && help[i + 1] != ' '
1031 		       && i > 0 && ISALPHA (help[i - 1]))
1032 		len = i + 1;
1033 	    }
1034 	}
1035 
1036       printf ("  %-*.*s %.*s\n", col_width, item_width, item, len, help);
1037       item_width = 0;
1038       while (help[len] == ' ')
1039 	len++;
1040       help += len;
1041       remaining -= len;
1042     }
1043   while (remaining);
1044 }
1045 
1046 /* Print help for a specific front-end, etc.  */
1047 static void
print_filtered_help(unsigned int include_flags,unsigned int exclude_flags,unsigned int any_flags,unsigned int columns,struct gcc_options * opts,unsigned int lang_mask)1048 print_filtered_help (unsigned int include_flags,
1049 		     unsigned int exclude_flags,
1050 		     unsigned int any_flags,
1051 		     unsigned int columns,
1052 		     struct gcc_options *opts,
1053 		     unsigned int lang_mask)
1054 {
1055   unsigned int i;
1056   const char *help;
1057   bool found = false;
1058   bool displayed = false;
1059   char new_help[256];
1060 
1061   if (include_flags == CL_PARAMS)
1062     {
1063       for (i = 0; i < LAST_PARAM; i++)
1064 	{
1065 	  const char *param = compiler_params[i].option;
1066 
1067 	  help = compiler_params[i].help;
1068 	  if (help == NULL || *help == '\0')
1069 	    {
1070 	      if (exclude_flags & CL_UNDOCUMENTED)
1071 		continue;
1072 	      help = undocumented_msg;
1073 	    }
1074 
1075 	  /* Get the translation.  */
1076 	  help = _(help);
1077 
1078 	  if (!opts->x_quiet_flag)
1079 	    {
1080 	      snprintf (new_help, sizeof (new_help),
1081 			_("default %d minimum %d maximum %d"),
1082 			compiler_params[i].default_value,
1083 			compiler_params[i].min_value,
1084 			compiler_params[i].max_value);
1085 	      help = new_help;
1086 	    }
1087 	  wrap_help (help, param, strlen (param), columns);
1088 	}
1089       putchar ('\n');
1090       return;
1091     }
1092 
1093   if (!opts->x_help_printed)
1094     opts->x_help_printed = XCNEWVAR (char, cl_options_count);
1095 
1096   if (!opts->x_help_enum_printed)
1097     opts->x_help_enum_printed = XCNEWVAR (char, cl_enums_count);
1098 
1099   for (i = 0; i < cl_options_count; i++)
1100     {
1101       const struct cl_option *option = cl_options + i;
1102       unsigned int len;
1103       const char *opt;
1104       const char *tab;
1105 
1106       if (include_flags == 0
1107 	  || ((option->flags & include_flags) != include_flags))
1108 	{
1109 	  if ((option->flags & any_flags) == 0)
1110 	    continue;
1111 	}
1112 
1113       /* Skip unwanted switches.  */
1114       if ((option->flags & exclude_flags) != 0)
1115 	continue;
1116 
1117       /* The driver currently prints its own help text.  */
1118       if ((option->flags & CL_DRIVER) != 0
1119 	  && (option->flags & (((1U << cl_lang_count) - 1)
1120 			       | CL_COMMON | CL_TARGET)) == 0)
1121 	continue;
1122 
1123       found = true;
1124       /* Skip switches that have already been printed.  */
1125       if (opts->x_help_printed[i])
1126 	continue;
1127 
1128       opts->x_help_printed[i] = true;
1129 
1130       help = option->help;
1131       if (help == NULL)
1132 	{
1133 	  if (exclude_flags & CL_UNDOCUMENTED)
1134 	    continue;
1135 
1136 	  help = undocumented_msg;
1137 	}
1138 
1139       if (option->alias_target < N_OPTS
1140 	  && cl_options [option->alias_target].help)
1141 	{
1142 	  if (help == undocumented_msg)
1143 	    {
1144 	      /* For undocumented options that are aliases for other options
1145 		 that are documented, point the reader to the other option in
1146 		 preference of the former.  */
1147 	      snprintf (new_help, sizeof new_help,
1148 			_("Same as %s.  Use the latter option instead."),
1149 			cl_options [option->alias_target].opt_text);
1150 	    }
1151 	  else
1152 	    {
1153 	      /* For documented options with aliases, mention the aliased
1154 		 option's name for reference.  */
1155 	      snprintf (new_help, sizeof new_help,
1156 			_("%s  Same as %s."),
1157 			help, cl_options [option->alias_target].opt_text);
1158 	    }
1159 
1160 	  help = new_help;
1161 	}
1162 
1163       if (option->warn_message)
1164 	{
1165 	  /* Mention that the use of the option will trigger a warning.  */
1166 	  if (help == new_help)
1167 	    snprintf (new_help + strlen (new_help),
1168 		      sizeof new_help - strlen (new_help),
1169 		      "  %s", _(use_diagnosed_msg));
1170 	  else
1171 	    snprintf (new_help, sizeof new_help,
1172 		      "%s  %s", help, _(use_diagnosed_msg));
1173 
1174 	  help = new_help;
1175 	}
1176 
1177       /* Get the translation.  */
1178       help = _(help);
1179 
1180       /* Find the gap between the name of the
1181 	 option and its descriptive text.  */
1182       tab = strchr (help, '\t');
1183       if (tab)
1184 	{
1185 	  len = tab - help;
1186 	  opt = help;
1187 	  help = tab + 1;
1188 	}
1189       else
1190 	{
1191 	  opt = option->opt_text;
1192 	  len = strlen (opt);
1193 	}
1194 
1195       /* With the -Q option enabled we change the descriptive text associated
1196 	 with an option to be an indication of its current setting.  */
1197       if (!opts->x_quiet_flag)
1198 	{
1199 	  void *flag_var = option_flag_var (i, opts);
1200 
1201 	  if (len < (LEFT_COLUMN + 2))
1202 	    strcpy (new_help, "\t\t");
1203 	  else
1204 	    strcpy (new_help, "\t");
1205 
1206 	  if (flag_var != NULL
1207 	      && option->var_type != CLVC_DEFER)
1208 	    {
1209 	      if (option->flags & CL_JOINED)
1210 		{
1211 		  if (option->var_type == CLVC_STRING)
1212 		    {
1213 		      if (* (const char **) flag_var != NULL)
1214 			snprintf (new_help + strlen (new_help),
1215 				  sizeof (new_help) - strlen (new_help),
1216 				  "%s", * (const char **) flag_var);
1217 		    }
1218 		  else if (option->var_type == CLVC_ENUM)
1219 		    {
1220 		      const struct cl_enum *e = &cl_enums[option->var_enum];
1221 		      int value;
1222 		      const char *arg = NULL;
1223 
1224 		      value = e->get (flag_var);
1225 		      enum_value_to_arg (e->values, &arg, value, lang_mask);
1226 		      if (arg == NULL)
1227 			arg = _("[default]");
1228 		      snprintf (new_help + strlen (new_help),
1229 				sizeof (new_help) - strlen (new_help),
1230 				"%s", arg);
1231 		    }
1232 		  else
1233 		    sprintf (new_help + strlen (new_help),
1234 			     "%#x", * (int *) flag_var);
1235 		}
1236 	      else
1237 		strcat (new_help, option_enabled (i, opts)
1238 			? _("[enabled]") : _("[disabled]"));
1239 	    }
1240 
1241 	  help = new_help;
1242 	}
1243 
1244       wrap_help (help, opt, len, columns);
1245       displayed = true;
1246 
1247       if (option->var_type == CLVC_ENUM
1248 	  && opts->x_help_enum_printed[option->var_enum] != 2)
1249 	opts->x_help_enum_printed[option->var_enum] = 1;
1250     }
1251 
1252   if (! found)
1253     {
1254       unsigned int langs = include_flags & CL_LANG_ALL;
1255 
1256       if (langs == 0)
1257 	printf (_(" No options with the desired characteristics were found\n"));
1258       else
1259 	{
1260 	  unsigned int i;
1261 
1262 	  /* PR 31349: Tell the user how to see all of the
1263 	     options supported by a specific front end.  */
1264 	  for (i = 0; (1U << i) < CL_LANG_ALL; i ++)
1265 	    if ((1U << i) & langs)
1266 	      printf (_(" None found.  Use --help=%s to show *all* the options supported by the %s front-end.\n"),
1267 		      lang_names[i], lang_names[i]);
1268 	}
1269 
1270     }
1271   else if (! displayed)
1272     printf (_(" All options with the desired characteristics have already been displayed\n"));
1273 
1274   putchar ('\n');
1275 
1276   /* Print details of enumerated option arguments, if those
1277      enumerations have help text headings provided.  If no help text
1278      is provided, presume that the possible values are listed in the
1279      help text for the relevant options.  */
1280   for (i = 0; i < cl_enums_count; i++)
1281     {
1282       unsigned int j, pos;
1283 
1284       if (opts->x_help_enum_printed[i] != 1)
1285 	continue;
1286       if (cl_enums[i].help == NULL)
1287 	continue;
1288       printf ("  %s\n    ", _(cl_enums[i].help));
1289       pos = 4;
1290       for (j = 0; cl_enums[i].values[j].arg != NULL; j++)
1291 	{
1292 	  unsigned int len = strlen (cl_enums[i].values[j].arg);
1293 
1294 	  if (pos > 4 && pos + 1 + len <= columns)
1295 	    {
1296 	      printf (" %s", cl_enums[i].values[j].arg);
1297 	      pos += 1 + len;
1298 	    }
1299 	  else
1300 	    {
1301 	      if (pos > 4)
1302 		{
1303 		  printf ("\n    ");
1304 		  pos = 4;
1305 		}
1306 	      printf ("%s", cl_enums[i].values[j].arg);
1307 	      pos += len;
1308 	    }
1309 	}
1310       printf ("\n\n");
1311       opts->x_help_enum_printed[i] = 2;
1312     }
1313 }
1314 
1315 /* Display help for a specified type of option.
1316    The options must have ALL of the INCLUDE_FLAGS set
1317    ANY of the flags in the ANY_FLAGS set
1318    and NONE of the EXCLUDE_FLAGS set.  The current option state is in
1319    OPTS; LANG_MASK is used for interpreting enumerated option state.  */
1320 static void
print_specific_help(unsigned int include_flags,unsigned int exclude_flags,unsigned int any_flags,struct gcc_options * opts,unsigned int lang_mask)1321 print_specific_help (unsigned int include_flags,
1322 		     unsigned int exclude_flags,
1323 		     unsigned int any_flags,
1324 		     struct gcc_options *opts,
1325 		     unsigned int lang_mask)
1326 {
1327   unsigned int all_langs_mask = (1U << cl_lang_count) - 1;
1328   const char * description = NULL;
1329   const char * descrip_extra = "";
1330   size_t i;
1331   unsigned int flag;
1332 
1333   /* Sanity check: Make sure that we do not have more
1334      languages than we have bits available to enumerate them.  */
1335   gcc_assert ((1U << cl_lang_count) <= CL_MIN_OPTION_CLASS);
1336 
1337   /* If we have not done so already, obtain
1338      the desired maximum width of the output.  */
1339   if (opts->x_help_columns == 0)
1340     {
1341       opts->x_help_columns = get_terminal_width ();
1342       if (opts->x_help_columns == INT_MAX)
1343 	/* Use a reasonable default.  */
1344 	opts->x_help_columns = 80;
1345     }
1346 
1347   /* Decide upon the title for the options that we are going to display.  */
1348   for (i = 0, flag = 1; flag <= CL_MAX_OPTION_CLASS; flag <<= 1, i ++)
1349     {
1350       switch (flag & include_flags)
1351 	{
1352 	case 0:
1353 	case CL_DRIVER:
1354 	  break;
1355 
1356 	case CL_TARGET:
1357 	  description = _("The following options are target specific");
1358 	  break;
1359 	case CL_WARNING:
1360 	  description = _("The following options control compiler warning messages");
1361 	  break;
1362 	case CL_OPTIMIZATION:
1363 	  description = _("The following options control optimizations");
1364 	  break;
1365 	case CL_COMMON:
1366 	  description = _("The following options are language-independent");
1367 	  break;
1368 	case CL_PARAMS:
1369 	  description = _("The --param option recognizes the following as parameters");
1370 	  break;
1371 	default:
1372 	  if (i >= cl_lang_count)
1373 	    break;
1374 	  if (exclude_flags & all_langs_mask)
1375 	    description = _("The following options are specific to just the language ");
1376 	  else
1377 	    description = _("The following options are supported by the language ");
1378 	  descrip_extra = lang_names [i];
1379 	  break;
1380 	}
1381     }
1382 
1383   if (description == NULL)
1384     {
1385       if (any_flags == 0)
1386 	{
1387 	  if (include_flags & CL_UNDOCUMENTED)
1388 	    description = _("The following options are not documented");
1389 	  else if (include_flags & CL_SEPARATE)
1390 	    description = _("The following options take separate arguments");
1391 	  else if (include_flags & CL_JOINED)
1392 	    description = _("The following options take joined arguments");
1393 	  else
1394 	    {
1395 	      internal_error ("unrecognized include_flags 0x%x passed to print_specific_help",
1396 			      include_flags);
1397 	      return;
1398 	    }
1399 	}
1400       else
1401 	{
1402 	  if (any_flags & all_langs_mask)
1403 	    description = _("The following options are language-related");
1404 	  else
1405 	    description = _("The following options are language-independent");
1406 	}
1407     }
1408 
1409   printf ("%s%s:\n", description, descrip_extra);
1410   print_filtered_help (include_flags, exclude_flags, any_flags,
1411 		       opts->x_help_columns, opts, lang_mask);
1412 }
1413 
1414 /* Enable FDO-related flags.  */
1415 
1416 static void
enable_fdo_optimizations(struct gcc_options * opts,struct gcc_options * opts_set,int value)1417 enable_fdo_optimizations (struct gcc_options *opts,
1418 			  struct gcc_options *opts_set,
1419 			  int value)
1420 {
1421   if (!opts_set->x_flag_branch_probabilities)
1422     opts->x_flag_branch_probabilities = value;
1423   if (!opts_set->x_flag_profile_values)
1424     opts->x_flag_profile_values = value;
1425   if (!opts_set->x_flag_unroll_loops)
1426     opts->x_flag_unroll_loops = value;
1427   if (!opts_set->x_flag_peel_loops)
1428     opts->x_flag_peel_loops = value;
1429   if (!opts_set->x_flag_tracer)
1430     opts->x_flag_tracer = value;
1431   if (!opts_set->x_flag_value_profile_transformations)
1432     opts->x_flag_value_profile_transformations = value;
1433   if (!opts_set->x_flag_inline_functions)
1434     opts->x_flag_inline_functions = value;
1435   if (!opts_set->x_flag_ipa_cp)
1436     opts->x_flag_ipa_cp = value;
1437   if (!opts_set->x_flag_ipa_cp_clone
1438       && value && opts->x_flag_ipa_cp)
1439     opts->x_flag_ipa_cp_clone = value;
1440   if (!opts_set->x_flag_ipa_cp_alignment
1441       && value && opts->x_flag_ipa_cp)
1442     opts->x_flag_ipa_cp_alignment = value;
1443   if (!opts_set->x_flag_predictive_commoning)
1444     opts->x_flag_predictive_commoning = value;
1445   if (!opts_set->x_flag_unswitch_loops)
1446     opts->x_flag_unswitch_loops = value;
1447   if (!opts_set->x_flag_gcse_after_reload)
1448     opts->x_flag_gcse_after_reload = value;
1449   if (!opts_set->x_flag_tree_loop_vectorize
1450       && !opts_set->x_flag_tree_vectorize)
1451     opts->x_flag_tree_loop_vectorize = value;
1452   if (!opts_set->x_flag_tree_slp_vectorize
1453       && !opts_set->x_flag_tree_vectorize)
1454     opts->x_flag_tree_slp_vectorize = value;
1455   if (!opts_set->x_flag_vect_cost_model)
1456     opts->x_flag_vect_cost_model = VECT_COST_MODEL_DYNAMIC;
1457   if (!opts_set->x_flag_tree_loop_distribute_patterns)
1458     opts->x_flag_tree_loop_distribute_patterns = value;
1459 }
1460 
1461 /* -f{,no-}sanitize{,-recover}= suboptions.  */
1462 const struct sanitizer_opts_s sanitizer_opts[] =
1463 {
1464 #define SANITIZER_OPT(name, flags) { #name, flags, sizeof #name - 1 }
1465   SANITIZER_OPT (address, SANITIZE_ADDRESS | SANITIZE_USER_ADDRESS),
1466   SANITIZER_OPT (kernel-address, SANITIZE_ADDRESS | SANITIZE_KERNEL_ADDRESS),
1467   SANITIZER_OPT (thread, SANITIZE_THREAD),
1468   SANITIZER_OPT (leak, SANITIZE_LEAK),
1469   SANITIZER_OPT (shift, SANITIZE_SHIFT),
1470   SANITIZER_OPT (integer-divide-by-zero, SANITIZE_DIVIDE),
1471   SANITIZER_OPT (undefined, SANITIZE_UNDEFINED),
1472   SANITIZER_OPT (unreachable, SANITIZE_UNREACHABLE),
1473   SANITIZER_OPT (vla-bound, SANITIZE_VLA),
1474   SANITIZER_OPT (return, SANITIZE_RETURN),
1475   SANITIZER_OPT (null, SANITIZE_NULL),
1476   SANITIZER_OPT (signed-integer-overflow, SANITIZE_SI_OVERFLOW),
1477   SANITIZER_OPT (bool, SANITIZE_BOOL),
1478   SANITIZER_OPT (enum, SANITIZE_ENUM),
1479   SANITIZER_OPT (float-divide-by-zero, SANITIZE_FLOAT_DIVIDE),
1480   SANITIZER_OPT (float-cast-overflow, SANITIZE_FLOAT_CAST),
1481   SANITIZER_OPT (bounds, SANITIZE_BOUNDS),
1482   SANITIZER_OPT (bounds-strict, SANITIZE_BOUNDS | SANITIZE_BOUNDS_STRICT),
1483   SANITIZER_OPT (alignment, SANITIZE_ALIGNMENT),
1484   SANITIZER_OPT (nonnull-attribute, SANITIZE_NONNULL_ATTRIBUTE),
1485   SANITIZER_OPT (returns-nonnull-attribute, SANITIZE_RETURNS_NONNULL_ATTRIBUTE),
1486   SANITIZER_OPT (object-size, SANITIZE_OBJECT_SIZE),
1487   SANITIZER_OPT (vptr, SANITIZE_VPTR),
1488   SANITIZER_OPT (all, ~0),
1489 #undef SANITIZER_OPT
1490   { NULL, 0, 0 }
1491 };
1492 
1493 /* Parse comma separated sanitizer suboptions from P for option SCODE,
1494    adjust previous FLAGS and return new ones.  If COMPLAIN is false,
1495    don't issue diagnostics.  */
1496 
1497 unsigned int
parse_sanitizer_options(const char * p,location_t loc,int scode,unsigned int flags,int value,bool complain)1498 parse_sanitizer_options (const char *p, location_t loc, int scode,
1499 			 unsigned int flags, int value, bool complain)
1500 {
1501   enum opt_code code = (enum opt_code) scode;
1502   while (*p != 0)
1503     {
1504       size_t len, i;
1505       bool found = false;
1506       const char *comma = strchr (p, ',');
1507 
1508       if (comma == NULL)
1509 	len = strlen (p);
1510       else
1511 	len = comma - p;
1512       if (len == 0)
1513 	{
1514 	  p = comma + 1;
1515 	  continue;
1516 	}
1517 
1518       /* Check to see if the string matches an option class name.  */
1519       for (i = 0; sanitizer_opts[i].name != NULL; ++i)
1520 	if (len == sanitizer_opts[i].len
1521 	    && memcmp (p, sanitizer_opts[i].name, len) == 0)
1522 	  {
1523 	    /* Handle both -fsanitize and -fno-sanitize cases.  */
1524 	    if (value && sanitizer_opts[i].flag == ~0U)
1525 	      {
1526 		if (code == OPT_fsanitize_)
1527 		  {
1528 		    if (complain)
1529 		      error_at (loc, "-fsanitize=all option is not valid");
1530 		  }
1531 		else
1532 		  flags |= ~(SANITIZE_USER_ADDRESS | SANITIZE_THREAD
1533 			     | SANITIZE_LEAK);
1534 	      }
1535 	    else if (value)
1536 	      flags |= sanitizer_opts[i].flag;
1537 	    else
1538 	      flags &= ~sanitizer_opts[i].flag;
1539 	    found = true;
1540 	    break;
1541 	  }
1542 
1543       if (! found && complain)
1544 	error_at (loc, "unrecognized argument to -fsanitize%s= option: %q.*s",
1545 		  code == OPT_fsanitize_ ? "" : "-recover", (int) len, p);
1546 
1547       if (comma == NULL)
1548 	break;
1549       p = comma + 1;
1550     }
1551   return flags;
1552 }
1553 
1554 /* Handle target- and language-independent options.  Return zero to
1555    generate an "unknown option" message.  Only options that need
1556    extra handling need to be listed here; if you simply want
1557    DECODED->value assigned to a variable, it happens automatically.  */
1558 
1559 bool
common_handle_option(struct gcc_options * opts,struct gcc_options * opts_set,const struct cl_decoded_option * decoded,unsigned int lang_mask,int kind ATTRIBUTE_UNUSED,location_t loc,const struct cl_option_handlers * handlers,diagnostic_context * dc,void (* target_option_override_hook)(void))1560 common_handle_option (struct gcc_options *opts,
1561 		      struct gcc_options *opts_set,
1562 		      const struct cl_decoded_option *decoded,
1563 		      unsigned int lang_mask, int kind ATTRIBUTE_UNUSED,
1564 		      location_t loc,
1565 		      const struct cl_option_handlers *handlers,
1566 		      diagnostic_context *dc,
1567 		      void (*target_option_override_hook) (void))
1568 {
1569   size_t scode = decoded->opt_index;
1570   const char *arg = decoded->arg;
1571   int value = decoded->value;
1572   enum opt_code code = (enum opt_code) scode;
1573 
1574   gcc_assert (decoded->canonical_option_num_elements <= 2);
1575 
1576   switch (code)
1577     {
1578     case OPT__param:
1579       handle_param (opts, opts_set, loc, arg);
1580       break;
1581 
1582     case OPT__help:
1583       {
1584 	unsigned int all_langs_mask = (1U << cl_lang_count) - 1;
1585 	unsigned int undoc_mask;
1586 	unsigned int i;
1587 
1588 	if (lang_mask == CL_DRIVER)
1589 	  break;
1590 
1591 	undoc_mask = ((opts->x_verbose_flag | opts->x_extra_warnings)
1592 		      ? 0
1593 		      : CL_UNDOCUMENTED);
1594 	target_option_override_hook ();
1595 	/* First display any single language specific options.  */
1596 	for (i = 0; i < cl_lang_count; i++)
1597 	  print_specific_help
1598 	    (1U << i, (all_langs_mask & (~ (1U << i))) | undoc_mask, 0, opts,
1599 	     lang_mask);
1600 	/* Next display any multi language specific options.  */
1601 	print_specific_help (0, undoc_mask, all_langs_mask, opts, lang_mask);
1602 	/* Then display any remaining, non-language options.  */
1603 	for (i = CL_MIN_OPTION_CLASS; i <= CL_MAX_OPTION_CLASS; i <<= 1)
1604 	  if (i != CL_DRIVER)
1605 	    print_specific_help (i, undoc_mask, 0, opts, lang_mask);
1606 	opts->x_exit_after_options = true;
1607 	break;
1608       }
1609 
1610     case OPT__target_help:
1611       if (lang_mask == CL_DRIVER)
1612 	break;
1613 
1614       target_option_override_hook ();
1615       print_specific_help (CL_TARGET, CL_UNDOCUMENTED, 0, opts, lang_mask);
1616       opts->x_exit_after_options = true;
1617       break;
1618 
1619     case OPT__help_:
1620       {
1621 	const char * a = arg;
1622 	unsigned int include_flags = 0;
1623 	/* Note - by default we include undocumented options when listing
1624 	   specific classes.  If you only want to see documented options
1625 	   then add ",^undocumented" to the --help= option.  E.g.:
1626 
1627 	   --help=target,^undocumented  */
1628 	unsigned int exclude_flags = 0;
1629 
1630 	if (lang_mask == CL_DRIVER)
1631 	  break;
1632 
1633 	/* Walk along the argument string, parsing each word in turn.
1634 	   The format is:
1635 	   arg = [^]{word}[,{arg}]
1636 	   word = {optimizers|target|warnings|undocumented|
1637 		   params|common|<language>}  */
1638 	while (* a != 0)
1639 	  {
1640 	    static const struct
1641 	    {
1642 	      const char * string;
1643 	      unsigned int flag;
1644 	    }
1645 	    specifics[] =
1646 	    {
1647 	      { "optimizers", CL_OPTIMIZATION },
1648 	      { "target", CL_TARGET },
1649 	      { "warnings", CL_WARNING },
1650 	      { "undocumented", CL_UNDOCUMENTED },
1651 	      { "params", CL_PARAMS },
1652 	      { "joined", CL_JOINED },
1653 	      { "separate", CL_SEPARATE },
1654 	      { "common", CL_COMMON },
1655 	      { NULL, 0 }
1656 	    };
1657 	    unsigned int * pflags;
1658 	    const char * comma;
1659 	    unsigned int lang_flag, specific_flag;
1660 	    unsigned int len;
1661 	    unsigned int i;
1662 
1663 	    if (* a == '^')
1664 	      {
1665 		++ a;
1666 		pflags = & exclude_flags;
1667 	      }
1668 	    else
1669 	      pflags = & include_flags;
1670 
1671 	    comma = strchr (a, ',');
1672 	    if (comma == NULL)
1673 	      len = strlen (a);
1674 	    else
1675 	      len = comma - a;
1676 	    if (len == 0)
1677 	      {
1678 		a = comma + 1;
1679 		continue;
1680 	      }
1681 
1682 	    /* Check to see if the string matches an option class name.  */
1683 	    for (i = 0, specific_flag = 0; specifics[i].string != NULL; i++)
1684 	      if (strncasecmp (a, specifics[i].string, len) == 0)
1685 		{
1686 		  specific_flag = specifics[i].flag;
1687 		  break;
1688 		}
1689 
1690 	    /* Check to see if the string matches a language name.
1691 	       Note - we rely upon the alpha-sorted nature of the entries in
1692 	       the lang_names array, specifically that shorter names appear
1693 	       before their longer variants.  (i.e. C before C++).  That way
1694 	       when we are attempting to match --help=c for example we will
1695 	       match with C first and not C++.  */
1696 	    for (i = 0, lang_flag = 0; i < cl_lang_count; i++)
1697 	      if (strncasecmp (a, lang_names[i], len) == 0)
1698 		{
1699 		  lang_flag = 1U << i;
1700 		  break;
1701 		}
1702 
1703 	    if (specific_flag != 0)
1704 	      {
1705 		if (lang_flag == 0)
1706 		  * pflags |= specific_flag;
1707 		else
1708 		  {
1709 		    /* The option's argument matches both the start of a
1710 		       language name and the start of an option class name.
1711 		       We have a special case for when the user has
1712 		       specified "--help=c", but otherwise we have to issue
1713 		       a warning.  */
1714 		    if (strncasecmp (a, "c", len) == 0)
1715 		      * pflags |= lang_flag;
1716 		    else
1717 		      warning_at (loc, 0,
1718 				  "--help argument %q.*s is ambiguous, "
1719 				  "please be more specific",
1720 				  len, a);
1721 		  }
1722 	      }
1723 	    else if (lang_flag != 0)
1724 	      * pflags |= lang_flag;
1725 	    else
1726 	      warning_at (loc, 0,
1727 			  "unrecognized argument to --help= option: %q.*s",
1728 			  len, a);
1729 
1730 	    if (comma == NULL)
1731 	      break;
1732 	    a = comma + 1;
1733 	  }
1734 
1735 	if (include_flags)
1736 	  {
1737 	    target_option_override_hook ();
1738 	    print_specific_help (include_flags, exclude_flags, 0, opts,
1739 				 lang_mask);
1740 	  }
1741 	opts->x_exit_after_options = true;
1742 	break;
1743       }
1744 
1745     case OPT__version:
1746       if (lang_mask == CL_DRIVER)
1747 	break;
1748 
1749       opts->x_exit_after_options = true;
1750       break;
1751 
1752     case OPT_fsanitize_:
1753       opts->x_flag_sanitize
1754 	= parse_sanitizer_options (arg, loc, code,
1755 				   opts->x_flag_sanitize, value, true);
1756 
1757       /* Kernel ASan implies normal ASan but does not yet support
1758 	 all features.  */
1759       if (opts->x_flag_sanitize & SANITIZE_KERNEL_ADDRESS)
1760 	{
1761 	  maybe_set_param_value (PARAM_ASAN_INSTRUMENTATION_WITH_CALL_THRESHOLD,
1762 				 0, opts->x_param_values,
1763 				 opts_set->x_param_values);
1764 	  maybe_set_param_value (PARAM_ASAN_GLOBALS, 0, opts->x_param_values,
1765 				 opts_set->x_param_values);
1766 	  maybe_set_param_value (PARAM_ASAN_STACK, 0, opts->x_param_values,
1767 				 opts_set->x_param_values);
1768 	  maybe_set_param_value (PARAM_ASAN_USE_AFTER_RETURN, 0,
1769 				 opts->x_param_values,
1770 				 opts_set->x_param_values);
1771 	}
1772       break;
1773 
1774     case OPT_fsanitize_recover_:
1775       opts->x_flag_sanitize_recover
1776 	= parse_sanitizer_options (arg, loc, code,
1777 				   opts->x_flag_sanitize_recover, value, true);
1778       break;
1779 
1780     case OPT_fasan_shadow_offset_:
1781       /* Deferred.  */
1782       break;
1783 
1784     case OPT_fsanitize_recover:
1785       if (value)
1786 	opts->x_flag_sanitize_recover
1787 	  |= SANITIZE_UNDEFINED | SANITIZE_NONDEFAULT;
1788       else
1789 	opts->x_flag_sanitize_recover
1790 	  &= ~(SANITIZE_UNDEFINED | SANITIZE_NONDEFAULT);
1791       break;
1792 
1793     case OPT_O:
1794     case OPT_Os:
1795     case OPT_Ofast:
1796     case OPT_Og:
1797       /* Currently handled in a prescan.  */
1798       break;
1799 
1800     case OPT_Werror:
1801       dc->warning_as_error_requested = value;
1802       break;
1803 
1804     case OPT_Werror_:
1805       if (lang_mask == CL_DRIVER)
1806 	break;
1807 
1808       enable_warning_as_error (arg, value, lang_mask, handlers,
1809 			       opts, opts_set, loc, dc);
1810       break;
1811 
1812     case OPT_Wlarger_than_:
1813       opts->x_larger_than_size = value;
1814       opts->x_warn_larger_than = value != -1;
1815       break;
1816 
1817     case OPT_Wfatal_errors:
1818       dc->fatal_errors = value;
1819       break;
1820 
1821     case OPT_Wframe_larger_than_:
1822       opts->x_frame_larger_than_size = value;
1823       opts->x_warn_frame_larger_than = value != -1;
1824       break;
1825 
1826     case OPT_Wstack_usage_:
1827       opts->x_warn_stack_usage = value;
1828       opts->x_flag_stack_usage_info = value != -1;
1829       break;
1830 
1831     case OPT_Wstrict_aliasing:
1832       set_Wstrict_aliasing (opts, value);
1833       break;
1834 
1835     case OPT_Wstrict_overflow:
1836       opts->x_warn_strict_overflow = (value
1837 				      ? (int) WARN_STRICT_OVERFLOW_CONDITIONAL
1838 				      : 0);
1839       break;
1840 
1841     case OPT_Wsystem_headers:
1842       dc->dc_warn_system_headers = value;
1843       break;
1844 
1845     case OPT_aux_info:
1846       opts->x_flag_gen_aux_info = 1;
1847       break;
1848 
1849     case OPT_auxbase_strip:
1850       {
1851 	char *tmp = xstrdup (arg);
1852 	strip_off_ending (tmp, strlen (tmp));
1853 	if (tmp[0])
1854 	  opts->x_aux_base_name = tmp;
1855 	else
1856 	  free (tmp);
1857       }
1858       break;
1859 
1860     case OPT_d:
1861       decode_d_option (arg, opts, loc, dc);
1862       break;
1863 
1864     case OPT_fcall_used_:
1865     case OPT_fcall_saved_:
1866       /* Deferred.  */
1867       break;
1868 
1869     case OPT_fdbg_cnt_:
1870       /* Deferred.  */
1871       break;
1872 
1873     case OPT_fdbg_cnt_list:
1874       /* Deferred.  */
1875       opts->x_exit_after_options = true;
1876       break;
1877 
1878     case OPT_fdebug_prefix_map_:
1879       /* Deferred.  */
1880       break;
1881 
1882     case OPT_fdiagnostics_show_location_:
1883       diagnostic_prefixing_rule (dc) = (diagnostic_prefixing_rule_t) value;
1884       break;
1885 
1886     case OPT_fdiagnostics_show_caret:
1887       dc->show_caret = value;
1888       break;
1889 
1890     case OPT_fdiagnostics_color_:
1891       diagnostic_color_init (dc, value);
1892       break;
1893 
1894     case OPT_fdiagnostics_show_option:
1895       dc->show_option_requested = value;
1896       break;
1897 
1898     case OPT_fdump_:
1899       /* Deferred.  */
1900       break;
1901 
1902     case OPT_ffast_math:
1903       set_fast_math_flags (opts, value);
1904       break;
1905 
1906     case OPT_funsafe_math_optimizations:
1907       set_unsafe_math_optimizations_flags (opts, value);
1908       break;
1909 
1910     case OPT_ffixed_:
1911       /* Deferred.  */
1912       break;
1913 
1914     case OPT_finline_limit_:
1915       set_param_value ("max-inline-insns-single", value / 2,
1916 		       opts->x_param_values, opts_set->x_param_values);
1917       set_param_value ("max-inline-insns-auto", value / 2,
1918 		       opts->x_param_values, opts_set->x_param_values);
1919       break;
1920 
1921     case OPT_finstrument_functions_exclude_function_list_:
1922       add_comma_separated_to_vector
1923 	(&opts->x_flag_instrument_functions_exclude_functions, arg);
1924       break;
1925 
1926     case OPT_finstrument_functions_exclude_file_list_:
1927       add_comma_separated_to_vector
1928 	(&opts->x_flag_instrument_functions_exclude_files, arg);
1929       break;
1930 
1931     case OPT_fmessage_length_:
1932       pp_set_line_maximum_length (dc->printer, value);
1933       diagnostic_set_caret_max_width (dc, value);
1934       break;
1935 
1936     case OPT_fopt_info:
1937     case OPT_fopt_info_:
1938       /* Deferred.  */
1939       break;
1940 
1941     case OPT_foffload_:
1942       {
1943 	const char *p = arg;
1944 	opts->x_flag_disable_hsa = true;
1945 	while (*p != 0)
1946 	  {
1947 	    const char *comma = strchr (p, ',');
1948 
1949 	    if ((strncmp (p, "disable", 7) == 0)
1950 		&& (p[7] == ',' || p[7] == '\0'))
1951 	      {
1952 		opts->x_flag_disable_hsa = true;
1953 		break;
1954 	      }
1955 
1956 	    if ((strncmp (p, "hsa", 3) == 0)
1957 		&& (p[3] == ',' || p[3] == '\0'))
1958 	      {
1959 #ifdef ENABLE_HSA
1960 		opts->x_flag_disable_hsa = false;
1961 #else
1962 		sorry ("HSA has not been enabled during configuration");
1963 #endif
1964 	      }
1965 	    if (!comma)
1966 	      break;
1967 	    p = comma + 1;
1968 	  }
1969 	break;
1970       }
1971 
1972 #ifndef ACCEL_COMPILER
1973     case OPT_foffload_abi_:
1974       error_at (loc, "-foffload-abi option can be specified only for "
1975 		"offload compiler");
1976       break;
1977 #endif
1978 
1979     case OPT_fpack_struct_:
1980       if (value <= 0 || (value & (value - 1)) || value > 16)
1981 	error_at (loc,
1982 		  "structure alignment must be a small power of two, not %d",
1983 		  value);
1984       else
1985 	opts->x_initial_max_fld_align = value;
1986       break;
1987 
1988     case OPT_fplugin_:
1989     case OPT_fplugin_arg_:
1990       /* Deferred.  */
1991       break;
1992 
1993     case OPT_fprofile_use_:
1994       opts->x_profile_data_prefix = xstrdup (arg);
1995       opts->x_flag_profile_use = true;
1996       value = true;
1997       /* No break here - do -fprofile-use processing. */
1998     case OPT_fprofile_use:
1999       enable_fdo_optimizations (opts, opts_set, value);
2000       if (!opts_set->x_flag_profile_reorder_functions)
2001 	  opts->x_flag_profile_reorder_functions = value;
2002 	/* Indirect call profiling should do all useful transformations
2003 	   speculative devirtualization does.  */
2004       if (!opts_set->x_flag_devirtualize_speculatively
2005 	  && opts->x_flag_value_profile_transformations)
2006 	opts->x_flag_devirtualize_speculatively = false;
2007       break;
2008 
2009     case OPT_fauto_profile_:
2010       opts->x_auto_profile_file = xstrdup (arg);
2011       opts->x_flag_auto_profile = true;
2012       value = true;
2013       /* No break here - do -fauto-profile processing. */
2014     case OPT_fauto_profile:
2015       enable_fdo_optimizations (opts, opts_set, value);
2016       if (!opts_set->x_flag_profile_correction)
2017 	opts->x_flag_profile_correction = value;
2018       maybe_set_param_value (
2019 	PARAM_EARLY_INLINER_MAX_ITERATIONS, 10,
2020 	opts->x_param_values, opts_set->x_param_values);
2021       break;
2022 
2023     case OPT_fprofile_generate_:
2024       opts->x_profile_data_prefix = xstrdup (arg);
2025       value = true;
2026       /* No break here - do -fprofile-generate processing. */
2027     case OPT_fprofile_generate:
2028       if (!opts_set->x_profile_arc_flag)
2029 	opts->x_profile_arc_flag = value;
2030       if (!opts_set->x_flag_profile_values)
2031 	opts->x_flag_profile_values = value;
2032       if (!opts_set->x_flag_inline_functions)
2033 	opts->x_flag_inline_functions = value;
2034       /* FIXME: Instrumentation we insert makes ipa-reference bitmaps
2035 	 quadratic.  Disable the pass until better memory representation
2036 	 is done.  */
2037       if (!opts_set->x_flag_ipa_reference)
2038         opts->x_flag_ipa_reference = false;
2039       break;
2040 
2041     case OPT_ftree_vectorize:
2042       if (!opts_set->x_flag_tree_loop_vectorize)
2043         opts->x_flag_tree_loop_vectorize = value;
2044       if (!opts_set->x_flag_tree_slp_vectorize)
2045         opts->x_flag_tree_slp_vectorize = value;
2046       break;
2047     case OPT_fshow_column:
2048       dc->show_column = value;
2049       break;
2050 
2051     case OPT_frandom_seed:
2052       /* The real switch is -fno-random-seed.  */
2053       if (value)
2054 	return false;
2055       /* Deferred.  */
2056       break;
2057 
2058     case OPT_frandom_seed_:
2059       /* Deferred.  */
2060       break;
2061 
2062     case OPT_fsched_verbose_:
2063 #ifdef INSN_SCHEDULING
2064       /* Handled with Var in common.opt.  */
2065       break;
2066 #else
2067       return false;
2068 #endif
2069 
2070     case OPT_fsched_stalled_insns_:
2071       opts->x_flag_sched_stalled_insns = value;
2072       if (opts->x_flag_sched_stalled_insns == 0)
2073 	opts->x_flag_sched_stalled_insns = -1;
2074       break;
2075 
2076     case OPT_fsched_stalled_insns_dep_:
2077       opts->x_flag_sched_stalled_insns_dep = value;
2078       break;
2079 
2080     case OPT_fstack_check_:
2081       if (!strcmp (arg, "no"))
2082 	opts->x_flag_stack_check = NO_STACK_CHECK;
2083       else if (!strcmp (arg, "generic"))
2084 	/* This is the old stack checking method.  */
2085 	opts->x_flag_stack_check = STACK_CHECK_BUILTIN
2086 			   ? FULL_BUILTIN_STACK_CHECK
2087 			   : GENERIC_STACK_CHECK;
2088       else if (!strcmp (arg, "specific"))
2089 	/* This is the new stack checking method.  */
2090 	opts->x_flag_stack_check = STACK_CHECK_BUILTIN
2091 			   ? FULL_BUILTIN_STACK_CHECK
2092 			   : STACK_CHECK_STATIC_BUILTIN
2093 			     ? STATIC_BUILTIN_STACK_CHECK
2094 			     : GENERIC_STACK_CHECK;
2095       else
2096 	warning_at (loc, 0, "unknown stack check parameter %qs", arg);
2097       break;
2098 
2099     case OPT_fstack_limit:
2100       /* The real switch is -fno-stack-limit.  */
2101       if (value)
2102 	return false;
2103       /* Deferred.  */
2104       break;
2105 
2106     case OPT_fstack_limit_register_:
2107     case OPT_fstack_limit_symbol_:
2108       /* Deferred.  */
2109       break;
2110 
2111     case OPT_fstack_usage:
2112       opts->x_flag_stack_usage = value;
2113       opts->x_flag_stack_usage_info = value != 0;
2114       break;
2115 
2116     case OPT_g:
2117       set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, arg, opts, opts_set,
2118                        loc);
2119       break;
2120 
2121     case OPT_gcoff:
2122       set_debug_level (SDB_DEBUG, false, arg, opts, opts_set, loc);
2123       break;
2124 
2125     case OPT_gdwarf:
2126       if (arg && strlen (arg) != 0)
2127         {
2128           error_at (loc, "%<-gdwarf%s%> is ambiguous; "
2129                     "use %<-gdwarf-%s%> for DWARF version "
2130                     "or %<-gdwarf -g%s%> for debug level", arg, arg, arg);
2131           break;
2132         }
2133       else
2134         value = opts->x_dwarf_version;
2135 
2136       /* FALLTHRU */
2137     case OPT_gdwarf_:
2138       if (value < 2 || value > 5)
2139 	error_at (loc, "dwarf version %d is not supported", value);
2140       else
2141 	opts->x_dwarf_version = value;
2142       set_debug_level (DWARF2_DEBUG, false, "", opts, opts_set, loc);
2143       break;
2144 
2145     case OPT_gsplit_dwarf:
2146       set_debug_level (NO_DEBUG, DEFAULT_GDB_EXTENSIONS, "", opts, opts_set,
2147 		       loc);
2148       break;
2149 
2150     case OPT_ggdb:
2151       set_debug_level (NO_DEBUG, 2, arg, opts, opts_set, loc);
2152       break;
2153 
2154     case OPT_gstabs:
2155     case OPT_gstabs_:
2156       set_debug_level (DBX_DEBUG, code == OPT_gstabs_, arg, opts, opts_set,
2157 		       loc);
2158       break;
2159 
2160     case OPT_gvms:
2161       set_debug_level (VMS_DEBUG, false, arg, opts, opts_set, loc);
2162       break;
2163 
2164     case OPT_gxcoff:
2165     case OPT_gxcoff_:
2166       set_debug_level (XCOFF_DEBUG, code == OPT_gxcoff_, arg, opts, opts_set,
2167 		       loc);
2168       break;
2169 
2170     case OPT_gz:
2171     case OPT_gz_:
2172       /* Handled completely via specs.  */
2173       break;
2174 
2175     case OPT_pedantic_errors:
2176       dc->pedantic_errors = 1;
2177       control_warning_option (OPT_Wpedantic, DK_ERROR, NULL, value,
2178 			      loc, lang_mask,
2179 			      handlers, opts, opts_set,
2180                               dc);
2181       break;
2182 
2183     case OPT_flto:
2184       opts->x_flag_lto = value ? "" : NULL;
2185       break;
2186 
2187     case OPT_w:
2188       dc->dc_inhibit_warnings = true;
2189       break;
2190 
2191     case OPT_fmax_errors_:
2192       dc->max_errors = value;
2193       break;
2194 
2195     case OPT_fuse_ld_bfd:
2196     case OPT_fuse_ld_gold:
2197     case OPT_fuse_linker_plugin:
2198       /* No-op. Used by the driver and passed to us because it starts with f.*/
2199       break;
2200 
2201     case OPT_fwrapv:
2202       if (value)
2203 	opts->x_flag_trapv = 0;
2204       break;
2205 
2206     case OPT_ftrapv:
2207       if (value)
2208 	opts->x_flag_wrapv = 0;
2209       break;
2210 
2211     case OPT_fipa_icf:
2212       opts->x_flag_ipa_icf_functions = value;
2213       opts->x_flag_ipa_icf_variables = value;
2214       break;
2215 
2216     default:
2217       /* If the flag was handled in a standard way, assume the lack of
2218 	 processing here is intentional.  */
2219       gcc_assert (option_flag_var (scode, opts));
2220       break;
2221     }
2222 
2223   common_handle_option_auto (opts, opts_set, decoded, lang_mask, kind,
2224                              loc, handlers, dc);
2225   return true;
2226 }
2227 
2228 /* Handle --param NAME=VALUE.  */
2229 static void
handle_param(struct gcc_options * opts,struct gcc_options * opts_set,location_t loc,const char * carg)2230 handle_param (struct gcc_options *opts, struct gcc_options *opts_set,
2231 	      location_t loc, const char *carg)
2232 {
2233   char *equal, *arg;
2234   int value;
2235 
2236   arg = xstrdup (carg);
2237   equal = strchr (arg, '=');
2238   if (!equal)
2239     error_at (loc, "%s: --param arguments should be of the form NAME=VALUE",
2240 	      arg);
2241   else
2242     {
2243       *equal = '\0';
2244 
2245       enum compiler_param index;
2246       if (!find_param (arg, &index))
2247 	error_at (loc, "invalid --param name %qs", arg);
2248       else
2249 	{
2250 	  if (!param_string_value_p (index, equal + 1, &value))
2251 	    value = integral_argument (equal + 1);
2252 
2253 	  if (value == -1)
2254 	    error_at (loc, "invalid --param value %qs", equal + 1);
2255 	  else
2256 	    set_param_value (arg, value,
2257 			     opts->x_param_values, opts_set->x_param_values);
2258 	}
2259     }
2260 
2261   free (arg);
2262 }
2263 
2264 /* Used to set the level of strict aliasing warnings in OPTS,
2265    when no level is specified (i.e., when -Wstrict-aliasing, and not
2266    -Wstrict-aliasing=level was given).
2267    ONOFF is assumed to take value 1 when -Wstrict-aliasing is specified,
2268    and 0 otherwise.  After calling this function, wstrict_aliasing will be
2269    set to the default value of -Wstrict_aliasing=level, currently 3.  */
2270 static void
set_Wstrict_aliasing(struct gcc_options * opts,int onoff)2271 set_Wstrict_aliasing (struct gcc_options *opts, int onoff)
2272 {
2273   gcc_assert (onoff == 0 || onoff == 1);
2274   if (onoff != 0)
2275     opts->x_warn_strict_aliasing = 3;
2276   else
2277     opts->x_warn_strict_aliasing = 0;
2278 }
2279 
2280 /* The following routines are useful in setting all the flags that
2281    -ffast-math and -fno-fast-math imply.  */
2282 static void
set_fast_math_flags(struct gcc_options * opts,int set)2283 set_fast_math_flags (struct gcc_options *opts, int set)
2284 {
2285   if (!opts->frontend_set_flag_unsafe_math_optimizations)
2286     {
2287       opts->x_flag_unsafe_math_optimizations = set;
2288       set_unsafe_math_optimizations_flags (opts, set);
2289     }
2290   if (!opts->frontend_set_flag_finite_math_only)
2291     opts->x_flag_finite_math_only = set;
2292   if (!opts->frontend_set_flag_errno_math)
2293     opts->x_flag_errno_math = !set;
2294   if (set)
2295     {
2296       if (!opts->frontend_set_flag_signaling_nans)
2297 	opts->x_flag_signaling_nans = 0;
2298       if (!opts->frontend_set_flag_rounding_math)
2299 	opts->x_flag_rounding_math = 0;
2300       if (!opts->frontend_set_flag_cx_limited_range)
2301 	opts->x_flag_cx_limited_range = 1;
2302     }
2303 }
2304 
2305 /* When -funsafe-math-optimizations is set the following
2306    flags are set as well.  */
2307 static void
set_unsafe_math_optimizations_flags(struct gcc_options * opts,int set)2308 set_unsafe_math_optimizations_flags (struct gcc_options *opts, int set)
2309 {
2310   if (!opts->frontend_set_flag_trapping_math)
2311     opts->x_flag_trapping_math = !set;
2312   if (!opts->frontend_set_flag_signed_zeros)
2313     opts->x_flag_signed_zeros = !set;
2314   if (!opts->frontend_set_flag_associative_math)
2315     opts->x_flag_associative_math = set;
2316   if (!opts->frontend_set_flag_reciprocal_math)
2317     opts->x_flag_reciprocal_math = set;
2318 }
2319 
2320 /* Return true iff flags in OPTS are set as if -ffast-math.  */
2321 bool
fast_math_flags_set_p(const struct gcc_options * opts)2322 fast_math_flags_set_p (const struct gcc_options *opts)
2323 {
2324   return (!opts->x_flag_trapping_math
2325 	  && opts->x_flag_unsafe_math_optimizations
2326 	  && opts->x_flag_finite_math_only
2327 	  && !opts->x_flag_signed_zeros
2328 	  && !opts->x_flag_errno_math);
2329 }
2330 
2331 /* Return true iff flags are set as if -ffast-math but using the flags stored
2332    in the struct cl_optimization structure.  */
2333 bool
fast_math_flags_struct_set_p(struct cl_optimization * opt)2334 fast_math_flags_struct_set_p (struct cl_optimization *opt)
2335 {
2336   return (!opt->x_flag_trapping_math
2337 	  && opt->x_flag_unsafe_math_optimizations
2338 	  && opt->x_flag_finite_math_only
2339 	  && !opt->x_flag_signed_zeros
2340 	  && !opt->x_flag_errno_math);
2341 }
2342 
2343 /* Handle a debug output -g switch for options OPTS
2344    (OPTS_SET->x_write_symbols storing whether a debug type was passed
2345    explicitly), location LOC.  EXTENDED is true or false to support
2346    extended output (2 is special and means "-ggdb" was given).  */
2347 static void
set_debug_level(enum debug_info_type type,int extended,const char * arg,struct gcc_options * opts,struct gcc_options * opts_set,location_t loc)2348 set_debug_level (enum debug_info_type type, int extended, const char *arg,
2349 		 struct gcc_options *opts, struct gcc_options *opts_set,
2350 		 location_t loc)
2351 {
2352   opts->x_use_gnu_debug_info_extensions = extended;
2353 
2354   if (type == NO_DEBUG)
2355     {
2356       if (opts->x_write_symbols == NO_DEBUG)
2357 	{
2358 	  opts->x_write_symbols = PREFERRED_DEBUGGING_TYPE;
2359 
2360 	  if (extended == 2)
2361 	    {
2362 #if defined DWARF2_DEBUGGING_INFO || defined DWARF2_LINENO_DEBUGGING_INFO
2363 	      opts->x_write_symbols = DWARF2_DEBUG;
2364 #elif defined DBX_DEBUGGING_INFO
2365 	      opts->x_write_symbols = DBX_DEBUG;
2366 #endif
2367 	    }
2368 
2369 	  if (opts->x_write_symbols == NO_DEBUG)
2370 	    warning_at (loc, 0, "target system does not support debug output");
2371 	}
2372     }
2373   else
2374     {
2375       /* Does it conflict with an already selected type?  */
2376       if (opts_set->x_write_symbols != NO_DEBUG
2377 	  && opts->x_write_symbols != NO_DEBUG
2378 	  && type != opts->x_write_symbols)
2379 	error_at (loc, "debug format %qs conflicts with prior selection",
2380 		  debug_type_names[type]);
2381       opts->x_write_symbols = type;
2382       opts_set->x_write_symbols = type;
2383     }
2384 
2385   /* A debug flag without a level defaults to level 2.
2386      If off or at level 1, set it to level 2, but if already
2387      at level 3, don't lower it.  */
2388   if (*arg == '\0')
2389     {
2390       if (opts->x_debug_info_level < DINFO_LEVEL_NORMAL)
2391 	opts->x_debug_info_level = DINFO_LEVEL_NORMAL;
2392     }
2393   else
2394     {
2395       int argval = integral_argument (arg);
2396       if (argval == -1)
2397 	error_at (loc, "unrecognised debug output level %qs", arg);
2398       else if (argval > 3)
2399 	error_at (loc, "debug output level %qs is too high", arg);
2400       else
2401 	opts->x_debug_info_level = (enum debug_info_levels) argval;
2402     }
2403 }
2404 
2405 /* Arrange to dump core on error for diagnostic context DC.  (The
2406    regular error message is still printed first, except in the case of
2407    abort ().)  */
2408 
2409 static void
setup_core_dumping(diagnostic_context * dc)2410 setup_core_dumping (diagnostic_context *dc)
2411 {
2412 #ifdef SIGABRT
2413   signal (SIGABRT, SIG_DFL);
2414 #endif
2415 #if defined(HAVE_SETRLIMIT)
2416   {
2417     struct rlimit rlim;
2418     if (getrlimit (RLIMIT_CORE, &rlim) != 0)
2419       fatal_error (input_location, "getting core file size maximum limit: %m");
2420     rlim.rlim_cur = rlim.rlim_max;
2421     if (setrlimit (RLIMIT_CORE, &rlim) != 0)
2422       fatal_error (input_location,
2423 		   "setting core file size limit to maximum: %m");
2424   }
2425 #endif
2426   diagnostic_abort_on_error (dc);
2427 }
2428 
2429 /* Parse a -d<ARG> command line switch for OPTS, location LOC,
2430    diagnostic context DC.  */
2431 
2432 static void
decode_d_option(const char * arg,struct gcc_options * opts,location_t loc,diagnostic_context * dc)2433 decode_d_option (const char *arg, struct gcc_options *opts,
2434 		 location_t loc, diagnostic_context *dc)
2435 {
2436   int c;
2437 
2438   while (*arg)
2439     switch (c = *arg++)
2440       {
2441       case 'A':
2442 	opts->x_flag_debug_asm = 1;
2443 	break;
2444       case 'p':
2445 	opts->x_flag_print_asm_name = 1;
2446 	break;
2447       case 'P':
2448 	opts->x_flag_dump_rtl_in_asm = 1;
2449 	opts->x_flag_print_asm_name = 1;
2450 	break;
2451       case 'x':
2452 	opts->x_rtl_dump_and_exit = 1;
2453 	break;
2454       case 'D':	/* These are handled by the preprocessor.  */
2455       case 'I':
2456       case 'M':
2457       case 'N':
2458       case 'U':
2459 	break;
2460       case 'H':
2461 	setup_core_dumping (dc);
2462 	break;
2463       case 'a':
2464 	opts->x_flag_dump_all_passed = true;
2465 	break;
2466 
2467       default:
2468 	  warning_at (loc, 0, "unrecognized gcc debugging option: %c", c);
2469 	break;
2470       }
2471 }
2472 
2473 /* Enable (or disable if VALUE is 0) a warning option ARG (language
2474    mask LANG_MASK, option handlers HANDLERS) as an error for option
2475    structures OPTS and OPTS_SET, diagnostic context DC (possibly
2476    NULL), location LOC.  This is used by -Werror=.  */
2477 
2478 static void
enable_warning_as_error(const char * arg,int value,unsigned int lang_mask,const struct cl_option_handlers * handlers,struct gcc_options * opts,struct gcc_options * opts_set,location_t loc,diagnostic_context * dc)2479 enable_warning_as_error (const char *arg, int value, unsigned int lang_mask,
2480 			 const struct cl_option_handlers *handlers,
2481 			 struct gcc_options *opts,
2482 			 struct gcc_options *opts_set,
2483 			 location_t loc, diagnostic_context *dc)
2484 {
2485   char *new_option;
2486   int option_index;
2487 
2488   new_option = XNEWVEC (char, strlen (arg) + 2);
2489   new_option[0] = 'W';
2490   strcpy (new_option + 1, arg);
2491   option_index = find_opt (new_option, lang_mask);
2492   if (option_index == OPT_SPECIAL_unknown)
2493     error_at (loc, "-Werror=%s: no option -%s", arg, new_option);
2494   else if (!(cl_options[option_index].flags & CL_WARNING))
2495     error_at (loc, "-Werror=%s: -%s is not an option that controls warnings",
2496 	      arg, new_option);
2497   else
2498     {
2499       const diagnostic_t kind = value ? DK_ERROR : DK_WARNING;
2500       const char *arg = NULL;
2501 
2502       if (cl_options[option_index].flags & CL_JOINED)
2503 	arg = new_option + cl_options[option_index].opt_len;
2504       control_warning_option (option_index, (int) kind, arg, value,
2505 			      loc, lang_mask,
2506 			      handlers, opts, opts_set, dc);
2507     }
2508   free (new_option);
2509 }
2510 
2511 /* Return malloced memory for the name of the option OPTION_INDEX
2512    which enabled a diagnostic (context CONTEXT), originally of type
2513    ORIG_DIAG_KIND but possibly converted to DIAG_KIND by options such
2514    as -Werror.  */
2515 
2516 char *
option_name(diagnostic_context * context,int option_index,diagnostic_t orig_diag_kind,diagnostic_t diag_kind)2517 option_name (diagnostic_context *context, int option_index,
2518 	     diagnostic_t orig_diag_kind, diagnostic_t diag_kind)
2519 {
2520   if (option_index)
2521     {
2522       /* A warning classified as an error.  */
2523       if ((orig_diag_kind == DK_WARNING || orig_diag_kind == DK_PEDWARN)
2524 	  && diag_kind == DK_ERROR)
2525 	return concat (cl_options[OPT_Werror_].opt_text,
2526 		       /* Skip over "-W".  */
2527 		       cl_options[option_index].opt_text + 2,
2528 		       NULL);
2529       /* A warning with option.  */
2530       else
2531 	return xstrdup (cl_options[option_index].opt_text);
2532     }
2533   /* A warning without option classified as an error.  */
2534   else if ((orig_diag_kind == DK_WARNING || orig_diag_kind == DK_PEDWARN
2535 	    || diag_kind == DK_WARNING)
2536 	   && context->warning_as_error_requested)
2537     return xstrdup (cl_options[OPT_Werror].opt_text);
2538   else
2539     return NULL;
2540 }
2541