OSDN Git Service

* fold-const.c (invert_tree_comparison): Always invert EQ_EXPR/NE_EXPR.
[pf3gnuchains/gcc-fork.git] / gcc / gcc.c
index a0343fa..3bfdf77 100644 (file)
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -1,7 +1,7 @@
 /* Compiler driver program that can handle many languages.
    Copyright (C) 1987, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
    1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
-   2010
+   2010, 2011
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -43,7 +43,9 @@ compilation is specified by a string called a "spec".  */
 #include "diagnostic.h"
 #include "flags.h"
 #include "opts.h"
+#include "params.h"
 #include "vec.h"
+#include "filenames.h"
 
 /* By default there is no special suffix for target executables.  */
 /* FIXME: when autoconf is fixed, remove the host check - dj */
@@ -390,6 +392,7 @@ or with constant text in a single argument.
         Note - this command is position dependent.  % commands in the
         spec string before this one will see -S, % commands in the
         spec string after this one will not.
+ %>S   Similar to "%<S", but keep it in the GCC command line.
  %<S*  remove all occurrences of all switches beginning with -S from the
         command line.
  %:function(args)
@@ -435,7 +438,6 @@ or with constant text in a single argument.
           This may be combined with '.', '!', ',', '|', and '*' as above.
 
  %(Spec) processes a specification defined in a specs file as *Spec:
- %[Spec] as above, but put __ around -D arguments
 
 The conditional text X in a %{S:X} or similar construct may contain
 other nested % constructs or spaces, or even newlines.  They are
@@ -515,7 +517,7 @@ proper position among the other output files.  */
 /* XXX: should exactly match hooks provided by libmudflap.a */
 #define MFWRAP_SPEC " %{static: %{fmudflap|fmudflapth: \
  --wrap=malloc --wrap=free --wrap=calloc --wrap=realloc\
- --wrap=mmap --wrap=munmap --wrap=alloca\
+ --wrap=mmap --wrap=mmap64 --wrap=munmap --wrap=alloca\
 } %{fmudflapth: --wrap=pthread_create\
 }} %{fmudflap|fmudflapth: --wrap=main}"
 #endif
@@ -620,6 +622,38 @@ proper position among the other output files.  */
 # endif
 #endif
 
+/* Conditional to test whether the LTO plugin is used or not.
+   FIXME: For slim LTO we will need to enable plugin unconditionally.  This
+   still cause problems with PLUGIN_LD != LD and when plugin is built but
+   not useable.  For GCC 4.6 we don't support slim LTO and thus we can enable
+   plugin only when LTO is enabled.  We still honor explicit
+   -fuse-linker-plugin if the linker used understands -plugin.  */
+
+/* The linker has some plugin support.  */
+#if HAVE_LTO_PLUGIN > 0
+/* The linker used has full plugin support, use LTO plugin by default.  */
+#if HAVE_LTO_PLUGIN == 2
+#define PLUGIN_COND "!fno-use-linker-plugin:%{flto|flto=*|fuse-linker-plugin"
+#define PLUGIN_COND_CLOSE "}"
+#else
+/* The linker used has limited plugin support, use LTO plugin with explicit
+   -fuse-linker-plugin.  */
+#define PLUGIN_COND "fuse-linker-plugin"
+#define PLUGIN_COND_CLOSE ""
+#endif
+#define LINK_PLUGIN_SPEC \
+    "%{"PLUGIN_COND": \
+    -plugin %(linker_plugin_file) \
+    -plugin-opt=%(lto_wrapper) \
+    -plugin-opt=-fresolution=%u.res \
+    %{!nostdlib:%{!nodefaultlibs:%:pass-through-libs(%(link_gcc_c_sequence))}} \
+    }"PLUGIN_COND_CLOSE
+#else
+/* The linker used doesn't support -plugin, reject -fuse-linker-plugin.  */
+#define LINK_PLUGIN_SPEC "%{fuse-linker-plugin:\
+    %e-fuse-linker-plugin is not supported in this configuration}"
+#endif
+
 
 /* -u* was put back because both BSD and SysV seem to support it.  */
 /* %{static:} simply prevents an error message if the target machine
@@ -629,26 +663,22 @@ proper position among the other output files.  */
    directories.  */
 /* We pass any -flto flags on to the linker, which is expected
    to understand them.  In practice, this means it had better be collect2.  */
