options.c 21.9 KB
Newer Older
1
/* Parse and display command line options.
Jakub Jelinek committed
2
   Copyright (C) 2000-2015 Free Software Foundation, Inc.
3 4
   Contributed by Andy Vaught

5
This file is part of GCC.
6

7 8
GCC is free software; you can redistribute it and/or modify it under
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 13 14 15
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.
16 17

You should have received a copy of the GNU General Public License
18 19
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */
20 21 22 23

#include "config.h"
#include "system.h"
#include "coretypes.h"
24 25 26 27 28 29 30 31 32 33
#include "hash-set.h"
#include "machmode.h"
#include "vec.h"
#include "double-int.h"
#include "input.h"
#include "alias.h"
#include "symtab.h"
#include "options.h"
#include "wide-int.h"
#include "inchash.h"
34 35 36 37
#include "tree.h"
#include "flags.h"
#include "intl.h"
#include "opts.h"
38
#include "toplev.h"  /* For save_decoded_options.  */
39
#include "params.h"
40 41
#include "tree-inline.h"
#include "gfortran.h"
42
#include "target.h"
43
#include "cpp.h"
44
#include "diagnostic.h"	/* For global_dc.  */
45
#include "tm.h"
46
#include "langhooks.h"
47 48 49 50

gfc_option_t gfc_option;


51
/* Set flags that control warnings and errors for different
52 53
   Fortran standards to their default values.  Keep in sync with
   libgfortran/runtime/compile_options.c (init_compile_options).  */
54 55 56 57 58

static void
set_default_std_flags (void)
{
  gfc_option.allow_std = GFC_STD_F95_OBS | GFC_STD_F95_DEL
59
    | GFC_STD_F2003 | GFC_STD_F2008 | GFC_STD_F95 | GFC_STD_F77
60
    | GFC_STD_F2008_OBS | GFC_STD_F2008_TS | GFC_STD_GNU | GFC_STD_LEGACY;
61 62 63
  gfc_option.warn_std = GFC_STD_F95_DEL | GFC_STD_LEGACY;
}

64

65 66 67 68 69 70 71 72
/* Return language mask for Fortran options.  */

unsigned int
gfc_option_lang_mask (void)
{
  return CL_Fortran;
}

73 74 75 76 77 78
/* Initialize options structure OPTS.  */

void
gfc_init_options_struct (struct gcc_options *opts)
{
  opts->x_flag_errno_math = 0;
79
  opts->frontend_set_flag_errno_math = true;
80
  opts->x_flag_associative_math = -1;
81
  opts->frontend_set_flag_associative_math = true;
82
}
83

84
/* Get ready for options handling. Keep in sync with
85
   libgfortran/runtime/compile_options.c (init_compile_options).  */
86

87 88 89
void
gfc_init_options (unsigned int decoded_options_count,
		  struct cl_decoded_option *decoded_options)
90
{
91
  gfc_source_file = NULL;
92 93
  gfc_option.module_dir = NULL;
  gfc_option.source_form = FORM_UNKNOWN;
94 95
  gfc_option.max_continue_fixed = 255;
  gfc_option.max_continue_free = 255;
96
  gfc_option.max_identifier_length = GFC_MAX_SYMBOL_LEN;
97
  gfc_option.max_errors = 25;
98

99
  gfc_option.flag_preprocessed = 0;
100
  gfc_option.flag_d_lines = -1;
101 102 103 104 105 106
  gfc_option.flag_init_integer = GFC_INIT_INTEGER_OFF;
  gfc_option.flag_init_integer_value = 0;
  gfc_option.flag_init_logical = GFC_INIT_LOGICAL_OFF;
  gfc_option.flag_init_character = GFC_INIT_CHARACTER_OFF;
  gfc_option.flag_init_character_value = (char)0;
  
107
  gfc_option.fpe = 0;
108 109 110 111
  /* All except GFC_FPE_INEXACT.  */
  gfc_option.fpe_summary = GFC_FPE_INVALID | GFC_FPE_DENORMAL
			   | GFC_FPE_ZERO | GFC_FPE_OVERFLOW
			   | GFC_FPE_UNDERFLOW;
112
  gfc_option.rtcheck = 0;
113

114 115 116 117
  /* ??? Wmissing-include-dirs is disabled by default in C/C++ but
     enabled by default in Fortran.  Ideally, we should express this
     in .opt, but that is not supported yet.  */
  if (!global_options_set.x_cpp_warn_missing_include_dirs)
118
    global_options.x_cpp_warn_missing_include_dirs = 1;
119

120
  set_default_std_flags ();
121

122
  /* Initialize cpp-related options.  */
123
  gfc_cpp_init_options (decoded_options_count, decoded_options);
124
  gfc_diagnostics_init ();
125 126 127
}


