maint: update copyright
[gnulib.git] / lib / javacomp.c
index ba0f437..6a15f10 100644 (file)
@@ -1,11 +1,11 @@
 /* Compile a Java program.
-   Copyright (C) 2001-2003, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2001-2003, 2006-2014 Free Software Foundation, Inc.
    Written by Bruno Haible <haible@clisp.cons.org>, 2001.
 
-   This program is free software; you can redistribute it and/or modify
+   This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2, or (at your option)
-   any later version.
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -13,8 +13,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software Foundation,
-   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include <config.h>
 #include <alloca.h>
@@ -33,7 +32,7 @@
 
 #include "javaversion.h"
 #include "execute.h"
-#include "pipe.h"
+#include "spawn-pipe.h"
 #include "wait-process.h"
 #include "classpath.h"
 #include "xsetenv.h"
 #include "binary-io.h"
 #include "safe-read.h"
 #include "xalloc.h"
-#include "xallocsa.h"
-#include "getline.h"
-#include "pathname.h"
+#include "xmalloca.h"
+#include "concat-filename.h"
 #include "fwriteerror.h"
 #include "clean-temp.h"
 #include "error.h"
 #include "xvasprintf.h"
-#include "strstr.h"
+#include "c-strstr.h"
 #include "gettext.h"
 
 #define _(str) gettext (str)
 
+/* The results of open() in this file are not used with fchdir,
+   therefore save some unnecessary work in fchdir.c.  */
+#undef open
+#undef close
+
 
 /* Survey of Java compilers.
 
 
    We try the Java compilers in the following order:
      1. getenv ("JAVAC"), because the user must be able to override our
-       preferences,
+        preferences,
      2. "gcj -C", because it is a completely free compiler,
      3. "javac", because it is a standard compiler,
      4. "jikes", comes last because it has some deviating interpretation
-       of the Java Language Specification and because it requires a
-       CLASSPATH environment variable.
+        of the Java Language Specification and because it requires a
+        CLASSPATH environment variable.
 
    We unset the JAVA_HOME environment variable, because a wrong setting of
    this variable can confuse the JDK's javac.
@@ -101,10 +104,10 @@ default_target_version (void)
       /* Determine the version from the found JVM.  */
       java_version_cache = javaexec_version ();
       if (java_version_cache == NULL
-         || !(java_version_cache[0] == '1' && java_version_cache[1] == '.'
-              && (java_version_cache[2] >= '1' && java_version_cache[2] <= '6')
-              && java_version_cache[3] == '\0'))
-       java_version_cache = "1.1";
+          || !(java_version_cache[0] == '1' && java_version_cache[1] == '.'
+               && (java_version_cache[2] >= '1' && java_version_cache[2] <= '6')
+               && java_version_cache[3] == '\0'))
+        java_version_cache = "1.1";
     }
   return java_version_cache;
 }
@@ -196,11 +199,11 @@ corresponding_classfile_version (const char *target_version)
    Return a failure indicator (true upon error).  */
 static bool
 compile_using_envjavac (const char *javac,
-                       const char * const *java_sources,
-                       unsigned int java_sources_count,
-                       const char *directory,
-                       bool optimize, bool debug,
-                       bool verbose, bool null_stderr)
+                        const char * const *java_sources,
+                        unsigned int java_sources_count,
+                        const char *directory,
+                        bool optimize, bool debug,
+                        bool verbose, bool null_stderr)
 {
   /* Because $JAVAC may consist of a command and options, we use the
      shell.  Because $JAVAC has been set by the user, we leave all
@@ -225,7 +228,7 @@ compile_using_envjavac (const char *javac,
     command_length += 1 + shell_quote_length (java_sources[i]);
   command_length += 1;
 
-  command = (char *) xallocsa (command_length);
+  command = (char *) xmalloca (command_length);
   p = command;
   /* Don't shell_quote $JAVAC, because it may consist of a command
      and options.  */
@@ -265,10 +268,10 @@ compile_using_envjavac (const char *javac,
   argv[2] = command;
   argv[3] = NULL;
   exitstatus = execute (javac, "/bin/sh", argv, false, false, false,
-                       null_stderr, true, true);
+                        null_stderr, true, true, NULL);
   err = (exitstatus != 0);
 
-  freesa (command);
+  freea (command);
 
   return err;
 }
@@ -277,29 +280,52 @@ compile_using_envjavac (const char *javac,
    Return a failure indicator (true upon error).  */
 static bool
 compile_using_gcj (const char * const *java_sources,
-                  unsigned int java_sources_count,
-                  bool no_assert_option,
-                  const char *directory,
-                  bool optimize, bool debug,
-                  bool verbose, bool null_stderr)
+                   unsigned int java_sources_count,
+                   bool no_assert_option,
+                   bool fsource_option, const char *source_version,
+                   bool ftarget_option, const char *target_version,
+                   const char *directory,
+                   bool optimize, bool debug,
+                   bool verbose, bool null_stderr)
 {
   bool err;
   unsigned int argc;
   char **argv;
   char **argp;
+  char *fsource_arg;
+  char *ftarget_arg;
   int exitstatus;
   unsigned int i;
 
   argc =
-    2 + (no_assert_option ? 1 : 0) + (optimize ? 1 : 0) + (debug ? 1 : 0)
+    2 + (no_assert_option ? 1 : 0) + (fsource_option ? 1 : 0)
+    + (ftarget_option ? 1 : 0) + (optimize ? 1 : 0) + (debug ? 1 : 0)
     + (directory != NULL ? 2 : 0) + java_sources_count;
-  argv = (char **) xallocsa ((argc + 1) * sizeof (char *));
+  argv = (char **) xmalloca ((argc + 1) * sizeof (char *));
 
   argp = argv;
   *argp++ = "gcj";
   *argp++ = "-C";
   if (no_assert_option)
     *argp++ = "-fno-assert";
+  if (fsource_option)
+    {
+      fsource_arg = (char *) xmalloca (9 + strlen (source_version) + 1);
+      memcpy (fsource_arg, "-fsource=", 9);
+      strcpy (fsource_arg + 9, source_version);
+      *argp++ = fsource_arg;
+    }
+  else
+    fsource_arg = NULL;
+  if (ftarget_option)
+    {
+      ftarget_arg = (char *) xmalloca (9 + strlen (target_version) + 1);
+      memcpy (ftarget_arg, "-ftarget=", 9);
+      strcpy (ftarget_arg + 9, target_version);
+      *argp++ = ftarget_arg;
+    }
+  else
+    ftarget_arg = NULL;
   if (optimize)
     *argp++ = "-O";
   if (debug)
@@ -324,10 +350,14 @@ compile_using_gcj (const char * const *java_sources,
     }
 
   exitstatus = execute ("gcj", "gcj", argv, false, false, false, null_stderr,
-                       true, true);
+                        true, true, NULL);
   err = (exitstatus != 0);
 
-  freesa (argv);
+  if (ftarget_arg != NULL)
+    freea (ftarget_arg);
+  if (fsource_arg != NULL)
+    freea (fsource_arg);
+  freea (argv);
 
   return err;
 }
@@ -336,12 +366,12 @@ compile_using_gcj (const char * const *java_sources,
    Return a failure indicator (true upon error).  */
 static bool
 compile_using_javac (const char * const *java_sources,
-                    unsigned int java_sources_count,
-                    bool source_option, const char *source_version,
-                    bool target_option, const char *target_version,
-                    const char *directory,
-                    bool optimize, bool debug,
-                    bool verbose, bool null_stderr)
+                     unsigned int java_sources_count,
+                     bool source_option, const char *source_version,
+                     bool target_option, const char *target_version,
+                     const char *directory,
+                     bool optimize, bool debug,
+                     bool verbose, bool null_stderr)
 {
   bool err;
   unsigned int argc;
@@ -353,7 +383,7 @@ compile_using_javac (const char * const *java_sources,
   argc =
     1 + (source_option ? 2 : 0) + (target_option ? 2 : 0) + (optimize ? 1 : 0)
     + (debug ? 1 : 0) + (directory != NULL ? 2 : 0) + java_sources_count;
-  argv = (char **) xallocsa ((argc + 1) * sizeof (char *));
+  argv = (char **) xmalloca ((argc + 1) * sizeof (char *));
 
   argp = argv;
   *argp++ = "javac";
@@ -391,10 +421,10 @@ compile_using_javac (const char * const *java_sources,
     }
 
   exitstatus = execute ("javac", "javac", argv, false, false, false,
-                       null_stderr, true, true);
+                        null_stderr, true, true, NULL);
   err = (exitstatus != 0);
 
-  freesa (argv);
+  freea (argv);
 
   return err;
 }
@@ -403,10 +433,10 @@ compile_using_javac (const char * const *java_sources,
    Return a failure indicator (true upon error).  */
 static bool
 compile_using_jikes (const char * const *java_sources,
-                    unsigned int java_sources_count,
-                    const char *directory,
-                    bool optimize, bool debug,
-                    bool verbose, bool null_stderr)
+                     unsigned int java_sources_count,
+                     const char *directory,
+                     bool optimize, bool debug,
+                     bool verbose, bool null_stderr)
 {
   bool err;
   unsigned int argc;
@@ -418,7 +448,7 @@ compile_using_jikes (const char * const *java_sources,
   argc =
     1 + (optimize ? 1 : 0) + (debug ? 1 : 0) + (directory != NULL ? 2 : 0)
     + java_sources_count;
-  argv = (char **) xallocsa ((argc + 1) * sizeof (char *));
+  argv = (char **) xmalloca ((argc + 1) * sizeof (char *));
 
   argp = argv;
   *argp++ = "jikes";
@@ -446,10 +476,10 @@ compile_using_jikes (const char * const *java_sources,
     }
 
   exitstatus = execute ("jikes", "jikes", argv, false, false, false,
-                       null_stderr, true, true);
+                        null_stderr, true, true, NULL);
   err = (exitstatus != 0);
 
-  freesa (argv);
+  freea (argv);
 
   return err;
 }
