OSDN Git Service

* Makefile.in (build/gencondmd.o): Be sure to use GTM_H instead of
[pf3gnuchains/gcc-fork.git] / gcc / gcc.c
index 31e4ab3..ffb69ce 100644 (file)
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -82,6 +82,7 @@ compilation is specified by a string called a "spec".  */
 #include "intl.h"
 #include "prefix.h"
 #include "gcc.h"
+#include "diagnostic.h"
 #include "flags.h"
 #include "opts.h"
 
@@ -262,11 +263,11 @@ static int use_pipes;
 
 static const char *compiler_version;
 
-/* The target version specified with -V */
+/* The target version */
 
 static const char *const spec_version = DEFAULT_TARGET_VERSION;
 
-/* The target machine specified with -b.  */
+/* The target machine.  */
 
 static const char *spec_machine = DEFAULT_TARGET_MACHINE;
 
@@ -296,10 +297,6 @@ static const struct modify_target
 modify_target[] = MODIFY_TARGET_NAME;
 #endif
 
-/* The number of errors that have occurred; the link phase will not be
-   run if this is nonzero.  */
-static int error_count = 0;
-
 /* Greatest exit code of sub-processes that has been encountered up to
    now.  */
 static int greatest_status = 1;
@@ -378,8 +375,6 @@ static int default_arg (const char *, int);
 static void set_multilib_dir (void);
 static void print_multilib_info (void);
 static void perror_with_name (const char *);
-static void fatal_ice (const char *, ...) ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN;
-static void notice (const char *, ...) ATTRIBUTE_PRINTF_1;
 static void display_help (void);
 static void add_preprocessor_option (const char *, int);
 static void add_assembler_option (const char *, int);
@@ -388,7 +383,7 @@ static void process_command (int, const char **);
 static int execute (void);
 static void alloc_args (void);
 static void clear_args (void);
-static void fatal_error (int);
+static void fatal_signal (int);
 #if defined(ENABLE_SHARED_LIBGCC) && !defined(REAL_LIBGCC_SPEC)
 static void init_gcc_specs (struct obstack *, const char *, const char *,
                            const char *);
@@ -403,6 +398,7 @@ static const char *if_exists_else_spec_function (int, const char **);
 static const char *replace_outfile_spec_function (int, const char **);
 static const char *version_compare_spec_function (int, const char **);
 static const char *include_spec_function (int, const char **);
+static const char *find_file_spec_function (int, const char **);
 static const char *print_asm_header_spec_function (int, const char **);
 static const char *compare_debug_dump_opt_spec_function (int, const char **);
 static const char *compare_debug_self_opt_spec_function (int, const char **);
@@ -780,16 +776,11 @@ proper position among the other output files.  */
     %{fuse-linker-plugin: \
     -plugin %(linker_plugin_file) \
     -plugin-opt=%(lto_wrapper) \
-    -plugin-opt=%(lto_gcc) \
+    -plugin-opt=-fresolution=%u.res \
     %{static|static-libgcc:-plugin-opt=-pass-through=%(lto_libgcc)}    \
     %{static:-plugin-opt=-pass-through=-lc}    \
-    %{O*:-plugin-opt=-O%*} \
-    %{w:-plugin-opt=-w} \
-    %{f*:-plugin-opt=-f%*} \
-    %{m*:-plugin-opt=-m%*} \
-    %{v:-plugin-opt=-v} \
     } \
-    %{flto} %{fwhopr} %l " LINK_PIE_SPEC \
+    %{flto} %{fwhopr*} %l " LINK_PIE_SPEC \
    "%X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r}\
     %{s} %{t} %{u*} %{x} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}}\
     %{static:} %{L*} %(mfwrap) %(link_libgcc) %o\
@@ -872,6 +863,7 @@ static const char *cpp_unique_options =
  %{M} %{MM} %{MF*} %{MG} %{MP} %{MQ*} %{MT*}\
  %{!E:%{!M:%{!MM:%{!MT:%{!MQ:%{MD|MMD:%{o*:-MQ %*}}}}}}}\
  %{remap} %{g3|ggdb3|gstabs3|gcoff3|gxcoff3|gvms3:-dD}\
+ %{!iplugindir*:%{fplugin*:-iplugindir=%:find-file(plugin)}}\
  %{H} %C %{D*&U*&A*} %{i*} %Z %i\
  %{fmudflap:-D_MUDFLAP -include mf-runtime.h}\
  %{fmudflapth:-D_MUDFLAP -D_MUDFLAPTH -include mf-runtime.h}\
@@ -894,6 +886,7 @@ static const char *cpp_debug_options = "%{d*}";
 /* NB: This is shared amongst all front-ends, except for Ada.  */
 static const char *cc1_options =
 "%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
+ %{!iplugindir*:%{fplugin*:-iplugindir=%:find-file(plugin)}}\
  %1 %{!Q:-quiet} %{!dumpbase:-dumpbase %B} %{d*} %{m*} %{a*}\
  %{fcompare-debug-second:%:compare-debug-auxbase-opt(%b)} \
  %{!fcompare-debug-second:%{c|S:%{o*:-auxbase-strip %*}%{!o*:-auxbase %b}}}%{!c:%{!S:-auxbase %b}} \
@@ -1726,6 +1719,7 @@ static const struct spec_function static_spec_functions[] =
   { "replace-outfile",         replace_outfile_spec_function },
   { "version-compare",         version_compare_spec_function },
   { "include",                 include_spec_function },
+  { "find-file",               find_file_spec_function },
   { "print-asm-header",                print_asm_header_spec_function },
   { "compare-debug-dump-opt",  compare_debug_dump_opt_spec_function },
   { "compare-debug-self-opt",  compare_debug_self_opt_spec_function },
@@ -1796,7 +1790,7 @@ init_spec (void)
     return;                    /* Already initialized.  */
 
   if (verbose_flag)
-    notice ("Using built-in specs.\n");
+    fnotice (stderr, "Using built-in specs.\n");
 
 #ifdef EXTRA_SPECS
   extra_specs = XCNEWVEC (struct spec_list, ARRAY_SIZE (extra_specs_1));
@@ -1981,7 +1975,7 @@ set_spec (const char *name, const char *spec)
 
 #ifdef DEBUG_SPECS
   if (verbose_flag)
-    notice ("Setting spec %s to '%s'\n\n", name, *(sl->ptr_spec));
+    fnotice (stderr, "Setting spec %s to '%s'\n\n", name, *(sl->ptr_spec));
 #endif
 
   /* Free the old spec.  */
@@ -2036,10 +2030,6 @@ static int execution_count;
 /* Number of commands that exited with a signal.  */
 
 static int signal_count;
-
-/* Name with which this program was invoked.  */
-
-static const char *programname;
 \f
 /* Allocate the argument vector.  */
 
@@ -2077,7 +2067,15 @@ store_arg (const char *arg, int delete_always, int delete_failure)
   if (strcmp (arg, "-o") == 0)
     have_o_argbuf_index = argbuf_index;
   if (delete_always || delete_failure)