128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
/* Determine the source form from the filename extension.  We assume
   case insensitivity.  */

static gfc_source_form
form_from_filename (const char *filename)
{
  static const struct
  {
    const char *extension;
    gfc_source_form form;
  }
  exttype[] =
  {
    {
    ".f90", FORM_FREE}
    ,
    {
    ".f95", FORM_FREE}
    ,
    {
148 149 150
    ".f03", FORM_FREE}
    ,
    {
151 152 153
    ".f08", FORM_FREE}
    ,
    {
154 155 156 157 158 159
    ".f", FORM_FIXED}
    ,
    {
    ".for", FORM_FIXED}
    ,
    {
160 161 162
    ".ftn", FORM_FIXED}
    ,
    {
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203
    "", FORM_UNKNOWN}
  };		/* sentinel value */

  gfc_source_form f_form;
  const char *fileext;
  int i;

  /* Find end of file name.  Note, filename is either a NULL pointer or
     a NUL terminated string.  */
  i = 0;
  while (filename[i] != '\0')
    i++;

  /* Find last period.  */
  while (i >= 0 && (filename[i] != '.'))
    i--;

  /* Did we see a file extension?  */
  if (i < 0)
    return FORM_UNKNOWN; /* Nope  */

  /* Get file extension and compare it to others.  */
  fileext = &(filename[i]);

  i = -1;
  f_form = FORM_UNKNOWN;
  do
    {
      i++;
      if (strcasecmp (fileext, exttype[i].extension) == 0)
	{
	  f_form = exttype[i].form;
	  break;
	}
    }
  while (exttype[i].form != FORM_UNKNOWN);

  return f_form;
}


204 205 206 207 208
/* Finalize commandline options.  */