@@ -462,7 +492,7 @@ compile_using_jikes (const char * const *java_sources,
    Return a failure indicator (true upon error).  */
 static bool
 write_temp_file (struct temp_dir *tmpdir, const char *file_name,
-                const char *contents)
+                 const char *contents)
 {
   FILE *fp;
 
@@ -496,12 +526,12 @@ get_classfile_version (const char *compiled_file_name)
     {
       /* Read its first 8 bytes.  */
       if (safe_read (fd, header, 8) == 8)
-       {
-         /* Verify the class file signature.  */
-         if (header[0] == 0xCA && header[1] == 0xFE
-             && header[2] == 0xBA && header[3] == 0xBE)
-           return header[7];
-       }
+        {
+          /* Verify the class file signature.  */
+          if (header[0] == 0xCA && header[1] == 0xFE
+              && header[2] == 0xBA && header[3] == 0xBE)
+            return header[7];
+        }
       close (fd);
     }
 
@@ -519,7 +549,7 @@ is_envjavac_gcj (const char *javac)
   if (!envjavac_tested)
     {
       /* Test whether $JAVAC is gcj:
-        "$JAVAC --version 2>/dev/null | sed -e 1q | grep gcj > /dev/null"  */
+         "$JAVAC --version 2>/dev/null | sed -e 1q | grep gcj > /dev/null"  */
       unsigned int command_length;
       char *command;
       char *argv[4];
@@ -534,17 +564,17 @@ is_envjavac_gcj (const char *javac)
 
       /* Setup the command "$JAVAC --version".  */
       command_length = strlen (javac) + 1 + 9 + 1;
-      command = (char *) xallocsa (command_length);
+      command = (char *) xmalloca (command_length);
       p = command;
       /* Don't shell_quote $JAVAC, because it may consist of a command
-        and options.  */
+         and options.  */
       memcpy (p, javac, strlen (javac));
       p += strlen (javac);
       memcpy (p, " --version", 1 + 9 + 1);
       p += 1 + 9 + 1;
       /* Ensure command_length was correctly calculated.  */
       if (p - command > command_length)
-       abort ();
+        abort ();
 
       /* Call $JAVAC --version 2>/dev/null.  */
       argv[0] = "/bin/sh";
@@ -552,33 +582,36 @@ is_envjavac_gcj (const char *javac)
       argv[2] = command;
       argv[3] = NULL;
       child = create_pipe_in (javac, "/bin/sh", argv, DEV_NULL, true, true,
-                             false, fd);
+                              false, fd);
       if (child == -1)
-       goto failed;
+        goto failed;
 
       /* Retrieve its result.  */
       fp = fdopen (fd[0], "r");
       if (fp == NULL)
-       goto failed;
+        goto failed;
 
       line = NULL; linesize = 0;
       linelen = getline (&line, &linesize, fp);
       if (linelen == (size_t)(-1))
-       {
-         fclose (fp);
-         goto failed;
-       }
-      envjavac_gcj = (strstr (line, "gcj") != NULL);
+        {
+          fclose (fp);
+          goto failed;
+        }
+      /* It is safe to call c_strstr() instead of strstr() here; see the
+         comments in c-strstr.h.  */
+      envjavac_gcj = (c_strstr (line, "gcj") != NULL);
 
       fclose (fp);
 
       /* Remove zombie process from process list, and retrieve exit status.  */
-      exitstatus = wait_subprocess (child, javac, true, true, true, false);
+      exitstatus =
+        wait_subprocess (child, javac, true, true, true, false, NULL);
       if (exitstatus != 0)
-       envjavac_gcj = false;
+        envjavac_gcj = false;
 
      failed:
-      freesa (command);
+      freea (command);
 
       envjavac_tested = true;
     }
@@ -586,11 +619,259 @@ is_envjavac_gcj (const char *javac)
   return envjavac_gcj;
 }
 
-/* Test whether $JAVAC, known to be a version of gcj, can be used for
+/* Return true if $JAVAC, known to be a version of gcj, is a version >= 4.3
+   of gcj.  */
+static bool
+is_envjavac_gcj43 (const char *javac)
+{
+  static bool envjavac_tested;
+  static bool envjavac_gcj43;
+
+  if (!envjavac_tested)
+    {
+      /* Test whether $JAVAC is gcj:
+         "$JAVAC --version 2>/dev/null | sed -e 's,^[^0-9]*,,' -e 1q \
+          | sed -e '/^4\.[012]/d' | grep '^[4-9]' >/dev/null"  */
+      unsigned int command_length;
+      char *command;
+      char *argv[4];
+      pid_t child;
+      int fd[1];
+      FILE *fp;
+      char *line;
+      size_t linesize;
+      size_t linelen;
+      int exitstatus;
+      char *p;
+
+      /* Setup the command "$JAVAC --version".  */
+      command_length = strlen (javac) + 1 + 9 + 1;
+      command = (char *) xmalloca (command_length);
+      p = command;
+      /* Don't shell_quote $JAVAC, because it may consist of a command
+         and options.  */
+      memcpy (p, javac, strlen (javac));
+      p += strlen (javac);
+      memcpy (p, " --version", 1 + 9 + 1);
+      p += 1 + 9 + 1;
+      /* Ensure command_length was correctly calculated.  */
+      if (p - command > command_length)
+        abort ();
+
+      /* Call $JAVAC --version 2>/dev/null.  */
+      argv[0] = "/bin/sh";
+      argv[1] = "-c";
+      argv[2] = command;
+      argv[3] = NULL;
+      child = create_pipe_in (javac, "/bin/sh", argv, DEV_NULL, true, true,
+                              false, fd);
+      if (child == -1)
+        goto failed;
+
+      /* Retrieve its result.  */
+      fp = fdopen (fd[0], "r");
+      if (fp == NULL)
+        goto failed;
+
+      line = NULL; linesize = 0;
+      linelen = getline (&line, &linesize, fp);
+      if (linelen == (size_t)(-1))
+        {
+          fclose (fp);
+          goto failed;
+        }
+      p = line;
+      while (*p != '\0' && !(*p >= '0' && *p <= '9'))
+        p++;
+      envjavac_gcj43 =
+        !(*p == '4' && p[1] == '.' && p[2] >= '0' && p[2] <= '2')
+        && (*p >= '4' && *p <= '9');
+
+      fclose (fp);
+
+      /* Remove zombie process from process list, and retrieve exit status.  */
+      exitstatus =
+        wait_subprocess (child, javac, true, true, true, false, NULL);
+      if (exitstatus != 0)
+        envjavac_gcj43 = false;
+
+     failed:
+      freea (command);
+
+      envjavac_tested = true;
+    }
+
+  return envjavac_gcj43;
+}
+
+/* Test whether $JAVAC, known to be a version of gcj >= 4.3, can be used, and
+   whether it needs a -fsource and/or -ftarget option.
+   Return a failure indicator (true upon error).  */
+static bool
+is_envjavac_gcj43_usable (const char *javac,
+                          const char *source_version,
+                          const char *target_version,
+                          bool *usablep,
+                          bool *fsource_option_p, bool *ftarget_option_p)
+{
+  /* The cache depends on the source_version and target_version.  */
+  struct result_t
+  {
+    bool tested;
+    bool usable;
+    bool fsource_option;
+    bool ftarget_option;
+  };
+  static struct result_t result_cache[SOURCE_VERSION_BOUND][TARGET_VERSION_BOUND];
+  struct result_t *resultp;
+
+  resultp = &result_cache[source_version_index (source_version)]
+                         [target_version_index (target_version)];
+  if (!resultp->tested)
+    {
+      /* Try $JAVAC.  */
+      struct temp_dir *tmpdir;
+      char *conftest_file_name;
+      char *compiled_file_name;
+      const char *java_sources[1];
+      struct stat statbuf;
+
+      tmpdir = create_temp_dir ("java", NULL, false);
+      if (tmpdir == NULL)
+        return true;
+
+      conftest_file_name =
+        xconcatenated_filename (tmpdir->dir_name, "conftest.java", NULL);
+      if (write_temp_file (tmpdir, conftest_file_name,
+                           get_goodcode_snippet (source_version)))
+        {
+          free (conftest_file_name);
+          cleanup_temp_dir (tmpdir);
+          return true;
+        }
+
+      compiled_file_name =
+        xconcatenated_filename (tmpdir->dir_name, "conftest.class", NULL);
+      register_temp_file (tmpdir, compiled_file_name);
+
+      java_sources[0] = conftest_file_name;
+      if (!compile_using_envjavac (javac,
+                                   java_sources, 1, tmpdir->dir_name,
+                                   false, false, false, true)
+          && stat (compiled_file_name, &statbuf) >= 0
+          && get_classfile_version (compiled_file_name)
+             <= corresponding_classfile_version (target_version))
+        {
+          /* $JAVAC compiled conftest.java successfully.  */
+          /* Try adding -fsource option if it is useful.  */
+          char *javac_source =
+            xasprintf ("%s -fsource=%s", javac, source_version);
+
+          unlink (compiled_file_name);
+
+          java_sources[0] = conftest_file_name;
+          if (!compile_using_envjavac (javac_source,
+                                       java_sources, 1, tmpdir->dir_name,
+                                       false, false, false, true)
+              && stat (compiled_file_name, &statbuf) >= 0
+              && get_classfile_version (compiled_file_name)
+                 <= corresponding_classfile_version (target_version))
+            {
+              const char *failcode = get_failcode_snippet (source_version);
+
+              if (failcode != NULL)
+                {
+                  free (compiled_file_name);
+                  free (conftest_file_name);
+
+                  conftest_file_name =
+                    xconcatenated_filename (tmpdir->dir_name,
+                                            "conftestfail.java",
+                                            NULL);
+                  if (write_temp_file (tmpdir, conftest_file_name, failcode))
+                    {
+                      free (conftest_file_name);
+                      free (javac_source);
+                      cleanup_temp_dir (tmpdir);
+                      return true;
+                    }
+
+                  compiled_file_name =
+                    xconcatenated_filename (tmpdir->dir_name,
+                                            "conftestfail.class",
+                                            NULL);
+                  register_temp_file (tmpdir, compiled_file_name);
+
+                  java_sources[0] = conftest_file_name;
+                  if (!compile_using_envjavac (javac,
+                                               java_sources, 1,
+                                               tmpdir->dir_name,
+                                               false, false, false, true)
+                      && stat (compiled_file_name, &statbuf) >= 0)
+                    {
+                      unlink (compiled_file_name);
+
+                      java_sources[0] = conftest_file_name;
+                      if (compile_using_envjavac (javac_source,
+                                                  java_sources, 1,
+                                                  tmpdir->dir_name,
+                                                  false, false, false, true))
+                        /* $JAVAC compiled conftestfail.java successfully, and
+                           "$JAVAC -fsource=$source_version" rejects it.  So
+                           the -fsource option is useful.  */
+                        resultp->fsource_option = true;
+                    }
+                }
+            }
+
+          free (javac_source);
+
+          resultp->usable = true;
+        }
+      else
+        {
+          /* Try with -fsource and -ftarget options.  */
+          char *javac_target =
+            xasprintf ("%s -fsource=%s -ftarget=%s",
+                       javac, source_version, target_version);
+
+          unlink (compiled_file_name);
+
+          java_sources[0] = conftest_file_name;
+          if (!compile_using_envjavac (javac_target,
+                                       java_sources, 1, tmpdir->dir_name,
+                                       false, false, false, true)
+              && stat (compiled_file_name, &statbuf) >= 0
+              && get_classfile_version (compiled_file_name)
+                 <= corresponding_classfile_version (target_version))
+            {
+              /* "$JAVAC -fsource $source_version -ftarget $target_version"
+                 compiled conftest.java successfully.  */
+              resultp->fsource_option = true;
+              resultp->ftarget_option = true;
+              resultp->usable = true;
+            }
+
+          free (javac_target);
+        }
+
+      free (compiled_file_name);
+      free (conftest_file_name);
+
+      resultp->tested = true;
+    }
+
+  *usablep = resultp->usable;
+  *fsource_option_p = resultp->fsource_option;
+  *ftarget_option_p = resultp->ftarget_option;
+  return false;
+}
+
+/* Test whether $JAVAC, known to be a version of gcj < 4.3, can be used for
    compiling with target_version = 1.4 and source_version = 1.4.
    Return a failure indicator (true upon error).  */
 static bool
-is_envjavac_gcj_14_14_usable (const char *javac, bool *usablep)
+is_envjavac_oldgcj_14_14_usable (const char *javac, bool *usablep)
 {
   static bool envjavac_tested;
   static bool envjavac_usable;
@@ -606,28 +887,28 @@ is_envjavac_gcj_14_14_usable (const char *javac, bool *usablep)
 
       tmpdir = create_temp_dir ("java", NULL, false);
       if (tmpdir == NULL)
-       return true;
+        return true;
 
       conftest_file_name =
-       concatenated_pathname (tmpdir->dir_name, "conftest.java", NULL);
+        xconcatenated_filename (tmpdir->dir_name, "conftest.java", NULL);
       if (write_temp_file (tmpdir, conftest_file_name,
-                          get_goodcode_snippet ("1.4")))
-       {
-         free (conftest_file_name);
-         cleanup_temp_dir (tmpdir);
-         return true;
-       }
+                           get_goodcode_snippet ("1.4")))
+        {
+          free (conftest_file_name);
+          cleanup_temp_dir (tmpdir);
+          return true;
+        }
 
       compiled_file_name =