+/* %{e*} includes -export-dynamic; see comment in common.opt.  */
 #ifndef LINK_COMMAND_SPEC
 #define LINK_COMMAND_SPEC "\
 %{!fsyntax-only:%{!c:%{!M:%{!MM:%{!E:%{!S:\
-    %(linker) \
-    %{fuse-linker-plugin: \
-    -plugin %(linker_plugin_file) \
-    -plugin-opt=%(lto_wrapper) \
-    -plugin-opt=-fresolution=%u.res \
-    %{!nostdlib:%{!nodefaultlibs:%:pass-through-libs(%(link_gcc_c_sequence))}} \
-    } \
-    %{flto*:%<fcompare-debug*} \
-    %{flto*} %l " LINK_PIE_SPEC \
-   "%X %{o*} %{A} %{d} %{e*} %{m} %{N} %{n} %{r}\
-    %{s} %{t} %{u*} %{z} %{Z} %{!A:%{!nostdlib:%{!nostartfiles:%S}}}\
+    %(linker) " \
+    LINK_PLUGIN_SPEC \
+    "%{flto|flto=*:%<fcompare-debug*} \
+    %{flto} %{flto=*} %l " LINK_PIE_SPEC \
+   "%X %{o*} %{e*} %{N} %{n} %{r}\
+    %{s} %{t} %{u*} %{z} %{Z} %{!nostdlib:%{!nostartfiles:%S}}\
     %{static:} %{L*} %(mfwrap) %(link_libgcc) %o\
     %{fopenmp|ftree-parallelize-loops=*:%:include(libgomp.spec)%(link_gomp)}\
     %(mflib) " STACK_SPLIT_SPEC "\
     %{fprofile-arcs|fprofile-generate*|coverage:-lgcov}\
     %{!nostdlib:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}}\
-    %{!A:%{!nostdlib:%{!nostartfiles:%E}}} %{T*} }}}}}}"
+    %{!nostdlib:%{!nostartfiles:%E}} %{T*} }}}}}}"
 #endif
 
 #ifndef LINK_LIBGCC_SPEC
@@ -698,6 +728,7 @@ static const char *startfile_prefix_spec = STARTFILE_PREFIX_SPEC;
 static const char *sysroot_spec = SYSROOT_SPEC;
 static const char *sysroot_suffix_spec = SYSROOT_SUFFIX_SPEC;
 static const char *sysroot_hdrs_suffix_spec = SYSROOT_HEADERS_SUFFIX_SPEC;
+static const char *self_spec = "";
 
 /* Standard options to cpp, cc1, and as, to reduce duplication in specs.
    There should be no need to override these in target dependent files,
@@ -750,7 +781,7 @@ static const char *cc1_options =
  %{!fcompare-debug-second:%{c|S:%{o*:-auxbase-strip %*}%{!o*:-auxbase %b}}}%{!c:%{!S:-auxbase %b}} \
  %{g*} %{O*} %{W*&pedantic*} %{w} %{std*&ansi&trigraphs}\
  %{v:-version} %{pg:-p} %{p} %{f*} %{undef}\
- %{Qn:-fno-ident} %{-help:--help}\
+ %{Qn:-fno-ident} %{Qy:} %{-help:--help}\
  %{-target-help:--target-help}\
  %{-version:--version}\
  %{-help=*:--help=%*}\
@@ -760,7 +791,7 @@ static const char *cc1_options =
  %{coverage:-fprofile-arcs -ftest-coverage}";
 
 static const char *asm_options =
-"%{--target-help:%:print-asm-header()} "
+"%{-target-help:%:print-asm-header()} "
 #if HAVE_GNU_AS
 /* If GNU AS is used, then convert -w (no warnings), -I, and -v
    to the assembler equivalents.  */
@@ -934,12 +965,12 @@ static const struct compiler default_compilers[] =
                     %W{o*:--output-pch=%*}}%V}}}}}}", 0, 0, 0},
   {".i", "@cpp-output", 0, 0, 0},
   {"@cpp-output",
-   "%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options) %{!fsyntax-only:%(invoke_as)}}}}", 0, 1, 0},
-  {".s", "@assembler", 0, 1, 0},
+   "%{!M:%{!MM:%{!E:cc1 -fpreprocessed %i %(cc1_options) %{!fsyntax-only:%(invoke_as)}}}}", 0, 0, 0},
+  {".s", "@assembler", 0, 0, 0},
   {"@assembler",
-   "%{!M:%{!MM:%{!E:%{!S:as %(asm_debug) %(asm_options) %i %A }}}}", 0, 1, 0},
-  {".sx", "@assembler-with-cpp", 0, 1, 0},
-  {".S", "@assembler-with-cpp", 0, 1, 0},
+   "%{!M:%{!MM:%{!E:%{!S:as %(asm_debug) %(asm_options) %i %A }}}}", 0, 0, 0},
+  {".sx", "@assembler-with-cpp", 0, 0, 0},
+  {".S", "@assembler-with-cpp", 0, 0, 0},
   {"@assembler-with-cpp",
 #ifdef AS_NEEDS_DASH_FOR_PIPED_INPUT
    "%(trad_capable_cpp) -lang-asm %(cpp_options) -fno-directives-only\
@@ -952,7 +983,7 @@ static const struct compiler default_compilers[] =
       %{!M:%{!MM:%{!E:%{!S:-o %|.s |\n\
        as %(asm_debug) %(asm_options) %m.s %A }}}}"
 #endif
-   , 0, 1, 0},
+   , 0, 0, 0},
 
 #include "specs.h"
   /* Mark end of table.  */