bool
gfc_post_options (const char **pfilename)
{
209
  const char *filename = *pfilename, *canon_source_file = NULL;
210 211
  char *source_path;
  int i;
212

213 214 215 216 217 218 219
  /* Excess precision other than "fast" requires front-end
     support.  */
  if (flag_excess_precision_cmdline == EXCESS_PRECISION_STANDARD
      && TARGET_FLT_EVAL_METHOD_NON_DEFAULT)
    sorry ("-fexcess-precision=standard for Fortran");
  flag_excess_precision_cmdline = EXCESS_PRECISION_FAST;

220 221 222 223 224
  /* Fortran allows associative math - but we cannot reassociate if
     we want traps or signed zeros. Cf. also flag_protect_parens.  */
  if (flag_associative_math == -1)
    flag_associative_math = (!flag_trapping_math && !flag_signed_zeros);

225 226
  if (flag_protect_parens == -1)
    flag_protect_parens = !optimize_fast;
227

228 229
  if (flag_stack_arrays == -1)
    flag_stack_arrays = optimize_fast;
230

231
  /* By default, disable (re)allocation during assignment for -std=f95,
232
     and enable it for F2003/F2008/GNU/Legacy.  */
233
  if (flag_realloc_lhs == -1)
234 235
    {
      if (gfc_option.allow_std & GFC_STD_F2003)
236
	flag_realloc_lhs = 1;
237
      else
238
	flag_realloc_lhs = 0;
239 240
    }

241 242 243 244
  /* -fbounds-check is equivalent to -fcheck=bounds */
  if (flag_bounds_check)
    gfc_option.rtcheck |= GFC_RTCHECK_BOUNDS;

245
  if (flag_compare_debug)
246
    flag_dump_fortran_original = 0;
247

248 249 250 251
  /* Make -fmax-errors visible to gfortran's diagnostic machinery.  */
  if (global_options_set.x_flag_max_errors)
    gfc_option.max_errors = flag_max_errors;

252 253 254 255 256 257
  /* Verify the input file name.  */
  if (!filename || strcmp (filename, "-") == 0)
    {
      filename = "";
    }

258 259 260 261 262 263 264 265 266 267 268 269 270 271 272
  if (gfc_option.flag_preprocessed)
    {
      /* For preprocessed files, if the first tokens are of the form # NUM.
	 handle the directives so we know the original file name.  */
      gfc_source_file = gfc_read_orig_filename (filename, &canon_source_file);
      if (gfc_source_file == NULL)
	gfc_source_file = filename;
      else
	*pfilename = gfc_source_file;
    }
  else
    gfc_source_file = filename;

  if (canon_source_file == NULL)
    canon_source_file = gfc_source_file;
273

274 275
  /* Adds the path where the source file is to the list of include files.  */

276 277
  i = strlen (canon_source_file);
  while (i > 0 && !IS_DIR_SEPARATOR (canon_source_file[i]))
278
    i--;
279

280 281
  if (i != 0)
    {
282
      source_path = (char *) alloca (i + 1);
283
      memcpy (source_path, canon_source_file, i);
284
      source_path[i] = 0;
285
      gfc_add_include_path (source_path, true, true, true);
286 287
    }
  else
288
    gfc_add_include_path (".", true, true, true);
289

290
  if (canon_source_file != gfc_source_file)
291
    free (CONST_CAST (char *, canon_source_file));
292

293 294 295 296 297 298 299 300 301 302 303
  /* Decide which form the file will be read in as.  */

  if (gfc_option.source_form != FORM_UNKNOWN)
    gfc_current_form = gfc_option.source_form;
  else
    {
      gfc_current_form = form_from_filename (filename);

      if (gfc_current_form == FORM_UNKNOWN)
	{
	  gfc_current_form = FORM_FREE;
304
	  gfc_warning_now (0, "Reading file %qs as free form", 
305
			   (filename[0] == '\0') ? "<stdin>" : filename);
306 307 308 309 310 311 312 313
	}
    }

  /* If the user specified -fd-lines-as-{code|comments} verify that we're
     in fixed form.  */
  if (gfc_current_form == FORM_FREE)
    {
      if (gfc_option.flag_d_lines == 0)
314
	gfc_warning_now (0, "%<-fd-lines-as-comments%> has no effect "
315
			   "in free form");
316
      else if (gfc_option.flag_d_lines == 1)
317
	gfc_warning_now (0, "%<-fd-lines-as-code%> has no effect in free form");
318 319 320 321 322 323 324 325 326 327 328

      if (warn_line_truncation == -1)
	  warn_line_truncation = 1;

      /* Enable -Werror=line-truncation when -Werror and -Wno-error have
	 not been set.  */
      if (warn_line_truncation && !global_options_set.x_warnings_are_errors
	  && (global_dc->classify_diagnostic[OPT_Wline_truncation] ==
	      DK_UNSPECIFIED))
	diagnostic_classify_diagnostic (global_dc, OPT_Wline_truncation,
					DK_ERROR, UNKNOWN_LOCATION);
329
    }
330 331
  else if (warn_line_truncation == -1)
    warn_line_truncation = 0;
332

333 334 335
  /* If -pedantic, warn about the use of GNU extensions.  */
  if (pedantic && (gfc_option.allow_std & GFC_STD_GNU) != 0)
    gfc_option.warn_std |= GFC_STD_GNU;
336 337 338
  /* -std=legacy -pedantic is effectively -std=gnu.  */
  if (pedantic && (gfc_option.allow_std & GFC_STD_LEGACY) != 0)
    gfc_option.warn_std |= GFC_STD_F95_OBS | GFC_STD_F95_DEL | GFC_STD_LEGACY;
339

340 341 342
  /* If the user didn't explicitly specify -f(no)-second-underscore we
     use it if we're trying to be compatible with f2c, and not
     otherwise.  */
343
  if (flag_second_underscore == -1)
344
    flag_second_underscore = flag_f2c;
345

346
  if (!flag_automatic && flag_max_stack_var_size != -2
347
      && flag_max_stack_var_size != 0)
348
    gfc_warning_now (0, "Flag %<-fno-automatic%> overwrites %<-fmax-stack-var-size=%d%>",
349
		     flag_max_stack_var_size);
350
  else if (!flag_automatic && flag_recursive)
351
    gfc_warning_now (0, "Flag %<-fno-automatic%> overwrites %<-frecursive%>");
352
  else if (!flag_automatic && flag_openmp)
353
    gfc_warning_now (0, "Flag %<-fno-automatic%> overwrites %<-frecursive%> implied by "
354
		     "%<-fopenmp%>");
355
  else if (flag_max_stack_var_size != -2 && flag_recursive)
356
    gfc_warning_now (0, "Flag %<-frecursive%> overwrites %<-fmax-stack-var-size=%d%>",
357
		     flag_max_stack_var_size);
358
  else if (flag_max_stack_var_size != -2 && flag_openmp)
359
    gfc_warning_now (0, "Flag %<-fmax-stack-var-size=%d%> overwrites %<-frecursive%> "
360
		     "implied by %<-fopenmp%>", flag_max_stack_var_size);
361

362
  /* Implement -frecursive as -fmax-stack-var-size=-1.  */
363
  if (flag_recursive)
364
    flag_max_stack_var_size = -1;
365

366
  /* Implied -frecursive; implemented as -fmax-stack-var-size=-1.  */
367
  if (flag_max_stack_var_size == -2 && flag_openmp && flag_automatic)
368
    {
369
      flag_recursive = 1;
370
      flag_max_stack_var_size = -1;
371 372
    }

373
  /* Set default.  */
374 375
  if (flag_max_stack_var_size == -2)
    flag_max_stack_var_size = 32768;
376

377
  /* Implement -fno-automatic as -fmax-stack-var-size=0.  */
378
  if (!flag_automatic)
379
    flag_max_stack_var_size = 0;
380
  
381 382 383 384 385
  /* If we call BLAS directly, only inline up to the BLAS limit.  */

  if (flag_external_blas && flag_inline_matmul_limit < 0)
    flag_inline_matmul_limit = flag_blas_matmul_limit;

386 387 388
  /* Optimization implies front end optimization, unless the user
     specified it directly.  */

389 390 391
  if (flag_frontend_optimize == -1)
    flag_frontend_optimize = optimize;

392 393 394
  if (flag_max_array_constructor < 65535)
    flag_max_array_constructor = 65535;

395 396 397 398 399 400 401 402 403
  if (flag_fixed_line_length != 0 && flag_fixed_line_length < 7)
    gfc_fatal_error ("Fixed line length must be at least seven");

  if (flag_free_line_length != 0 && flag_free_line_length < 4)
    gfc_fatal_error ("Free line length must be at least three");

  if (flag_max_subrecord_length > MAX_SUBRECORD_LENGTH)
    gfc_fatal_error ("Maximum subrecord length cannot exceed %d",
		     MAX_SUBRECORD_LENGTH);
404

405 406
  gfc_cpp_post_options ();

407 408 409 410 411
  if (gfc_option.allow_std & GFC_STD_F2008)
    lang_hooks.name = "GNU Fortran2008";
  else if (gfc_option.allow_std & GFC_STD_F2003)
    lang_hooks.name = "GNU Fortran2003";

412
  return gfc_cpp_preprocess_only ();
413 414 415 416 417 418 419 420
}