-       concatenated_pathname (tmpdir->dir_name, "conftest.class", NULL);
+        xconcatenated_filename (tmpdir->dir_name, "conftest.class", NULL);
       register_temp_file (tmpdir, compiled_file_name);
 
       java_sources[0] = conftest_file_name;
       if (!compile_using_envjavac (javac, java_sources, 1, tmpdir->dir_name,
-                                  false, false, false, true)
-         && stat (compiled_file_name, &statbuf) >= 0)
-       /* Compilation succeeded.  */
-       envjavac_usable = true;
+                                   false, false, false, true)
+          && stat (compiled_file_name, &statbuf) >= 0)
+        /* Compilation succeeded.  */
+        envjavac_usable = true;
 
       free (compiled_file_name);
       free (conftest_file_name);
@@ -641,12 +922,12 @@ is_envjavac_gcj_14_14_usable (const char *javac, bool *usablep)
   return false;
 }
 
-/* Test whether $JAVAC, known to be a version of gcj, can be used for
+/* Test whether $JAVAC, known to be a version of gcj < 4.3, can be used for
    compiling with target_version = 1.4 and source_version = 1.3.
    Return a failure indicator (true upon error).  */
 static bool
-is_envjavac_gcj_14_13_usable (const char *javac,
-                             bool *usablep, bool *need_no_assert_option_p)
+is_envjavac_oldgcj_14_13_usable (const char *javac,
+                                 bool *usablep, bool *need_no_assert_option_p)
 {
   static bool envjavac_tested;
   static bool envjavac_usable;
@@ -655,7 +936,7 @@ is_envjavac_gcj_14_13_usable (const char *javac,
   if (!envjavac_tested)
     {
       /* Try $JAVAC and "$JAVAC -fno-assert".  But add -fno-assert only if
-        it makes a difference.  (It could already be part of $JAVAC.)  */
+         it makes a difference.  (It could already be part of $JAVAC.)  */
       struct temp_dir *tmpdir;
       char *conftest_file_name;
       char *compiled_file_name;
@@ -667,31 +948,31 @@ is_envjavac_gcj_14_13_usable (const char *javac,
 
       tmpdir = create_temp_dir ("java", NULL, false);
       if (tmpdir == NULL)
-       return true;
+        return true;
 
       conftest_file_name =
-       concatenated_pathname (tmpdir->dir_name, "conftest.java", NULL);
+        xconcatenated_filename (tmpdir->dir_name, "conftest.java", NULL);
       if (write_temp_file (tmpdir, conftest_file_name,
-                          get_goodcode_snippet ("1.3")))
-       {
-         free (conftest_file_name);
-         cleanup_temp_dir (tmpdir);
-         return true;
-       }
+                           get_goodcode_snippet ("1.3")))
+        {
+          free (conftest_file_name);
+          cleanup_temp_dir (tmpdir);
+          return true;
+        }
 
       compiled_file_name =
-       concatenated_pathname (tmpdir->dir_name, "conftest.class", NULL);
+        xconcatenated_filename (tmpdir->dir_name, "conftest.class", NULL);
       register_temp_file (tmpdir, compiled_file_name);
 
       java_sources[0] = conftest_file_name;
       if (!compile_using_envjavac (javac,
-                                  java_sources, 1, tmpdir->dir_name,
-                                  false, false, false, true)
-         && stat (compiled_file_name, &statbuf) >= 0)
-       /* Compilation succeeded.  */
-       javac_works = true;
+                                   java_sources, 1, tmpdir->dir_name,
+                                   false, false, false, true)
+          && stat (compiled_file_name, &statbuf) >= 0)
+        /* Compilation succeeded.  */
+        javac_works = true;
       else
-       javac_works = false;
+        javac_works = false;
 
       unlink (compiled_file_name);
 
@@ -699,71 +980,71 @@ is_envjavac_gcj_14_13_usable (const char *javac,
 
       java_sources[0] = conftest_file_name;
       if (!compile_using_envjavac (javac_noassert,
-                                  java_sources, 1, tmpdir->dir_name,
-                                  false, false, false, true)
-         && stat (compiled_file_name, &statbuf) >= 0)
-       /* Compilation succeeded.  */
-       javac_noassert_works = true;
+                                   java_sources, 1, tmpdir->dir_name,
+                                   false, false, false, true)
+          && stat (compiled_file_name, &statbuf) >= 0)
+        /* Compilation succeeded.  */
+        javac_noassert_works = true;
       else
-       javac_noassert_works = false;
+        javac_noassert_works = false;
 
       free (compiled_file_name);
       free (conftest_file_name);
 
       if (javac_works && javac_noassert_works)
-       {
-         conftest_file_name =
-           concatenated_pathname (tmpdir->dir_name, "conftestfail.java",
-                                  NULL);
-         if (write_temp_file (tmpdir, conftest_file_name,
-                              get_failcode_snippet ("1.3")))
-           {
-             free (conftest_file_name);
-             free (javac_noassert);
-             cleanup_temp_dir (tmpdir);
-             return true;
-           }
-
-         compiled_file_name =
-           concatenated_pathname (tmpdir->dir_name, "conftestfail.class",
-                                  NULL);
-         register_temp_file (tmpdir, compiled_file_name);
-
-         java_sources[0] = conftest_file_name;
-         if (!compile_using_envjavac (javac,
-                                      java_sources, 1, tmpdir->dir_name,
-                                      false, false, false, true)
-             && stat (compiled_file_name, &statbuf) >= 0)
-           {
-             /* Compilation succeeded.  */
-             unlink (compiled_file_name);
-
-             java_sources[0] = conftest_file_name;
-             if (!(!compile_using_envjavac (javac_noassert,
-                                            java_sources, 1, tmpdir->dir_name,
-                                            false, false, false, true)
-                   && stat (compiled_file_name, &statbuf) >= 0))
-               /* Compilation failed.  */
-               /* "$JAVAC -fno-assert" works better than $JAVAC.  */
-               javac_works = true;
-           }
-
-         free (compiled_file_name);
-         free (conftest_file_name);
-       }
+        {
+          conftest_file_name =
+            xconcatenated_filename (tmpdir->dir_name, "conftestfail.java",
+                                    NULL);
+          if (write_temp_file (tmpdir, conftest_file_name,
+                               get_failcode_snippet ("1.3")))
+            {
+              free (conftest_file_name);
+              free (javac_noassert);
+              cleanup_temp_dir (tmpdir);
+              return true;
+            }
+
+          compiled_file_name =
+            xconcatenated_filename (tmpdir->dir_name, "conftestfail.class",
+                                    NULL);
+          register_temp_file (tmpdir, compiled_file_name);
+
+          java_sources[0] = conftest_file_name;
+          if (!compile_using_envjavac (javac,
+                                       java_sources, 1, tmpdir->dir_name,
+                                       false, false, false, true)
+              && stat (compiled_file_name, &statbuf) >= 0)
+            {
+              /* Compilation succeeded.  */
+              unlink (compiled_file_name);
+
+              java_sources[0] = conftest_file_name;
+              if (!(!compile_using_envjavac (javac_noassert,
+                                             java_sources, 1, tmpdir->dir_name,
+                                             false, false, false, true)
+                    && stat (compiled_file_name, &statbuf) >= 0))
+                /* Compilation failed.  */
+                /* "$JAVAC -fno-assert" works better than $JAVAC.  */
+                javac_works = true;
+            }
+
+          free (compiled_file_name);
+          free (conftest_file_name);
+        }
 
       cleanup_temp_dir (tmpdir);
 
       if (javac_works)
-       {
-         envjavac_usable = true;
-         envjavac_need_no_assert_option = false;
-       }
+        {
+          envjavac_usable = true;
+          envjavac_need_no_assert_option = false;
+        }
       else if (javac_noassert_works)
-       {
-         envjavac_usable = true;
-         envjavac_need_no_assert_option = true;
-       }
+        {
+          envjavac_usable = true;
+          envjavac_need_no_assert_option = true;
+        }
 
       envjavac_tested = true;
     }
@@ -778,10 +1059,10 @@ is_envjavac_gcj_14_13_usable (const char *javac,
    Return a failure indicator (true upon error).  */
 static bool
 is_envjavac_nongcj_usable (const char *javac,
-                          const char *source_version,
-                          const char *target_version,
-                          bool *usablep,
-                          bool *source_option_p, bool *target_option_p)
+                           const char *source_version,
+                           const char *target_version,
+                           bool *usablep,
+                           bool *source_option_p, bool *target_option_p)
 {
   /* The cache depends on the source_version and target_version.  */
   struct result_t
@@ -795,7 +1076,7 @@ is_envjavac_nongcj_usable (const char *javac,
   struct result_t *resultp;
 
   resultp = &result_cache[source_version_index (source_version)]
-                        [target_version_index (target_version)];
+                         [target_version_index (target_version)];
   if (!resultp->tested)
     {
       /* Try $JAVAC.  */
@@ -807,215 +1088,215 @@ is_envjavac_nongcj_usable (const char *javac,
 
       tmpdir = create_temp_dir ("java", NULL, false);
       if (tmpdir == NULL)
-       return true;
+        return true;
 
       conftest_file_name =
-       concatenated_pathname (tmpdir->dir_name, "conftest.java", NULL);
+        xconcatenated_filename (tmpdir->dir_name, "conftest.java", NULL);
       if (write_temp_file (tmpdir, conftest_file_name,
-                          get_goodcode_snippet (source_version)))
-       {
-         free (conftest_file_name);
-         cleanup_temp_dir (tmpdir);
-         return true;
-       }
+                           get_goodcode_snippet (source_version)))
+        {
+          free (conftest_file_name);
+          cleanup_temp_dir (tmpdir);
+          return true;
+        }
 
       compiled_file_name =
-       concatenated_pathname (tmpdir->dir_name, "conftest.class", NULL);
+        xconcatenated_filename (tmpdir->dir_name, "conftest.class", NULL);
       register_temp_file (tmpdir, compiled_file_name);
 
       java_sources[0] = conftest_file_name;
       if (!compile_using_envjavac (javac,
-                                  java_sources, 1, tmpdir->dir_name,
-                                  false, false, false, true)
-         && stat (compiled_file_name, &statbuf) >= 0
-         && get_classfile_version (compiled_file_name)
-            <= corresponding_classfile_version (target_version))
-       {
-         /* $JAVAC compiled conftest.java successfully.  */
-         /* Try adding -source option if it is useful.  */
-         char *javac_source =
-           xasprintf ("%s -source %s", javac, source_version);
-
-         unlink (compiled_file_name);
-
-         java_sources[0] = conftest_file_name;
-         if (!compile_using_envjavac (javac_source,
-                                      java_sources, 1, tmpdir->dir_name,
-                                      false, false, false, true)
-             && stat (compiled_file_name, &statbuf) >= 0
-             && get_classfile_version (compiled_file_name)
-                <= corresponding_classfile_version (target_version))
-           {
-             const char *failcode = get_failcode_snippet (source_version);
-
-             if (failcode != NULL)
-               {
-                 free (compiled_file_name);
-                 free (conftest_file_name);
-
-                 conftest_file_name =
-                   concatenated_pathname (tmpdir->dir_name,
-                                          "conftestfail.java",
-                                          NULL);
-                 if (write_temp_file (tmpdir, conftest_file_name, failcode))
-                   {
-                     free (conftest_file_name);
-                     free (javac_source);
-                     cleanup_temp_dir (tmpdir);
-                     return true;
-                   }
-
-                 compiled_file_name =
-                   concatenated_pathname (tmpdir->dir_name,
-                                          "conftestfail.class",
-                                          NULL);
-                 register_temp_file (tmpdir, compiled_file_name);
-
-                 java_sources[0] = conftest_file_name;
-                 if (!compile_using_envjavac (javac,
-                                              java_sources, 1,
-                                              tmpdir->dir_name,
-                                              false, false, false, true)
-                     && stat (compiled_file_name, &statbuf) >= 0)
-                   {
-                     unlink (compiled_file_name);
-
-                     java_sources[0] = conftest_file_name;
-                     if (compile_using_envjavac (javac_source,
-                                                 java_sources, 1,
-                                                 tmpdir->dir_name,
-                                                 false, false, false, true))
-                       /* $JAVAC compiled conftestfail.java successfully, and
-                          "$JAVAC -source $source_version" rejects it.  So the
-                          -source option is useful.  */
-                       resultp->source_option = true;
-                   }
-               }
-           }
-
-         free (javac_source);
-
-         resultp->usable = true;
-       }
+                                   java_sources, 1, tmpdir->dir_name,
+                                   false, false, false, true)
+          && stat (compiled_file_name, &statbuf) >= 0
+          && get_classfile_version (compiled_file_name)
+             <= corresponding_classfile_version (target_version))
+        {
+          /* $JAVAC compiled conftest.java successfully.  */
+          /* Try adding -source option if it is useful.  */
+          char *javac_source =
+            xasprintf ("%s -source %s", javac, source_version);
+
+          unlink (compiled_file_name);
+
+          java_sources[0] = conftest_file_name;
+          if (!compile_using_envjavac (javac_source,
+                                       java_sources, 1, tmpdir->dir_name,
+                                       false, false, false, true)
+              && stat (compiled_file_name, &statbuf) >= 0
+              && get_classfile_version (compiled_file_name)
+                 <= corresponding_classfile_version (target_version))
+            {
+              const char *failcode = get_failcode_snippet (source_version);
+
+              if (failcode != NULL)
+                {
+                  free (compiled_file_name);
+                  free (conftest_file_name);
+
+                  conftest_file_name =
+                    xconcatenated_filename (tmpdir->dir_name,
+                                            "conftestfail.java",
+                                            NULL);
+                  if (write_temp_file (tmpdir, conftest_file_name, failcode))
+                    {
+                      free (conftest_file_name);
+                      free (javac_source);
+                      cleanup_temp_dir (tmpdir);
+                      return true;
+                    }
+
+                  compiled_file_name =
+                    xconcatenated_filename (tmpdir->dir_name,
+                                            "conftestfail.class",
+                                            NULL);
+                  register_temp_file (tmpdir, compiled_file_name);
+
+                  java_sources[0] = conftest_file_name;
+                  if (!compile_using_envjavac (javac,
+                                               java_sources, 1,
+                                               tmpdir->dir_name,
+                                               false, false, false, true)
+                      && stat (compiled_file_name, &statbuf) >= 0)
+                    {
+                      unlink (compiled_file_name);
+
+                      java_sources[0] = conftest_file_name;
+                      if (compile_using_envjavac (javac_source,
+                                                  java_sources, 1,
+                                                  tmpdir->dir_name,
+                                                  false, false, false, true))
+                        /* $JAVAC compiled conftestfail.java successfully, and
+                           "$JAVAC -source $source_version" rejects it.  So the
+                           -source option is useful.  */
+                        resultp->source_option = true;
+                    }
+                }
+            }
+
+          free (javac_source);
+
+          resultp->usable = true;
+        }
       else