@@ -1118,8 +1149,8 @@ static const char *multilib_dir;
 static const char *multilib_os_dir;
 \f
 /* Structure to keep track of the specs that have been defined so far.
-   These are accessed using %(specname) or %[specname] in a compiler
-   or link spec.  */
+   These are accessed using %(specname) in a compiler or link
+   spec.  */
 
 struct spec_list
 {
@@ -1185,6 +1216,7 @@ static struct spec_list static_specs[] =
   INIT_STATIC_SPEC ("sysroot_spec",             &sysroot_spec),
   INIT_STATIC_SPEC ("sysroot_suffix_spec",     &sysroot_suffix_spec),
   INIT_STATIC_SPEC ("sysroot_hdrs_suffix_spec",        &sysroot_hdrs_suffix_spec),
+  INIT_STATIC_SPEC ("self_spec",               &self_spec),
 };
 
 #ifdef EXTRA_SPECS             /* additional specs needed */
@@ -1360,7 +1392,8 @@ init_spec (void)
                            "-lgcc_eh"
 #ifdef USE_LIBUNWIND_EXCEPTIONS
 # ifdef HAVE_LD_STATIC_DYNAMIC
-                           " %{!static:-Bstatic} -lunwind %{!static:-Bdynamic}"
+                           " %{!static:" LD_STATIC_OPTION "} -lunwind"
+                           " %{!static:" LD_DYNAMIC_OPTION "}"
 # else
                            " -lunwind"
 # endif
@@ -1407,7 +1440,8 @@ init_spec (void)
   }
 #endif
 
-#if defined LINK_EH_SPEC || defined LINK_BUILDID_SPEC
+#if defined LINK_EH_SPEC || defined LINK_BUILDID_SPEC || \
+    defined LINKER_HASH_STYLE
 # ifdef LINK_BUILDID_SPEC
   /* Prepend LINK_BUILDID_SPEC to whatever link_spec we had before.  */
   obstack_grow (&obstack, LINK_BUILDID_SPEC, sizeof(LINK_BUILDID_SPEC) - 1);
@@ -1416,6 +1450,16 @@ init_spec (void)
   /* Prepend LINK_EH_SPEC to whatever link_spec we had before.  */
   obstack_grow (&obstack, LINK_EH_SPEC, sizeof(LINK_EH_SPEC) - 1);
 # endif
+# ifdef LINKER_HASH_STYLE
+  /* Prepend --hash-style=LINKER_HASH_STYLE to whatever link_spec we had
+     before.  */
+  {
+    static const char hash_style[] = "--hash-style=";
+    obstack_grow (&obstack, hash_style, sizeof(hash_style) - 1);
+    obstack_grow (&obstack, LINKER_HASH_STYLE, sizeof(LINKER_HASH_STYLE) - 1);
+    obstack_1grow (&obstack, ' ');
+  }
+# endif
   obstack_grow0 (&obstack, link_spec, strlen (link_spec));
   link_spec = XOBFINISH (&obstack, const char *);
 #endif
@@ -1919,7 +1963,7 @@ record_temp_file (const char *filename, int always_delete, int fail_delete)
     {
       struct temp_file *temp;
       for (temp = always_delete_queue; temp; temp = temp->next)
-       if (! strcmp (name, temp->name))
+       if (! filename_cmp (name, temp->name))
          goto already1;
 
       temp = XNEW (struct temp_file);
@@ -1934,7 +1978,7 @@ record_temp_file (const char *filename, int always_delete, int fail_delete)
     {
       struct temp_file *temp;
       for (temp = failure_delete_queue; temp; temp = temp->next)
-       if (! strcmp (name, temp->name))
+       if (! filename_cmp (name, temp->name))
          goto already2;
 
       temp = XNEW (struct temp_file);
@@ -2521,13 +2565,20 @@ execute (void)
                        }
                      fputc ('"', stderr);
                    }