static void
gfc_handle_module_path_options (const char *arg)
{

  if (gfc_option.module_dir != NULL)
421
    gfc_fatal_error ("gfortran: Only one %<-J%> option allowed");
422

423
  gfc_option.module_dir = XCNEWVEC (char, strlen (arg) + 2);
424
  strcpy (gfc_option.module_dir, arg);
425

426
  gfc_add_include_path (gfc_option.module_dir, true, false, true);
427 428

  strcat (gfc_option.module_dir, "/");
429 430
}

431

432 433
/* Handle options -ffpe-trap= and -ffpe-summary=.  */

434
static void
435
gfc_handle_fpe_option (const char *arg, bool trap)
436 437
{
  int result, pos = 0, n;
438
  /* precision is a backwards compatibility alias for inexact.  */
439
  static const char * const exception[] = { "invalid", "denormal", "zero",
440
					    "overflow", "underflow",
441
					    "inexact", "precision", NULL };
442 443
  static const int opt_exception[] = { GFC_FPE_INVALID, GFC_FPE_DENORMAL,
				       GFC_FPE_ZERO, GFC_FPE_OVERFLOW,
444 445
				       GFC_FPE_UNDERFLOW, GFC_FPE_INEXACT,
				       GFC_FPE_INEXACT,
446
				       0 };
447

448
  /* As the default for -ffpe-summary= is nonzero, set it to 0.  */
449 450 451
  if (!trap)
    gfc_option.fpe_summary = 0;

452 453 454 455
  while (*arg)
    {
      while (*arg == ',')
	arg++;
456

457 458
      while (arg[pos] && arg[pos] != ',')
	pos++;
459

460
      result = 0;
461
      if (!trap && strncmp ("none", arg, pos) == 0)
462
	{
463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479
	  gfc_option.fpe_summary = 0;
	  arg += pos;
	  pos = 0;
	  continue;
	}
      else if (!trap && strncmp ("all", arg, pos) == 0)
	{
	  gfc_option.fpe_summary = GFC_FPE_INVALID | GFC_FPE_DENORMAL
				   | GFC_FPE_ZERO | GFC_FPE_OVERFLOW
				   | GFC_FPE_UNDERFLOW | GFC_FPE_INEXACT;
	  arg += pos;
	  pos = 0;
	  continue;
	}
      else
	for (n = 0; exception[n] != NULL; n++)
	  {
480 481
	  if (exception[n] && strncmp (exception[n], arg, pos) == 0)
	    {
482 483 484 485
	      if (trap)
		gfc_option.fpe |= opt_exception[n];
	      else
		gfc_option.fpe_summary |= opt_exception[n];
486 487 488 489 490
	      arg += pos;
	      pos = 0;
	      result = 1;
	      break;
	    }
491 492
	  }
      if (!result && !trap)
493
	gfc_fatal_error ("Argument to %<-ffpe-trap%> is not valid: %s", arg);
494
      else if (!result)
495
	gfc_fatal_error ("Argument to %<-ffpe-summary%> is not valid: %s", arg);
496

497 498 499
    }
}