-       {
-         /* Try with -target option alone. (Sun javac 1.3.1 has the -target
-            option but no -source option.)  */
-         char *javac_target =
-           xasprintf ("%s -target %s", javac, target_version);
-
-         unlink (compiled_file_name);
-
-         java_sources[0] = conftest_file_name;
-         if (!compile_using_envjavac (javac_target,
-                                      java_sources, 1, tmpdir->dir_name,
-                                      false, false, false, true)
-             && stat (compiled_file_name, &statbuf) >= 0
-             && get_classfile_version (compiled_file_name)
-                <= corresponding_classfile_version (target_version))
-           {
-             /* "$JAVAC -target $target_version" compiled conftest.java
-                successfully.  */
-             /* Try adding -source option if it is useful.  */
-             char *javac_target_source =
-               xasprintf ("%s -source %s", javac_target, source_version);
-
-             unlink (compiled_file_name);
-
-             java_sources[0] = conftest_file_name;
-             if (!compile_using_envjavac (javac_target_source,
-                                          java_sources, 1, tmpdir->dir_name,
-                                          false, false, false, true)
-                 && stat (compiled_file_name, &statbuf) >= 0
-                 && get_classfile_version (compiled_file_name)
-                    <= corresponding_classfile_version (target_version))
-               {
-                 const char *failcode = get_failcode_snippet (source_version);
-
-                 if (failcode != NULL)
-                   {
-                     free (compiled_file_name);
-                     free (conftest_file_name);
-
-                     conftest_file_name =
-                       concatenated_pathname (tmpdir->dir_name,
-                                              "conftestfail.java",
-                                              NULL);
-                     if (write_temp_file (tmpdir, conftest_file_name,
-                                          failcode))
-                       {
-                         free (conftest_file_name);
-                         free (javac_target_source);
-                         free (javac_target);
-                         cleanup_temp_dir (tmpdir);
-                         return true;
-                       }
-
-                     compiled_file_name =
-                       concatenated_pathname (tmpdir->dir_name,
-                                              "conftestfail.class",
-                                              NULL);
-                     register_temp_file (tmpdir, compiled_file_name);
-
-                     java_sources[0] = conftest_file_name;
-                     if (!compile_using_envjavac (javac_target,
-                                                  java_sources, 1,
-                                                  tmpdir->dir_name,
-                                                  false, false, false, true)
-                         && stat (compiled_file_name, &statbuf) >= 0)
-                       {
-                         unlink (compiled_file_name);
-
-                         java_sources[0] = conftest_file_name;
-                         if (compile_using_envjavac (javac_target_source,
-                                                     java_sources, 1,
-                                                     tmpdir->dir_name,
-                                                     false, false, false,
-                                                     true))
-                           /* "$JAVAC -target $target_version" compiled
-                              conftestfail.java successfully, and
-                              "$JAVAC -target $target_version -source $source_version"
-                              rejects it.  So the -source option is useful.  */
-                           resultp->source_option = true;
-                       }
-                   }
-               }
-
-             free (javac_target_source);
-
-             resultp->target_option = true;
-             resultp->usable = true;
-           }
-         else
-           {
-             /* Maybe this -target option requires a -source option? Try with
-                -target and -source options. (Supported by Sun javac 1.4 and
-                higher.)  */
-             char *javac_target_source =
-               xasprintf ("%s -source %s", javac_target, source_version);
-
-             unlink (compiled_file_name);
-
-             java_sources[0] = conftest_file_name;
-             if (!compile_using_envjavac (javac_target_source,
-                                          java_sources, 1, tmpdir->dir_name,
-                                          false, false, false, true)
-                 && stat (compiled_file_name, &statbuf) >= 0
-                 && get_classfile_version (compiled_file_name)
-                    <= corresponding_classfile_version (target_version))
-               {
-                 /* "$JAVAC -target $target_version -source $source_version"
-                    compiled conftest.java successfully.  */
-                 resultp->source_option = true;
-                 resultp->target_option = true;
-                 resultp->usable = true;
-               }
-
-             free (javac_target_source);
-           }
-
-         free (javac_target);
-       }
+        {
+          /* Try with -target option alone. (Sun javac 1.3.1 has the -target
+             option but no -source option.)  */
+          char *javac_target =
+            xasprintf ("%s -target %s", javac, target_version);
+
+          unlink (compiled_file_name);
+
+          java_sources[0] = conftest_file_name;
+          if (!compile_using_envjavac (javac_target,
+                                       java_sources, 1, tmpdir->dir_name,
+                                       false, false, false, true)
+              && stat (compiled_file_name, &statbuf) >= 0
+              && get_classfile_version (compiled_file_name)
+                 <= corresponding_classfile_version (target_version))
+            {
+              /* "$JAVAC -target $target_version" compiled conftest.java
+                 successfully.  */
+              /* Try adding -source option if it is useful.  */
+              char *javac_target_source =
+                xasprintf ("%s -source %s", javac_target, source_version);
+
+              unlink (compiled_file_name);
+
+              java_sources[0] = conftest_file_name;
+              if (!compile_using_envjavac (javac_target_source,
+                                           java_sources, 1, tmpdir->dir_name,
+                                           false, false, false, true)
+                  && stat (compiled_file_name, &statbuf) >= 0
+                  && get_classfile_version (compiled_file_name)
+                     <= corresponding_classfile_version (target_version))
+                {
+                  const char *failcode = get_failcode_snippet (source_version);
+
+                  if (failcode != NULL)
+                    {
+                      free (compiled_file_name);
+                      free (conftest_file_name);
+
+                      conftest_file_name =
+                        xconcatenated_filename (tmpdir->dir_name,
+                                                "conftestfail.java",
+                                                NULL);
+                      if (write_temp_file (tmpdir, conftest_file_name,
+                                           failcode))
+                        {
+                          free (conftest_file_name);
+                          free (javac_target_source);
+                          free (javac_target);
+                          cleanup_temp_dir (tmpdir);
+                          return true;
+                        }
+
+                      compiled_file_name =
+                        xconcatenated_filename (tmpdir->dir_name,
+                                                "conftestfail.class",
+                                                NULL);
+                      register_temp_file (tmpdir, compiled_file_name);
+
+                      java_sources[0] = conftest_file_name;
+                      if (!compile_using_envjavac (javac_target,
+                                                   java_sources, 1,
+                                                   tmpdir->dir_name,
+                                                   false, false, false, true)
+                          && stat (compiled_file_name, &statbuf) >= 0)
+                        {
+                          unlink (compiled_file_name);
+
+                          java_sources[0] = conftest_file_name;
+                          if (compile_using_envjavac (javac_target_source,
+                                                      java_sources, 1,
+                                                      tmpdir->dir_name,
+                                                      false, false, false,
+                                                      true))
+                            /* "$JAVAC -target $target_version" compiled
+                               conftestfail.java successfully, and
+                               "$JAVAC -target $target_version -source $source_version"
+                               rejects it.  So the -source option is useful.  */
+                            resultp->source_option = true;
+                        }
+                    }
+                }
+
+              free (javac_target_source);
+
+              resultp->target_option = true;
+              resultp->usable = true;
+            }
+          else
+            {
+              /* Maybe this -target option requires a -source option? Try with
+                 -target and -source options. (Supported by Sun javac 1.4 and
+                 higher.)  */
+              char *javac_target_source =
+                xasprintf ("%s -source %s", javac_target, source_version);
+
+              unlink (compiled_file_name);
+
+              java_sources[0] = conftest_file_name;
+              if (!compile_using_envjavac (javac_target_source,
+                                           java_sources, 1, tmpdir->dir_name,
+                                           false, false, false, true)
+                  && stat (compiled_file_name, &statbuf) >= 0
+                  && get_classfile_version (compiled_file_name)
+                     <= corresponding_classfile_version (target_version))
+                {
+                  /* "$JAVAC -target $target_version -source $source_version"
+                     compiled conftest.java successfully.  */
+                  resultp->source_option = true;
+                  resultp->target_option = true;
+                  resultp->usable = true;
+                }
+
+              free (javac_target_source);
+            }
+
+          free (javac_target);
+        }
 
       free (compiled_file_name);
       free (conftest_file_name);
