OSDN Git Service

* tree-ssa-forwprop.c (substitute_single_use_vars): Remove
[pf3gnuchains/gcc-fork.git] / gcc / gcc.c
index 78974ab..eda9e5e 100644 (file)
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -361,6 +361,7 @@ static const char *convert_filename (const char *, int, int);
 
 static const char *if_exists_spec_function (int, const char **);
 static const char *if_exists_else_spec_function (int, const char **);
+static const char *replace_outfile_spec_function (int, const char **);
 \f
 /* The Specs Language
 
@@ -782,7 +783,7 @@ static const char *cpp_unique_options =
    options used to set target flags.  Those special target flags settings may
    in turn cause preprocessor symbols to be defined specially.  */
 static const char *cpp_options =
-"%(cpp_unique_options) %1 %{m*} %{std*} %{ansi} %{W*&pedantic*} %{w} %{f*}\
+"%(cpp_unique_options) %1 %{m*} %{std*&ansi} %{W*&pedantic*} %{w} %{f*}\
  %{g*:%{!g0:%{!fno-working-directory:-fworking-directory}}} %{O*} %{undef}\
  %{save-temps:-fpch-preprocess}";
 
@@ -795,7 +796,7 @@ static const char *cc1_options =
 "%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
  %1 %{!Q:-quiet} -dumpbase %B %{d*} %{m*} %{a*}\
  %{c|S:%{o*:-auxbase-strip %*}%{!o*:-auxbase %b}}%{!c:%{!S:-auxbase %b}}\
- %{g*} %{O*} %{W*&pedantic*} %{w} %{std*} %{ansi}\
+ %{g*} %{O*} %{W*&pedantic*} %{w} %{std*&ansi}\
  %{v:-version} %{pg:-p} %{p} %{f*} %{undef}\
  %{Qn:-fno-ident} %{--help:--help}\
  %{--target-help:--target-help}\
@@ -918,6 +919,8 @@ static const struct compiler default_compilers[] =
      and be given a more meaningful error than "file not used since
      linking is not done".  */
   {".m",  "#Objective-C", 0, 0, 0}, {".mi",  "#Objective-C", 0, 0, 0},
+  {".mm", "#Objective-C++", 0, 0, 0}, {".M", "#Objective-C++", 0, 0, 0},
+  {".mii", "#Objective-C++", 0, 0, 0},
   {".cc", "#C++", 0, 0, 0}, {".cxx", "#C++", 0, 0, 0}, 
   {".cpp", "#C++", 0, 0, 0}, {".cp", "#C++", 0, 0, 0}, 
   {".c++", "#C++", 0, 0, 0}, {".C", "#C++", 0, 0, 0},
@@ -1061,8 +1064,10 @@ static const struct option_map option_map[] =
    {"--dependencies", "-M", 0},
    {"--dump", "-d", "a"},
    {"--dumpbase", "-dumpbase", "a"},
+   {"--encoding", "-fencoding=", "aj"},
    {"--entry", "-e", 0},
    {"--extra-warnings", "-W", 0},
+   {"--extdirs", "-fextdirs=", "aj"},
    {"--for-assembler", "-Wa", "a"},
    {"--for-linker", "-Xlinker", "a"},
    {"--force-link", "-u", "a"},
@@ -1261,7 +1266,7 @@ translate_options (int *argcp, const char *const **argvp)
 
                  else if (strchr (arginfo, '*') != 0)
                    {
-                     error ("incomplete `%s' option", option_map[j].name);
+                     error ("incomplete '%s' option", option_map[j].name);
                      break;
                    }
 