-    record_temp_file (arg, delete_always, delete_failure);
+    {
+      const char *p;
+      /* If the temporary file we should delete is specified as
+        part of a joined argument extract the filename.  */
+      if (arg[0] == '-'
+         && (p = strrchr (arg, '=')))
+       arg = p + 1;
+      record_temp_file (arg, delete_always, delete_failure);
+    }
 }
 \f
 /* Load specs from a file name named FILENAME, replacing occurrences of
@@ -2096,7 +2094,7 @@ load_specs (const char *filename)
   char *specs_p;
 
   if (verbose_flag)
-    notice ("Reading specs from %s\n", filename);
+    fnotice (stderr, "Reading specs from %s\n", filename);
 
   /* Open and stat the file.  */
   desc = open (filename, O_RDONLY, 0);
@@ -2192,8 +2190,9 @@ read_specs (const char *filename, int main_p)
                p1++;
 
              if (*p1++ != '<' || p[-2] != '>')
-               fatal ("specs %%include syntax malformed after %ld characters",
-                      (long) (p1 - buffer + 1));
+               fatal_error ("specs %%include syntax malformed after "
+                            "%ld characters",
+                            (long) (p1 - buffer + 1));
 
              p[-2] = '\0';
              new_filename = find_a_file (&startfile_prefixes, p1, R_OK, true);
@@ -2211,15 +2210,16 @@ read_specs (const char *filename, int main_p)
                p1++;
 
              if (*p1++ != '<' || p[-2] != '>')
-               fatal ("specs %%include syntax malformed after %ld characters",
-                      (long) (p1 - buffer + 1));
+               fatal_error ("specs %%include syntax malformed after "
+                            "%ld characters",
+                            (long) (p1 - buffer + 1));
 
              p[-2] = '\0';
              new_filename = find_a_file (&startfile_prefixes, p1, R_OK, true);
              if (new_filename)
                read_specs (new_filename, FALSE);
              else if (verbose_flag)
-               notice ("could not find specs file %s\n", p1);
+               fnotice (stderr, "could not find specs file %s\n", p1);
              continue;
            }
          else if (!strncmp (p1, "%rename", sizeof "%rename" - 1)
@@ -2236,16 +2236,18 @@ read_specs (const char *filename, int main_p)
                p1++;
 
              if (! ISALPHA ((unsigned char) *p1))
-               fatal ("specs %%rename syntax malformed after %ld characters",
-                      (long) (p1 - buffer));
+               fatal_error ("specs %%rename syntax malformed after "
+                            "%ld characters",
+                            (long) (p1 - buffer));
 
              p2 = p1;
              while (*p2 && !ISSPACE ((unsigned char) *p2))
                p2++;
 
              if (*p2 != ' ' && *p2 != '\t')
-               fatal ("specs %%rename syntax malformed after %ld characters",
-                      (long) (p2 - buffer));
+               fatal_error ("specs %%rename syntax malformed after "
+                            "%ld characters",
+                            (long) (p2 - buffer));
 
              name_len = p2 - p1;
              *p2++ = '\0';
@@ -2253,8 +2255,9 @@ read_specs (const char *filename, int main_p)
                p2++;
 
              if (! ISALPHA ((unsigned char) *p2))
-               fatal ("specs %%rename syntax malformed after %ld characters",
-                      (long) (p2 - buffer));
+               fatal_error ("specs %%rename syntax malformed after "
+                            "%ld characters",
+                            (long) (p2 - buffer));
 
              /* Get new spec name.  */
              p3 = p2;
@@ -2262,8 +2265,9 @@ read_specs (const char *filename, int main_p)
                p3++;
 
              if (p3 != p - 1)
-               fatal ("specs %%rename syntax malformed after %ld characters",
-                      (long) (p3 - buffer));
+               fatal_error ("specs %%rename syntax malformed after "
+                            "%ld characters",
+                            (long) (p3 - buffer));
              *p3 = '\0';
 
              for (sl = specs; sl; sl = sl->next)
@@ -2271,21 +2275,22 @@ read_specs (const char *filename, int main_p)
                  break;
 
              if (!sl)
-               fatal ("specs %s spec was not found to be renamed", p1);
+               fatal_error ("specs %s spec was not found to be renamed", p1);
 
              if (strcmp (p1, p2) == 0)
                continue;
 
              for (newsl = specs; newsl; newsl = newsl->next)
                if (strcmp (newsl->name, p2) == 0)
-                 fatal ("%s: attempt to rename spec '%s' to already defined spec '%s'",
+                 fatal_error ("%s: attempt to rename spec '%s' to "
+                              "already defined spec '%s'",
                    filename, p1, p2);
 
              if (verbose_flag)
                {
-                 notice ("rename spec %s to %s\n", p1, p2);
+                 fnotice (stderr, "rename spec %s to %s\n", p1, p2);
 #ifdef DEBUG_SPECS
-                 notice ("spec is '%s'\n\n", *(sl->ptr_spec));
+                 fnotice (stderr, "spec is '%s'\n\n", *(sl->ptr_spec));
 #endif
                }
 
@@ -2298,8 +2303,8 @@ read_specs (const char *filename, int main_p)
              continue;
            }
          else
-           fatal ("specs unknown %% command after %ld characters",
-                  (long) (p1 - buffer));
+           fatal_error ("specs unknown %% command after %ld characters",
+                        (long) (p1 - buffer));
        }
 
       /* Find the colon that should end the suffix.  */
@@ -2309,8 +2314,8 @@ read_specs (const char *filename, int main_p)
 
       /* The colon shouldn't be missing.  */
       if (*p1 != ':')
-       fatal ("specs file malformed after %ld characters",
-              (long) (p1 - buffer));
+       fatal_error ("specs file malformed after %ld characters",
+                    (long) (p1 - buffer));
 
       /* Skip back over trailing whitespace.  */
       p2 = p1;
@@ -2322,8 +2327,8 @@ read_specs (const char *filename, int main_p)
       /* Find the next line.  */
       p = skip_whitespace (p1 + 1);
       if (p[1] == 0)
-       fatal ("specs file malformed after %ld characters",
-              (long) (p - buffer));
+       fatal_error ("specs file malformed after %ld characters",
+                    (long) (p - buffer));
 
       p1 = p;
       /* Find next blank line or end of string.  */
@@ -2374,7 +2379,7 @@ read_specs (const char *filename, int main_p)
     }
 
   if (link_command_spec == 0)
-    fatal ("spec file has no spec for linking");
+    fatal_error ("spec file has no spec for linking");
 }
 \f
 /* Record the names of temporary files we tell compilers to write,
@@ -2702,7 +2707,7 @@ static void
 xputenv (const char *string)
 {
   if (verbose_flag)
-    notice ("%s\n", string);
+    fnotice (stderr, "%s\n", string);
   putenv (CONST_CAST (char *, string));
 }
 
@@ -2903,7 +2908,7 @@ add_sysrooted_prefix (struct path_prefix *pprefix, const char *prefix,
                      int require_machine_suffix, int os_multilib)
 {
   if (!IS_ABSOLUTE_PATH (prefix))
-    fatal ("system path '%s' is not absolute", prefix);
+    fatal_error ("system path '%s' is not absolute", prefix);
 
   if (target_system_root)
     {
@@ -2975,7 +2980,7 @@ execute (void)
     if (strcmp (argbuf[i], "|") == 0)
       {                                /* each command.  */
 #if defined (__MSDOS__) || defined (OS2) || defined (VMS)
