]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR other/32998 (-frecord-gcc-switches issues)
authorJoseph Myers <joseph@codesourcery.com>
Sun, 20 Jun 2010 21:02:46 +0000 (22:02 +0100)
committerJoseph Myers <jsm28@gcc.gnu.org>
Sun, 20 Jun 2010 21:02:46 +0000 (22:02 +0100)
PR other/32998
* opth-gen.awk: Generate definitions of OPT_SPECIAL_unknown,
OPT_SPECIAL_program_name and OPT_SPECIAL_input_file.
* opts-common.c (find_opt): Return OPT_SPECIAL_unknown on failure.
(decode_cmdline_option): Update for this return value.  Set
orig_option_with_args_text field.  Set arg field for unknown
options.  Make static.
(decode_cmdline_options_to_array): New.
(prune_options): Update handling of find_opt return value.
* opts.c (read_cmdline_option): Take decoded option.  Return void.
(read_cmdline_options): Take decoded options.
(decode_options): Add parameters for decoded options.  Use
decode_cmdline_options_to_array.  Use decoded options for -O
scan.  Use integral_argument for -O parameters.  Update call to
read_cmdline_options.
(enable_warning_as_error): Update handling of find_opt return
value.
* opts.h: Update comment on unknown options.
(struct cl_decoded_option): Update comments on opt_index and arg.
Add orig_option_with_args_text.
(decode_cmdline_option): Remove.
(decode_cmdline_options_to_array): Declare.
(decode_options): Update prototype.
* toplev.c (save_argv): Remove.
(save_decoded_options, save_decoded_options_count): New.
(read_integral_parameter): Remove.
(print_switch_values): Use decoded options.
(toplev_main): Don't set save_argv.  Update call to
decode_options.
* toplev.h (read_integral_parameter): Remove.
* varasm.c (elf_record_gcc_switches): Don't handle holding back
names.

c-family:
* c-common.c (parse_optimize_options): Update call to
decode_options.

fortran:
* options.c (gfc_handle_option): Don't handle N_OPTS.

testsuite:
* gcc.dg/opts-2.c: New test.

From-SVN: r161053

14 files changed:
gcc/ChangeLog
gcc/c-family/ChangeLog
gcc/c-family/c-common.c
gcc/fortran/ChangeLog
gcc/fortran/options.c
gcc/opth-gen.awk
gcc/opts-common.c
gcc/opts.c
gcc/opts.h
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/opts-2.c [new file with mode: 0644]
gcc/toplev.c
gcc/toplev.h
gcc/varasm.c

index d8853252dd8bb82716bac926ff11b811adefdf2d..a0cbd409b17ff4772067ff9f53a4c8212700aac5 100644 (file)
@@ -1,3 +1,38 @@
+2010-06-20  Joseph Myers  <joseph@codesourcery.com>
+
+       PR other/32998
+       * opth-gen.awk: Generate definitions of OPT_SPECIAL_unknown,
+       OPT_SPECIAL_program_name and OPT_SPECIAL_input_file.
+       * opts-common.c (find_opt): Return OPT_SPECIAL_unknown on failure.
+       (decode_cmdline_option): Update for this return value.  Set
+       orig_option_with_args_text field.  Set arg field for unknown
+       options.  Make static.
+       (decode_cmdline_options_to_array): New.
+       (prune_options): Update handling of find_opt return value.
+       * opts.c (read_cmdline_option): Take decoded option.  Return void.
+       (read_cmdline_options): Take decoded options.
+       (decode_options): Add parameters for decoded options.  Use
+       decode_cmdline_options_to_array.  Use decoded options for -O
+       scan.  Use integral_argument for -O parameters.  Update call to
+       read_cmdline_options.
+       (enable_warning_as_error): Update handling of find_opt return
+       value.
+       * opts.h: Update comment on unknown options.
+       (struct cl_decoded_option): Update comments on opt_index and arg.
+       Add orig_option_with_args_text.
+       (decode_cmdline_option): Remove.
+       (decode_cmdline_options_to_array): Declare.
+       (decode_options): Update prototype.
+       * toplev.c (save_argv): Remove.
+       (save_decoded_options, save_decoded_options_count): New.
+       (read_integral_parameter): Remove.
+       (print_switch_values): Use decoded options.
+       (toplev_main): Don't set save_argv.  Update call to
+       decode_options.
+       * toplev.h (read_integral_parameter): Remove.
+       * varasm.c (elf_record_gcc_switches): Don't handle holding back
+       names.
+
 2010-06-19  Richard Earnshaw  <rearnsha@arm.com>
 
        PR target/44072
