OSDN Git Service

Backport from mainline
[pf3gnuchains/gcc-fork.git] / gcc / gcc.c
index fc0cb1b..cc6a08e 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, 2011
+   2010, 2011, 2012
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -675,6 +675,7 @@ proper position among the other output files.  */
     %{s} %{t} %{u*} %{z} %{Z} %{!nostdlib:%{!nostartfiles:%S}}\
     %{static:} %{L*} %(mfwrap) %(link_libgcc) %o\
     %{fopenmp|ftree-parallelize-loops=*:%:include(libgomp.spec)%(link_gomp)}\
+    %{fgnu-tm:%:include(libitm.spec)%(link_itm)}\
     %(mflib) " STACK_SPLIT_SPEC "\
     %{fprofile-arcs|fprofile-generate*|coverage:-lgcov}\
     %{!nostdlib:%{!nodefaultlibs:%(link_ssp) %(link_gcc_c_sequence)}}\
@@ -728,6 +729,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,
@@ -838,9 +840,14 @@ static const char *const multilib_defaults_raw[] = MULTILIB_DEFAULTS;
 #define GOMP_SELF_SPECS "%{fopenmp|ftree-parallelize-loops=*: -pthread}"
 #endif
 
+/* Likewise for -fgnu-tm.  */
+#ifndef GTM_SELF_SPECS
+#define GTM_SELF_SPECS "%{fgnu-tm: -pthread}"
+#endif
+
 static const char *const driver_self_specs[] = {
   "%{fdump-final-insns:-fdump-final-insns=.} %<fdump-final-insns",
-  DRIVER_SELF_SPECS, CONFIGURE_SPECS, GOMP_SELF_SPECS
+  DRIVER_SELF_SPECS, CONFIGURE_SPECS, GOMP_SELF_SPECS, GTM_SELF_SPECS
 };
 
 #ifndef OPTION_DEFAULT_SPECS
@@ -1215,6 +1222,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 */
@@ -2443,9 +2451,17 @@ add_sysrooted_prefix (struct path_prefix *pprefix, const char *prefix,
 
   if (target_system_root)
     {
+      char *sysroot_no_trailing_dir_separator = xstrdup (target_system_root);
+      size_t sysroot_len = strlen (target_system_root);
+
+      if (sysroot_len > 0
+         && target_system_root[sysroot_len - 1] == DIR_SEPARATOR)
+       sysroot_no_trailing_dir_separator[sysroot_len - 1] = '\0';
+
       if (target_sysroot_suffix)
          prefix = concat (target_sysroot_suffix, prefix, NULL);
-      prefix = concat (target_system_root, prefix, NULL);
+      prefix = concat (sysroot_no_trailing_dir_separator, prefix, NULL);
+      free (sysroot_no_trailing_dir_separator);
 
       /* We have to override this because GCC's notion of sysroot
         moves along with GCC.  */
@@ -2942,7 +2958,7 @@ display_help (void)
   fputs (_("  -pass-exit-codes         Exit with highest error code from a phase\n"), stdout);
   fputs (_("  --help                   Display this information\n"), stdout);
   fputs (_("  --target-help            Display target specific command line options\n"), stdout);
-  fputs (_("  --help={target|optimizers|warnings|params|[^]{joined|separate|undocumented}}[,...]\n"), stdout);
+  fputs (_("  --help={common|optimizers|params|target|warnings|[^]{joined|separate|undocumented}}[,...]\n"), stdout);
   fputs (_("                           Display specific types of command line options\n"), stdout);
   if (! verbose_flag)
     fputs (_("  (Use '-v --help' to display command line options of sub-processes)\n"), stdout);
@@ -2986,6 +3002,8 @@ display_help (void)
   fputs (_("  -S                       Compile only; do not assemble or link\n"), stdout);
   fputs (_("  -c                       Compile and assemble, but do not link\n"), stdout);
   fputs (_("  -o <file>                Place the output into <file>\n"), stdout);
+  fputs (_("  -pie                     Create a position independent executable\n"), stdout);
+  fputs (_("  -shared                  Create a shared library\n"), stdout);
   fputs (_("\
   -x <language>            Specify the language of the following input files\n\
                            Permissible languages include: c c++ assembler none\n\
@@ -3135,16 +3153,6 @@ driver_wrong_lang_callback (const struct cl_decoded_option *decoded,
                 &decoded->canonical_option[1], false);
 }
 
-/* Note that an option (index OPT_INDEX, argument ARG, value VALUE)
-   has been successfully handled with a handler for mask MASK.  */
-
-static void
-driver_post_handling_callback (const struct cl_decoded_option *decoded ATTRIBUTE_UNUSED,
-                              unsigned int mask ATTRIBUTE_UNUSED)
-{
-  /* Nothing to do here.  */
-}
-
 static const char *spec_lang = 0;
 static int last_language_n_infiles;
 
@@ -3531,7 +3539,6 @@ 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 = 3;
   handlers->handlers[0].handler = driver_handle_option;
   handlers->handlers[0].mask = CL_DRIVER;
@@ -5454,6 +5461,21 @@ switch_matches (const char *atom, const char *end_atom, int starred)
        && check_live_switch (i, plen))
       return true;
 
+    /* Check if a switch with separated form matching the atom.
+       We check -D and -U switches. */
+    else if (switches[i].args != 0)
+      {
+       if ((*switches[i].part1 == 'D' || *switches[i].part1 == 'U')
+           && *switches[i].part1 == atom[0])
+         {
+           if (!strncmp (switches[i].args[0], &atom[1], len - 1)
+               && (starred || (switches[i].part1[1] == '\0'
+                               && switches[i].args[0][len - 1] == '\0'))
+               && check_live_switch (i, (starred ? 1 : -1)))
+             return true;
+         }
+      }
+
   return false;
 }
 