500

501 502 503 504 505
static void
gfc_handle_runtime_check_option (const char *arg)
{
  int result, pos = 0, n;
  static const char * const optname[] = { "all", "bounds", "array-temps",
506 507
					  "recursion", "do", "pointer",
					  "mem", NULL };
508 509
  static const int optmask[] = { GFC_RTCHECK_ALL, GFC_RTCHECK_BOUNDS,
				 GFC_RTCHECK_ARRAY_TEMPS,
510
				 GFC_RTCHECK_RECURSION, GFC_RTCHECK_DO,
511
				 GFC_RTCHECK_POINTER, GFC_RTCHECK_MEM,
512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534
				 0 };
 
  while (*arg)
    {
      while (*arg == ',')
	arg++;

      while (arg[pos] && arg[pos] != ',')
	pos++;

      result = 0;
      for (n = 0; optname[n] != NULL; n++)
	{
	  if (optname[n] && strncmp (optname[n], arg, pos) == 0)
	    {
	      gfc_option.rtcheck |= optmask[n];
	      arg += pos;
	      pos = 0;
	      result = 1;
	      break;
	    }
	}
      if (!result)
535
	gfc_fatal_error ("Argument to %<-fcheck%> is not valid: %s", arg);
536 537 538 539
    }
}


540 541
/* Handle command-line options.  Returns 0 if unrecognized, 1 if
   recognized and handled.  */
542

543
bool
544
gfc_handle_option (size_t scode, const char *arg, int value,
545
		   int kind ATTRIBUTE_UNUSED, location_t loc ATTRIBUTE_UNUSED,
546
		   const struct cl_option_handlers *handlers ATTRIBUTE_UNUSED)