-       fatal ("-pipe not supported");
+       fatal_error ("-pipe not supported");
 #endif
        argbuf[i] = 0;  /* termination of command args.  */
        commands[n_commands].prog = argbuf[i + 1];
@@ -3007,14 +3012,23 @@ execute (void)
              for (j = commands[i].argv; *j; j++)
                {
                  const char *p;
-                 fprintf (stderr, " \"");
                  for (p = *j; *p; ++p)
+                   if (!ISALNUM ((unsigned char) *p)
+                       && *p != '_' && *p != '/' && *p != '-' && *p != '.')
+                     break;
+                 if (*p || !*j)
                    {
-                     if (*p == '"' || *p == '\\' || *p == '$')
-                       fputc ('\\', stderr);
-                     fputc (*p, stderr);
+                     fprintf (stderr, " \"");
+                     for (p = *j; *p; ++p)
+                       {
+                         if (*p == '"' || *p == '\\' || *p == '$')
+                           fputc ('\\', stderr);
+                         fputc (*p, stderr);
+                       }
+                     fputc ('"', stderr);
                    }
-                 fputc ('"', stderr);
+                 else
+                   fprintf (stderr, " %s", *j);
                }
            }
          else
@@ -3037,7 +3051,7 @@ execute (void)
          return 0;
         }
 #ifdef DEBUG
-      notice ("\nGo ahead? (y or n) ");
+      fnotice (stderr, "\nGo ahead? (y or n) ");
       fflush (stderr);
       i = getchar ();
       if (i != '\n')
@@ -3080,7 +3094,7 @@ execute (void)
 
   pex = pex_init (PEX_USE_PIPES | ((report_times || report_times_to_file)
                                   ? PEX_RECORD_TIMES : 0),
-                 programname, temp_filename);
+                 progname, temp_filename);
   if (pex == NULL)
     pfatal_with_name (_("pex_init failed"));
 
@@ -3098,7 +3112,7 @@ execute (void)
       if (errmsg != NULL)
        {
          if (err == 0)
-           fatal (errmsg);
+           fatal_error (errmsg);
          else
            {
              errno = err;
@@ -3153,12 +3167,8 @@ execute (void)
              }
            else
 #endif
-             fatal_ice ("\
-Internal error: %s (program %s)\n\
-Please submit a full bug report.\n\
-See %s for instructions.",
-                       strsignal (WTERMSIG (status)), commands[i].prog,
-                       bug_report_url);
+             internal_error ("%s (program %s)",
+                             strsignal (WTERMSIG (status)), commands[i].prog);
          }
        else if (WIFEXITED (status)
                 && WEXITSTATUS (status) >= MIN_FATAL_STATUS)