index c13367e9a6a8744c67be56d6ac7ad1ad858d40c9..68c11653c62eaa0d758945aa2e26c6cd9f72c446 100644 (file)
@@ -1,3 +1,8 @@
+2010-06-20  Joseph Myers  <joseph@codesourcery.com>
+
+       * c-common.c (parse_optimize_options): Update call to
+       decode_options.
+
 2010-06-18  Nathan Froyd  <froydnj@codesourcery.com>
 
        * c-common.c (record_types_used_by_current_var_decl): Adjust for
index 4bafd1cfad5f822ece8705a765a85e022bd7f6c2..86c3802b0d2e4184ea0c13da519481f01bb311f8 100644 (file)
@@ -7624,6 +7624,8 @@ parse_optimize_options (tree args, bool attr_p)
   unsigned i;
   int saved_flag_strict_aliasing;
   const char **opt_argv;
+  struct cl_decoded_option *decoded_options;
+  unsigned int decoded_options_count;
   tree ap;
 
   /* Build up argv vector.  Just in case the string is stored away, use garbage
@@ -7716,7 +7718,8 @@ parse_optimize_options (tree args, bool attr_p)
   saved_flag_strict_aliasing = flag_strict_aliasing;
 
   /* Now parse the options.  */
-  decode_options (opt_argc, opt_argv);
+  decode_options (opt_argc, opt_argv, &decoded_options,
+                 &decoded_options_count);
 
   targetm.override_options_after_change();
 
index 1d2edde95a3c9df9b2944e6ef2cdf18a4a88dfb3..077c42e8706658cc62dd9bf36f7f71d9bd1f9941 100644 (file)
@@ -1,3 +1,7 @@
+2010-06-20  Joseph Myers  <joseph@codesourcery.com>
+
+       * options.c (gfc_handle_option): Don't handle N_OPTS.
+
 2010-06-19  Janus Weil  <janus@gcc.gnu.org>
 
        PR fortran/44584
index d50c080b42fe764cf3be9088bce23ae23c06d551..3b8b8dc1667c9dcc7e20ca51d9208410d7f410b3 100644 (file)
@@ -541,10 +541,6 @@ gfc_handle_option (size_t scode, const char *arg, int value,
   int result = 1;
   enum opt_code code = (enum opt_code) scode;
 
-  /* Ignore file names.  */
-  if (code == N_OPTS)
-    return 1;
-
   if (gfc_cpp_handle_option (scode, arg, value) == 1)
     return 1;
 
index cf2ef9683c842bcf11f354f387afa4fefb728683..19af0ef0f0c6bd9c69be6fa357c818c8e46d9e91 100644 (file)
@@ -358,7 +358,10 @@ for (i = 0; i < n_opts; i++) {
        print "  " enum "," s "/* -" opts[i] " */"
 }
 
-print "  N_OPTS"
+print "  N_OPTS,"
+print "  OPT_SPECIAL_unknown,"
+print "  OPT_SPECIAL_program_name,"
+print "  OPT_SPECIAL_input_file"
 print "};"
 print ""
 print "#endif /* OPTIONS_H */"
index 513a766e520da221be38f845977a863ca5ce99c1..cde8ccfe29b3a43c4c109eecad965696a93decd5 100644 (file)
@@ -25,8 +25,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "options.h"
 
 /* Perform a binary search to find which option the command-line INPUT
-   matches.  Returns its index in the option array, and N_OPTS
-   (cl_options_count) on failure.
+   matches.  Returns its index in the option array, and
+   OPT_SPECIAL_unknown on failure.
 
    This routine is quite subtle.  A normal binary search is not good
    enough because some options can be suffixed with an argument, and
@@ -73,8 +73,8 @@ find_opt (const char *input, int lang_mask)
     }
 
   /* This is the switch that is the best match but for a different
-     front end, or cl_options_count if there is no match at all.  */
-  match_wrong_lang = cl_options_count;
+     front end, or OPT_SPECIAL_unknown if there is no match at all.  */
+  match_wrong_lang = OPT_SPECIAL_unknown;
 
   /* Backtrace the chain of possible matches, returning the longest
      one, if any, that fits best.  With current GCC switches, this
@@ -94,7 +94,7 @@ find_opt (const char *input, int lang_mask)
 
          /* If we haven't remembered a prior match, remember this
             one.  Any prior match is necessarily better.  */
-         if (match_wrong_lang == cl_options_count)
+         if (match_wrong_lang == OPT_SPECIAL_unknown)
            match_wrong_lang = mn;
        }
 