@@ -1038,9 +1319,9 @@ is_gcj_present (void)
   if (!gcj_tested)
     {
       /* Test for presence of gcj:
-        "gcj --version 2> /dev/null | \
-         sed -e 's,^[^0-9]*,,' -e 1q | \
-         sed -e '/^3\.[01]/d' | grep '^[3-9]' > /dev/null"  */
+         "gcj --version 2> /dev/null | \
+          sed -e 's,^[^0-9]*,,' -e 1q | \
+          sed -e '/^3\.[01]/d' | grep '^[3-9]' > /dev/null"  */
       char *argv[3];
       pid_t child;
       int fd[1];
@@ -1050,93 +1331,94 @@ is_gcj_present (void)
       argv[1] = "--version";
       argv[2] = NULL;
       child = create_pipe_in ("gcj", "gcj", argv, DEV_NULL, true, true,
-                             false, fd);
+                              false, fd);
       gcj_present = false;
       if (child != -1)
-       {
-         /* Read the subprocess output, drop all lines except the first,
-            drop all characters before the first digit, and test whether
-            the remaining string starts with a digit >= 3, but not with
-            "3.0" or "3.1".  */
-         char c[3];
-         size_t count = 0;
-
-         while (safe_read (fd[0], &c[count], 1) > 0)
-           {
-             if (c[count] == '\n')
-               break;
-             if (count == 0)
-               {
-                 if (!(c[0] >= '0' && c[0] <= '9'))
-                   continue;
-                 gcj_present = (c[0] >= '3');
-               }
-             count++;
-             if (count == 3)
-               {
-                 if (c[0] == '3' && c[1] == '.'
-                     && (c[2] == '0' || c[2] == '1'))
-                   gcj_present = false;
-                 break;
-               }
-           }
-         while (safe_read (fd[0], &c[0], 1) > 0)
-           ;
-
-         close (fd[0]);
-
-         /* Remove zombie process from process list, and retrieve exit
-            status.  */
-         exitstatus =
-           wait_subprocess (child, "gcj", false, true, true, false);
-         if (exitstatus != 0)
-           gcj_present = false;
-       }
+        {
+          /* Read the subprocess output, drop all lines except the first,
+             drop all characters before the first digit, and test whether
+             the remaining string starts with a digit >= 3, but not with
+             "3.0" or "3.1".  */
+          char c[3];
+          size_t count = 0;
+
+          while (safe_read (fd[0], &c[count], 1) > 0)
+            {
+              if (c[count] == '\n')
+                break;
+              if (count == 0)
+                {
+                  if (!(c[0] >= '0' && c[0] <= '9'))
+                    continue;
+                  gcj_present = (c[0] >= '3');
+                }
+              count++;
+              if (count == 3)
+                {
+                  if (c[0] == '3' && c[1] == '.'
+                      && (c[2] == '0' || c[2] == '1'))
+                    gcj_present = false;
+                  break;
+                }
+            }
+          while (safe_read (fd[0], &c[0], 1) > 0)
+            ;
+
+          close (fd[0]);
+
+          /* Remove zombie process from process list, and retrieve exit
+             status.  */
+          exitstatus =
+            wait_subprocess (child, "gcj", false, true, true, false, NULL);
+          if (exitstatus != 0)
+            gcj_present = false;
+        }
 
       if (gcj_present)
-       {
-         /* See if libgcj.jar is well installed.  */
-         struct temp_dir *tmpdir;
-
-         tmpdir = create_temp_dir ("java", NULL, false);
-         if (tmpdir == NULL)
-           gcj_present = false;
-         else
-           {
-             char *conftest_file_name;
-
-             conftest_file_name =
-               concatenated_pathname (tmpdir->dir_name, "conftestlib.java",
-                                      NULL);
-             if (write_temp_file (tmpdir, conftest_file_name,
+        {
+          /* See if libgcj.jar is well installed.  */
+          struct temp_dir *tmpdir;
+
+          tmpdir = create_temp_dir ("java", NULL, false);
+          if (tmpdir == NULL)
+            gcj_present = false;
+          else
+            {
+              char *conftest_file_name;
+
+              conftest_file_name =
+                xconcatenated_filename (tmpdir->dir_name, "conftestlib.java",
+                                        NULL);
+              if (write_temp_file (tmpdir, conftest_file_name,
 "public class conftestlib {\n"
 "  public static void main (String[] args) {\n"
 "  }\n"
 "}\n"))
-               gcj_present = false;
-             else
-               {
-                 char *compiled_file_name;
-                 const char *java_sources[1];
-
-                 compiled_file_name =
-                   concatenated_pathname (tmpdir->dir_name,
-                                          "conftestlib.class",
-                                          NULL);
-                 register_temp_file (tmpdir, compiled_file_name);
-
-                 java_sources[0] = conftest_file_name;
-                 if (compile_using_gcj (java_sources, 1, false,
-                                        tmpdir->dir_name,
-                                        false, false, false, true))
-                   gcj_present = false;
-
-                 free (compiled_file_name);
-               }
-             free (conftest_file_name);
-           }
-         cleanup_temp_dir (tmpdir);
-       }
+                gcj_present = false;
+              else
+                {
+                  char *compiled_file_name;
+                  const char *java_sources[1];
+
+                  compiled_file_name =
+                    xconcatenated_filename (tmpdir->dir_name,
+                                            "conftestlib.class",
+                                            NULL);
+                  register_temp_file (tmpdir, compiled_file_name);
+
+                  java_sources[0] = conftest_file_name;
+                  if (compile_using_gcj (java_sources, 1, false,
+                                         false, NULL, false, NULL,
+                                         tmpdir->dir_name,
+                                         false, false, false, true))
+                    gcj_present = false;
+
+                  free (compiled_file_name);
+                }
+              free (conftest_file_name);
+            }
+          cleanup_temp_dir (tmpdir);
+        }
 
       gcj_tested = true;
     }
@@ -1144,11 +1426,232 @@ is_gcj_present (void)
   return gcj_present;
 }
 
-/* Test gcj can be used for compiling with target_version = 1.4 and
-   source_version = 1.4.
+static bool
+is_gcj_43 (void)
+{
+  static bool gcj_tested;
+  static bool gcj_43;
+
+  if (!gcj_tested)
+    {
+      /* Test for presence of gcj:
+         "gcj --version 2> /dev/null | \
+          sed -e 's,^[^0-9]*,,' -e 1q | \
+          sed -e '/^4\.[012]/d' | grep '^[4-9]'"  */
+      char *argv[3];
+      pid_t child;
+      int fd[1];
+      int exitstatus;
+
+      argv[0] = "gcj";
+      argv[1] = "--version";
+      argv[2] = NULL;
+      child = create_pipe_in ("gcj", "gcj", argv, DEV_NULL, true, true,
+                              false, fd);
+      gcj_43 = false;
+      if (child != -1)
+        {
+          /* Read the subprocess output, drop all lines except the first,
+             drop all characters before the first digit, and test whether
+             the remaining string starts with a digit >= 4, but not with
+             "4.0" or "4.1" or "4.2".  */
+          char c[3];
+          size_t count = 0;
+
+          while (safe_read (fd[0], &c[count], 1) > 0)
+            {
+              if (c[count] == '\n')
+                break;
+              if (count == 0)
+                {
+                  if (!(c[0] >= '0' && c[0] <= '9'))
+                    continue;
+                  gcj_43 = (c[0] >= '4');
+                }
+              count++;
+              if (count == 3)
+                {
+                  if (c[0] == '4' && c[1] == '.' && c[2] >= '0' && c[2] <= '2')
+                    gcj_43 = false;
+                  break;
+                }
+            }
+          while (safe_read (fd[0], &c[0], 1) > 0)
+            ;
+
+          close (fd[0]);
+
+          /* Remove zombie process from process list, and retrieve exit
+             status.  */
+          exitstatus =
+            wait_subprocess (child, "gcj", false, true, true, false, NULL);
+          if (exitstatus != 0)
+            gcj_43 = false;
+        }
+
+      gcj_tested = true;
+    }
+
+  return gcj_43;
+}
+
+/* Test whether gcj >= 4.3 can be used, and whether it needs a -fsource and/or
+   -ftarget option.
+   Return a failure indicator (true upon error).  */
+static bool
+is_gcj43_usable (const char *source_version,
+                 const char *target_version,
+                 bool *usablep,
+                 bool *fsource_option_p, bool *ftarget_option_p)
+{
+  /* The cache depends on the source_version and target_version.  */
+  struct result_t
+  {
+    bool tested;
+    bool usable;
+    bool fsource_option;
+    bool ftarget_option;
+  };
+  static struct result_t result_cache[SOURCE_VERSION_BOUND][TARGET_VERSION_BOUND];
+  struct result_t *resultp;
+
+  resultp = &result_cache[source_version_index (source_version)]
+                         [target_version_index (target_version)];
+  if (!resultp->tested)
+    {
+      /* Try gcj.  */
+      struct temp_dir *tmpdir;
+      char *conftest_file_name;
+      char *compiled_file_name;
+      const char *java_sources[1];
+      struct stat statbuf;
+
+      tmpdir = create_temp_dir ("java", NULL, false);
+      if (tmpdir == NULL)
+        return true;
+
+      conftest_file_name =
+        xconcatenated_filename (tmpdir->dir_name, "conftest.java", NULL);
+      if (write_temp_file (tmpdir, conftest_file_name,
+                           get_goodcode_snippet (source_version)))
+        {
+          free (conftest_file_name);
+          cleanup_temp_dir (tmpdir);
+          return true;
+        }
+
+      compiled_file_name =
+        xconcatenated_filename (tmpdir->dir_name, "conftest.class", NULL);
+      register_temp_file (tmpdir, compiled_file_name);
+
+      java_sources[0] = conftest_file_name;
+      if (!compile_using_gcj (java_sources, 1, false, false, NULL, false, NULL,
+                              tmpdir->dir_name, false, false, false, true)
+          && stat (compiled_file_name, &statbuf) >= 0
+          && get_classfile_version (compiled_file_name)
+             <= corresponding_classfile_version (target_version))
+        {
+          /* gcj compiled conftest.java successfully.  */
+          /* Try adding -fsource option if it is useful.  */
+          unlink (compiled_file_name);
+
+          java_sources[0] = conftest_file_name;
+          if (!compile_using_gcj (java_sources, 1,
+                                  false, true, source_version, false, NULL,
+                                  tmpdir->dir_name, false, false, false, true)
+              && stat (compiled_file_name, &statbuf) >= 0
+              && get_classfile_version (compiled_file_name)
+                 <= corresponding_classfile_version (target_version))
+            {
+              const char *failcode = get_failcode_snippet (source_version);
+
+              if (failcode != NULL)
+                {
+                  free (compiled_file_name);
+                  free (conftest_file_name);
+
+                  conftest_file_name =
+                    xconcatenated_filename (tmpdir->dir_name,
+                                            "conftestfail.java",
+                                            NULL);
+                  if (write_temp_file (tmpdir, conftest_file_name, failcode))
+                    {
+                      free (conftest_file_name);
+                      cleanup_temp_dir (tmpdir);
+                      return true;
+                    }
+
+                  compiled_file_name =
+                    xconcatenated_filename (tmpdir->dir_name,
+                                            "conftestfail.class",
+                                            NULL);
+                  register_temp_file (tmpdir, compiled_file_name);
+
+                  java_sources[0] = conftest_file_name;
+                  if (!compile_using_gcj (java_sources, 1,
+                                          false, false, NULL, false, NULL,
+                                          tmpdir->dir_name,
+                                          false, false, false, true)
+                      && stat (compiled_file_name, &statbuf) >= 0)
+                    {
+                      unlink (compiled_file_name);
+
+                      java_sources[0] = conftest_file_name;
+                      if (compile_using_gcj (java_sources, 1,
+                                             false, true, source_version,
+                                             false, NULL,
+                                             tmpdir->dir_name,
+                                             false, false, false, true))
+                        /* gcj compiled conftestfail.java successfully, and
+                           "gcj -fsource=$source_version" rejects it.  So
+                           the -fsource option is useful.  */
+                        resultp->fsource_option = true;
+                    }
+                }
+            }
+
+          resultp->usable = true;
+        }
+      else
+        {
+          /* Try with -fsource and -ftarget options.  */
+          unlink (compiled_file_name);
+
+          java_sources[0] = conftest_file_name;
+          if (!compile_using_gcj (java_sources, 1,
+                                  false, true, source_version,
+                                  true, target_version,
+                                  tmpdir->dir_name,
+                                  false, false, false, true)
+              && stat (compiled_file_name, &statbuf) >= 0
+              && get_classfile_version (compiled_file_name)
+                 <= corresponding_classfile_version (target_version))
+            {
+              /* "gcj -fsource $source_version -ftarget $target_version"
+                 compiled conftest.java successfully.  */
+              resultp->fsource_option = true;
+              resultp->ftarget_option = true;
+              resultp->usable = true;
+            }
+        }
+
+      free (compiled_file_name);
+      free (conftest_file_name);
+
+      resultp->tested = true;
+    }
+
+  *usablep = resultp->usable;
+  *fsource_option_p = resultp->fsource_option;
+  *ftarget_option_p = resultp->ftarget_option;
+  return false;
+}
+
+/* Test whether gcj < 4.3 can be used for compiling with target_version = 1.4
+   and source_version = 1.4.
    Return a failure indicator (true upon error).  */
 static bool