@@ -3181,7 +3191,8 @@ See %s for instructions.",
            if (ut + st != 0)
              {
                if (report_times)
-                 notice ("# %s %.2f %.2f\n", commands[i].prog, ut, st);
+                 fnotice (stderr, "# %s %.2f %.2f\n",
+                          commands[i].prog, ut, st);
 
                if (report_times_to_file)
                  {
@@ -3375,7 +3386,7 @@ convert_filename (const char *name, int do_exe ATTRIBUTE_UNUSED,
 static void
 display_help (void)
 {
-  printf (_("Usage: %s [options] file...\n"), programname);
+  printf (_("Usage: %s [options] file...\n"), progname);
   fputs (_("Options:\n"), stdout);
 
   fputs (_("  -pass-exit-codes         Exit with highest error code from a phase\n"), stdout);
@@ -3420,8 +3431,6 @@ display_help (void)
   --sysroot=<directory>    Use <directory> as the root directory for headers\n\
                            and libraries\n"), stdout);
   fputs (_("  -B <directory>           Add <directory> to the compiler's search paths\n"), stdout);
-  fputs (_("  -b <machine>             Run gcc for target <machine>, if installed\n"), stdout);
-  fputs (_("  -V <version>             Run gcc version number <version>, if installed\n"), stdout);
   fputs (_("  -v                       Display the programs invoked by the compiler\n"), stdout);
   fputs (_("  -###                     Like -v but options quoted and commands not executed\n"), stdout);
   fputs (_("  -E                       Preprocess only; do not compile, assemble or link\n"), stdout);
@@ -3439,7 +3448,7 @@ display_help (void)
 \nOptions starting with -g, -f, -m, -O, -W, or --param are automatically\n\
  passed on to the various sub-processes invoked by %s.  In order to pass\n\
  other options on to these processes the -W<letter> options must be used.\n\
-"), programname);
+"), progname);
 
   /* The rest of the options are displayed by invocations of the various
      sub-processes.  */
@@ -3526,81 +3535,6 @@ process_command (int argc, const char **argv)
        }
     }
 
-  /* If there is a -V or -b option (or both), process it now, before
-     trying to interpret the rest of the command line.
-     Use heuristic that all configuration names must have at least
-     one dash '-'. This allows us to pass options starting with -b.  */
-  if (argc > 1 && argv[1][0] == '-'
-      && (argv[1][1] == 'V'
-         || (argv[1][1] == 'b'
-             && (argv[1][2] == '\0'
-                 || NULL != strchr (argv[1] + 2, '-')))))
-    {
-      const char *new_version = DEFAULT_TARGET_VERSION;
-      const char *new_machine = DEFAULT_TARGET_MACHINE;
-      const char *progname = argv[0];
-      char **new_argv;
-      char *new_argv0;
-      int baselen;
-      int status = 0;
-      int err = 0;
-      const char *errmsg;
-
-      while (argc > 1 && argv[1][0] == '-'
-            && (argv[1][1] == 'V'
-                || (argv[1][1] == 'b'
-                    && (argv[1][2] == '\0'
-                        || NULL != strchr (argv[1] + 2, '-')))))
-       {
-         char opt = argv[1][1];
-         const char *arg;
-         if (argv[1][2] != '\0')
-           {
-             arg = argv[1] + 2;
-             argc -= 1;
-             argv += 1;
-           }
-         else if (argc > 2)
-           {
-             arg = argv[2];
-             argc -= 2;
-             argv += 2;
-           }
-         else
-           fatal ("'-%c' option must have argument", opt);
-         if (opt == 'V')
-           new_version = arg;
-         else
-           new_machine = arg;
-       }
-
-      for (baselen = strlen (progname); baselen > 0; baselen--)
-       if (IS_DIR_SEPARATOR (progname[baselen-1]))
-         break;
-      new_argv0 = XDUPVAR (char, progname, baselen,
-                          baselen + concat_length (new_version, new_machine,
-                                                   "-gcc-", NULL) + 1);
-      strcpy (new_argv0 + baselen, new_machine);
-      strcat (new_argv0, "-gcc-");
-      strcat (new_argv0, new_version);
-
-      new_argv = XDUPVEC (char *, argv, argc + 1);
-      new_argv[0] = new_argv0;
-
-      errmsg = pex_one (PEX_SEARCH, new_argv0, new_argv, progname, NULL,
-                       NULL, &status, &err);
-
-      if (errmsg)
-       {
-         if (err == 0)
-           fatal ("couldn't run '%s': %s", new_argv0, errmsg);
-         else
-           fatal ("couldn't run '%s': %s: %s", new_argv0, errmsg,
-                   xstrerror (err));
-        }
-      exit (status);
-    }
-
   /* Convert new-style -- options to old-style.  */
   translate_options (&argc,
                     CONST_CAST2 (const char *const **, const char ***,
@@ -3973,7 +3907,7 @@ process_command (int argc, const char **argv)
       else if (strcmp (argv[i], "-Xlinker") == 0)
        {
          if (i + 1 == argc)
-           fatal ("argument to '-Xlinker' is missing");
+           fatal_error ("argument to '-Xlinker' is missing");
 
          n_infiles++;
          i++;
@@ -3981,21 +3915,21 @@ process_command (int argc, const char **argv)
       else if (strcmp (argv[i], "-Xpreprocessor") == 0)
        {
          if (i + 1 == argc)
-           fatal ("argument to '-Xpreprocessor' is missing");
+           fatal_error ("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_error ("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_error ("argument to '-l' is missing");
 
          n_infiles++;
          i++;
@@ -4016,7 +3950,7 @@ process_command (int argc, const char **argv)
                   || strcmp (argv[i]+12, "object") == 0)
            save_temps_flag = SAVE_TEMPS_OBJ;
          else
-           fatal ("'%s' is an unknown -save-temps option", argv[i]);
+           fatal_error ("'%s' is an unknown -save-temps option", argv[i]);
        }
       else if (strcmp (argv[i], "-no-canonical-prefixes") == 0)
        /* Already handled as a special case, so ignored here.  */
@@ -4030,7 +3964,7 @@ process_command (int argc, const char **argv)
        {
          struct user_specs *user = XNEW (struct user_specs);
          if (++i >= argc)
-           fatal ("argument to '-specs' is missing");
+           fatal_error ("argument to '-specs' is missing");
 
          user->next = (struct user_specs *) 0;
          user->filename = argv[i];
@@ -4044,7 +3978,7 @@ process_command (int argc, const char **argv)
        {
          struct user_specs *user = XNEW (struct user_specs);
          if (strlen (argv[i]) == 7)
-           fatal ("argument to '-specs=' is missing");
+           fatal_error ("argument to '-specs=' is missing");
 
          user->next = (struct user_specs *) 0;
          user->filename = argv[i] + 7;
@@ -4072,7 +4006,7 @@ process_command (int argc, const char **argv)
       else if (strcmp (argv[i], "-wrapper") == 0)
         {
          if (++i >= argc)
-           fatal ("argument to '-wrapper' is missing");
+           fatal_error ("argument to '-wrapper' is missing");
 
           wrapper_string = argv[i];
          n_switches++;
@@ -4094,22 +4028,13 @@ process_command (int argc, const char **argv)
 
          switch (c)
            {
-           case 'b':
-             if (p[1] && NULL == strchr (argv[i] + 2, '-'))
-               goto normal_switch;
-
-             /* Fall through.  */
-           case 'V':
-             fatal ("'-%c' must come at the start of the command line", c);
-             break;
-
            case 'B':
              {
                const char *value;
                int len;
 
                if (p[1] == 0 && i + 1 == argc)
-                 fatal ("argument to '-B' is missing");
+                 fatal_error ("argument to '-B' is missing");
                if (p[1] == 0)
                  value = argv[++i];
                else
@@ -4286,7 +4211,7 @@ process_command (int argc, const char **argv)
     {
       /* -save-temps overrides -pipe, so that temp files are produced */
       if (save_temps_flag)
-       error ("warning: -pipe ignored because -save-temps specified");
+       warning (0, "-pipe ignored because -save-temps specified");
       use_pipes = 0;
     }
 
@@ -4502,7 +4427,7 @@ process_command (int argc, const char **argv)
          if (c == 'x')
            {
              if (p[1] == 0 && i + 1 == argc)
-               fatal ("argument to '-x' is missing");
+               fatal_error ("argument to '-x' is missing");
              if (p[1] == 0)
                spec_lang = argv[++i];
              else
@@ -4530,7 +4455,7 @@ process_command (int argc, const char **argv)
                  n_args = SWITCH_TAKES_ARG (c) - (p[1] != 0);
                }
              if (i + n_args >= argc)
-               fatal ("argument to '-%s' is missing", p);
+               fatal_error ("argument to '-%s' is missing", p);
              switches[n_switches].args
                = XNEWVEC (const char *, n_args + 1);
              while (j < n_args)
@@ -4558,12 +4483,14 @@ process_command (int argc, const char **argv)
          switches[n_switches].validated = 0;
          switches[n_switches].ordering = 0;
          /* These are always valid, since gcc.c itself understands the
-            first four and gfortranspec.c understands -static-libgfortran.  */
+            first four, gfortranspec.c understands -static-libgfortran
+            and g++spec.c understands -static-libstdc++ */
          if (!strcmp (p, "save-temps")
              || !strcmp (p, "static-libgcc")
              || !strcmp (p, "shared-libgcc")
              || !strcmp (p, "pipe")
-             || !strcmp (p, "static-libgfortran"))
+             || !strcmp (p, "static-libgfortran")
+             || !strcmp (p, "static-libstdc++"))
            switches[n_switches].validated = 1;
          else
            {
@@ -4605,10 +4532,7 @@ process_command (int argc, const char **argv)
            fname = xstrdup (argv[i]);
  
           if (strcmp (fname, "-") != 0 && access (fname, F_OK) < 0)
-            {
-              perror_with_name (fname);
-              error_count++;
-            }
+           perror_with_name (fname);
           else
             {
               infiles[n_infiles].language = spec_lang;
@@ -4620,7 +4544,7 @@ process_command (int argc, const char **argv)
     }
 
   if (n_infiles == last_language_n_infiles && spec_lang != 0)
-    error ("warning: '-x %s' after last input file has no effect", spec_lang);
+    warning (0, "'-x %s' after last input file has no effect", spec_lang);
 
   if (compare_debug == 2 || compare_debug == 3)
     {
@@ -4716,7 +4640,7 @@ set_collect_gcc_options (void)
    sans all directory names, and basename_length is the number
    of characters starting there excluding the suffix .c or whatever.  */
 
-static const char *input_filename;
+static const char *gcc_input_filename;
 static int input_file_number;
 size_t input_filename_length;
 static int basename_length;
@@ -4783,7 +4707,7 @@ end_going_arg (void)
 
          if (full_script_path == NULL)
            {
-             error (_("unable to locate default linker script '%s' in the library search paths"), string);
+             error ("unable to locate default linker script '%s' in the library search paths", string);
              /* Script was not found on search path.  */
              return;
            }
@@ -4971,7 +4895,7 @@ do_self_spec (const char *spec)
 
          /* Each switch should start with '-'.  */
          if (c != '-')
-           fatal ("switch '%s' does not start with '-'", argbuf[i]);
+           fatal_error ("switch '%s' does not start with '-'", argbuf[i]);
 
          p++;
          c = *p;
@@ -4995,7 +4919,7 @@ do_self_spec (const char *spec)
                  n_args = SWITCH_TAKES_ARG (c) - (p[1] != 0);
                }
              if (i + n_args >= argbuf_index)
-               fatal ("argument to '-%s' is missing", p);
+               fatal_error ("argument to '-%s' is missing", p);
              sw->args
                = XNEWVEC (const char *, n_args + 1);
              while (j < n_args)
@@ -5087,20 +5011,20 @@ create_at_file (char **argv)
   int status;
 
   if (f == NULL)
-    fatal ("could not open temporary response file %s",
-          temp_file);
+    fatal_error ("could not open temporary response file %s",
+                temp_file);
 
   status = writeargv (argv, f);
 
   if (status)
-    fatal ("could not write to temporary response file %s",
-          temp_file);
+    fatal_error ("could not write to temporary response file %s",
+                temp_file);
 
   status = fclose (f);
 
   if (EOF == status)
-    fatal ("could not close temporary response file %s",
-          temp_file);
+    fatal_error ("could not close temporary response file %s",
+                temp_file);
 
   store_arg (at_argument, 0, 0);
 
@@ -5201,7 +5125,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
        switch (c = *p++)
          {
          case 0:
-           fatal ("spec '%s' invalid", spec);
+           fatal_error ("spec '%s' invalid", spec);
 
          case 'b':
            if (save_temps_length)
@@ -5277,7 +5201,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
              buf = (char *) alloca (p - q + 1);
              strncpy (buf, q, p - q);
              buf[p - q] = 0;
-             notice ("%s\n", _(buf));
+             inform (0, "%s", _(buf));
              if (*p)
                p++;
            }
@@ -5350,7 +5274,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 == '.' || ISALNUM ((unsigned char) *p))
-                     fatal ("spec '%s' has invalid '%%0%c'", spec, *p);
+                     fatal_error ("spec '%s' has invalid '%%0%c'", spec, *p);
                    if (suffix_length == 0)
                      suffix = TARGET_OBJECT_SUFFIX;
                    else
@@ -5391,7 +5315,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
                    break;
                  }
 
-               /* If the input_filename has the same suffix specified
+               /* If the gcc_input_filename has the same suffix specified
                   for the %g, %u, or %U, and -save-temps is specified,
                   we could end up using that file as an intermediate
                   thus clobbering the user's source file (.e.g.,
@@ -5409,7 +5333,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
                    tmp[basename_length + suffix_length] = '\0';
                    temp_filename = tmp;
 
-                   if (strcmp (temp_filename, input_filename) != 0)
+                   if (strcmp (temp_filename, gcc_input_filename) != 0)
                      {
 #ifndef HOST_LACKS_INODE_NUMBERS
                        struct stat st_temp;
@@ -5417,12 +5341,13 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
                        /* Note, set_input() resets input_stat_set to 0.  */
                        if (input_stat_set == 0)
                          {
-                           input_stat_set = stat (input_filename, &input_stat);
+                           input_stat_set = stat (gcc_input_filename,
+                                                  &input_stat);
                            if (input_stat_set >= 0)
                              input_stat_set = 1;
                          }
 
-                       /* If we have the stat for the input_filename
+                       /* If we have the stat for the gcc_input_filename
                           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.  */
@@ -5432,7 +5357,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
                            || input_stat.st_ino != st_temp.st_ino)
 #else
                        /* Just compare canonical pathnames.  */
-                       char* input_realname = lrealpath (input_filename);
+                       char* input_realname = lrealpath (gcc_input_filename);
                        char* temp_realname = lrealpath (temp_filename);
                        bool files_differ = strcmp (input_realname, temp_realname);
                        free (input_realname);
@@ -5534,7 +5459,8 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
              }
            else
              {
-               obstack_grow (&obstack, input_filename, input_filename_length);
+               obstack_grow (&obstack, gcc_input_filename,
+                             input_filename_length);
                arg_going = 1;
              }
            break;
@@ -5659,7 +5585,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 != '{')
-               fatal ("spec '%s' has invalid '%%W%c", spec, *p);
+               fatal_error ("spec '%s' has invalid '%%W%c", spec, *p);
              p = handle_braces (p + 1);
              if (p == 0)
                return -1;
@@ -5679,7 +5605,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 != '{')
-               fatal ("spec '%s' has invalid '%%x%c'", spec, *p);
+               fatal_error ("spec '%s' has invalid '%%x%c'", spec, *p);
              while (*p++ != '}')
                ;
              string = save_string (p1 + 1, p - p1 - 2);
@@ -5883,7 +5809,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
               %[...] modifies -D options the way %P does;
               %(...) uses the spec unmodified.  */
          case '[':
-           error ("warning: use of obsolete %%[ operator in specs");
+           warning (0, "use of obsolete %%[ operator in specs");
          case '(':
            {
              const char *name = p;
@@ -5901,7 +5827,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
                  {
                    name = *(sl->ptr_spec);
 #ifdef DEBUG_SPECS
-                   notice ("Processing spec %c%s%c, which is '%s'\n",
+                   fnotice (stderr, "Processing spec %c%s%c, which is '%s'\n",
                            c, sl->name, (c == '(') ? ')' : ']', name);
 #endif
                    break;
@@ -6026,7 +5952,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_error ("unknown spec function '%s'", func);
 
   /* Push the spec processing context.  */
   save_argbuf_index = argbuf_index;
@@ -6046,7 +5972,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 ("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.  */
@@ -6095,10 +6021,10 @@ handle_spec_function (const char *p)
         break;
       /* Only allow [A-Za-z0-9], -, and _ in function names.  */
       if (!ISALNUM (*endp) && !(*endp == '-' || *endp == '_'))
-       fatal ("malformed spec function name");
+       fatal_error ("malformed spec function name");
     }
   if (*endp != '(')            /* ) */
-    fatal ("no arguments for spec function");
+    fatal_error ("no arguments for spec function");
   func = save_string (p, endp - p);
   p = ++endp;
 
@@ -6117,7 +6043,7 @@ handle_spec_function (const char *p)
     }
   /* ( */
   if (*endp != ')')
-    fatal ("malformed spec function arguments");
+    fatal_error ("malformed spec function arguments");
   args = save_string (p, endp - p);
   p = ++endp;
 
@@ -6363,7 +6289,7 @@ handle_braces (const char *p)
   return p;
 
  invalid:
-  fatal ("braced spec '%s' is invalid at '%c'", orig, *p);
+  fatal_error ("braced spec '%s' is invalid at '%c'", orig, *p);
 
 #undef SKIP_WHITE
 }
@@ -6451,7 +6377,7 @@ process_brace_body (const char *p, const char *atom, const char *end_atom,
   return p;
 
  invalid:
-  fatal ("braced spec body '%s' is invalid", body);
+  fatal_error ("braced spec body '%s' is invalid", body);
 }
 \f
 /* Return 0 iff switch number SWITCHNUM is obsoleted by a later switch
@@ -6640,9 +6566,9 @@ set_input (const char *filename)
 {
   const char *p;
 
-  input_filename = filename;
-  input_filename_length = strlen (input_filename);
-  input_basename = lbasename (input_filename);
+  gcc_input_filename = filename;
+  input_filename_length = strlen (gcc_input_filename);
+  input_basename = lbasename (gcc_input_filename);
 
   /* Find a suffix starting with the last period,
      and set basename_length to exclude that suffix.  */
@@ -6660,7 +6586,7 @@ set_input (const char *filename)
     input_suffix = "";
 
   /* If a spec for 'g', 'u', or 'U' is seen with -save-temps then
-     we will need to do a stat on the input_filename.  The
+     we will need to do a stat on the gcc_input_filename.  The
      INPUT_STAT_SET signals that the stat is needed.  */
   input_stat_set = 0;
 }
@@ -6668,7 +6594,7 @@ set_input (const char *filename)
 /* On fatal signals, delete all the temporary files.  */
 
 static void
-fatal_error (int signum)
+fatal_signal (int signum)
 {
   signal (signum, SIG_DFL);
   delete_failure_queue ();
@@ -6701,7 +6627,7 @@ compare_files (char *cmpfile[])
        if (stat (cmpfile[i], &st) < 0 || !S_ISREG (st.st_mode))
          {
            error ("%s: could not determine length of compare-debug file %s",
-                  input_filename, cmpfile[i]);
+                  gcc_input_filename, cmpfile[i]);
            ret = 1;
            break;
          }
@@ -6711,7 +6637,7 @@ compare_files (char *cmpfile[])
 
     if (!ret && length[0] != length[1])
       {
-       error ("%s: -fcompare-debug failure (length)", input_filename);
+       error ("%s: -fcompare-debug failure (length)", gcc_input_filename);
        ret = 1;
       }
 
@@ -6722,7 +6648,7 @@ compare_files (char *cmpfile[])
          if (fd < 0)
            {
              error ("%s: could not open compare-debug file %s",
-                    input_filename, cmpfile[i]);
+                    gcc_input_filename, cmpfile[i]);
              ret = 1;
              break;
            }
@@ -6741,7 +6667,7 @@ compare_files (char *cmpfile[])
       {
        if (memcmp (map[0], map[1], length[0]) != 0)
          {
-           error ("%s: -fcompare-debug failure", input_filename);
+           error ("%s: -fcompare-debug failure", gcc_input_filename);
            ret = 1;
          }
       }
@@ -6763,7 +6689,7 @@ compare_files (char *cmpfile[])
       if (!temp[i])
        {
          error ("%s: could not open compare-debug file %s",
-                input_filename, cmpfile[i]);
+                gcc_input_filename, cmpfile[i]);
          ret = 1;
          break;
        }
@@ -6779,7 +6705,7 @@ compare_files (char *cmpfile[])
        if (c0 != c1)
          {
            error ("%s: -fcompare-debug failure",
-                  input_filename);
+                  gcc_input_filename);
            ret = 1;
            break;
          }
@@ -6820,9 +6746,9 @@ main (int argc, char **argv)
   p = argv[0] + strlen (argv[0]);
   while (p != argv[0] && !IS_DIR_SEPARATOR (p[-1]))
     --p;
-  programname = p;
+  progname = p;
 
-  xmalloc_set_program_name (programname);
+  xmalloc_set_program_name (progname);
 
   expandargv (&argc, &argv);
 
@@ -6842,17 +6768,21 @@ main (int argc, char **argv)
 
   gcc_init_libintl ();
 
+  diagnostic_initialize (global_dc, 0);
+  if (atexit (delete_temp_files) != 0)
+    fatal_error ("atexit failed");
+
   if (signal (SIGINT, SIG_IGN) != SIG_IGN)
-    signal (SIGINT, fatal_error);
+    signal (SIGINT, fatal_signal);
 #ifdef SIGHUP
   if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
-    signal (SIGHUP, fatal_error);
+    signal (SIGHUP, fatal_signal);
 #endif
   if (signal (SIGTERM, SIG_IGN) != SIG_IGN)
-    signal (SIGTERM, fatal_error);
+    signal (SIGTERM, fatal_signal);
 #ifdef SIGPIPE
   if (signal (SIGPIPE, SIG_IGN) != SIG_IGN)
-    signal (SIGPIPE, fatal_error);
+    signal (SIGPIPE, fatal_signal);
 #endif
 #ifdef SIGCHLD
   /* We *MUST* set SIGCHLD to SIG_DFL so that the wait4() call will
@@ -7121,7 +7051,7 @@ main (int argc, char **argv)
   set_multilib_dir ();
 
   /* Set up to remember the pathname of gcc and any options
-     needed for collect.  We use argv[0] instead of programname because
+     needed for collect.  We use argv[0] instead of progname because
      we need the complete pathname.  */
   obstack_init (&collect_obstack);
   obstack_grow (&collect_obstack, "COLLECT_GCC=", sizeof ("COLLECT_GCC=") - 1);
@@ -7222,7 +7152,7 @@ main (int argc, char **argv)
       else
        /* The error status indicates that only one set of fixed
           headers should be built.  */
-       fatal ("not configured with sysroot headers suffix");
+       fatal_error ("not configured with sysroot headers suffix");
     }
 
   if (print_help_list)
