1/* Parse and display command line options.
2   Copyright (C) 2000-2022 Free Software Foundation, Inc.
3   Contributed by Andy Vaught
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 3, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along 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 "coretypes.h"
24#include "target.h"
25#include "tree.h"
26#include "gfortran.h"
27#include "diagnostic.h"	/* For global_dc.  */
28#include "opts.h"
29#include "toplev.h"  /* For save_decoded_options.  */
30#include "cpp.h"
31#include "langhooks.h"
32
33gfc_option_t gfc_option;
34
35#define SET_FLAG(flag, condition, on_value, off_value) \
36  do \
37    { \
38      if (condition) \
39	flag = (on_value); \
40      else \
41	flag = (off_value); \
42    } while (0)
43
44#define SET_BITFLAG2(m) m
45
46#define SET_BITFLAG(flag, condition, value) \
47  SET_BITFLAG2 (SET_FLAG (flag, condition, (flag | (value)), (flag & ~(value))))
48
49
50/* Set flags that control warnings and errors for different
51   Fortran standards to their default values.  Keep in sync with
52   libgfortran/runtime/compile_options.c (init_compile_options).  */
53
54static void
55set_default_std_flags (void)
56{
57  gfc_option.allow_std = GFC_STD_F95_OBS | GFC_STD_F95_DEL
58    | GFC_STD_F2003 | GFC_STD_F2008 | GFC_STD_F95 | GFC_STD_F77
59    | GFC_STD_F2008_OBS | GFC_STD_GNU | GFC_STD_LEGACY
60    | GFC_STD_F2018 | GFC_STD_F2018_DEL | GFC_STD_F2018_OBS;
61  gfc_option.warn_std = GFC_STD_F2018_DEL | GFC_STD_F95_DEL | GFC_STD_LEGACY;
62}
63
64/* Set (or unset) the DEC extension flags.  */
65
66static void
67set_dec_flags (int value)
68{
69  /* Set (or unset) other DEC compatibility extensions.  */
70  SET_BITFLAG (flag_dollar_ok, value, value);
71  SET_BITFLAG (flag_cray_pointer, value, value);
72  SET_BITFLAG (flag_dec_structure, value, value);
73  SET_BITFLAG (flag_dec_intrinsic_ints, value, value);
74  SET_BITFLAG (flag_dec_static, value, value);
75  SET_BITFLAG (flag_dec_math, value, value);
76  SET_BITFLAG (flag_dec_include, value, value);
77  SET_BITFLAG (flag_dec_format_defaults, value, value);
78  SET_BITFLAG (flag_dec_blank_format_item, value, value);
79  SET_BITFLAG (flag_dec_char_conversions, value, value);
80}
81
82/* Finalize DEC flags.  */
83
84static void
85post_dec_flags (int value)
86{
87  /* Don't warn for legacy code if -fdec is given; however, setting -fno-dec
88     does not force these warnings.  We make one final determination on this
89     at the end because -std= is always set first; thus, we can avoid
90     clobbering the user's desired standard settings in gfc_handle_option
91     e.g. when -fdec and -fno-dec are both given.  */
92  if (value)
93    {
94      gfc_option.allow_std |= GFC_STD_F95_OBS | GFC_STD_F95_DEL
95	| GFC_STD_GNU | GFC_STD_LEGACY;
96      gfc_option.warn_std &= ~(GFC_STD_LEGACY | GFC_STD_F95_DEL);
97    }
98}
99
100/* Enable (or disable) -finit-local-zero.  */
101
102static void
103set_init_local_zero (int value)
104{
105  gfc_option.flag_init_integer_value = 0;
106  gfc_option.flag_init_character_value = (char)0;
107
108  SET_FLAG (gfc_option.flag_init_integer, value, GFC_INIT_INTEGER_ON,
109	    GFC_INIT_INTEGER_OFF);
110  SET_FLAG (gfc_option.flag_init_logical, value, GFC_INIT_LOGICAL_FALSE,
111	    GFC_INIT_LOGICAL_OFF);
112  SET_FLAG (gfc_option.flag_init_character, value, GFC_INIT_CHARACTER_ON,
113	    GFC_INIT_CHARACTER_OFF);
114  SET_FLAG (flag_init_real, value, GFC_INIT_REAL_ZERO, GFC_INIT_REAL_OFF);
115}
116
117/* Return language mask for Fortran options.  */
118
119unsigned int
120gfc_option_lang_mask (void)
121{
122  return CL_Fortran;
123}
124
125/* Initialize options structure OPTS.  */
126
127void
128gfc_init_options_struct (struct gcc_options *opts)
129{
130  opts->x_flag_errno_math = 0;
131  opts->frontend_set_flag_errno_math = true;
132  opts->x_flag_associative_math = -1;
133  opts->frontend_set_flag_associative_math = true;
134}
135
136/* Get ready for options handling. Keep in sync with
137   libgfortran/runtime/compile_options.c (init_compile_options).  */
138
139void
140gfc_init_options (unsigned int decoded_options_count,
141		  struct cl_decoded_option *decoded_options)
142{
143  gfc_source_file = NULL;
144  gfc_option.module_dir = NULL;
145  gfc_option.source_form = FORM_UNKNOWN;
146  gfc_option.max_continue_fixed = 255;
147  gfc_option.max_continue_free = 255;
148  gfc_option.max_identifier_length = GFC_MAX_SYMBOL_LEN;
149  gfc_option.max_errors = 25;
150
151  gfc_option.flag_preprocessed = 0;
152  gfc_option.flag_d_lines = -1;
153  set_init_local_zero (0);
154
155  gfc_option.fpe = 0;
156  /* All except GFC_FPE_INEXACT.  */
157  gfc_option.fpe_summary = GFC_FPE_INVALID | GFC_FPE_DENORMAL
158			   | GFC_FPE_ZERO | GFC_FPE_OVERFLOW
159			   | GFC_FPE_UNDERFLOW;
160  gfc_option.rtcheck = 0;
161
162  set_dec_flags (0);
163  set_default_std_flags ();
164
165  /* Initialize cpp-related options.  */
166  gfc_cpp_init_options (decoded_options_count, decoded_options);
167  gfc_diagnostics_init ();
168}
169
170
171/* Determine the source form from the filename extension.  We assume
172   case insensitivity.  */
173
174static gfc_source_form
175form_from_filename (const char *filename)
176{
177  static const struct
178  {
179    const char *extension;
180    gfc_source_form form;
181  }
182  exttype[] =
183  {
184    {
185    ".f90", FORM_FREE}
186    ,
187    {
188    ".f95", FORM_FREE}
189    ,
190    {
191    ".f03", FORM_FREE}
192    ,
193    {
194    ".f08", FORM_FREE}
195    ,
196    {
197    ".f", FORM_FIXED}
198    ,
199    {
200    ".for", FORM_FIXED}
201    ,
202    {
203    ".ftn", FORM_FIXED}
204    ,
205    {
206    "", FORM_UNKNOWN}
207  };		/* sentinel value */
208
209  gfc_source_form f_form;
210  const char *fileext;
211  int i;
212
213  /* Find end of file name.  Note, filename is either a NULL pointer or
214     a NUL terminated string.  */
215  i = 0;
216  while (filename[i] != '\0')
217    i++;
218
219  /* Find last period.  */
220  while (i >= 0 && (filename[i] != '.'))
221    i--;
222
223  /* Did we see a file extension?  */
224  if (i < 0)
225    return FORM_UNKNOWN; /* Nope  */
226
227  /* Get file extension and compare it to others.  */
228  fileext = &(filename[i]);
229
230  i = -1;
231  f_form = FORM_UNKNOWN;
232  do
233    {
234      i++;
235      if (strcasecmp (fileext, exttype[i].extension) == 0)
236	{
237	  f_form = exttype[i].form;
238	  break;
239	}
240    }
241  while (exttype[i].form != FORM_UNKNOWN);
242
243  return f_form;
244}
245
246
247/* Finalize commandline options.  */
248
249bool
250gfc_post_options (const char **pfilename)
251{
252  const char *filename = *pfilename, *canon_source_file = NULL;
253  char *source_path;
254  bool verbose_missing_dir_warn;
255  int i;
256
257  /* This needs to be after the commandline has been processed.
258     In Fortran, the options is by default enabled, in C/C++
259     by default disabled.
260     If not enabled explicitly by the user, only warn for -I
261     and -J, otherwise warn for all include paths.  */
262  verbose_missing_dir_warn
263    = (OPTION_SET_P (cpp_warn_missing_include_dirs)
264       && global_options.x_cpp_warn_missing_include_dirs);
265  SET_OPTION_IF_UNSET (&global_options, &global_options_set,
266		       cpp_warn_missing_include_dirs, 1);
267  gfc_check_include_dirs (verbose_missing_dir_warn);
268
269  /* Finalize DEC flags.  */
270  post_dec_flags (flag_dec);
271
272  /* Excess precision other than "fast" requires front-end
273     support.  */
274  if (flag_excess_precision == EXCESS_PRECISION_STANDARD)
275    sorry ("%<-fexcess-precision=standard%> for Fortran");
276  else if (flag_excess_precision == EXCESS_PRECISION_FLOAT16)
277    sorry ("%<-fexcess-precision=16%> for Fortran");
278
279  flag_excess_precision = EXCESS_PRECISION_FAST;
280
281  /* Fortran allows associative math - but we cannot reassociate if
282     we want traps or signed zeros. Cf. also flag_protect_parens.  */
283  if (flag_associative_math == -1)
284    flag_associative_math = (!flag_trapping_math && !flag_signed_zeros);
285
286  if (flag_protect_parens == -1)
287    flag_protect_parens = !optimize_fast;
288
289  /* -Ofast sets implies -fstack-arrays unless an explicit size is set for
290     stack arrays.  */
291  if (flag_stack_arrays == -1 && flag_max_stack_var_size == -2)
292    flag_stack_arrays = optimize_fast;
293
294  /* By default, disable (re)allocation during assignment for -std=f95,
295     and enable it for F2003/F2008/GNU/Legacy.  */
296  if (flag_realloc_lhs == -1)
297    {
298      if (gfc_option.allow_std & GFC_STD_F2003)
299	flag_realloc_lhs = 1;
300      else
301	flag_realloc_lhs = 0;
302    }
303
304  /* -fbounds-check is equivalent to -fcheck=bounds */
305  if (flag_bounds_check)
306    gfc_option.rtcheck |= GFC_RTCHECK_BOUNDS;
307
308  if (flag_compare_debug)
309    flag_dump_fortran_original = 0;
310
311  /* Make -fmax-errors visible to gfortran's diagnostic machinery.  */
312  if (OPTION_SET_P (flag_max_errors))
313    gfc_option.max_errors = flag_max_errors;
314
315  /* Verify the input file name.  */
316  if (!filename || strcmp (filename, "-") == 0)
317    {
318      filename = "";
319    }
320
321  if (gfc_option.flag_preprocessed)
322    {
323      /* For preprocessed files, if the first tokens are of the form # NUM.
324	 handle the directives so we know the original file name.  */
325      gfc_source_file = gfc_read_orig_filename (filename, &canon_source_file);
326      if (gfc_source_file == NULL)
327	gfc_source_file = filename;
328      else
329	*pfilename = gfc_source_file;
330    }
331  else
332    gfc_source_file = filename;
333
334  if (canon_source_file == NULL)
335    canon_source_file = gfc_source_file;
336
337  /* Adds the path where the source file is to the list of include files.  */
338
339  i = strlen (canon_source_file);
340  while (i > 0 && !IS_DIR_SEPARATOR (canon_source_file[i]))
341    i--;
342
343  if (i != 0)
344    {
345      source_path = (char *) alloca (i + 1);
346      memcpy (source_path, canon_source_file, i);
347      source_path[i] = 0;
348      /* Only warn if the directory is different from the input file as
349	 if that one is not found, already an error is shown.  */
350      bool warn = gfc_option.flag_preprocessed && gfc_source_file != filename;
351      gfc_add_include_path (source_path, true, true, warn, false);
352    }
353  else
354    gfc_add_include_path (".", true, true, false, false);
355
356  if (canon_source_file != gfc_source_file)
357    free (CONST_CAST (char *, canon_source_file));
358
359  /* Decide which form the file will be read in as.  */
360
361  if (gfc_option.source_form != FORM_UNKNOWN)
362    gfc_current_form = gfc_option.source_form;
363  else
364    {
365      gfc_current_form = form_from_filename (filename);
366
367      if (gfc_current_form == FORM_UNKNOWN)
368	{
369	  gfc_current_form = FORM_FREE;
370	  main_input_filename = filename;
371	  gfc_warning_now (0, "Reading file %qs as free form",
372			   (filename[0] == '\0') ? "<stdin>" : filename);
373	}
374    }
375
376  /* If the user specified -fd-lines-as-{code|comments} verify that we're
377     in fixed form.  */
378  if (gfc_current_form == FORM_FREE)
379    {
380      if (gfc_option.flag_d_lines == 0)
381	gfc_warning_now (0, "%<-fd-lines-as-comments%> has no effect "
382			   "in free form");
383      else if (gfc_option.flag_d_lines == 1)
384	gfc_warning_now (0, "%<-fd-lines-as-code%> has no effect in free form");
385
386      if (warn_line_truncation == -1)
387	  warn_line_truncation = 1;
388
389      /* Enable -Werror=line-truncation when -Werror and -Wno-error have
390	 not been set.  */
391      if (warn_line_truncation && !OPTION_SET_P (warnings_are_errors)
392	  && (global_dc->classify_diagnostic[OPT_Wline_truncation] ==
393	      DK_UNSPECIFIED))
394	diagnostic_classify_diagnostic (global_dc, OPT_Wline_truncation,
395					DK_ERROR, UNKNOWN_LOCATION);
396    }
397  else
398    {
399      /* With -fdec, set -fd-lines-as-comments by default in fixed form.  */
400      if (flag_dec && gfc_option.flag_d_lines == -1)
401	gfc_option.flag_d_lines = 0;
402
403      if (warn_line_truncation == -1)
404	warn_line_truncation = 0;
405    }
406
407  /* If -pedantic, warn about the use of GNU extensions.  */
408  if (pedantic && (gfc_option.allow_std & GFC_STD_GNU) != 0)
409    gfc_option.warn_std |= GFC_STD_GNU;
410  /* -std=legacy -pedantic is effectively -std=gnu.  */
411  if (pedantic && (gfc_option.allow_std & GFC_STD_LEGACY) != 0)
412    gfc_option.warn_std |= GFC_STD_F95_OBS | GFC_STD_F95_DEL | GFC_STD_LEGACY;
413
414  /* If the user didn't explicitly specify -f(no)-second-underscore we
415     use it if we're trying to be compatible with f2c, and not
416     otherwise.  */
417  if (flag_second_underscore == -1)
418    flag_second_underscore = flag_f2c;
419
420  if (!flag_automatic && flag_max_stack_var_size != -2
421      && flag_max_stack_var_size != 0)
422    gfc_warning_now (0, "Flag %<-fno-automatic%> overwrites %<-fmax-stack-var-size=%d%>",
423		     flag_max_stack_var_size);
424  else if (!flag_automatic && flag_recursive)
425    gfc_warning_now (OPT_Woverwrite_recursive, "Flag %<-fno-automatic%> "
426		     "overwrites %<-frecursive%>");
427  else if (!flag_automatic && (flag_openmp || flag_openacc))
428    gfc_warning_now (0, "Flag %<-fno-automatic%> overwrites %<-frecursive%> "
429		     "implied by %qs", flag_openmp ? "-fopenmp" : "-fopenacc");
430  else if (flag_max_stack_var_size != -2 && flag_recursive)
431    gfc_warning_now (0, "Flag %<-frecursive%> overwrites %<-fmax-stack-var-size=%d%>",
432		     flag_max_stack_var_size);
433  else if (flag_max_stack_var_size != -2 && (flag_openmp || flag_openacc))
434    gfc_warning_now (0, "Flag %<-fmax-stack-var-size=%d%> overwrites "
435		     "%<-frecursive%> implied by %qs", flag_max_stack_var_size,
436		     flag_openmp ? "-fopenmp" : "-fopenacc");
437
438  /* Implement -frecursive as -fmax-stack-var-size=-1.  */
439  if (flag_recursive)
440    flag_max_stack_var_size = -1;
441
442  /* Implied -frecursive; implemented as -fmax-stack-var-size=-1.  */
443  if (flag_max_stack_var_size == -2 && flag_automatic
444      && (flag_openmp || flag_openacc))
445    {
446      flag_recursive = 1;
447      flag_max_stack_var_size = -1;
448    }
449
450  /* Set flag_stack_arrays correctly.  */
451  if (flag_stack_arrays == -1)
452    flag_stack_arrays = 0;
453
454  /* Set default.  */
455  if (flag_max_stack_var_size == -2)
456    flag_max_stack_var_size = 65536;
457
458  /* Implement -fno-automatic as -fmax-stack-var-size=0.  */
459  if (!flag_automatic)
460    flag_max_stack_var_size = 0;
461
462  /* If the user did not specify an inline matmul limit, inline up to the BLAS
463     limit or up to 30 if no external BLAS is specified.  */
464
465  if (flag_inline_matmul_limit < 0)
466    {
467      if (flag_external_blas)
468	flag_inline_matmul_limit = flag_blas_matmul_limit;
469      else
470	flag_inline_matmul_limit = 30;
471    }
472
473  /* Optimization implies front end optimization, unless the user
474     specified it directly.  */
475
476  if (flag_frontend_optimize == -1)
477    flag_frontend_optimize = optimize && !optimize_debug;
478
479  /* Same for front end loop interchange.  */
480
481  if (flag_frontend_loop_interchange == -1)
482    flag_frontend_loop_interchange = optimize;
483
484  /* Do inline packing by default if optimizing, but not if
485     optimizing for size.  */
486  if (flag_inline_arg_packing == -1)
487    flag_inline_arg_packing = optimize && !optimize_size;
488
489  if (flag_max_array_constructor < 65535)
490    flag_max_array_constructor = 65535;
491
492  if (flag_fixed_line_length != 0 && flag_fixed_line_length < 7)
493    gfc_fatal_error ("Fixed line length must be at least seven");
494
495  if (flag_free_line_length != 0 && flag_free_line_length < 4)
496    gfc_fatal_error ("Free line length must be at least three");
497
498  if (flag_max_subrecord_length > MAX_SUBRECORD_LENGTH)
499    gfc_fatal_error ("Maximum subrecord length cannot exceed %d",
500		     MAX_SUBRECORD_LENGTH);
501
502  gfc_cpp_post_options (verbose_missing_dir_warn);
503
504  if (gfc_option.allow_std & GFC_STD_F2008)
505    lang_hooks.name = "GNU Fortran2008";
506  else if (gfc_option.allow_std & GFC_STD_F2003)
507    lang_hooks.name = "GNU Fortran2003";
508
509  return gfc_cpp_preprocess_only ();
510}
511
512
513static void
514gfc_handle_module_path_options (const char *arg)
515{
516
517  if (gfc_option.module_dir != NULL)
518    gfc_fatal_error ("gfortran: Only one %<-J%> option allowed");
519
520  gfc_option.module_dir = XCNEWVEC (char, strlen (arg) + 2);
521  strcpy (gfc_option.module_dir, arg);
522
523  gfc_add_include_path (gfc_option.module_dir, true, false, true, true);
524
525  strcat (gfc_option.module_dir, "/");
526}
527
528
529/* Handle options -ffpe-trap= and -ffpe-summary=.  */
530
531static void
532gfc_handle_fpe_option (const char *arg, bool trap)
533{
534  int result, pos = 0, n;
535  /* precision is a backwards compatibility alias for inexact.  */
536  static const char * const exception[] = { "invalid", "denormal", "zero",
537					    "overflow", "underflow",
538					    "inexact", "precision", NULL };
539  static const int opt_exception[] = { GFC_FPE_INVALID, GFC_FPE_DENORMAL,
540				       GFC_FPE_ZERO, GFC_FPE_OVERFLOW,
541				       GFC_FPE_UNDERFLOW, GFC_FPE_INEXACT,
542				       GFC_FPE_INEXACT,
543				       0 };
544
545  /* As the default for -ffpe-summary= is nonzero, set it to 0.  */
546  if (!trap)
547    gfc_option.fpe_summary = 0;
548
549  while (*arg)
550    {
551      while (*arg == ',')
552	arg++;
553
554      while (arg[pos] && arg[pos] != ',')
555	pos++;
556
557      result = 0;
558      if (!trap && strncmp ("none", arg, pos) == 0)
559	{
560	  gfc_option.fpe_summary = 0;
561	  arg += pos;
562	  pos = 0;
563	  continue;
564	}
565      else if (!trap && strncmp ("all", arg, pos) == 0)
566	{
567	  gfc_option.fpe_summary = GFC_FPE_INVALID | GFC_FPE_DENORMAL
568				   | GFC_FPE_ZERO | GFC_FPE_OVERFLOW
569				   | GFC_FPE_UNDERFLOW | GFC_FPE_INEXACT;
570	  arg += pos;
571	  pos = 0;
572	  continue;
573	}
574      else
575	for (n = 0; exception[n] != NULL; n++)
576	  {
577	  if (exception[n] && strncmp (exception[n], arg, pos) == 0)
578	    {
579	      if (trap)
580		gfc_option.fpe |= opt_exception[n];
581	      else
582		gfc_option.fpe_summary |= opt_exception[n];
583	      arg += pos;
584	      pos = 0;
585	      result = 1;
586	      break;
587	    }
588	  }
589      if (!result && !trap)
590	gfc_fatal_error ("Argument to %<-ffpe-trap%> is not valid: %s", arg);
591      else if (!result)
592	gfc_fatal_error ("Argument to %<-ffpe-summary%> is not valid: %s", arg);
593
594    }
595}
596
597
598static void
599gfc_handle_runtime_check_option (const char *arg)
600{
601  int result, pos = 0, n;
602  static const char * const optname[] = { "all", "bounds", "array-temps",
603					  "recursion", "do", "pointer",
604					  "mem", "bits", NULL };
605  static const int optmask[] = { GFC_RTCHECK_ALL, GFC_RTCHECK_BOUNDS,
606				 GFC_RTCHECK_ARRAY_TEMPS,
607				 GFC_RTCHECK_RECURSION, GFC_RTCHECK_DO,
608				 GFC_RTCHECK_POINTER, GFC_RTCHECK_MEM,
609				 GFC_RTCHECK_BITS, 0 };
610
611  while (*arg)
612    {
613      while (*arg == ',')
614	arg++;
615
616      while (arg[pos] && arg[pos] != ',')
617	pos++;
618
619      result = 0;
620      for (n = 0; optname[n] != NULL; n++)
621	{
622	  if (optname[n] && strncmp (optname[n], arg, pos) == 0)
623	    {
624	      gfc_option.rtcheck |= optmask[n];
625	      arg += pos;
626	      pos = 0;
627	      result = 1;
628	      break;
629	    }
630	  else if (optname[n] && pos > 3 && startswith (arg, "no-")
631		   && strncmp (optname[n], arg+3, pos-3) == 0)
632	    {
633	      gfc_option.rtcheck &= ~optmask[n];
634	      arg += pos;
635	      pos = 0;
636	      result = 1;
637	      break;
638	    }
639	}
640      if (!result)
641	gfc_fatal_error ("Argument to %<-fcheck%> is not valid: %s", arg);
642    }
643}
644
645
646/* Handle command-line options.  Returns 0 if unrecognized, 1 if
647   recognized and handled.  */
648
649bool
650gfc_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
651		   int kind ATTRIBUTE_UNUSED, location_t loc ATTRIBUTE_UNUSED,
652		   const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED)
653{
654  bool result = true;
655  enum opt_code code = (enum opt_code) scode;
656
657  if (gfc_cpp_handle_option (scode, arg, value) == 1)
658    return true;
659
660  switch (code)
661    {
662    default:
663      if (cl_options[code].flags & gfc_option_lang_mask ())
664	break;
665      result = false;
666      break;
667
668    case OPT_fcheck_array_temporaries:
669      SET_BITFLAG (gfc_option.rtcheck, value, GFC_RTCHECK_ARRAY_TEMPS);
670      break;
671
672    case OPT_fd_lines_as_code:
673      gfc_option.flag_d_lines = 1;
674      break;
675
676    case OPT_fd_lines_as_comments:
677      gfc_option.flag_d_lines = 0;
678      break;
679
680    case OPT_ffixed_form:
681      gfc_option.source_form = FORM_FIXED;
682      break;
683
684    case OPT_ffree_form:
685      gfc_option.source_form = FORM_FREE;
686      break;
687
688    case OPT_static_libgfortran:
689#ifndef HAVE_LD_STATIC_DYNAMIC
690      gfc_fatal_error ("%<-static-libgfortran%> is not supported in this "
691		       "configuration");
692#endif
693      break;
694
695    case OPT_fintrinsic_modules_path:
696    case OPT_fintrinsic_modules_path_:
697
698      /* This is needed because omp_lib.h is in a directory together
699	 with intrinsic modules.  Do no warn because during testing
700	 without an installed compiler, we would get lots of bogus
701	 warnings for a missing include directory.  */
702      gfc_add_include_path (arg, false, false, false, true);
703
704      gfc_add_intrinsic_modules_path (arg);
705      break;
706
707    case OPT_fpreprocessed:
708      gfc_option.flag_preprocessed = value;
709      break;
710
711    case OPT_fmax_identifier_length_:
712      if (value > GFC_MAX_SYMBOL_LEN)
713	gfc_fatal_error ("Maximum supported identifier length is %d",
714			 GFC_MAX_SYMBOL_LEN);
715      gfc_option.max_identifier_length = value;
716      break;
717
718    case OPT_finit_local_zero:
719      set_init_local_zero (value);
720      break;
721
722    case OPT_finit_logical_:
723      if (!strcasecmp (arg, "false"))
724	gfc_option.flag_init_logical = GFC_INIT_LOGICAL_FALSE;
725      else if (!strcasecmp (arg, "true"))
726	gfc_option.flag_init_logical = GFC_INIT_LOGICAL_TRUE;
727      else
728	gfc_fatal_error ("Unrecognized option to %<-finit-logical%>: %s",
729			 arg);
730      break;
731
732    case OPT_finit_integer_:
733      gfc_option.flag_init_integer = GFC_INIT_INTEGER_ON;
734      gfc_option.flag_init_integer_value = strtol (arg, NULL, 10);
735      break;
736
737    case OPT_finit_character_:
738      if (value >= 0 && value <= 127)
739	{
740	  gfc_option.flag_init_character = GFC_INIT_CHARACTER_ON;
741	  gfc_option.flag_init_character_value = (char)value;
742	}
743      else
744	gfc_fatal_error ("The value of n in %<-finit-character=n%> must be "
745			 "between 0 and 127");
746      break;
747
748    case OPT_I:
749      gfc_add_include_path (arg, true, false, true, true);
750      break;
751
752    case OPT_J:
753      gfc_handle_module_path_options (arg);
754      break;
755
756    case OPT_ffpe_trap_:
757      gfc_handle_fpe_option (arg, true);
758      break;
759
760    case OPT_ffpe_summary_:
761      gfc_handle_fpe_option (arg, false);
762      break;
763
764    case OPT_std_f95:
765      gfc_option.allow_std = GFC_STD_OPT_F95;
766      gfc_option.warn_std = GFC_STD_F95_OBS;
767      gfc_option.max_continue_fixed = 19;
768      gfc_option.max_continue_free = 39;
769      gfc_option.max_identifier_length = 31;
770      warn_ampersand = 1;
771      warn_tabs = 1;
772      break;
773
774    case OPT_std_f2003:
775      gfc_option.allow_std = GFC_STD_OPT_F03;
776      gfc_option.warn_std = GFC_STD_F95_OBS;
777      gfc_option.max_identifier_length = 63;
778      warn_ampersand = 1;
779      warn_tabs = 1;
780      break;
781
782    case OPT_std_f2008:
783      gfc_option.allow_std = GFC_STD_OPT_F08;
784      gfc_option.warn_std = GFC_STD_F95_OBS | GFC_STD_F2008_OBS;
785      gfc_option.max_identifier_length = 63;
786      warn_ampersand = 1;
787      warn_tabs = 1;
788      break;
789
790    case OPT_std_f2008ts:
791    case OPT_std_f2018:
792      gfc_option.allow_std = GFC_STD_OPT_F18;
793      gfc_option.warn_std = GFC_STD_F95_OBS | GFC_STD_F2008_OBS
794	| GFC_STD_F2018_OBS;
795      gfc_option.max_identifier_length = 63;
796      warn_ampersand = 1;
797      warn_tabs = 1;
798      break;
799
800    case OPT_std_gnu:
801      set_default_std_flags ();
802      break;
803
804    case OPT_std_legacy:
805      set_default_std_flags ();
806      gfc_option.warn_std = 0;
807      break;
808
809    case OPT_fshort_enums:
810      /* Handled in language-independent code.  */
811      break;
812
813    case OPT_fcheck_:
814      gfc_handle_runtime_check_option (arg);
815      break;
816
817    case OPT_fdec:
818      /* Set (or unset) the DEC extension flags.  */
819      set_dec_flags (value);
820      break;
821    }
822
823  Fortran_handle_option_auto (&global_options, &global_options_set,
824                              scode, arg, value,
825                              gfc_option_lang_mask (), kind,
826                              loc, handlers, global_dc);
827  return result;
828}
829
830
831/* Return a string with the options passed to the compiler; used for
832   Fortran's compiler_options() intrinsic.  */
833
834char *
835gfc_get_option_string (void)
836{
837  unsigned j;
838  size_t len, pos;
839  char *result;
840
841  /* Allocate and return a one-character string with '\0'.  */
842  if (!save_decoded_options_count)
843    return XCNEWVEC (char, 1);
844
845  /* Determine required string length.  */
846
847  len = 0;
848  for (j = 1; j < save_decoded_options_count; j++)
849    {
850      switch (save_decoded_options[j].opt_index)
851        {
852        case OPT_o:
853        case OPT_d:
854        case OPT_dumpbase:
855        case OPT_dumpbase_ext:
856        case OPT_dumpdir:
857        case OPT_quiet:
858        case OPT_version:
859        case OPT_fintrinsic_modules_path:
860        case OPT_fintrinsic_modules_path_:
861          /* Ignore these.  */
862          break;
863	default:
864	  /* Ignore file names.  */
865	  if (save_decoded_options[j].orig_option_with_args_text[0] == '-')
866	    len += 1
867		 + strlen (save_decoded_options[j].orig_option_with_args_text);
868        }
869    }
870
871  result = XCNEWVEC (char, len);
872
873  pos = 0;
874  for (j = 1; j < save_decoded_options_count; j++)
875    {
876      switch (save_decoded_options[j].opt_index)
877        {
878        case OPT_o:
879        case OPT_d:
880        case OPT_dumpbase:
881        case OPT_dumpbase_ext:
882        case OPT_dumpdir:
883        case OPT_quiet:
884        case OPT_version:
885        case OPT_fintrinsic_modules_path:
886        case OPT_fintrinsic_modules_path_:
887          /* Ignore these.  */
888	  continue;
889
890        case OPT_cpp_:
891	  /* Use "-cpp" rather than "-cpp=<temporary file>".  */
892	  len = 4;
893	  break;
894
895        default:
896	  /* Ignore file names.  */
897	  if (save_decoded_options[j].orig_option_with_args_text[0] != '-')
898	    continue;
899
900	  len = strlen (save_decoded_options[j].orig_option_with_args_text);
901        }
902
903      memcpy (&result[pos], save_decoded_options[j].orig_option_with_args_text, len);
904      pos += len;
905      result[pos++] = ' ';
906    }
907
908  result[--pos] = '\0';
909  return result;
910}
911
912#undef SET_BITFLAG
913#undef SET_BITFLAG2
914#undef SET_FLAG
915