@@ -1272,7 +1277,7 @@ translate_options (int *argcp, const char *const **argvp)
                        {
                          if (i + 1 == argc)
                            {
-                             error ("missing argument to `%s' option",
+                             error ("missing argument to '%s' option",
                                     option_map[j].name);
                              break;
                            }
@@ -1285,7 +1290,7 @@ translate_options (int *argcp, const char *const **argvp)
                  else if (strchr (arginfo, 'o') == 0)
                    {
                      if (arg != 0)
-                       error ("extraneous argument to `%s' option",
+                       error ("extraneous argument to '%s' option",
                               option_map[j].name);
                      arg = 0;
                    }
@@ -1570,6 +1575,7 @@ static const struct spec_function static_spec_functions[] =
 {
   { "if-exists",               if_exists_spec_function },
   { "if-exists-else",          if_exists_else_spec_function },
+  { "replace-outfile",         replace_outfile_spec_function },
   { 0, 0 }
 };
 
@@ -1701,6 +1707,9 @@ init_spec (void)
 #else
                            "-lgcc_s%M"
 #endif
+#ifdef USE_LIBUNWIND_EXCEPTIONS
+                           " -lunwind"
+#endif
                            ,
                            "-lgcc",
                            "-lgcc_eh"
@@ -2623,7 +2632,7 @@ add_sysrooted_prefix (struct path_prefix *pprefix, const char *prefix,
                      int require_machine_suffix, int os_multilib)
 {
   if (!IS_ABSOLUTE_PATH (prefix))
-    abort ();
+    fatal ("system path '%s' is not absolute", prefix);
 
   if (target_system_root)
     {
@@ -2661,8 +2670,7 @@ execute (void)
 
   struct command *commands;    /* each command buffer with above info.  */
 
-  if (processing_spec_function)
-    abort ();
+  gcc_assert (!processing_spec_function);
 
   /* Count # of piped commands.  */
   for (n_commands = 1, i = 0; i < argbuf_index; i++)
@@ -2835,8 +2843,7 @@ execute (void)
        int pid;
 
        pid = pwait (commands[i].pid, &status, 0);
-       if (pid < 0)
-         abort ();
+       gcc_assert (pid >= 0);
 
 #ifdef HAVE_GETRUSAGE
        if (report_times)
@@ -3191,7 +3198,7 @@ process_command (int argc, const char **argv)
              argv += 2;
            }
          else
-           fatal ("`-%c' option must have argument", opt);
+           fatal ("'-%c' option must have argument", opt);
          if (opt == 'V')
            new_version = arg;
          else
@@ -3213,7 +3220,7 @@ process_command (int argc, const char **argv)
       new_argv[0] = new_argv0;
 
       execvp (new_argv0, new_argv);
-      fatal ("couldn't run `%s': %s", new_argv0, xstrerror (errno));
+      fatal ("couldn't run '%s': %s", new_argv0, xstrerror (errno));
     }
 
   /* Set up the default search paths.  If there is no GCC_EXEC_PREFIX,
@@ -3502,7 +3509,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
       else if (strcmp (argv[i], "-Xlinker") == 0)
        {
          if (i + 1 == argc)
-           fatal ("argument to `-Xlinker' is missing");
+           fatal ("argument to '-Xlinker' is missing");
 
          n_infiles++;
          i++;
@@ -3510,21 +3517,21 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
       else if (strcmp (argv[i], "-Xpreprocessor") == 0)
        {
          if (i + 1 == argc)
-           fatal ("argument to `-Xpreprocessor' is missing");
+           fatal ("argument to '-Xpreprocessor' is missing");
 
          add_preprocessor_option (argv[i+1], strlen (argv[i+1]));
        }
       else if (strcmp (argv[i], "-Xassembler") == 0)
        {
          if (i + 1 == argc)
-           fatal ("argument to `-Xassembler' is missing");
+           fatal ("argument to '-Xassembler' is missing");
 
          add_assembler_option (argv[i+1], strlen (argv[i+1]));
        }
       else if (strcmp (argv[i], "-l") == 0)
        {
          if (i + 1 == argc)
-           fatal ("argument to `-l' is missing");
+           fatal ("argument to '-l' is missing");
 
          n_infiles++;
          i++;
@@ -3545,7 +3552,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
        {
          struct user_specs *user = xmalloc (sizeof (struct user_specs));
          if (++i >= argc)
-           fatal ("argument to `-specs' is missing");
+           fatal ("argument to '-specs' is missing");
 
          user->next = (struct user_specs *) 0;
          user->filename = argv[i];
@@ -3559,7 +3566,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
        {
          struct user_specs *user = xmalloc (sizeof (struct user_specs));
          if (strlen (argv[i]) == 7)
-           fatal ("argument to `-specs=' is missing");
+           fatal ("argument to '-specs=' is missing");
 
          user->next = (struct user_specs *) 0;
          user->filename = argv[i] + 7;
@@ -3596,7 +3603,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
            {
            case 'b':
            case 'V':
-             fatal ("`-%c' must come at the start of the command line", c);
+             fatal ("'-%c' must come at the start of the command line", c);
              break;
 
            case 'B':
@@ -3605,7 +3612,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
                int len;
 
                if (p[1] == 0 && i + 1 == argc)
-                 fatal ("argument to `-B' is missing");
+                 fatal ("argument to '-B' is missing");
                if (p[1] == 0)
                  value = argv[++i];
                else
@@ -3994,7 +4001,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
          if (c == 'x')
            {
              if (p[1] == 0 && i + 1 == argc)
-               fatal ("argument to `-x' is missing");
+               fatal ("argument to '-x' is missing");
              if (p[1] == 0)
                spec_lang = argv[++i];
              else
@@ -4022,7 +4029,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
                  n_args = SWITCH_TAKES_ARG (c) - (p[1] != 0);
                }
              if (i + n_args >= argc)
-               fatal ("argument to `-%s' is missing", p);
+               fatal ("argument to '-%s' is missing", p);
              switches[n_switches].args
                = xmalloc ((n_args + 1) * sizeof(const char *));
              while (j < n_args)
@@ -4083,7 +4090,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
     }
 
   if (n_infiles == last_language_n_infiles && spec_lang != 0)
-    error ("warning: `-x %s' after last input file has no effect", spec_lang);
+    error ("warning: '-x %s' after last input file has no effect", spec_lang);
 
   /* Ensure we only invoke each subprocess once.  */
   if (target_help_flag || print_help_list)
@@ -4193,7 +4200,9 @@ static int basename_length;
 static int suffixed_basename_length;
 static const char *input_basename;
 static const char *input_suffix;
+#ifndef HOST_LACKS_INODE_NUMBERS
 static struct stat input_stat;
+#endif
 static int input_stat_set;
 
 /* The compiler used to process the current input file.  */
@@ -4358,7 +4367,7 @@ do_self_spec (const char *spec)
 
          /* Each switch should start with '-'.  */
          if (argbuf[i][0] != '-')
-           abort ();
+           fatal ("switch '%s' does not start with '-'", argbuf[i]);
 
          sw = &switches[i + first];
          sw->part1 = &argbuf[i][1];
@@ -4585,7 +4594,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
        switch (c = *p++)
          {
          case 0:
-           fatal ("invalid specification!  Bug in cc");
+           fatal ("spec '%s' invalid", spec);
 
          case 'b':
            obstack_grow (&obstack, input_basename, basename_length);
@@ -4724,7 +4733,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
                    p += 2;
                    /* We don't support extra suffix characters after %O.  */
                    if (*p == '.' || ISALPHA ((unsigned char) *p))
-                     abort ();
+                     fatal ("spec '%s' has invalid '%%0%c'", spec, *p);
                    if (suffix_length == 0)
                      suffix = TARGET_OBJECT_SUFFIX;
                    else
@@ -4757,6 +4766,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
                    *((char *) temp_filename + temp_filename_length) = '\0';
                    if (strcmp (temp_filename, input_filename) != 0)
                      {
+#ifndef HOST_LACKS_INODE_NUMBERS
                        struct stat st_temp;
 
                        /* Note, set_input() resets input_stat_set to 0.  */
@@ -4771,11 +4781,19 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
                           and we can do the stat for the temp_filename
                           then the they could still refer to the same
                           file if st_dev/st_ino's are the same.  */
-
                        if (input_stat_set != 1
                            || stat (temp_filename, &st_temp) < 0
                            || input_stat.st_dev != st_temp.st_dev
                            || input_stat.st_ino != st_temp.st_ino)
+#else
+                       /* Just compare canonical pathnames.  */
+                       char* input_realname = lrealpath (input_filename);
+                       char* temp_realname = lrealpath (temp_filename);
+                       bool files_differ = strcmp (input_realname, temp_realname);
+                       free (input_realname);
+                       free (temp_realname);
+                       if (files_differ)       
+#endif
                          {
                            temp_filename = save_string (temp_filename,
                                                         temp_filename_length + 1);
@@ -4912,7 +4930,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
              int cur_index = argbuf_index;
              /* Handle the {...} following the %W.  */
              if (*p != '{')
-               abort ();
+               fatal ("spec '%s' has invalid '%%W%c", spec, *p);
              p = handle_braces (p + 1);
              if (p == 0)
                return -1;
@@ -4943,7 +4961,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
 
              /* Skip past the option value and make a copy.  */
              if (*p != '{')
-               abort ();
+               fatal ("spec '%s' has invalid '%%x%c'", spec, *p);
              while (*p++ != '}')
                ;
              string = save_string (p1 + 1, p - p1 - 2);
@@ -5153,7 +5171,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
              }
            else
              /* Catch the case where a spec string contains something like
-                '%{foo:%*}'.  ie there is no * in the pattern on the left
+                '%{foo:%*}'.  i.e. there is no * in the pattern on the left
                 hand side of the :.  */
              error ("spec failure: '%%*' has not been initialized by pattern match");
            break;
@@ -5324,7 +5342,7 @@ eval_spec_function (const char *func, const char *args)
 
   sf = lookup_spec_function (func);
   if (sf == NULL)
-    fatal ("unknown spec function `%s'", func);
+    fatal ("unknown spec function '%s'", func);
 
   /* Push the spec processing context.  */
   save_argbuf_index = argbuf_index;
@@ -5343,7 +5361,7 @@ eval_spec_function (const char *func, const char *args)
 
   alloc_args ();
   if (do_spec_2 (args) < 0)
-    fatal ("error in args to spec function `%s'", func);
+    fatal ("error in args to spec function '%s'", func);
 
   /* argbuf_index is an index for the next argument to be inserted, and
      so contains the count of the args already inserted.  */
@@ -5501,6 +5519,7 @@ handle_braces (const char *p)
 {
   const char *atom, *end_atom;
   const char *d_atom = NULL, *d_end_atom = NULL;
+  const char *orig = p;
 
   bool a_is_suffix;
   bool a_is_starred;
@@ -5520,7 +5539,7 @@ handle_braces (const char *p)
   do
     {
       if (a_must_be_last)
-       abort ();
+       goto invalid;
 
       /* Scan one "atom" (S in the description above of %{}, possibly
         with !, ., or * modifiers).  */
@@ -5544,32 +5563,33 @@ handle_braces (const char *p)
        p++, a_is_starred = 1;
 
       SKIP_WHITE();
-      if (*p == '&' || *p == '}')
+      switch (*p)
        {
+       case '&': case '}':
          /* Substitute the switch(es) indicated by the current atom.  */
          ordered_set = true;
          if (disjunct_set || n_way_choice || a_is_negated || a_is_suffix
              || atom == end_atom)
-           abort ();
+           goto invalid;
 
          mark_matching_switches (atom, end_atom, a_is_starred);
 
          if (*p == '}')
            process_marked_switches ();
-       }
-      else if (*p == '|' || *p == ':')
-       {
+         break;
+
+       case '|': case ':':
          /* Substitute some text if the current atom appears as a switch
             or suffix.  */
          disjunct_set = true;
          if (ordered_set)
-           abort ();
+           goto invalid;
 
          if (atom == end_atom)
            {
              if (!n_way_choice || disj_matched || *p == '|'
                  || a_is_negated || a_is_suffix || a_is_starred)
-               abort ();
+               goto invalid;
 
              /* An empty term may appear as the last choice of an
                 N-way choice set; it means "otherwise".  */
@@ -5580,7 +5600,7 @@ handle_braces (const char *p)
          else
            {
               if (a_is_suffix && a_is_starred)
-                abort ();
+                goto invalid;
 
               if (!a_is_starred)
                 disj_starred = false;
@@ -5623,14 +5643,19 @@ handle_braces (const char *p)
                  d_atom = d_end_atom = NULL;
                }
            }
+         break;
+
+       default:
+         goto invalid;
        }
-      else
-       abort ();
     }
   while (*p++ != '}');
 
   return p;
-
+  
+ invalid:
+  fatal ("braced spec '%s' is invalid at '%c'", orig, *p);
+  
 #undef SKIP_WHITE
 }
 
@@ -5670,7 +5695,7 @@ process_brace_body (const char *p, const char *atom, const char *end_atom,
       else if (*p == '%' && p[1] == '*' && nesting_level == 1)
        have_subst = true;
       else if (*p == '\0')
-       abort ();
+       goto invalid;
       p++;
     }
 
@@ -5679,7 +5704,7 @@ process_brace_body (const char *p, const char *atom, const char *end_atom,
     end_body--;
 
   if (have_subst && !starred)
-    abort ();
+    goto invalid;
 
   if (matched)
     {
@@ -5715,6 +5740,9 @@ process_brace_body (const char *p, const char *atom, const char *end_atom,
     }
 
   return p;
+
+ invalid:
+  fatal ("braced spec body '%s' is invalid", body);
 }
 \f
 /* Return 0 iff switch number SWITCHNUM is obsoleted by a later switch
@@ -6243,7 +6271,7 @@ main (int argc, const char **argv)
 
   for (i = 0; (int) i < n_switches; i++)
     if (! switches[i].validated)
-      error ("unrecognized option `-%s'", switches[i].part1);
+      error ("unrecognized option '-%s'", switches[i].part1);
 
   /* Obey some of the options.  */
 
@@ -6438,13 +6466,13 @@ main (int argc, const char **argv)
                {
                  value = do_spec (input_file_compiler->spec);
                  infiles[i].preprocessed = true;
-                 if (have_o_argbuf_index)
-                   infiles[i].name = argbuf[have_o_argbuf_index];
-                 else
-                   abort ();
-                 infiles[i].incompiler = lookup_compiler (infiles[i].name,
-                                                      strlen (infiles[i].name),
-                                                      infiles[i].language);
+                 if (!have_o_argbuf_index)
+                   fatal ("spec '%s' is invalid", input_file_compiler->spec);
+                 infiles[i].name = argbuf[have_o_argbuf_index];
+                 infiles[i].incompiler
+                   = lookup_compiler (infiles[i].name,
+                                      strlen (infiles[i].name),
+                                      infiles[i].language);
 
                  if (value < 0)
                    this_file_error = 1;
@@ -6711,9 +6739,9 @@ pfatal_pexecute (const char *errmsg_fmt, const char *errmsg_arg)
 /* Output an error message and exit.  */
 
 void
-fancy_abort (void)
+fancy_abort (const char *file, int line, const char *func)
 {
-  fatal ("internal gcc abort");
+  fatal ("internal gcc abort in %s, at %s:%d", func, file, line);
 }
 \f
 /* Output an error message and exit.  */
@@ -6905,7 +6933,10 @@ used_arg (const char *p, int len)
          while (*q != ' ')
            {
              if (*q == '\0')
-               abort ();
+               {
+               invalid_matches:
+                 fatal ("multilib spec '%s' is invalid", multilib_matches);
+               }
              q++;
            }
          matches[i].len = q - matches[i].str;
@@ -6914,7 +6945,7 @@ used_arg (const char *p, int len)
          while (*q != ';' && *q != '\0')
            {
              if (*q == ' ')
-               abort ();
+               goto invalid_matches;
              q++;
            }
          matches[i].rep_len = q - matches[i].replace;
@@ -7094,7 +7125,11 @@ set_multilib_dir (void)
       while (*p != ';')
        {
          if (*p == '\0')
-           abort ();
+           {
+           invalid_exclusions:
+             fatal ("multilib exclusions '%s' is invalid",
+                    multilib_exclusions);
+           }
 
          if (! ok)
            {
@@ -7106,7 +7141,7 @@ set_multilib_dir (void)
          while (*p != ' ' && *p != ';')
            {
              if (*p == '\0')
-               abort ();
+               goto invalid_exclusions;
              ++p;
            }
 
@@ -7148,7 +7183,11 @@ set_multilib_dir (void)
       while (*p != ' ')
        {
          if (*p == '\0')
-           abort ();
+           {
+           invalid_select:
+             fatal ("multilib select '%s' is invalid",
+                    multilib_select);
+           }
          ++p;
        }
       this_path_len = p - this_path;
@@ -7160,7 +7199,7 @@ set_multilib_dir (void)
       while (*p != ';')
        {
          if (*p == '\0')
-           abort ();
+           goto invalid_select;
 
          if (! ok)
            {
@@ -7172,7 +7211,7 @@ set_multilib_dir (void)
          while (*p != ' ' && *p != ';')
            {
              if (*p == '\0')
-               abort ();
+               goto invalid_select;
              ++p;
            }
 
@@ -7285,7 +7324,11 @@ print_multilib_info (void)
       while (*p != ' ')
        {
          if (*p == '\0')
-           abort ();
+           {
+           invalid_select:
+             fatal ("multilib select '%s' is invalid", multilib_select);
+           }
+         
          ++p;
        }
 
@@ -7319,7 +7362,11 @@ print_multilib_info (void)
                int mp = 0;
 
                if (*e == '\0')
-                 abort ();
+                 {
+                 invalid_exclusion:
+                   fatal ("multilib exclusion '%s' is invalid",
+                          multilib_exclusions);
+                 }
 
                if (! m)
                  {
@@ -7332,7 +7379,7 @@ print_multilib_info (void)
                while (*e != ' ' && *e != ';')
                  {
                    if (*e == '\0')
-                     abort ();
+                     goto invalid_exclusion;
                    ++e;
                  }
 
@@ -7343,19 +7390,20 @@ print_multilib_info (void)
                    int len = e - this_arg;
 
                    if (*q == '\0')
-                     abort ();
+                     goto invalid_select;
 
                    arg = q;
 
                    while (*q != ' ' && *q != ';')
                      {
                        if (*q == '\0')
-                         abort ();
+                         goto invalid_select;
                        ++q;
                      }
 
-                   if (! strncmp (arg, this_arg, (len < q - arg) ? q - arg : len) ||
-                       default_arg (this_arg, e - this_arg))
+                   if (! strncmp (arg, this_arg,
+                                  (len < q - arg) ? q - arg : len)
+                       || default_arg (this_arg, e - this_arg))
                      {
                        mp = 1;
                        break;
@@ -7386,7 +7434,8 @@ print_multilib_info (void)
       if (! skip)
        {
          /* If this is a duplicate, skip it.  */
-         skip = (last_path != 0 && (unsigned int) (p - this_path) == last_path_len
+         skip = (last_path != 0
+                 && (unsigned int) (p - this_path) == last_path_len
                  && ! strncmp (last_path, this_path, last_path_len));
 
          last_path = this_path;
@@ -7406,7 +7455,7 @@ print_multilib_info (void)
              const char *arg;
 
              if (*q == '\0')
-               abort ();
+               goto invalid_select;
 
              if (*q == '!')
                arg = NULL;
@@ -7416,7 +7465,7 @@ print_multilib_info (void)
              while (*q != ' ' && *q != ';')
                {
                  if (*q == '\0')
-                   abort ();
+                   goto invalid_select;
                  ++q;
                }
 
@@ -7447,7 +7496,7 @@ print_multilib_info (void)
          int use_arg;
 
          if (*p == '\0')
-           abort ();
+           goto invalid_select;
 
          if (skip)
            {
@@ -7463,7 +7512,7 @@ print_multilib_info (void)
          while (*p != ' ' && *p != ';')
            {
              if (*p == '\0')
-               abort ();
+               goto invalid_select;
              if (use_arg)
                putchar (*p);
              ++p;
@@ -7537,3 +7586,24 @@ if_exists_else_spec_function (int argc, const char **argv)
 
   return argv[1];
 }
+
+/* replace-outfile built-in spec function.
+   This looks for the first argument in the outfiles array's name and replaces it
+   with the second argument.  */
+
+static const char *
+replace_outfile_spec_function (int argc, const char **argv)
+{
+  int i;
+  /* Must have exactly two arguments.  */
+  if (argc != 2)
+    abort ();
+  
+  for (i = 0; i < n_infiles; i++)
+    {
+      if (outfiles[i] && !strcmp (outfiles[i], argv[0]))
+       outfiles[i] = xstrdup (argv[1]);
+    }
+  return NULL;
+}
+