@@ -7247,7 +7177,7 @@ main (int argc, char **argv)
 
   if (print_version)
     {
-      printf (_("%s %s%s\n"), programname, pkgversion_string,
+      printf (_("%s %s%s\n"), progname, pkgversion_string,
              version_string);
       printf ("Copyright %s 2010 Free Software Foundation, Inc.\n",
              _("(C)"));
@@ -7268,8 +7198,8 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
       int n;
       const char *thrmod;
 
-      notice ("Target: %s\n", spec_machine);
-      notice ("Configured with: %s\n", configuration_arguments);
+      fnotice (stderr, "Target: %s\n", spec_machine);
+      fnotice (stderr, "Configured with: %s\n", configuration_arguments);
 
 #ifdef THREAD_MODEL_SPEC
       /* We could have defined THREAD_MODEL_SPEC to "%*" by default,
@@ -7283,7 +7213,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
       thrmod = thread_model;
 #endif
 
-      notice ("Thread model: %s\n", thrmod);
+      fnotice (stderr, "Thread model: %s\n", thrmod);
 
       /* compiler_version is truncated at the first space when initialized
         from version string, so truncate version_string at the first space
@@ -7294,17 +7224,18 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
 
       if (! strncmp (version_string, compiler_version, n)
          && compiler_version[n] == 0)
-       notice ("gcc version %s %s\n", version_string, pkgversion_string);
+       fnotice (stderr, "gcc version %s %s\n", version_string,
+                pkgversion_string);
       else
-       notice ("gcc driver version %s %sexecuting gcc version %s\n",
-               version_string, pkgversion_string, compiler_version);
+       fnotice (stderr, "gcc driver version %s %sexecuting gcc version %s\n",
+                version_string, pkgversion_string, compiler_version);
 
       if (n_infiles == 0)
        return (0);
     }
 
   if (n_infiles == added_libraries)
-    fatal ("no input files");
+    fatal_error ("no input files");
 
   /* Make a place to record the compiler output file names
      that correspond to the input files.  */
@@ -7353,7 +7284,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
     }
 
   if (!combine_inputs && have_c && have_o && lang_n_infiles > 1)
-   fatal ("cannot specify -o with -c, -S or -E with multiple files");
+   fatal_error ("cannot specify -o with -c, -S or -E with multiple files");
 
   if (combine_flag && save_temps_flag)
     {
@@ -7379,7 +7310,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
              if (input_file_compiler->spec[0] == '#')
                {
                  error ("%s: %s compiler not installed on this system",
-                        input_filename, &input_file_compiler->spec[1]);
+                        gcc_input_filename, &input_file_compiler->spec[1]);
                  this_file_error = 1;
                }
              else
@@ -7387,7 +7318,8 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
                  value = do_spec (input_file_compiler->spec);
                  infiles[i].preprocessed = true;
                  if (!have_o_argbuf_index)
-                   fatal ("spec '%s' is invalid", input_file_compiler->spec);
+                   fatal_error ("spec '%s' is invalid",
+                                input_file_compiler->spec);
                  infiles[i].name = argbuf[have_o_argbuf_index];
                  infiles[i].incompiler
                    = lookup_compiler (infiles[i].name,
@@ -7402,7 +7334,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
          if (this_file_error)
            {
              delete_failure_queue ();
-             error_count++;
+             errorcount++;
              break;
            }
          clear_failure_queue ();
@@ -7424,7 +7356,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
 
       /* Use the same thing in %o, unless cp->spec says otherwise.  */
 
-      outfiles[i] = input_filename;
+      outfiles[i] = gcc_input_filename;
 
       /* Figure out which compiler from the file's suffix.  */
 
@@ -7442,7 +7374,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
          if (input_file_compiler->spec[0] == '#')
            {
              error ("%s: %s compiler not installed on this system",
-                    input_filename, &input_file_compiler->spec[1]);
+                    gcc_input_filename, &input_file_compiler->spec[1]);
              this_file_error = 1;
            }
          else
@@ -7465,7 +7397,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
              else if (compare_debug && debug_check_temp_file[0])
                {
                  if (verbose_flag)
-                   error ("Recompiling with -fcompare-debug");
+                   inform (0, "recompiling with -fcompare-debug");
 
                  compare_debug = -compare_debug;
                  n_switches = n_switches_debug_check[1];
@@ -7488,7 +7420,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
                                         debug_check_temp_file[1]));
 
                  if (verbose_flag)