547
{
548
  bool result = true;
549 550
  enum opt_code code = (enum opt_code) scode;

551
  if (gfc_cpp_handle_option (scode, arg, value) == 1)
552
    return true;
553

554 555 556
  switch (code)
    {
    default:
557 558
      if (cl_options[code].flags & gfc_option_lang_mask ())
	break;
559
      result = false;
560 561
      break;

562
    case OPT_fcheck_array_temporaries:
563
      gfc_option.rtcheck |= GFC_RTCHECK_ARRAY_TEMPS;
564 565
      break;
      
566 567 568 569 570 571 572 573
    case OPT_fd_lines_as_code:
      gfc_option.flag_d_lines = 1;
      break;

    case OPT_fd_lines_as_comments:
      gfc_option.flag_d_lines = 0;
      break;

574 575 576 577 578 579 580 581
    case OPT_ffixed_form:
      gfc_option.source_form = FORM_FIXED;
      break;

    case OPT_ffree_form:
      gfc_option.source_form = FORM_FREE;
      break;

582 583
    case OPT_static_libgfortran:
#ifndef HAVE_LD_STATIC_DYNAMIC
584
      gfc_fatal_error ("%<-static-libgfortran%> is not supported in this "
585 586 587 588
		       "configuration");
#endif
      break;

589
    case OPT_fintrinsic_modules_path:
590
    case OPT_fintrinsic_modules_path_:
591 592 593 594 595 596 597

      /* This is needed because omp_lib.h is in a directory together
	 with intrinsic modules.  Do no warn because during testing
	 without an installed compiler, we would get lots of bogus
	 warnings for a missing include directory.  */
      gfc_add_include_path (arg, false, false, false);

598 599 600
      gfc_add_intrinsic_modules_path (arg);
      break;

601 602 603 604
    case OPT_fpreprocessed:
      gfc_option.flag_preprocessed = value;
      break;

605 606
    case OPT_fmax_identifier_length_:
      if (value > GFC_MAX_SYMBOL_LEN)
607
	gfc_fatal_error ("Maximum supported identifier length is %d",
608 609 610 611
			 GFC_MAX_SYMBOL_LEN);
      gfc_option.max_identifier_length = value;
      break;

612 613 614
    case OPT_finit_local_zero:
      gfc_option.flag_init_integer = GFC_INIT_INTEGER_ON;
      gfc_option.flag_init_integer_value = 0;
615
      flag_init_real = GFC_INIT_REAL_ZERO;
616 617 618 619 620 621 622 623 624 625 626
      gfc_option.flag_init_logical = GFC_INIT_LOGICAL_FALSE;
      gfc_option.flag_init_character = GFC_INIT_CHARACTER_ON;
      gfc_option.flag_init_character_value = (char)0;
      break;

    case OPT_finit_logical_:
      if (!strcasecmp (arg, "false"))
	gfc_option.flag_init_logical = GFC_INIT_LOGICAL_FALSE;
      else if (!strcasecmp (arg, "true"))
	gfc_option.flag_init_logical = GFC_INIT_LOGICAL_TRUE;
      else
627
	gfc_fatal_error ("Unrecognized option to %<-finit-logical%>: %s",
628 629 630 631 632 633 634 635 636 637 638 639 640 641 642
			 arg);
      break;

    case OPT_finit_integer_:
      gfc_option.flag_init_integer = GFC_INIT_INTEGER_ON;
      gfc_option.flag_init_integer_value = atoi (arg);
      break;

    case OPT_finit_character_:
      if (value >= 0 && value <= 127)
	{
	  gfc_option.flag_init_character = GFC_INIT_CHARACTER_ON;
	  gfc_option.flag_init_character_value = (char)value;
	}
      else
643
	gfc_fatal_error ("The value of n in %<-finit-character=n%> must be "
644 645 646
			 "between 0 and 127");
      break;

647
    case OPT_I:
648
      gfc_add_include_path (arg, true, false, true);
649 650 651 652
      break;

    case OPT_J:
      gfc_handle_module_path_options (arg);
653
      break;
654

655
    case OPT_ffpe_trap_:
656 657 658 659 660
      gfc_handle_fpe_option (arg, true);
      break;

    case OPT_ffpe_summary_:
      gfc_handle_fpe_option (arg, false);
661 662
      break;

663
    case OPT_std_f95:
664 665
      gfc_option.allow_std = GFC_STD_F95_OBS | GFC_STD_F95 | GFC_STD_F77
			     | GFC_STD_F2008_OBS;
666
      gfc_option.warn_std = GFC_STD_F95_OBS;
667 668
      gfc_option.max_continue_fixed = 19;
      gfc_option.max_continue_free = 39;
669
      gfc_option.max_identifier_length = 31;
670
      warn_ampersand = 1;
671
      warn_tabs = 1;
672 673 674
      break;

    case OPT_std_f2003:
675
      gfc_option.allow_std = GFC_STD_F95_OBS | GFC_STD_F77 
676
	| GFC_STD_F2003 | GFC_STD_F95 | GFC_STD_F2008_OBS;
677
      gfc_option.warn_std = GFC_STD_F95_OBS;
678
      gfc_option.max_identifier_length = 63;
679
      warn_ampersand = 1;
680
      warn_tabs = 1;
681 682
      break;

683 684
    case OPT_std_f2008:
      gfc_option.allow_std = GFC_STD_F95_OBS | GFC_STD_F77 
685 686
	| GFC_STD_F2003 | GFC_STD_F95 | GFC_STD_F2008 | GFC_STD_F2008_OBS;
      gfc_option.warn_std = GFC_STD_F95_OBS | GFC_STD_F2008_OBS;
687
      gfc_option.max_identifier_length = 63;
688
      warn_ampersand = 1;
689
      warn_tabs = 1;
690 691
      break;

692
    case OPT_std_f2008ts:
693 694
      gfc_option.allow_std = GFC_STD_F95_OBS | GFC_STD_F77 
	| GFC_STD_F2003 | GFC_STD_F95 | GFC_STD_F2008 | GFC_STD_F2008_OBS
695
	| GFC_STD_F2008_TS;
696 697
      gfc_option.warn_std = GFC_STD_F95_OBS | GFC_STD_F2008_OBS;
      gfc_option.max_identifier_length = 63;
698
      warn_ampersand = 1;
699
      warn_tabs = 1;
700 701
      break;

702
    case OPT_std_gnu:
703
      set_default_std_flags ();
704 705 706
      break;

    case OPT_std_legacy:
707
      set_default_std_flags ();
708
      gfc_option.warn_std = 0;
709 710
      break;

711
    case OPT_fshort_enums:
712
      /* Handled in language-independent code.  */
713
      break;
714

715 716 717
    case OPT_fcheck_:
      gfc_handle_runtime_check_option (arg);
      break;
718 719
    }

720 721 722 723
  Fortran_handle_option_auto (&global_options, &global_options_set, 
                              scode, arg, value, 
                              gfc_option_lang_mask (), kind,
                              loc, handlers, global_dc);
724 725
  return result;
}
726 727 728 729 730 731 732 733 734 735 736 737