-is_gcj_14_14_usable (bool *usablep)
+is_oldgcj_14_14_usable (bool *usablep)
 {
   static bool gcj_tested;
   static bool gcj_usable;
@@ -1164,28 +1667,28 @@ is_gcj_14_14_usable (bool *usablep)
 
       tmpdir = create_temp_dir ("java", NULL, false);
       if (tmpdir == NULL)
-       return true;
+        return true;
 
       conftest_file_name =
-       concatenated_pathname (tmpdir->dir_name, "conftest.java", NULL);
+        xconcatenated_filename (tmpdir->dir_name, "conftest.java", NULL);
       if (write_temp_file (tmpdir, conftest_file_name,
-                          get_goodcode_snippet ("1.4")))
-       {
-         free (conftest_file_name);
-         cleanup_temp_dir (tmpdir);
-         return true;
-       }
+                           get_goodcode_snippet ("1.4")))
+        {
+          free (conftest_file_name);
+          cleanup_temp_dir (tmpdir);
+          return true;
+        }
 
       compiled_file_name =
-       concatenated_pathname (tmpdir->dir_name, "conftest.class", NULL);
+        xconcatenated_filename (tmpdir->dir_name, "conftest.class", NULL);
       register_temp_file (tmpdir, compiled_file_name);
 
       java_sources[0] = conftest_file_name;
-      if (!compile_using_gcj (java_sources, 1, false, tmpdir->dir_name,
-                             false, false, false, true)
-         && stat (compiled_file_name, &statbuf) >= 0)
-       /* Compilation succeeded.  */
-       gcj_usable = true;
+      if (!compile_using_gcj (java_sources, 1, false, false, NULL, false, NULL,
+                              tmpdir->dir_name, false, false, false, true)
+          && stat (compiled_file_name, &statbuf) >= 0)
+        /* Compilation succeeded.  */
+        gcj_usable = true;
 
       free (compiled_file_name);
       free (conftest_file_name);
@@ -1199,11 +1702,11 @@ is_gcj_14_14_usable (bool *usablep)
   return false;
 }
 
-/* Test whether gcj can be used for compiling with target_version = 1.4 and
-   source_version = 1.3.
+/* Test whether gcj < 4.3 can be used for compiling with target_version = 1.4
+   and source_version = 1.3.
    Return a failure indicator (true upon error).  */
 static bool
-is_gcj_14_13_usable (bool *usablep, bool *need_no_assert_option_p)
+is_oldgcj_14_13_usable (bool *usablep, bool *need_no_assert_option_p)
 {
   static bool gcj_tested;
   static bool gcj_usable;
@@ -1212,7 +1715,7 @@ is_gcj_14_13_usable (bool *usablep, bool *need_no_assert_option_p)
   if (!gcj_tested)
     {
       /* Try gcj and "gcj -fno-assert".  But add -fno-assert only if
-        it works (not gcj < 3.3).  */
+         it works (not gcj < 3.3).  */
       struct temp_dir *tmpdir;
       char *conftest_file_name;
       char *compiled_file_name;
@@ -1221,45 +1724,46 @@ is_gcj_14_13_usable (bool *usablep, bool *need_no_assert_option_p)
 
       tmpdir = create_temp_dir ("java", NULL, false);
       if (tmpdir == NULL)
-       return true;
+        return true;
 
       conftest_file_name =
-       concatenated_pathname (tmpdir->dir_name, "conftest.java", NULL);
+        xconcatenated_filename (tmpdir->dir_name, "conftest.java", NULL);
       if (write_temp_file (tmpdir, conftest_file_name,
-                          get_goodcode_snippet ("1.3")))
-       {
-         free (conftest_file_name);
-         cleanup_temp_dir (tmpdir);
-         return true;
-       }
+                           get_goodcode_snippet ("1.3")))
+        {
+          free (conftest_file_name);
+          cleanup_temp_dir (tmpdir);
+          return true;
+        }
 
       compiled_file_name =
-       concatenated_pathname (tmpdir->dir_name, "conftest.class", NULL);
+        xconcatenated_filename (tmpdir->dir_name, "conftest.class", NULL);
       register_temp_file (tmpdir, compiled_file_name);
 
       java_sources[0] = conftest_file_name;
-      if (!compile_using_gcj (java_sources, 1, true, tmpdir->dir_name,
-                             false, false, false, true)
-         && stat (compiled_file_name, &statbuf) >= 0)
-       /* Compilation succeeded.  */
-       {
-         gcj_usable = true;
-         gcj_need_no_assert_option = true;
-       }
+      if (!compile_using_gcj (java_sources, 1, true, false, NULL, false, NULL,
+                              tmpdir->dir_name, false, false, false, true)
+          && stat (compiled_file_name, &statbuf) >= 0)
+        /* Compilation succeeded.  */
+        {
+          gcj_usable = true;
+          gcj_need_no_assert_option = true;
+        }
       else
-       {
-         unlink (compiled_file_name);
-
-         java_sources[0] = conftest_file_name;
-         if (!compile_using_gcj (java_sources, 1, false, tmpdir->dir_name,
-                                 false, false, false, true)
-             && stat (compiled_file_name, &statbuf) >= 0)
-           /* Compilation succeeded.  */
-           {
-             gcj_usable = true;
-             gcj_need_no_assert_option = false;
-           }
-       }
+        {
+          unlink (compiled_file_name);
+
+          java_sources[0] = conftest_file_name;
+          if (!compile_using_gcj (java_sources, 1, false,
+                                  false, NULL, false, NULL,
+                                  tmpdir->dir_name, false, false, false, true)
+              && stat (compiled_file_name, &statbuf) >= 0)
+            /* Compilation succeeded.  */
+            {
+              gcj_usable = true;
+              gcj_need_no_assert_option = false;
+            }
+        }
 
       free (compiled_file_name);
       free (conftest_file_name);
@@ -1289,7 +1793,7 @@ is_javac_present (void)
       argv[0] = "javac";
       argv[1] = NULL;
       exitstatus = execute ("javac", "javac", argv, false, false, true, true,
-                           true, false);
+                            true, false, NULL);
       javac_present = (exitstatus == 0 || exitstatus == 1 || exitstatus == 2);
       javac_tested = true;
     }
@@ -1302,7 +1806,7 @@ is_javac_present (void)
    Return a failure indicator (true upon error).  */
 static bool
 is_javac_usable (const char *source_version, const char *target_version,
-                bool *usablep, bool *source_option_p, bool *target_option_p)
+                 bool *usablep, bool *source_option_p, bool *target_option_p)
 {
   /* The cache depends on the source_version and target_version.  */
   struct result_t
@@ -1316,7 +1820,7 @@ is_javac_usable (const char *source_version, const char *target_version,
   struct result_t *resultp;
 
   resultp = &result_cache[source_version_index (source_version)]
-                        [target_version_index (target_version)];
+                         [target_version_index (target_version)];
   if (!resultp->tested)
     {
       /* Try javac.  */
@@ -1328,203 +1832,203 @@ is_javac_usable (const char *source_version, const char *target_version,
 
       tmpdir = create_temp_dir ("java", NULL, false);
       if (tmpdir == NULL)
-       return true;
+        return true;
 
       conftest_file_name =
-       concatenated_pathname (tmpdir->dir_name, "conftest.java", NULL);
+        xconcatenated_filename (tmpdir->dir_name, "conftest.java", NULL);
       if (write_temp_file (tmpdir, conftest_file_name,
-                          get_goodcode_snippet (source_version)))
-       {
-         free (conftest_file_name);
-         cleanup_temp_dir (tmpdir);
-         return true;
-       }
+                           get_goodcode_snippet (source_version)))
+        {
+          free (conftest_file_name);
+          cleanup_temp_dir (tmpdir);
+          return true;
+        }
 
       compiled_file_name =
-       concatenated_pathname (tmpdir->dir_name, "conftest.class", NULL);
+        xconcatenated_filename (tmpdir->dir_name, "conftest.class", NULL);
       register_temp_file (tmpdir, compiled_file_name);
 
       java_sources[0] = conftest_file_name;
       if (!compile_using_javac (java_sources, 1,
-                               false, source_version,
-                               false, target_version,
-                               tmpdir->dir_name, false, false, false, true)
-         && stat (compiled_file_name, &statbuf) >= 0
-         && get_classfile_version (compiled_file_name)
-            <= corresponding_classfile_version (target_version))
-       {
-         /* javac compiled conftest.java successfully.  */
-         /* Try adding -source option if it is useful.  */
-         unlink (compiled_file_name);
-
-         java_sources[0] = conftest_file_name;
-         if (!compile_using_javac (java_sources, 1,
-                                   true, source_version,
-                                   false, target_version,
-                                   tmpdir->dir_name, false, false, false, true)
-             && stat (compiled_file_name, &statbuf) >= 0
-             && get_classfile_version (compiled_file_name)
-                <= corresponding_classfile_version (target_version))
-           {
-             const char *failcode = get_failcode_snippet (source_version);
-
-             if (failcode != NULL)
-               {
-                 free (compiled_file_name);
-                 free (conftest_file_name);
-
-                 conftest_file_name =
-                   concatenated_pathname (tmpdir->dir_name,
-                                          "conftestfail.java",
-                                          NULL);
-                 if (write_temp_file (tmpdir, conftest_file_name, failcode))
-                   {
-                     free (conftest_file_name);
-                     cleanup_temp_dir (tmpdir);
-                     return true;
-                   }
-
-                 compiled_file_name =
-                   concatenated_pathname (tmpdir->dir_name,
-                                          "conftestfail.class",
-                                          NULL);
-                 register_temp_file (tmpdir, compiled_file_name);
-
-                 java_sources[0] = conftest_file_name;
-                 if (!compile_using_javac (java_sources, 1,
-                                           false, source_version,
-                                           false, target_version,
-                                           tmpdir->dir_name,
-                                           false, false, false, true)
-                     && stat (compiled_file_name, &statbuf) >= 0)
-                   {
-                     unlink (compiled_file_name);
-
-                     java_sources[0] = conftest_file_name;
-                     if (compile_using_javac (java_sources, 1,
-                                              true, source_version,
-                                              false, target_version,
-                                              tmpdir->dir_name,
-                                              false, false, false, true))
-                       /* javac compiled conftestfail.java successfully, and
-                          "javac -source $source_version" rejects it.  So the
-                          -source option is useful.  */
-                       resultp->source_option = true;
-                   }
-               }
-           }
-
-         resultp->usable = true;
-       }
+                                false, source_version,
+                                false, target_version,
+                                tmpdir->dir_name, false, false, false, true)
+          && stat (compiled_file_name, &statbuf) >= 0
+          && get_classfile_version (compiled_file_name)
+             <= corresponding_classfile_version (target_version))
+        {
+          /* javac compiled conftest.java successfully.  */
+          /* Try adding -source option if it is useful.  */
+          unlink (compiled_file_name);
+
+          java_sources[0] = conftest_file_name;
+          if (!compile_using_javac (java_sources, 1,
+                                    true, source_version,
+                                    false, target_version,
+                                    tmpdir->dir_name, false, false, false, true)
+              && stat (compiled_file_name, &statbuf) >= 0
+              && get_classfile_version (compiled_file_name)
+                 <= corresponding_classfile_version (target_version))
+            {
+              const char *failcode = get_failcode_snippet (source_version);
+
+              if (failcode != NULL)
+                {
+                  free (compiled_file_name);
+                  free (conftest_file_name);
+
+                  conftest_file_name =
+                    xconcatenated_filename (tmpdir->dir_name,
+                                            "conftestfail.java",
+                                            NULL);
+                  if (write_temp_file (tmpdir, conftest_file_name, failcode))
+                    {
+                      free (conftest_file_name);
+                      cleanup_temp_dir (tmpdir);
+                      return true;
+                    }
+
+                  compiled_file_name =
+                    xconcatenated_filename (tmpdir->dir_name,
+                                            "conftestfail.class",
+                                            NULL);
+                  register_temp_file (tmpdir, compiled_file_name);
+
+                  java_sources[0] = conftest_file_name;
+                  if (!compile_using_javac (java_sources, 1,
+                                            false, source_version,
+                                            false, target_version,
+                                            tmpdir->dir_name,
+                                            false, false, false, true)
+                      && stat (compiled_file_name, &statbuf) >= 0)
+                    {
+                      unlink (compiled_file_name);
+
+                      java_sources[0] = conftest_file_name;
+                      if (compile_using_javac (java_sources, 1,
+                                               true, source_version,
+                                               false, target_version,
+                                               tmpdir->dir_name,
+                                               false, false, false, true))
+                        /* javac compiled conftestfail.java successfully, and
+                           "javac -source $source_version" rejects it.  So the
+                           -source option is useful.  */
+                        resultp->source_option = true;
+                    }
+                }
+            }
+
+          resultp->usable = true;
+        }
       else