-                   error ("Comparing final insns dumps");
+                   inform (0, "comparing final insns dumps");
 
                  if (compare_files (debug_check_temp_file))
                    this_file_error = 1;
@@ -7519,7 +7451,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
       if (this_file_error)
        {
          delete_failure_queue ();
-         error_count++;
+         errorcount++;
        }
       /* If this compilation succeeded, don't delete those files later.  */
       clear_failure_queue ();
@@ -7541,13 +7473,13 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
          }
     }
 
-  if (error_count == 0)
+  if (!seen_error ())
     {
       /* Make sure INPUT_FILE_NUMBER points to first available open
         slot.  */
       input_file_number = n_infiles;
       if (lang_specific_pre_link ())
-       error_count++;
+       errorcount++;
     }
 
   /* Determine if there are any linker input files.  */
@@ -7558,7 +7490,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
 
   /* Run ld to link all the compiler output files.  */
 
-  if (num_linker_inputs > 0 && error_count == 0 && print_subprocess_help < 2)
+  if (num_linker_inputs > 0 && !seen_error () && print_subprocess_help < 2)
     {
       int tmp = execution_count;
       const char *fuse_linker_plugin = "fuse-linker-plugin";
@@ -7575,15 +7507,15 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
                          fuse_linker_plugin + strlen (fuse_linker_plugin), 0))
        {
          linker_plugin_file_spec = find_a_file (&exec_prefixes,
-                                                "liblto_plugin.so", X_OK,
+                                                "liblto_plugin.so", R_OK,
                                                 false);
          if (!linker_plugin_file_spec)
-           fatal ("-fuse-linker-plugin, but liblto_plugin.so not found");
+           fatal_error ("-fuse-linker-plugin, but liblto_plugin.so not found");
 
          lto_libgcc_spec = find_a_file (&startfile_prefixes, "libgcc.a",
                                         R_OK, true);
          if (!lto_libgcc_spec)
-           fatal ("could not find libgcc.a");
+           fatal_error ("could not find libgcc.a");
        }
       lto_gcc_spec = argv[0];
 