+                 /* If it's empty, print "".  */
+                 else if (!**j)
+                   fprintf (stderr, " \"\"");
                  else
                    fprintf (stderr, " %s", *j);
                }
            }
          else
            for (j = commands[i].argv; *j; j++)
-             fprintf (stderr, " %s", *j);
+             /* If it's empty, print "".  */
+             if (!**j)
+               fprintf (stderr, " \"\"");
+             else
+               fprintf (stderr, " %s", *j);
 
          /* Print a pipe symbol after all but the last command.  */
          if (i + 1 != n_commands)
@@ -2743,10 +2794,11 @@ execute (void)
    The `validated' field is nonzero if any spec has looked at this switch;
    if it remains zero at the end of the run, it must be meaningless.  */
 
-#define SWITCH_LIVE                            0x1
-#define SWITCH_FALSE                           0x2
-#define SWITCH_IGNORE                  0x4
-#define SWITCH_IGNORE_PERMANENTLY      0x8
+#define SWITCH_LIVE                            (1 << 0)
+#define SWITCH_FALSE                           (1 << 1)
+#define SWITCH_IGNORE                  (1 << 2)
+#define SWITCH_IGNORE_PERMANENTLY      (1 << 3)
+#define SWITCH_KEEP_FOR_GCC            (1 << 4)
 
 struct switchstr
 {
@@ -3042,16 +3094,24 @@ save_switch (const char *opt, size_t n_args, const char *const *args,
 }
 
 /* Handle an option DECODED that is unknown to the option-processing
-   machinery, but may be known to specs.  */
+   machinery.  */
 
 static bool
 driver_unknown_option_callback (const struct cl_decoded_option *decoded)
 {
-  save_switch (decoded->canonical_option[0],
-              decoded->canonical_option_num_elements - 1,
-              &decoded->canonical_option[1], false);
-
-  return false;
+  const char *opt = decoded->arg;
+  if (opt[1] == 'W' && opt[2] == 'n' && opt[3] == 'o' && opt[4] == '-'
+      && !(decoded->errors & CL_ERR_NEGATIVE))
+    {
+      /* Leave unknown -Wno-* options for the compiler proper, to be
+        diagnosed only if there are warnings.  */
+      save_switch (decoded->canonical_option[0],
+                  decoded->canonical_option_num_elements - 1,
+                  &decoded->canonical_option[1], false);
+      return false;
+    }
+  else
+    return true;
 }
 
 /* Handle an option DECODED that is not marked as CL_DRIVER.
@@ -3068,11 +3128,13 @@ driver_wrong_lang_callback (const struct cl_decoded_option *decoded,
      options.  */
   const struct cl_option *option = &cl_options[decoded->opt_index];
 
-  if (option->flags & CL_REJECT_DRIVER)
+  if (option->cl_reject_driver)
     error ("unrecognized command line option %qs",
           decoded->orig_option_with_args_text);
   else
-    driver_unknown_option_callback (decoded);
+    save_switch (decoded->canonical_option[0],
+                decoded->canonical_option_num_elements - 1,
+                &decoded->canonical_option[1], false);
 }
 
 /* Note that an option (index OPT_INDEX, argument ARG, value VALUE)
@@ -3217,7 +3279,7 @@ driver_handle_option (struct gcc_options *opts,
     compare_debug_with_arg:
       gcc_assert (decoded->canonical_option_num_elements == 1);
       gcc_assert (arg != NULL);
-      if (arg)
+      if (*arg)
        compare_debug = 1;
       else
        compare_debug = -1;
@@ -3313,6 +3375,11 @@ driver_handle_option (struct gcc_options *opts,
       save_switch (concat ("-L", arg, NULL), 0, NULL, validated);
       return true;
 
+    case OPT_F:
+      /* Likewise -F.  */
+      save_switch (concat ("-F", arg, NULL), 0, NULL, validated);
+      return true;
+
     case OPT_save_temps:
       save_temps_flag = SAVE_TEMPS_CWD;
       validated = true;
@@ -3467,9 +3534,13 @@ set_option_handlers (struct cl_option_handlers *handlers)
   handlers->unknown_option_callback = driver_unknown_option_callback;
   handlers->wrong_lang_callback = driver_wrong_lang_callback;
   handlers->post_handling_callback = driver_post_handling_callback;
-  handlers->num_handlers = 1;
+  handlers->num_handlers = 3;
   handlers->handlers[0].handler = driver_handle_option;
   handlers->handlers[0].mask = CL_DRIVER;
+  handlers->handlers[1].handler = common_handle_option;
+  handlers->handlers[1].mask = CL_COMMON;
+  handlers->handlers[2].handler = target_handle_option;
+  handlers->handlers[2].mask = CL_TARGET;
 }
 
 /* Create the vector `switches' and its contents.