/* Return a string with the options passed to the compiler; used for
   Fortran's compiler_options() intrinsic.  */

char *
gfc_get_option_string (void)
{
  unsigned j;
  size_t len, pos;
  char *result;

738 739 740 741
  /* Allocate and return a one-character string with '\0'.  */
  if (!save_decoded_options_count)
    return XCNEWVEC (char, 1);

742 743 744 745 746 747 748 749 750 751 752 753 754 755 756
  /* Determine required string length.  */

  len = 0;
  for (j = 1; j < save_decoded_options_count; j++)
    {
      switch (save_decoded_options[j].opt_index)
        {
        case OPT_o:
        case OPT_d:
        case OPT_dumpbase:
        case OPT_dumpdir:
        case OPT_auxbase:
        case OPT_quiet:
        case OPT_version:
        case OPT_fintrinsic_modules_path:
757
        case OPT_fintrinsic_modules_path_:
758 759 760
          /* Ignore these.  */
          break;
	default:
761
	  /* Ignore file names.  */
762 763 764 765 766 767
	  if (save_decoded_options[j].orig_option_with_args_text[0] == '-')
	    len += 1
		 + strlen (save_decoded_options[j].orig_option_with_args_text);
        }
    }

768
  result = XCNEWVEC (char, len);
769 770 771 772 773 774 775 776 777 778 779 780 781 782

  pos = 0; 
  for (j = 1; j < save_decoded_options_count; j++)
    {
      switch (save_decoded_options[j].opt_index)
        {
        case OPT_o:
        case OPT_d:
        case OPT_dumpbase:
        case OPT_dumpdir:
        case OPT_auxbase:
        case OPT_quiet:
        case OPT_version:
        case OPT_fintrinsic_modules_path:
783
        case OPT_fintrinsic_modules_path_:
784 785 786 787 788 789 790 791 792
          /* Ignore these.  */
	  continue;

        case OPT_cpp_:
	  /* Use "-cpp" rather than "-cpp=<temporary file>".  */
	  len = 4;
	  break;

        default:
793
	  /* Ignore file names.  */
794 795 796 797 798 799 800 801 802 803 804 805 806 807
	  if (save_decoded_options[j].orig_option_with_args_text[0] != '-')
	    continue;

	  len = strlen (save_decoded_options[j].orig_option_with_args_text);
        }

      memcpy (&result[pos], save_decoded_options[j].orig_option_with_args_text, len);
      pos += len;
      result[pos++] = ' ';
    }

  result[--pos] = '\0';
  return result;
}