@@ -7601,23 +7533,23 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
        }
       value = do_spec (link_command_spec);
       if (value < 0)
-       error_count = 1;
+       errorcount = 1;
       linker_was_run = (tmp != execution_count);
     }
 
   /* If options said don't run linker,
      complain about input files to be given to the linker.  */
 
-  if (! linker_was_run && error_count == 0)
+  if (! linker_was_run && !seen_error ())
     for (i = 0; (int) i < n_infiles; i++)
       if (explicit_link_files[i]
          && !(infiles[i].language && infiles[i].language[0] == '*'))
-       error ("%s: linker input file unused because linking not done",
-              outfiles[i]);
+       warning (0, "%s: linker input file unused because linking not done",
+                outfiles[i]);
 
   /* Delete some or all of the temporary files we made.  */
 
-  if (error_count)
+  if (seen_error ())
     delete_failure_queue ();
   delete_temp_files ();
 
@@ -7628,7 +7560,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
     }
 
   return (signal_count != 0 ? 2
-         : error_count > 0 ? (pass_exit_codes ? greatest_status : 1)
+         : seen_error () ? (pass_exit_codes ? greatest_status : 1)
          : 0);
 }
 
@@ -7725,75 +7657,6 @@ perror_with_name (const char *name)
 {
   error ("%s: %s", name, xstrerror (errno));
 }