@@ -3576,9 +3647,9 @@ process_command (unsigned int decoded_options_count,
        {
          temp = gcc_exec_prefix + len - sizeof ("/lib/gcc/") + 1;
          if (IS_DIR_SEPARATOR (*temp)
-             && strncmp (temp + 1, "lib", 3) == 0
+             && filename_ncmp (temp + 1, "lib", 3) == 0
              && IS_DIR_SEPARATOR (temp[4])
-             && strncmp (temp + 5, "gcc", 3) == 0)
+             && filename_ncmp (temp + 5, "gcc", 3) == 0)
            len -= sizeof ("/lib/gcc/") - 1;
        }
 
@@ -3926,7 +3997,9 @@ set_collect_gcc_options (void)
       first_time = FALSE;
 
       /* Ignore elided switches.  */
-      if ((switches[i].live_cond & SWITCH_IGNORE) != 0)
+      if ((switches[i].live_cond
+          & (SWITCH_IGNORE | SWITCH_KEEP_FOR_GCC))
+         == SWITCH_IGNORE)
        continue;
 
       obstack_grow (&collect_obstack, "'-", 2);
@@ -4398,6 +4471,10 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
   int i;
   int value;
 
+  /* If it's an empty string argument to a switch, keep it as is.  */
+  if (inswitch && !*p)
+    arg_going = 1;
+
   while ((c = *p++))
     /* If substituting a switch, treat all chars like letters.
        Otherwise, NL, SPC, TAB and % are special.  */
@@ -4670,7 +4747,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, gcc_input_filename) != 0)
+                   if (filename_cmp (temp_filename, gcc_input_filename) != 0)
                      {
 #ifndef HOST_LACKS_INODE_NUMBERS
                        struct stat st_temp;
@@ -4696,7 +4773,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
                        /* Just compare canonical pathnames.  */
                        char* input_realname = lrealpath (gcc_input_filename);
                        char* temp_realname = lrealpath (temp_filename);
-                       bool files_differ = strcmp (input_realname, temp_realname);
+                       bool files_differ = filename_cmp (input_realname, temp_realname);
                        free (input_realname);
                        free (temp_realname);
                        if (files_differ)
@@ -4746,8 +4823,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
                    t->filename_length = temp_filename_length;
                  }
 
-               if (saved_suffix)
-                 free (saved_suffix);
+               free (saved_suffix);
 
                obstack_grow (&obstack, t->filename, t->filename_length);
                delete_this_arg = 1;
@@ -5091,10 +5167,17 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
           /* Henceforth ignore the option(s) matching the pattern
              after the %<.  */
          case '<':