@@ -104,7 +104,7 @@ find_opt (const char *input, int lang_mask)
     }
   while (mn != cl_options_count);
 
-  /* Return the best wrong match, or cl_options_count if none.  */
+  /* Return the best wrong match, or OPT_SPECIAL_unknown if none.  */
   return match_wrong_lang;
 }
 
@@ -129,7 +129,7 @@ integral_argument (const char *arg)
    LANG_MASK, into the structure *DECODED.  Returns the number of
    switches consumed.  */
 
-unsigned int
+static unsigned int
 decode_cmdline_option (const char **argv, unsigned int lang_mask,
                       struct cl_decoded_option *decoded)
 {
@@ -144,7 +144,7 @@ decode_cmdline_option (const char **argv, unsigned int lang_mask,
   opt = argv[0];
 
   opt_index = find_opt (opt + 1, lang_mask | CL_COMMON | CL_TARGET);
-  if (opt_index == cl_options_count
+  if (opt_index == OPT_SPECIAL_unknown
       && (opt[1] == 'W' || opt[1] == 'f' || opt[1] == 'm')
       && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-')
     {
@@ -160,8 +160,11 @@ decode_cmdline_option (const char **argv, unsigned int lang_mask,
       opt_index = find_opt (opt + 1, lang_mask | CL_COMMON | CL_TARGET);
     }
 
-  if (opt_index == cl_options_count)
-    goto done;
+  if (opt_index == OPT_SPECIAL_unknown)
+    {
+      arg = argv[0];
+      goto done;
+    }
 
   option = &cl_options[opt_index];
 
@@ -169,7 +172,8 @@ decode_cmdline_option (const char **argv, unsigned int lang_mask,
      unrecognized.  */
   if (!value && (option->flags & CL_REJECT_NEGATIVE))
     {
-      opt_index = cl_options_count;
+      opt_index = OPT_SPECIAL_unknown;
+      arg = argv[0];
       goto done;
     }
 
@@ -237,9 +241,76 @@ decode_cmdline_option (const char **argv, unsigned int lang_mask,
   decoded->arg = arg;
   decoded->value = value;
   decoded->errors = errors;
+  switch (result)
+    {
+    case 1:
+      decoded->orig_option_with_args_text = argv[0];
+      break;
+    case 2:
+      decoded->orig_option_with_args_text = concat (argv[0], " ",
+                                                   argv[1], NULL);
+      break;
+    default:
+      gcc_unreachable ();
+    }
   return result;
 }
 
+/* Decode command-line options (ARGC and ARGV being the arguments of
+   main) into an array, setting *DECODED_OPTIONS to a pointer to that
+   array and *DECODED_OPTIONS_COUNT to the number of entries in the
+   array.  The first entry in the array is always one for the program
+   name (OPT_SPECIAL_program_name).  LANG_MASK indicates the language
+   applicable for decoding.  Do not produce any diagnostics or set
+   state outside of these variables.  */
+
+void
+decode_cmdline_options_to_array (unsigned int argc, const char **argv, 
+                                unsigned int lang_mask,
+                                struct cl_decoded_option **decoded_options,
+                                unsigned int *decoded_options_count)
+{
+  unsigned int n, i;
+  struct cl_decoded_option *opt_array;
+  unsigned int num_decoded_options;
+
+  opt_array = XNEWVEC (struct cl_decoded_option, argc);
+
+  opt_array[0].opt_index = OPT_SPECIAL_program_name;
+  opt_array[0].arg = argv[0];
+  opt_array[0].orig_option_with_args_text = argv[0];
+  opt_array[0].value = 1;
+  opt_array[0].errors = 0;
+  num_decoded_options = 1;
+
+  for (i = 1; i < argc; i += n)
+    {
+      const char *opt = argv[i];
+
+      /* Interpret "-" or a non-switch as a file name.  */
+      if (opt[0] != '-' || opt[1] == '\0')
+       {
+         opt_array[num_decoded_options].opt_index = OPT_SPECIAL_input_file;
+         opt_array[num_decoded_options].arg = opt;
+         opt_array[num_decoded_options].orig_option_with_args_text = opt;
+         opt_array[num_decoded_options].value = 1;
+         opt_array[num_decoded_options].errors = 0;
+         num_decoded_options++;
+         n = 1;
+         continue;
+       }
+
+      n = decode_cmdline_option (argv + i, lang_mask,
+                                &opt_array[num_decoded_options]);
+      num_decoded_options++;
+    }
+
+  opt_array = XRESIZEVEC (struct cl_decoded_option, opt_array,
+                         num_decoded_options);
+  *decoded_options = opt_array;
+  *decoded_options_count = num_decoded_options;
+}
+
 /* Return true if NEXT_OPT_IDX cancels OPT_IDX.  Return false if the
    next one is the same as ORIG_NEXT_OPT_IDX.  */
 
@@ -281,7 +352,7 @@ prune_options (int *argcp, char ***argvp)
       const char *opt = (*argvp) [i];
 
       opt_index = find_opt (opt + 1, -1);
-      if (opt_index == cl_options_count
+      if (opt_index == OPT_SPECIAL_unknown
          && (opt[1] == 'W' || opt[1] == 'f' || opt[1] == 'm')
          && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-')
        {
@@ -300,7 +371,7 @@ prune_options (int *argcp, char ***argvp)
          free (dup);
        }
 
-      if (opt_index == cl_options_count)
+      if (opt_index == OPT_SPECIAL_unknown)
        {
 cont:
          options [i] = 0;
index d5fe326bced1ecd83219a10ba3861e4561e5afec..006e0f18b16dc8a6ec86e6fdaadc4ed5c425da6f 100644 (file)
@@ -515,67 +515,63 @@ handle_option (int opt_index, int value, const char *arg,
   return true;
 }
 
-/* Handle the switch beginning at ARGV for the language indicated by
-   LANG_MASK.  Returns the number of switches consumed.  */
-static unsigned int
-read_cmdline_option (const char **argv, unsigned int lang_mask)
+/* Handle the switch DECODED for the language indicated by
+   LANG_MASK.  */
+static void
+read_cmdline_option (struct cl_decoded_option *decoded,
+                    unsigned int lang_mask)
 {
-  struct cl_decoded_option decoded;
-  unsigned int result;
-  const char *opt;
   const struct cl_option *option;
+  const char *opt;
 
-  opt = argv[0];
-
-  result = decode_cmdline_option (argv, lang_mask, &decoded);
-  if (decoded.opt_index == cl_options_count)
+  if (decoded->opt_index == OPT_SPECIAL_unknown)
     {
+      opt = decoded->arg;
+
       if (opt[1] == 'W' && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-')
        /* We don't generate warnings for unknown -Wno-* options
           unless we issue diagnostics.  */
-         postpone_unknown_option_warning (argv[0]);
+         postpone_unknown_option_warning (opt);
       else
        error ("unrecognized command line option %qs", opt);
-      return result;
+      return;
     }
 
-  option = &cl_options[decoded.opt_index];
+  option = &cl_options[decoded->opt_index];
+  opt = decoded->orig_option_with_args_text;
 
-  if (decoded.errors & CL_ERR_DISABLED)
+  if (decoded->errors & CL_ERR_DISABLED)
     {
       error ("command line option %qs"
             " is not supported by this configuration", opt);
-      goto done;
+      return;
     }
 
-  if (decoded.errors & CL_ERR_WRONG_LANG)
+  if (decoded->errors & CL_ERR_WRONG_LANG)
     {
-      complain_wrong_lang (argv[0], option, lang_mask);
-      goto done;
+      complain_wrong_lang (opt, option, lang_mask);
+      return;
     }
 
-  if (decoded.errors & CL_ERR_MISSING_ARG)
+  if (decoded->errors & CL_ERR_MISSING_ARG)
     {
-      if (!lang_hooks.missing_argument (opt, decoded.opt_index))
+      if (!lang_hooks.missing_argument (opt, decoded->opt_index))
        error ("missing argument to %qs", opt);
-      goto done;
+      return;
     }
 
-  if (decoded.errors & CL_ERR_UINT_ARG)
+  if (decoded->errors & CL_ERR_UINT_ARG)
     {
       error ("argument to %qs should be a non-negative integer",
             option->opt_text);
-      goto done;
+      return;
     }
 
-  gcc_assert (!decoded.errors);
+  gcc_assert (!decoded->errors);
 
-  if (!handle_option (decoded.opt_index, decoded.value, decoded.arg,
+  if (!handle_option (decoded->opt_index, decoded->value, decoded->arg,
                      lang_mask, DK_UNSPECIFIED))
     error ("unrecognized command line option %qs", opt);
-
- done:
-  return result;
 }
 
 /* Handle FILENAME from the command line.  */
@@ -667,40 +663,41 @@ flag_instrument_functions_exclude_p (tree fndecl)
 }
 
 
-/* Decode and handle the vector of command line options.  LANG_MASK
+/* Handle the vector of command line options.  LANG_MASK
    contains has a single bit set representing the current
    language.  */
 static void
-read_cmdline_options (unsigned int argc, const char **argv, unsigned int lang_mask)
+read_cmdline_options (struct cl_decoded_option *decoded_options,
+                     unsigned int decoded_options_count,
+                     unsigned int lang_mask)
 {
-  unsigned int n, i;
+  unsigned int i;
 
-  for (i = 1; i < argc; i += n)
+  for (i = 1; i < decoded_options_count; i++)
     {
-      const char *opt = argv[i];
-
-      /* Interpret "-" or a non-switch as a file name.  */
-      if (opt[0] != '-' || opt[1] == '\0')
+      if (decoded_options[i].opt_index == OPT_SPECIAL_input_file)
        {
          if (main_input_filename == NULL)
            {
-             main_input_filename = opt;
+             main_input_filename = decoded_options[i].arg;
              main_input_baselength
                = base_of_path (main_input_filename, &main_input_basename);
            }
-         add_input_filename (opt);
-         n = 1;
+         add_input_filename (decoded_options[i].arg);
          continue;
        }
 
-      n = read_cmdline_option (argv + i, lang_mask);
+      read_cmdline_option (decoded_options + i, lang_mask);
     }
 }
 
 /* Parse command line options and set default flag values.  Do minimal
-   options processing.  */
+   options processing.  The decoded options are placed in *DECODED_OPTIONS
+   and *DECODED_OPTIONS_COUNT.  */
 void
-decode_options (unsigned int argc, const char **argv)
+decode_options (unsigned int argc, const char **argv,
+               struct cl_decoded_option **decoded_options,
+               unsigned int *decoded_options_count)
 {
   static bool first_time_p = true;
   static int initial_min_crossjump_insns;
@@ -733,40 +730,30 @@ decode_options (unsigned int argc, const char **argv)
   else
     lang_mask = initial_lang_mask;
 
+  decode_cmdline_options_to_array (argc, argv, lang_mask,
+                                  decoded_options, decoded_options_count);
+
   /* Scan to see what optimization level has been specified.  That will
      determine the default value of many flags.  */
-  for (i = 1; i < argc; i++)
+  for (i = 1; i < *decoded_options_count; i++)
     {
-      if (!strcmp (argv[i], "-O"))
-       {
-         optimize = 1;
-         optimize_size = 0;
-         ofast = 0;
-       }
-      else if (argv[i][0] == '-' && argv[i][1] == 'O')
+      struct cl_decoded_option *opt = &(*decoded_options)[i];
+      switch (opt->opt_index)
        {
-         /* Handle -Os, -O2, -O3, -O69, ...  */
-         const char *p = &argv[i][2];
-
-         if ((p[0] == 's') && (p[1] == 0))
-           {
-             optimize_size = 1;
-
-             /* Optimizing for size forces optimize to be 2.  */
-             optimize = 2;
-             ofast = 0;
-           }
-         else if (strcmp (p, "fast") == 0)
+       case OPT_O:
+         if (*opt->arg == '\0')
            {
-             /* -Ofast only adds flags to -O3.  */
+             optimize = 1;
              optimize_size = 0;
-             optimize = 3;
-             ofast = 1;
+             ofast = 0;
            }
          else
            {
-             const int optimize_val = read_integral_parameter (p, p - 2, -1);
-             if (optimize_val != -1)
+             const int optimize_val = integral_argument (opt->arg);
+             if (optimize_val == -1)
+               error ("argument to %qs should be a non-negative integer",
+                      "-O");
+             else
                {
                  optimize = optimize_val;
                  if ((unsigned int) optimize > 255)
@@ -775,6 +762,26 @@ decode_options (unsigned int argc, const char **argv)
                  ofast = 0;
                }
            }
+         break;
+
+       case OPT_Os:
+         optimize_size = 1;
+
+         /* Optimizing for size forces optimize to be 2.  */
+         optimize = 2;
+         ofast = 0;
+         break;
+
+       case OPT_Ofast:
+         /* -Ofast only adds flags to -O3.  */
+         optimize_size = 0;
+         optimize = 3;
+         ofast = 1;
+         break;
+
+       default:
+         /* Ignore other options in this prescan.  */
+         break;
        }
     }
 
@@ -927,7 +934,7 @@ decode_options (unsigned int argc, const char **argv)
   OPTIMIZATION_OPTIONS (optimize, optimize_size);
 #endif
 
-  read_cmdline_options (argc, argv, lang_mask);
+  read_cmdline_options (*decoded_options, *decoded_options_count, lang_mask);
 
   if (dump_base_name && ! IS_ABSOLUTE_PATH (dump_base_name))
     {
@@ -2419,7 +2426,7 @@ enable_warning_as_error (const char *arg, int value, unsigned int lang_mask)
   new_option[0] = 'W';
   strcpy (new_option + 1, arg);
   option_index = find_opt (new_option, lang_mask);
-  if (option_index == N_OPTS)
+  if (option_index == OPT_SPECIAL_unknown)
     {
       error ("-Werror=%s: No option -%s", arg, new_option);
     }
index c50cbca1c1e648eb2608dfaded658354997b1cc9..554bb235b3dab1ba2606bb5ecd5460cbe68064e7 100644 (file)
@@ -92,7 +92,7 @@ extern const unsigned int cl_lang_count;
 
 /* Possible ways in which a command-line option may be erroneous.
    These do not include not being known at all; an option index of
-   cl_options_count is used for that.  */
+   OPT_SPECIAL_unknown is used for that.  */
 
 #define CL_ERR_DISABLED                (1 << 0) /* Disabled in this configuration.  */
 #define CL_ERR_MISSING_ARG     (1 << 1) /* Argument required but missing.  */
@@ -103,12 +103,20 @@ extern const unsigned int cl_lang_count;
 
 struct cl_decoded_option
 {
-  /* The index of this option, or cl_options_count if not known.  */
+  /* The index of this option, or an OPT_SPECIAL_* value for
+     non-options and unknown options.  */
   size_t opt_index;
 
-  /* The string argument, or NULL if none.  */
+  /* The string argument, or NULL if none.  For OPT_SPECIAL_* cases,
+     the option or non-option command-line argument.  */
   const char *arg;
 
+  /* The original text of option plus arguments, with separate argv
+     elements concatenated into one string with spaces separating
+     them.  This is for such uses as diagnostics and
+     -frecord-gcc-switches.  */
+  const char *orig_option_with_args_text;
+
   /* For a boolean option, 1 for the true case and 0 for the "no-"
      case.  For an unsigned integer option, the value of the
      argument.  1 in all other cases.  */
@@ -128,11 +136,15 @@ extern unsigned num_in_fnames;
 
 size_t find_opt (const char *input, int lang_mask);
 extern int integral_argument (const char *arg);
-extern unsigned int decode_cmdline_option (const char **argv,
-                                          unsigned int lang_mask,
-                                          struct cl_decoded_option *decoded);
+extern void decode_cmdline_options_to_array (unsigned int argc,
+                                            const char **argv, 
+                                            unsigned int lang_mask,
+                                            struct cl_decoded_option **decoded_options,
+                                            unsigned int *decoded_options_count);
 extern void prune_options (int *argcp, char ***argvp);
-extern void decode_options (unsigned int argc, const char **argv);
+extern void decode_options (unsigned int argc, const char **argv,
+                           struct cl_decoded_option **decoded_options,
+                           unsigned int *decoded_options_count);
 extern int option_enabled (int opt_idx);
 extern bool get_option_state (int, struct cl_option_state *);
 extern void set_option (int opt_index, int value, const char *arg, int);
index 0d35274cb2e47faa6021a77cfb828755a280adc4..922073a03b002e41e55e5fb19c4686be602e3793 100644 (file)
@@ -1,3 +1,7 @@
+2010-06-20  Joseph Myers  <joseph@codesourcery.com>
+
+       * gcc.dg/opts-2.c: New test.
+
 2010-06-19  Janus Weil  <janus@gcc.gnu.org>
 
        PR fortran/44584
diff --git a/gcc/testsuite/gcc.dg/opts-2.c b/gcc/testsuite/gcc.dg/opts-2.c
new file mode 100644 (file)
index 0000000..f768363
--- /dev/null
@@ -0,0 +1,8 @@
+/* -O as an operand to another option should not take effect as an
+    optimization option.  */
+/* { dg-do compile } */
+/* { dg-options "-I -O" } */
+
+#ifdef __OPTIMIZE__
+#error "__OPTIMIZE__ defined"
+#endif
index 20da382b1dde7107d8220c64d24aebffa5361a6d..220c1f777f0e7db103ffa94d0150d4a73336155f 100644 (file)
@@ -126,8 +126,9 @@ static bool no_backend;
 /* Length of line when printing switch values.  */
 #define MAX_LINE 75
 
-/* Copy of argument vector to toplev_main.  */
-static const char **save_argv;
+/* Decoded options, and number of such options.  */
+static struct cl_decoded_option *save_decoded_options;
+static unsigned int save_decoded_options_count;
 
 /* Name of top-level original source file (what was input to cpp).
    This comes from the #-command at the beginning of the actual input.
@@ -488,34 +489,6 @@ set_random_seed (const char *val)
   return old;
 }
 
-/* Decode the string P as an integral parameter.
-   If the string is indeed an integer return its numeric value else
-   issue an Invalid Option error for the option PNAME and return DEFVAL.
-   If PNAME is zero just return DEFVAL, do not call error.  */
-
-int
-read_integral_parameter (const char *p, const char *pname, const int  defval)
-{
-  const char *endp = p;
-
-  while (*endp)
-    {
-      if (ISDIGIT (*endp))
-       endp++;
-      else
-       break;
-    }
-
-  if (*endp != 0)
-    {
-      if (pname != 0)
-       error ("invalid option argument %qs", pname);
-      return defval;
-    }
-
-  return atoi (p);
-}
-
 #if GCC_VERSION < 3004
 
 /* The functions floor_log2 and exact_log2 are defined as inline
@@ -1338,7 +1311,6 @@ print_switch_values (print_switch_fn_type print_fn)
 {
   int pos = 0;
   size_t j;
-  const char **p;
 
   /* Fill in the -frandom-seed option, if the user didn't pass it, so
      that it can be printed below.  This helps reproducibility.  */
@@ -1349,30 +1321,23 @@ print_switch_values (print_switch_fn_type print_fn)
   pos = print_single_switch (print_fn, pos,
                             SWITCH_TYPE_DESCRIPTIVE, _("options passed: "));
 
-  for (p = &save_argv[1]; *p != NULL; p++)
+  for (j = 1; j < save_decoded_options_count; j++)
     {
-      if (**p == '-')
+      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:
          /* Ignore these.  */
-         if (strcmp (*p, "-o") == 0
-             || strcmp (*p, "-dumpbase") == 0
-             || strcmp (*p, "-dumpdir") == 0
-             || strcmp (*p, "-auxbase") == 0)
-           {
-             if (p[1] != NULL)
-               p++;
-             continue;
-           }
-
-         if (strcmp (*p, "-quiet") == 0
-             || strcmp (*p, "-version") == 0)
-           continue;
-
-         if ((*p)[1] == 'd')
-           continue;
+         continue;
        }
 
-      pos = print_single_switch (print_fn, pos, SWITCH_TYPE_PASSED, *p);
+      pos = print_single_switch (print_fn, pos, SWITCH_TYPE_PASSED,
+                                save_decoded_options[j].orig_option_with_args_text);
     }
 
   if (pos > 0)
@@ -2395,14 +2360,13 @@ toplev_main (int argc, char **argv)
 {
   expandargv (&argc, &argv);
 
-  save_argv = CONST_CAST2 (const char **, char **, argv);
-
   /* Initialization of GCC's environment, and diagnostics.  */
   general_init (argv[0]);
 
   /* Parse the options and do minimal processing; basically just
      enough to default flags appropriately.  */
-  decode_options (argc, CONST_CAST2 (const char **, char **, argv));
+  decode_options (argc, CONST_CAST2 (const char **, char **, argv),
+                 &save_decoded_options, &save_decoded_options_count);
 
   init_local_tick ();
 
index 0afe33f1d35496ffd1f587edbede80e8c4203bfd..a7ded4c47ad154a692bf9140747638c8b35dd73d 100644 (file)
@@ -31,7 +31,6 @@ along with GCC; see the file COPYING3.  If not see
    (strncmp (whole, part, strlen (part)) ? NULL : whole + strlen (part))
 
 extern int toplev_main (int, char **);
-extern int read_integral_parameter (const char *, const char *, const int);
 extern void strip_off_ending (char *, int);
 extern void _fatal_insn_not_found (const_rtx, const char *, int, const char *)
      ATTRIBUTE_NORETURN;
index 8ef41e3264b6507bff5dcdfcd467b06ef14ccb8f..98187c13cf283c8145f8759ff5a8ead4916bcadc 100644 (file)
@@ -7199,50 +7199,11 @@ output_object_blocks (void)
 int
 elf_record_gcc_switches (print_switch_type type, const char * name)
 {
-  static char buffer[1024];
-
-  /* This variable is used as part of a simplistic heuristic to detect
-     command line switches which take an argument:
-
-       "If a command line option does not start with a dash then
-        it is an argument for the previous command line option."
-
-     This fails in the case of the command line option which is the name
-     of the file to compile, but otherwise it is pretty reasonable.  */
-  static bool previous_name_held_back = FALSE;
-
   switch (type)
     {
     case SWITCH_TYPE_PASSED:
-      if (* name != '-')
-       {
-         if (previous_name_held_back)
-           {
-             unsigned int len = strlen (buffer);
-
-             snprintf (buffer + len, sizeof buffer - len, " %s", name);
-             ASM_OUTPUT_ASCII (asm_out_file, buffer, strlen (buffer));
-             ASM_OUTPUT_SKIP (asm_out_file, (unsigned HOST_WIDE_INT) 1);
-             previous_name_held_back = FALSE;
-           }
-         else
-           {
-             strncpy (buffer, name, sizeof buffer);
-             ASM_OUTPUT_ASCII (asm_out_file, buffer, strlen (buffer));
-             ASM_OUTPUT_SKIP (asm_out_file, (unsigned HOST_WIDE_INT) 1);
-           }
-       }
-      else
-       {
-         if (previous_name_held_back)
-           {
-             ASM_OUTPUT_ASCII (asm_out_file, buffer, strlen (buffer));
-             ASM_OUTPUT_SKIP (asm_out_file, (unsigned HOST_WIDE_INT) 1);
-           }
-
-         strncpy (buffer, name, sizeof buffer);
-         previous_name_held_back = TRUE;
-       }
+      ASM_OUTPUT_ASCII (asm_out_file, name, strlen (name));
+      ASM_OUTPUT_SKIP (asm_out_file, (unsigned HOST_WIDE_INT) 1);
       break;
 
     case SWITCH_TYPE_DESCRIPTIVE:
@@ -7251,15 +7212,7 @@ elf_record_gcc_switches (print_switch_type type, const char * name)
          /* Distinguish between invocations where name is NULL.  */
          static bool started = false;
 
-         if (started)
-           {
-             if (previous_name_held_back)
-               {
-                 ASM_OUTPUT_ASCII (asm_out_file, buffer, strlen (buffer));
-                 ASM_OUTPUT_SKIP (asm_out_file, (unsigned HOST_WIDE_INT) 1);
-               }
-           }
-         else
+         if (!started)
            {
              section * sec;