-
-/* Output an error message and exit.  */
-
-void
-fancy_abort (const char *file, int line, const char *func)
-{
-  fatal_ice ("internal gcc abort in %s, at %s:%d", func, file, line);
-}
-\f
-/* Output an error message and exit.  */
-
-void
-fatal_ice (const char *cmsgid, ...)
-{
-  va_list ap;
-
-  va_start (ap, cmsgid);
-
-  fprintf (stderr, "%s: ", programname);
-  vfprintf (stderr, _(cmsgid), ap);
-  va_end (ap);
-  fprintf (stderr, "\n");
-  delete_temp_files ();
-  exit (pass_exit_codes ? ICE_EXIT_CODE : 1);
-}
-
-void
-fatal (const char *cmsgid, ...)
-{
-  va_list ap;
-
-  va_start (ap, cmsgid);
-
-  fprintf (stderr, "%s: ", programname);
-  vfprintf (stderr, _(cmsgid), ap);
-  va_end (ap);
-  fprintf (stderr, "\n");
-  delete_temp_files ();
-  exit (1);
-}
-
-/* The argument is actually c-format, not gcc-internal-format,
-   but because functions with identical names are used through
-   the rest of the compiler with gcc-internal-format, we just
-   need to hope all users of these functions use the common
-   subset between c-format and gcc-internal-format.  */
-
-void
-error (const char *gmsgid, ...)
-{
-  va_list ap;
-
-  va_start (ap, gmsgid);
-  fprintf (stderr, "%s: ", programname);
-  vfprintf (stderr, _(gmsgid), ap);
-  va_end (ap);
-
-  fprintf (stderr, "\n");
-}
-
-static void
-notice (const char *cmsgid, ...)
-{
-  va_list ap;
-
-  va_start (ap, cmsgid);
-  vfprintf (stderr, _(cmsgid), ap);
-  va_end (ap);
-}
 \f
 static inline void
 validate_switches_from_spec (const char *spec)
@@ -7947,7 +7810,8 @@ used_arg (const char *p, int len)
              if (*q == '\0')
                {
                invalid_matches:
-                 fatal ("multilib spec '%s' is invalid", multilib_matches);
+                 fatal_error ("multilib spec '%s' is invalid",
+                              multilib_matches);
                }
              q++;
            }
@@ -8138,8 +8002,8 @@ set_multilib_dir (void)
          if (*p == '\0')
            {
            invalid_exclusions:
-             fatal ("multilib exclusions '%s' is invalid",
-                    multilib_exclusions);
+             fatal_error ("multilib exclusions '%s' is invalid",
+                          multilib_exclusions);
            }
 
          if (! ok)
@@ -8196,8 +8060,8 @@ set_multilib_dir (void)
          if (*p == '\0')
            {
            invalid_select:
-             fatal ("multilib select '%s' is invalid",
-                    multilib_select);
+             fatal_error ("multilib select '%s' is invalid",
+                          multilib_select);
            }
          ++p;
        }
@@ -8337,7 +8201,7 @@ print_multilib_info (void)
          if (*p == '\0')
            {
            invalid_select:
-             fatal ("multilib select '%s' is invalid", multilib_select);
+             fatal_error ("multilib select '%s' is invalid", multilib_select);
            }
 
          ++p;
@@ -8375,8 +8239,8 @@ print_multilib_info (void)
                if (*e == '\0')
                  {
                  invalid_exclusion:
-                   fatal ("multilib exclusion '%s' is invalid",
-                          multilib_exclusions);
+                   fatal_error ("multilib exclusion '%s' is invalid",
+                                multilib_exclusions);
                  }
 
                if (! m)
@@ -8581,7 +8445,7 @@ getenv_spec_function (int argc, const char **argv)
 
   value = getenv (argv[0]);
   if (!value)
-    fatal ("environment variable \"%s\" not defined", argv[0]);
+    fatal_error ("environment variable \"%s\" not defined", argv[0]);
 
   /* We have to escape every character of the environment variable so
      they are not interpreted as active spec characters.  A
@@ -8672,12 +8536,12 @@ compare_version_strings (const char *v1, const char *v2)
     abort ();
   rresult = regexec (&r, v1, 0, NULL, 0);
   if (rresult == REG_NOMATCH)
-    fatal ("invalid version number `%s'", v1);
+    fatal_error ("invalid version number `%s'", v1);
   else if (rresult != 0)
     abort ();
   rresult = regexec (&r, v2, 0, NULL, 0);
   if (rresult == REG_NOMATCH)
-    fatal ("invalid version number `%s'", v2);
+    fatal_error ("invalid version number `%s'", v2);
   else if (rresult != 0)
     abort ();
 
@@ -8720,13 +8584,13 @@ version_compare_spec_function (int argc, const char **argv)
   bool result;
 
   if (argc < 3)
-    fatal ("too few arguments to %%:version-compare");
+    fatal_error ("too few arguments to %%:version-compare");
   if (argv[0][0] == '\0')
     abort ();
   if ((argv[0][1] == '<' || argv[0][1] == '>') && argv[0][0] != '!')
     nargs = 2;
   if (argc != nargs + 3)
-    fatal ("too many arguments to %%:version-compare");
+    fatal_error ("too many arguments to %%:version-compare");
 
   switch_len = strlen (argv[nargs + 1]);
   for (i = 0; i < n_switches; i++)
@@ -8767,7 +8631,7 @@ version_compare_spec_function (int argc, const char **argv)
       break;
 
     default:
-      fatal ("unknown operator '%s' in %%:version-compare", argv[0]);
+      fatal_error ("unknown operator '%s' in %%:version-compare", argv[0]);
     }
   if (! result)
     return NULL;
@@ -8794,6 +8658,22 @@ include_spec_function (int argc, const char **argv)
   return NULL;
 }
 
+/* %:find-file spec function.  This function replace its argument by
+    the file found thru find_file, that is the -print-file-name gcc
+    program option. */
+static const char *
+find_file_spec_function (int argc, const char**argv)
+{
+  const char *file;
+
+  if (argc != 1)
+    abort ();
+
+  file = find_file (argv[0]);
+  return file;
+}
+
+
 /* %:print-asm-header spec function.  Print a banner to say that the
    following output is from the assembler.  */
 
@@ -8848,7 +8728,7 @@ compare_debug_dump_opt_spec_function (int arg,
   static char random_seed[HOST_BITS_PER_WIDE_INT / 4 + 3];
 
   if (arg != 0)
-    fatal ("too many arguments to %%:compare-debug-dump-opt");
+    fatal_error ("too many arguments to %%:compare-debug-dump-opt");
 
   do_spec_2 ("%{fdump-final-insns=*:%*}");
   do_spec_1 (" ", 0, NULL);
@@ -8915,7 +8795,7 @@ compare_debug_self_opt_spec_function (int arg,
                                      const char **argv ATTRIBUTE_UNUSED)
 {
   if (arg != 0)
-    fatal ("too many arguments to %%:compare-debug-self-opt");
+    fatal_error ("too many arguments to %%:compare-debug-self-opt");
 
   if (compare_debug >= 0)
     return NULL;
@@ -8950,17 +8830,18 @@ compare_debug_auxbase_opt_spec_function (int arg,
   int len;
 
   if (arg == 0)
-    fatal ("too few arguments to %%:compare-debug-auxbase-opt");
+    fatal_error ("too few arguments to %%:compare-debug-auxbase-opt");
 
   if (arg != 1)
-    fatal ("too many arguments to %%:compare-debug-auxbase-opt");
+    fatal_error ("too many arguments to %%:compare-debug-auxbase-opt");
 
   if (compare_debug >= 0)
     return NULL;
 
   len = strlen (argv[0]);
   if (len < 3 || strcmp (argv[0] + len - 3, ".gk") != 0)
-    fatal ("argument to %%:compare-debug-auxbase-opt does not end in .gk");
+    fatal_error ("argument to %%:compare-debug-auxbase-opt "
+                "does not end in .gk");
 
   if (debug_auxbase_opt)
     return debug_auxbase_opt;