+         case '>':
            {
              unsigned len = 0;
              int have_wildcard = 0;
              int i;
+             int switch_option;
+
+             if (c == '>')
+               switch_option = SWITCH_IGNORE | SWITCH_KEEP_FOR_GCC;
+             else
+               switch_option = SWITCH_IGNORE;
 
              while (p[len] && p[len] != ' ' && p[len] != '\t')
                len++;
@@ -5106,7 +5189,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
                if (!strncmp (switches[i].part1, p, len - have_wildcard)
                    && (have_wildcard || switches[i].part1[len] == '\0'))
                  {
-                   switches[i].live_cond |= SWITCH_IGNORE;
+                   switches[i].live_cond |= switch_option;
                    switches[i].validated = 1;
                  }
 
@@ -5117,7 +5200,8 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
          case '*':
            if (soft_matched_part)
              {
-               do_spec_1 (soft_matched_part, 1, NULL);
+               if (soft_matched_part[0])
+                 do_spec_1 (soft_matched_part, 1, NULL);
                do_spec_1 (" ", 0, NULL);
              }
            else
@@ -5129,11 +5213,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
 
            /* Process a string found as the value of a spec given by name.
               This feature allows individual machine descriptions
-              to add and use their own specs.
-              %[...] modifies -D options the way %P does;
-              %(...) uses the spec unmodified.  */
-         case '[':
-           warning (0, "use of obsolete %%[ operator in specs");
+              to add and use their own specs.  */
          case '(':
            {
              const char *name = p;
@@ -5142,7 +5222,7 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
 
              /* The string after the S/P is the name of a spec that is to be
                 processed.  */
-             while (*p && *p != ')' && *p != ']')
+             while (*p && *p != ')')
                p++;
 
              /* See if it's in the list.  */
@@ -5151,63 +5231,20 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
                  {
                    name = *(sl->ptr_spec);
 #ifdef DEBUG_SPECS
-                   fnotice (stderr, "Processing spec %c%s%c, which is '%s'\n",
-                           c, sl->name, (c == '(') ? ')' : ']', name);
+                   fnotice (stderr, "Processing spec (%s), which is '%s'\n",
+                            sl->name, name);
 #endif
                    break;
                  }
 
              if (sl)
                {
-                 if (c == '(')
-                   {
-                     value = do_spec_1 (name, 0, NULL);
-                     if (value != 0)
-                       return value;
-                   }
-                 else
-                   {
-                     char *x = (char *) alloca (strlen (name) * 2 + 1);
-                     char *buf = x;
-                     const char *y = name;
-                     int flag = 0;
-
-                     /* Copy all of NAME into BUF, but put __ after
-                        every -D and at the end of each arg.  */
-                     while (1)
-                       {
-                         if (! strncmp (y, "-D", 2))
-                           {
-                             *x++ = '-';
-                             *x++ = 'D';
-                             *x++ = '_';
-                             *x++ = '_';
-                             y += 2;
-                             flag = 1;
-                             continue;
-                           }
-                         else if (flag
-                                  && (*y == ' ' || *y == '\t' || *y == '='
-                                      || *y == '}' || *y == 0))
-                           {
-                             *x++ = '_';
-                             *x++ = '_';
-                             flag = 0;
-                           }
-                         if (*y == 0)
-                           break;
-                         else
-                           *x++ = *y++;
-                       }
-                     *x = 0;
-
-                     value = do_spec_1 (buf, 0, NULL);
-                     if (value != 0)
-                       return value;
-                   }
+                 value = do_spec_1 (name, 0, NULL);
+                 if (value != 0)
+                   return value;
                }
 
-             /* Discard the closing paren or bracket.  */
+             /* Discard the closing paren.  */
              if (*p)
                p++;
            }
@@ -5867,11 +5904,11 @@ is_directory (const char *path1, bool linker)
   if (linker
       && IS_DIR_SEPARATOR (path[0])
       && ((cp - path == 6
-          && strncmp (path + 1, "lib", 3) == 0)
+          && filename_ncmp (path + 1, "lib", 3) == 0)
          || (cp - path == 10
-             && strncmp (path + 1, "usr", 3) == 0
+             && filename_ncmp (path + 1, "usr", 3) == 0
              && IS_DIR_SEPARATOR (path[4])
-             && strncmp (path + 5, "lib", 3) == 0)))
+             && filename_ncmp (path + 5, "lib", 3) == 0)))
     return 0;
 
   return (stat (path, &st) >= 0 && S_ISDIR (st.st_mode));
@@ -6078,7 +6115,11 @@ main (int argc, char **argv)
   if (argv != old_argv)
     at_file_supplied = true;
 
-  global_options = global_options_init;
+  /* Register the language-independent parameters.  */
+  global_init_params ();
+  finish_params ();
+
+  init_options_struct (&global_options, &global_options_set);
 
   decode_cmdline_options_to_array (argc, CONST_CAST2 (const char **, char **,
                                                      argv),
@@ -6117,6 +6158,10 @@ main (int argc, char **argv)
   signal (SIGCHLD, SIG_DFL);
 #endif
 
+  /* Parsing and gimplification sometimes need quite large stack.
+     Increase stack size limits if possible.  */
+  stack_limit_increase (64 * 1024 * 1024);
+
   /* Allocate the argument vector.  */
   alloc_args ();
 
@@ -6218,48 +6263,6 @@ main (int argc, char **argv)
   for (i = 0; i < ARRAY_SIZE (driver_self_specs); i++)
     do_self_spec (driver_self_specs[i]);
 
-  if (compare_debug)
-    {
-      enum save_temps save;
-
-      if (!compare_debug_second)
-       {
-         n_switches_debug_check[1] = n_switches;
-         n_switches_alloc_debug_check[1] = n_switches_alloc;
-         switches_debug_check[1] = XDUPVEC (struct switchstr, switches,
-                                            n_switches_alloc);
-
-         do_self_spec ("%:compare-debug-self-opt()");
-         n_switches_debug_check[0] = n_switches;
-         n_switches_alloc_debug_check[0] = n_switches_alloc;
-         switches_debug_check[0] = switches;
-
-         n_switches = n_switches_debug_check[1];
-         n_switches_alloc = n_switches_alloc_debug_check[1];
-         switches = switches_debug_check[1];
-       }
-
-      /* Avoid crash when computing %j in this early.  */
-      save = save_temps_flag;
-      save_temps_flag = SAVE_TEMPS_NONE;
-
-      compare_debug = -compare_debug;
-      do_self_spec ("%:compare-debug-self-opt()");
-
-      save_temps_flag = save;
-
-      if (!compare_debug_second)
-       {
-         n_switches_debug_check[1] = n_switches;
-         n_switches_alloc_debug_check[1] = n_switches_alloc;
-         switches_debug_check[1] = switches;
-         compare_debug = -compare_debug;
-         n_switches = n_switches_debug_check[0];
-         n_switches_alloc = n_switches_debug_check[0];
-         switches = switches_debug_check[0];
-       }
-    }
-
   /* If not cross-compiling, look for executables in the standard
      places.  */
   if (*cross_compile == '0')
@@ -6369,6 +6372,58 @@ main (int argc, char **argv)
       read_specs (filename ? filename : uptr->filename, FALSE);
     }
 