-       {
-         /* Try with -target option alone. (Sun javac 1.3.1 has the -target
-            option but no -source option.)  */
-         unlink (compiled_file_name);
-
-         java_sources[0] = conftest_file_name;
-         if (!compile_using_javac (java_sources, 1,
-                                   false, source_version,
-                                   true, target_version,
-                                   tmpdir->dir_name,
-                                   false, false, false, true)
-             && stat (compiled_file_name, &statbuf) >= 0
-             && get_classfile_version (compiled_file_name)
-                <= corresponding_classfile_version (target_version))
-           {
-             /* "javac -target $target_version" compiled conftest.java
-                successfully.  */
-             /* Try adding -source option if it is useful.  */
-             unlink (compiled_file_name);
-
-             java_sources[0] = conftest_file_name;
-             if (!compile_using_javac (java_sources, 1,
-                                       true, source_version,
-                                       true, target_version,
-                                       tmpdir->dir_name,
-                                       false, false, false, true)
-                 && stat (compiled_file_name, &statbuf) >= 0
-                 && get_classfile_version (compiled_file_name)
-                    <= corresponding_classfile_version (target_version))
-               {
-                 const char *failcode = get_failcode_snippet (source_version);
-
-                 if (failcode != NULL)
-                   {
-                     free (compiled_file_name);
-                     free (conftest_file_name);
-
-                     conftest_file_name =
-                       concatenated_pathname (tmpdir->dir_name,
-                                              "conftestfail.java",
-                                              NULL);
-                     if (write_temp_file (tmpdir, conftest_file_name,
-                                          failcode))
-                       {
-                         free (conftest_file_name);
-                         cleanup_temp_dir (tmpdir);
-                         return true;
-                       }
-
-                     compiled_file_name =
-                       concatenated_pathname (tmpdir->dir_name,
-                                              "conftestfail.class",
-                                              NULL);
-                     register_temp_file (tmpdir, compiled_file_name);
-
-                     java_sources[0] = conftest_file_name;
-                     if (!compile_using_javac (java_sources, 1,
-                                               false, source_version,
-                                               true, target_version,
-                                               tmpdir->dir_name,
-                                               false, false, false, true)
-                         && stat (compiled_file_name, &statbuf) >= 0)
-                       {
-                         unlink (compiled_file_name);
-
-                         java_sources[0] = conftest_file_name;
-                         if (compile_using_javac (java_sources, 1,
-                                                  true, source_version,
-                                                  true, target_version,
-                                                  tmpdir->dir_name,
-                                                  false, false, false, true))
-                           /* "javac -target $target_version" compiled
-                              conftestfail.java successfully, and
-                              "javac -target $target_version -source $source_version"
-                              rejects it.  So the -source option is useful.  */
-                           resultp->source_option = true;
-                       }
-                   }
-               }
-
-             resultp->target_option = true;
-             resultp->usable = true;
-           }
-         else
-           {
-             /* Maybe this -target option requires a -source option? Try with
-                -target and -source options. (Supported by Sun javac 1.4 and
-                higher.)  */
-             unlink (compiled_file_name);
-
-             java_sources[0] = conftest_file_name;
-             if (!compile_using_javac (java_sources, 1,
-                                       true, source_version,
-                                       true, target_version,
-                                       tmpdir->dir_name,
-                                       false, false, false, true)
-                 && stat (compiled_file_name, &statbuf) >= 0
-                 && get_classfile_version (compiled_file_name)
-                    <= corresponding_classfile_version (target_version))
-               {
-                 /* "javac -target $target_version -source $source_version"
-                    compiled conftest.java successfully.  */
-                 resultp->source_option = true;
-                 resultp->target_option = true;
-                 resultp->usable = true;
-               }
-           }
-       }
+        {
+          /* Try with -target option alone. (Sun javac 1.3.1 has the -target
+             option but no -source option.)  */
+          unlink (compiled_file_name);
+
+          java_sources[0] = conftest_file_name;
+          if (!compile_using_javac (java_sources, 1,
+                                    false, source_version,
+                                    true, target_version,
+                                    tmpdir->dir_name,
+                                    false, false, false, true)
+              && stat (compiled_file_name, &statbuf) >= 0
+              && get_classfile_version (compiled_file_name)
+                 <= corresponding_classfile_version (target_version))
+            {
+              /* "javac -target $target_version" compiled conftest.java
+                 successfully.  */
+              /* Try adding -source option if it is useful.  */
+              unlink (compiled_file_name);
+
+              java_sources[0] = conftest_file_name;
+              if (!compile_using_javac (java_sources, 1,
+                                        true, source_version,
+                                        true, target_version,
+                                        tmpdir->dir_name,
+                                        false, false, false, true)
+                  && stat (compiled_file_name, &statbuf) >= 0
+                  && get_classfile_version (compiled_file_name)
+                     <= corresponding_classfile_version (target_version))
+                {
+                  const char *failcode = get_failcode_snippet (source_version);
+
+                  if (failcode != NULL)
+                    {
+                      free (compiled_file_name);
+                      free (conftest_file_name);
+
+                      conftest_file_name =
+                        xconcatenated_filename (tmpdir->dir_name,
+                                                "conftestfail.java",
+                                                NULL);
+                      if (write_temp_file (tmpdir, conftest_file_name,
+                                           failcode))
+                        {
+                          free (conftest_file_name);
+                          cleanup_temp_dir (tmpdir);
+                          return true;
+                        }
+
+                      compiled_file_name =
+                        xconcatenated_filename (tmpdir->dir_name,
+                                                "conftestfail.class",
+                                                NULL);
+                      register_temp_file (tmpdir, compiled_file_name);
+
+                      java_sources[0] = conftest_file_name;
+                      if (!compile_using_javac (java_sources, 1,
+                                                false, source_version,
+                                                true, target_version,
+                                                tmpdir->dir_name,
+                                                false, false, false, true)
+                          && stat (compiled_file_name, &statbuf) >= 0)
+                        {
+                          unlink (compiled_file_name);
+
+                          java_sources[0] = conftest_file_name;
+                          if (compile_using_javac (java_sources, 1,
+                                                   true, source_version,
+                                                   true, target_version,
+                                                   tmpdir->dir_name,
+                                                   false, false, false, true))
+                            /* "javac -target $target_version" compiled
+                               conftestfail.java successfully, and
+                               "javac -target $target_version -source $source_version"
+                               rejects it.  So the -source option is useful.  */
+                            resultp->source_option = true;
+                        }
+                    }
+                }
+
+              resultp->target_option = true;
+              resultp->usable = true;
+            }
+          else
+            {
+              /* Maybe this -target option requires a -source option? Try with
+                 -target and -source options. (Supported by Sun javac 1.4 and
+                 higher.)  */
+              unlink (compiled_file_name);
+
+              java_sources[0] = conftest_file_name;
+              if (!compile_using_javac (java_sources, 1,
+                                        true, source_version,
+                                        true, target_version,
+                                        tmpdir->dir_name,
+                                        false, false, false, true)
+                  && stat (compiled_file_name, &statbuf) >= 0
+                  && get_classfile_version (compiled_file_name)
+                     <= corresponding_classfile_version (target_version))
+                {
+                  /* "javac -target $target_version -source $source_version"
+                     compiled conftest.java successfully.  */
+                  resultp->source_option = true;
+                  resultp->target_option = true;
+                  resultp->usable = true;
+                }
+            }
+        }
 
       free (compiled_file_name);
       free (conftest_file_name);
@@ -1553,7 +2057,7 @@ is_jikes_present (void)
       argv[0] = "jikes";
       argv[1] = NULL;
       exitstatus = execute ("jikes", "jikes", argv, false, false, true, true,
-                           true, false);
+                            true, false, NULL);
       jikes_present = (exitstatus == 0 || exitstatus == 1);
       jikes_tested = true;
     }