@@ -6261,48 +6283,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')
@@ -6412,6 +6392,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,
@@ -6436,7 +6468,11 @@ main (int argc, char **argv)
 
   /* Set up to remember the pathname of the lto wrapper. */
 
-  lto_wrapper_file = find_a_file (&exec_prefixes, "lto-wrapper", X_OK, false);
+  if (have_c)
+    lto_wrapper_file = NULL;
+  else
+    lto_wrapper_file = find_a_file (&exec_prefixes, "lto-wrapper",
+                                   X_OK, false);
   if (lto_wrapper_file)
     {
       lto_wrapper_spec = lto_wrapper_file;
@@ -6556,7 +6592,7 @@ main (int argc, char **argv)
     {
       printf (_("%s %s%s\n"), progname, pkgversion_string,
              version_string);
-      printf ("Copyright %s 2011 Free Software Foundation, Inc.\n",
+      printf ("Copyright %s 2012 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"),
@@ -6810,39 +6846,46 @@ 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_c)
+       {
 #if HAVE_LTO_PLUGIN > 0
 #if HAVE_LTO_PLUGIN == 2
-      const char *fno_use_linker_plugin = "fno-use-linker-plugin";
+         const char *fno_use_linker_plugin = "fno-use-linker-plugin";
 #else
-      const char *fuse_linker_plugin = "fuse-linker-plugin";
+         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"))
-       {
-         char *s = find_a_file (&exec_prefixes, "collect2", X_OK, false);
-         if (s == NULL)
-           linker_name_spec = "ld";
-       }
+         /* We'll use ld if we can't find collect2.  */
+         if (! strcmp (linker_name_spec, "collect2"))
+           {
+             char *s = find_a_file (&exec_prefixes, "collect2", X_OK, false);
+             if (s == NULL)
+               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))
+         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))
+         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,
-                                                false);
-         if (!linker_plugin_file_spec)
-           fatal_error ("-fuse-linker-plugin, but " LTOPLUGINSONAME " not found");
-       }
+           {
+             linker_plugin_file_spec = find_a_file (&exec_prefixes,
+                                                    LTOPLUGINSONAME, R_OK,
+                                                    false);
+             if (!linker_plugin_file_spec)
+               fatal_error ("-fuse-linker-plugin, but %s not found",
+                            LTOPLUGINSONAME);
+           }
 #endif
-      lto_gcc_spec = argv[0];
+         lto_gcc_spec = argv[0];
+       }
 
       /* Rebuild the COMPILER_PATH and LIBRARY_PATH environment variables
         for collect.  */
@@ -8050,12 +8093,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
@@ -8074,7 +8127,7 @@ get_local_tick (void)
   }
 #endif
 
-  return ret;
+  return ret ^ getpid();
 }
 
 /* %:compare-debug-dump-opt spec function.  Save the last argument,
@@ -8133,7 +8186,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);
     }