+  /* Process any user self specs.  */
+  {
+    struct spec_list *sl;
+    for (sl = specs; sl; sl = sl->next)
+      if (sl->name_len == sizeof "self_spec" - 1
+         && !strcmp (sl->name, "self_spec"))
+       do_self_spec (*sl->ptr_spec);
+  }
+
+  if (compare_debug)
+    {
+      enum save_temps save;
+
+      if (!compare_debug_second)
+       {
+         n_switches_debug_check[1] = n_switches;
+         n_switches_alloc_debug_check[1] = n_switches_alloc;
+         switches_debug_check[1] = XDUPVEC (struct switchstr, switches,
+                                            n_switches_alloc);
+
+         do_self_spec ("%:compare-debug-self-opt()");
+         n_switches_debug_check[0] = n_switches;
+         n_switches_alloc_debug_check[0] = n_switches_alloc;
+         switches_debug_check[0] = switches;
+
+         n_switches = n_switches_debug_check[1];
+         n_switches_alloc = n_switches_alloc_debug_check[1];
+         switches = switches_debug_check[1];
+       }
+
+      /* Avoid crash when computing %j in this early.  */
+      save = save_temps_flag;
+      save_temps_flag = SAVE_TEMPS_NONE;
+
+      compare_debug = -compare_debug;
+      do_self_spec ("%:compare-debug-self-opt()");
+
+      save_temps_flag = save;
+
+      if (!compare_debug_second)
+       {
+         n_switches_debug_check[1] = n_switches;
+         n_switches_alloc_debug_check[1] = n_switches_alloc;
+         switches_debug_check[1] = switches;
+         compare_debug = -compare_debug;
+         n_switches = n_switches_debug_check[0];
+         n_switches_alloc = n_switches_debug_check[0];
+         switches = switches_debug_check[0];
+       }
+    }
+
+
   /* If we have a GCC_EXEC_PREFIX envvar, modify it for cpp's sake.  */
   if (gcc_exec_prefix)
     gcc_exec_prefix = concat (gcc_exec_prefix, spec_machine, dir_separator_str,
@@ -6513,7 +6568,7 @@ main (int argc, char **argv)
     {
       printf (_("%s %s%s\n"), progname, pkgversion_string,
              version_string);
-      printf ("Copyright %s 2010 Free Software Foundation, Inc.\n",
+      printf ("Copyright %s 2011 Free Software Foundation, Inc.\n",
              _("(C)"));
       fputs (_("This is free software; see the source for copying conditions.  There is NO\n\
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"),
@@ -6571,6 +6626,9 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
   if (n_infiles == added_libraries)
     fatal_error ("no input files");
 
+  if (seen_error ())
+    goto out;
+
   /* Make a place to record the compiler output file names
      that correspond to the input files.  */
 
@@ -6653,12 +6711,10 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
            {
              if (compare_debug)
                {
-                 if (debug_check_temp_file[0])
-                   free (debug_check_temp_file[0]);
+                 free (debug_check_temp_file[0]);
                  debug_check_temp_file[0] = NULL;
 
-                 if (debug_check_temp_file[1])
-                   free (debug_check_temp_file[1]);
+                 free (debug_check_temp_file[1]);
                  debug_check_temp_file[1] = NULL;
                }
 
@@ -6690,8 +6746,8 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
                    }
 
                  gcc_assert (debug_check_temp_file[1]
-                             && strcmp (debug_check_temp_file[0],
-                                        debug_check_temp_file[1]));
+                             && filename_cmp (debug_check_temp_file[0],
+                                              debug_check_temp_file[1]));
 
                  if (verbose_flag)
                    inform (0, "comparing final insns dumps");
@@ -6702,12 +6758,10 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
 
              if (compare_debug)
                {
-                 if (debug_check_temp_file[0])
-                   free (debug_check_temp_file[0]);
+                 free (debug_check_temp_file[0]);
                  debug_check_temp_file[0] = NULL;
 
-                 if (debug_check_temp_file[1])
-                   free (debug_check_temp_file[1]);
+                 free (debug_check_temp_file[1]);
                  debug_check_temp_file[1] = NULL;
                }
            }
@@ -6768,7 +6822,13 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
   if (num_linker_inputs > 0 && !seen_error () && print_subprocess_help < 2)
     {
       int tmp = execution_count;
+#if HAVE_LTO_PLUGIN > 0
+#if HAVE_LTO_PLUGIN == 2
+      const char *fno_use_linker_plugin = "fno-use-linker-plugin";
+#else
       const char *fuse_linker_plugin = "fuse-linker-plugin";
+#endif
+#endif
 
       /* We'll use ld if we can't find collect2.  */
       if (! strcmp (linker_name_spec, "collect2"))
@@ -6778,8 +6838,14 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
            linker_name_spec = "ld";
        }
 
+#if HAVE_LTO_PLUGIN > 0
+#if HAVE_LTO_PLUGIN == 2
+      if (!switch_matches (fno_use_linker_plugin,
+                          fno_use_linker_plugin + strlen (fno_use_linker_plugin), 0))
+#else
       if (switch_matches (fuse_linker_plugin,
                          fuse_linker_plugin + strlen (fuse_linker_plugin), 0))
+#endif
        {
          linker_plugin_file_spec = find_a_file (&exec_prefixes,
                                                 LTOPLUGINSONAME, R_OK,
@@ -6787,6 +6853,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
          if (!linker_plugin_file_spec)
            fatal_error ("-fuse-linker-plugin, but " LTOPLUGINSONAME " not found");
        }
+#endif
       lto_gcc_spec = argv[0];
 
       /* Rebuild the COMPILER_PATH and LIBRARY_PATH environment variables
@@ -6829,6 +6896,7 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\n"
       printf ("%s\n", bug_report_url);
     }
 
+ out:
   return (signal_count != 0 ? 2
          : seen_error () ? (pass_exit_codes ? greatest_status : 1)
          : 0);
@@ -7581,7 +7649,7 @@ print_multilib_info (void)
          /* If this is a duplicate, skip it.  */
          skip = (last_path != 0
                  && (unsigned int) (p - this_path) == last_path_len
-                 && ! strncmp (last_path, this_path, last_path_len));
+                 && ! filename_ncmp (last_path, this_path, last_path_len));
 
          last_path = this_path;
          last_path_len = p - this_path;
@@ -7785,7 +7853,7 @@ replace_outfile_spec_function (int argc, const char **argv)
 
   for (i = 0; i < n_infiles; i++)
     {
-      if (outfiles[i] && !strcmp (outfiles[i], argv[0]))
+      if (outfiles[i] && !filename_cmp (outfiles[i], argv[0]))
        outfiles[i] = xstrdup (argv[1]);
     }
   return NULL;
@@ -7806,7 +7874,7 @@ remove_outfile_spec_function (int argc, const char **argv)
 
   for (i = 0; i < n_infiles; i++)
     {
-      if (outfiles[i] && !strcmp (outfiles[i], argv[0]))
+      if (outfiles[i] && !filename_cmp (outfiles[i], argv[0]))
         outfiles[i] = NULL;
     }
   return NULL;
@@ -7994,12 +8062,22 @@ print_asm_header_spec_function (int arg ATTRIBUTE_UNUSED,
   return NULL;
 }
 
-/* Compute a timestamp to initialize flag_random_seed.  */
+/* Get a random number for -frandom-seed */
 
-static unsigned
-get_local_tick (void)
+static unsigned HOST_WIDE_INT
+get_random_number (void)
 {
-  unsigned ret = 0;
+  unsigned HOST_WIDE_INT ret = 0;
+  int fd; 
+
+  fd = open ("/dev/urandom", O_RDONLY); 
+  if (fd >= 0)
+    {
+      read (fd, &ret, sizeof (HOST_WIDE_INT));
+      close (fd);
+      if (ret)
+        return ret;
+    }
 
   /* Get some more or less random data.  */
 #ifdef HAVE_GETTIMEOFDAY
@@ -8018,7 +8096,7 @@ get_local_tick (void)
   }
 #endif
 
-  return ret;
+  return ret ^ getpid();
 }
 
 /* %:compare-debug-dump-opt spec function.  Save the last argument,
@@ -8077,7 +8155,7 @@ compare_debug_dump_opt_spec_function (int arg,
 
   if (!which)
     {
-      unsigned HOST_WIDE_INT value = get_local_tick () ^ getpid ();
+      unsigned HOST_WIDE_INT value = get_random_number ();
 
       sprintf (random_seed, HOST_WIDE_INT_PRINT_HEX, value);
     }