@@ -1565,15 +2069,15 @@ is_jikes_present (void)
 
 bool
 compile_java_class (const char * const *java_sources,
-                   unsigned int java_sources_count,
-                   const char * const *classpaths,
-                   unsigned int classpaths_count,
-                   const char *source_version,
-                   const char *target_version,
-                   const char *directory,
-                   bool optimize, bool debug,
-                   bool use_minimal_classpath,
-                   bool verbose)
+                    unsigned int java_sources_count,
+                    const char * const *classpaths,
+                    unsigned int classpaths_count,
+                    const char *source_version,
+                    const char *target_version,
+                    const char *directory,
+                    bool optimize, bool debug,
+                    bool use_minimal_classpath,
+                    bool verbose)
 {
   bool err = false;
   char *old_JAVA_HOME;
@@ -1582,82 +2086,106 @@ compile_java_class (const char * const *java_sources,
     const char *javac = getenv ("JAVAC");
     if (javac != NULL && javac[0] != '\0')
       {
-       bool usable = false;
-       bool no_assert_option = false;
-       bool source_option = false;
-       bool target_option = false;
-
-       if (target_version == NULL)
-         target_version = default_target_version ();
-
-       if (is_envjavac_gcj (javac))
-         {
-           /* It's a version of gcj.  Ignore the version of the class files
-              that it creates.  */
-           if (strcmp (target_version, "1.4") == 0
-               && strcmp (source_version, "1.4") == 0)
-             {
-               if (is_envjavac_gcj_14_14_usable (javac, &usable))
-                 {
-                   err = true;
-                   goto done1;
-                 }
-             }
-           else if (strcmp (target_version, "1.4") == 0
-                    && strcmp (source_version, "1.3") == 0)
-             {
-               if (is_envjavac_gcj_14_13_usable (javac,
-                                                 &usable, &no_assert_option))
-                 {
-                   err = true;
-                   goto done1;
-                 }
-             }
-         }
-       else
-         {
-           /* It's not gcj.  Assume the classfile versions are correct.  */
-           if (is_envjavac_nongcj_usable (javac,
-                                          source_version, target_version,
-                                          &usable,
-                                          &source_option, &target_option))
-             {
-               err = true;
-               goto done1;
-             }
-         }
-
-       if (usable)
-         {
-           char *old_classpath;
-           char *javac_with_options;
-
-           /* Set CLASSPATH.  */
-           old_classpath =
-             set_classpath (classpaths, classpaths_count, false, verbose);
-
-           javac_with_options =
-             (no_assert_option
-              ? xasprintf ("%s -fno-assert", javac)
-              : xasprintf ("%s%s%s%s%s",
-                           javac,
-                           source_option ? " -source " : "",
-                           source_option ? source_version : "",
-                           target_option ? " -target " : "",
-                           target_option ? target_version : ""));
-
-           err = compile_using_envjavac (javac_with_options,
-                                         java_sources, java_sources_count,
-                                         directory, optimize, debug, verbose,
-                                         false);
-
-           free (javac_with_options);
-
-           /* Reset CLASSPATH.  */
-           reset_classpath (old_classpath);
-
-           goto done1;
-         }
+        bool usable = false;
+        bool no_assert_option = false;
+        bool source_option = false;
+        bool target_option = false;
+        bool fsource_option = false;
+        bool ftarget_option = false;
+
+        if (target_version == NULL)
+          target_version = default_target_version ();
+
+        if (is_envjavac_gcj (javac))
+          {
+            /* It's a version of gcj.  */
+            if (is_envjavac_gcj43 (javac))
+              {
+                /* It's a version of gcj >= 4.3.  Assume the classfile versions
+                   are correct.  */
+                if (is_envjavac_gcj43_usable (javac,
+                                              source_version, target_version,
+                                              &usable,
+                                              &fsource_option, &ftarget_option))
+                  {
+                    err = true;
+                    goto done1;
+                  }
+              }
+            else
+              {
+                /* It's a version of gcj < 4.3.  Ignore the version of the
+                   class files that it creates.  */
+                if (strcmp (target_version, "1.4") == 0
+                    && strcmp (source_version, "1.4") == 0)
+                  {
+                    if (is_envjavac_oldgcj_14_14_usable (javac, &usable))
+                      {
+                        err = true;
+                        goto done1;
+                      }
+                  }
+                else if (strcmp (target_version, "1.4") == 0
+                         && strcmp (source_version, "1.3") == 0)
+                  {
+                    if (is_envjavac_oldgcj_14_13_usable (javac,
+                                                         &usable,
+                                                         &no_assert_option))
+                      {
+                        err = true;
+                        goto done1;
+                      }
+                  }
+              }
+          }
+        else
+          {
+            /* It's not gcj.  Assume the classfile versions are correct.  */
+            if (is_envjavac_nongcj_usable (javac,
+                                           source_version, target_version,
+                                           &usable,
+                                           &source_option, &target_option))
+              {
+                err = true;
+                goto done1;
+              }
+          }
+
+        if (usable)
+          {
+            char *old_classpath;
+            char *javac_with_options;
+
+            /* Set CLASSPATH.  */
+            old_classpath =
+              set_classpath (classpaths, classpaths_count, false, verbose);
+
+            javac_with_options =
+              (no_assert_option
+               ? xasprintf ("%s -fno-assert", javac)
+               : xasprintf ("%s%s%s%s%s%s%s%s%s",
+                            javac,
+                            source_option ? " -source " : "",
+                            source_option ? source_version : "",
+                            target_option ? " -target " : "",
+                            target_option ? target_version : "",
+                            fsource_option ? " -fsource=" : "",
+                            fsource_option ? source_version : "",
+                            ftarget_option ? " -ftarget=" : "",
+                            ftarget_option ? target_version : ""));
+
+            err = compile_using_envjavac (javac_with_options,
+                                          java_sources, java_sources_count,
+                                          directory, optimize, debug, verbose,
+                                          false);
+
+            free (javac_with_options);
+
+            /* Reset CLASSPATH.  */
+            reset_classpath (old_classpath);
+
+            goto done1;
+          }
       }
   }
 
@@ -1671,55 +2199,75 @@ compile_java_class (const char * const *java_sources,
 
   if (is_gcj_present ())
     {
-      /* Test whether it supports the desired target-version and
-        source-version.  But ignore the version of the class files that
-        it creates.  */
+      /* It's a version of gcj.  */
       bool usable = false;
       bool no_assert_option = false;
+      bool fsource_option = false;
+      bool ftarget_option = false;
 
       if (target_version == NULL)
-       target_version = default_target_version ();
-
-      if (strcmp (target_version, "1.4") == 0
-         && strcmp (source_version, "1.4") == 0)
-       {
-         if (is_gcj_14_14_usable (&usable))
-           {
-             err = true;
-             goto done1;
-           }
-       }
-      else if (strcmp (target_version, "1.4") == 0
-              && strcmp (source_version, "1.3") == 0)
-       {
-         if (is_gcj_14_13_usable (&usable, &no_assert_option))
-           {
-             err = true;
-             goto done1;
-           }
-       }
+        target_version = default_target_version ();
+
+      if (is_gcj_43 ())
+        {
+          /* It's a version of gcj >= 4.3.  Assume the classfile versions
+             are correct.  */
+          if (is_gcj43_usable (source_version, target_version,
+                               &usable, &fsource_option, &ftarget_option))
+            {
+              err = true;
+              goto done1;
+            }
+        }
+      else
+        {
+          /* It's a version of gcj < 4.3.  Ignore the version of the class
+             files that it creates.
+             Test whether it supports the desired target-version and
+             source-version.  */
+          if (strcmp (target_version, "1.4") == 0
+              && strcmp (source_version, "1.4") == 0)
+            {
+              if (is_oldgcj_14_14_usable (&usable))
+                {
+                  err = true;
+                  goto done1;
+                }
+            }
+          else if (strcmp (target_version, "1.4") == 0
+                   && strcmp (source_version, "1.3") == 0)
+            {
+              if (is_oldgcj_14_13_usable (&usable, &no_assert_option))
+                {
+                  err = true;
+                  goto done1;
+                }
+            }
+        }
 
       if (usable)
-       {
-         char *old_classpath;
-
-         /* Set CLASSPATH.  We could also use the --CLASSPATH=... option
-            of gcj.  Note that --classpath=... option is different: its
-            argument should also contain gcj's libgcj.jar, but we don't
-            know its location.  */
-         old_classpath =
-           set_classpath (classpaths, classpaths_count, use_minimal_classpath,
-                          verbose);
-
-         err = compile_using_gcj (java_sources, java_sources_count,
-                                  no_assert_option,
-                                  directory, optimize, debug, verbose, false);
-
-         /* Reset CLASSPATH.  */
-         reset_classpath (old_classpath);
-
-         goto done2;
-       }
+        {
+          char *old_classpath;
+
+          /* Set CLASSPATH.  We could also use the --CLASSPATH=... option
+             of gcj.  Note that --classpath=... option is different: its
+             argument should also contain gcj's libgcj.jar, but we don't
+             know its location.  */
+          old_classpath =
+            set_classpath (classpaths, classpaths_count, use_minimal_classpath,
+                           verbose);
+
+          err = compile_using_gcj (java_sources, java_sources_count,
+                                   no_assert_option,
+                                   fsource_option, source_version,
+                                   ftarget_option, target_version,
+                                   directory, optimize, debug, verbose, false);
+
+          /* Reset CLASSPATH.  */
+          reset_classpath (old_classpath);
+
+          goto done2;
+        }
     }
 
   if (is_javac_present ())
@@ -1729,67 +2277,67 @@ compile_java_class (const char * const *java_sources,
       bool target_option = false;
 
       if (target_version == NULL)
-       target_version = default_target_version ();
+        target_version = default_target_version ();
 
       if (is_javac_usable (source_version, target_version,
-                          &usable, &source_option, &target_option))
-       {
-         err = true;
-         goto done1;
-       }
+                           &usable, &source_option, &target_option))
+        {
+          err = true;
+          goto done1;
+        }
 
       if (usable)
-       {
-         char *old_classpath;
-
-         /* Set CLASSPATH.  We don't use the "-classpath ..." option because
-            in JDK 1.1.x its argument should also contain the JDK's
-            classes.zip, but we don't know its location.  (In JDK 1.3.0 it
-            would work.)  */
-         old_classpath =
-           set_classpath (classpaths, classpaths_count, use_minimal_classpath,
-                          verbose);
-
-         err = compile_using_javac (java_sources, java_sources_count,
-                                    source_option, source_version,
-                                    target_option, target_version,
-                                    directory, optimize, debug, verbose,
-                                    false);
-
-         /* Reset CLASSPATH.  */
-         reset_classpath (old_classpath);
-
-         goto done2;
-       }
+        {
+          char *old_classpath;
+
+          /* Set CLASSPATH.  We don't use the "-classpath ..." option because
+             in JDK 1.1.x its argument should also contain the JDK's
+             classes.zip, but we don't know its location.  (In JDK 1.3.0 it
+             would work.)  */
+          old_classpath =
+            set_classpath (classpaths, classpaths_count, use_minimal_classpath,
+                           verbose);
+
+          err = compile_using_javac (java_sources, java_sources_count,
+                                     source_option, source_version,
+                                     target_option, target_version,
+                                     directory, optimize, debug, verbose,
+                                     false);
+
+          /* Reset CLASSPATH.  */
+          reset_classpath (old_classpath);
+
+          goto done2;
+        }
     }
 
   if (is_jikes_present ())
     {
       /* Test whether it supports the desired target-version and
-        source-version.  */
+         source-version.  */
       bool usable = (strcmp (source_version, "1.3") == 0);
 
       if (usable)
-       {
-         char *old_classpath;
-
-         /* Set CLASSPATH.  We could also use the "-classpath ..." option.
-            Since jikes doesn't come with its own standard library, it
-            needs a classes.zip or rt.jar or libgcj.jar in the CLASSPATH.
-            To increase the chance of success, we reuse the current CLASSPATH
-            if the user has set it.  */
-         old_classpath =
-           set_classpath (classpaths, classpaths_count, false, verbose);
-
-         err = compile_using_jikes (java_sources, java_sources_count,
-                                    directory, optimize, debug, verbose,
-                                    false);
-
-         /* Reset CLASSPATH.  */
-         reset_classpath (old_classpath);
-
-         goto done2;
-       }
+        {
+          char *old_classpath;
+
+          /* Set CLASSPATH.  We could also use the "-classpath ..." option.
+             Since jikes doesn't come with its own standard library, it
+             needs a classes.zip or rt.jar or libgcj.jar in the CLASSPATH.
+             To increase the chance of success, we reuse the current CLASSPATH
+             if the user has set it.  */
+          old_classpath =
+            set_classpath (classpaths, classpaths_count, false, verbose);
+
+          err = compile_using_jikes (java_sources, java_sources_count,
+                                     directory, optimize, debug, verbose,
+                                     false);
+
+          /* Reset CLASSPATH.  */
+          reset_classpath (old_classpath);
+
+          goto done2;
+        }
     }
 
   error (0, 0, _("Java compiler not found, try installing gcj or set $JAVAC"));