On Nov 14, 2019, Alexandre Oliva <ol...@adacore.com> wrote:

> In order to address this, I propose we add an internal option (not for
> the driver), -dumpbase-ext, that names the extension to be discarded
> from dumpbase to form aux output names.

Here's a WIP patch that implements much of the desired semantics.

I'm still struggling a bit with -gdwarf-split and -save-temps; -dumpbase
and multiple inputs, -dumpdir as a prefix, and -flto + -dump*.

-gdwarf-split uses %b to strip debug info into the .dwo file, so it
lands in the same location as the .o, rather than in a named -dumpdir as
specified in the .o debug info skeleton.  I'm thinking of arranging for
-dump* flags to affect %b and %B, just like -save-temps does.  I've
reviewed all uses of %b and %B, and it looks like this would enable us
to fix the .dwo naming mismatch without significant complication.

Which brings us to the next issue.  This would cause -dumpdir to
override the -save-temps location.  This is arguably an improvement.  It
might conflict with -save-temps=cwd, however.

I'm considering rejecting command lines that specify both an explicit
-dumpdir and -save-temps=cwd, and in the absence of an explicit
-dumpdir, arranging for -save-temps=cwd or -save-temps=obj to override
what would otherwise be the default -dumpdir.

Or, for the sake of simplifying and bringing more sanity to the logic of
naming extra output files, we could just discontinue -save-temps=*, and
require -dumpdir ./ along with plain -save-temps to get the effects of
-save-temps=cwd.


When compiling multiple inputs with a single -dumpbase, the current
implementation arranges for each compilation to take an adjusted
-dumpbase appending -<input> to the given dumpbase, minus extension.  An
alternative would be to reject such compilations, just as we reject
multiple compilations with a single object file named as output.  That
feels excessive for -dumpbase, however.  OTOH, adjusting -dumpbase only
when there are multiple inputs causes different behavior comparing:

  gcc -c foo.c -dumpbase foobar && gcc -c bar.c -dumpbase foobar

and

  gcc -c foo.c bar.c -dumpbase foobar

The latter will name outputs after foobar-foo and foobar-bar,
respectively, whereas the former will overwrite outputs named foobar
when compiling bar.c.  Under the proposal to modify %b according to
-dump*, even object files would be named after an explicit -dumpbase,
when -o is not explicitly specified.


Yet another thing I'm not so sure about is -dumpdir as a prefix, e.g.,
in cases we're compiling multiple files and then linking them together,
say 'gcc foo.c bar.c -o foobar', the proposal was to name dumps of the
compilations after foobar-foo and foobar-bar, respectively.

If we use -dumpdir as a prefix to dump names, as we historically have,
if it doesn't end with a slash (or any dir separator) then it could be
used to specify the prefix for multiple outputs, as in the above.  So
gcc -dumpdir foobar- foo.c bar.c -o foobar *could* be equivalent to the
above.  I.e., an executable output name would affect the -dumpdir, but
not the -dumpbase passed to the compiler, whereas -dumpbase would be
derived from an asm or obj output or from input.

In the end, they're pasted together one way or the other, the difference
is the ability to override one or the other.  E.g.,

  gcc -dumpbase foobar foo.c bar.c -c

could then be rejected, just as -o foo+bar.o would be, or foobar could
be appended to the implicit -dumpdir and then override -dumpbase to
foo.c or bar.c in each compilation, to get foobar-foo.o and foobar-bar.o
outputs, getting the same as:

  gcc -dumpdir foobar- foo.c bar.c -c

and then

  gcc -dumpdir temp/foobar- foo.c bar.c -o foo+bar -save-temps

would still create and preserve .o (and .i and .s) named after
foobar-foo and foobar-bar within temp, rather than foo+bar-foo and
foo+bar-bar.

Now, the implementation in the patch below places the link output name,
implicit or not, in the default -dumpbase rather than -dumpdir, so the
last command above would create temp/foobar-foo+bar-foo.o and
temp/foobar-foo+bar-bar.o.  It's this ability to override the
executable-name prefix we're adding to outputs separately from -dumpbase
that I find somewhat appealing, in that it enables even the effect of
such prefixing to be canceled out with e.g. -dumpdir ./

Any thoughts for or against (or requests for clarification on :-) any of
the above proposed changes?


As for -flto + -dump*, the problem is that lto-wrapper doesn't take any
-dump* flags into account, it just overrides them all as if none had
been specified, which is undesirable.  That's fixable, it's just that
I haven't got to it yet.

I haven't brought in the design/documentation into a .texi file yet.
Please refer to posts upthread for the proposal.


Here's the WIP patch, FTR:

---
 gcc/ada/gcc-interface/lang-specs.h |    7 +
 gcc/ada/switch.adb                 |    4 -
 gcc/common.opt                     |   19 ++-
 gcc/dwarf2out.c                    |    3 -
 gcc/fortran/options.c              |    4 -
 gcc/gcc.c                          |  213 ++++++++++++++++++++++--------------
 gcc/lto-wrapper.c                  |   38 +++++-
 gcc/opts.c                         |   35 ------
 gcc/toplev.c                       |   36 +++++-
 9 files changed, 211 insertions(+), 148 deletions(-)

diff --git a/gcc/ada/gcc-interface/lang-specs.h 
b/gcc/ada/gcc-interface/lang-specs.h
index 374fc1e..344fe64 100644
--- a/gcc/ada/gcc-interface/lang-specs.h
+++ b/gcc/ada/gcc-interface/lang-specs.h
@@ -34,11 +34,10 @@
  %{!S:%{!c:%e-c or -S required for Ada}}\
  gnat1 %{I*} %{k8:-gnatk8} %{Wall:-gnatwa} %{w:-gnatws} %{!Q:-quiet}\
     %{nostdinc*} %{nostdlib*}\
-    -dumpbase %{.adb:%b.adb}%{.ads:%b.ads}%{!.adb:%{!.ads:%b.ada}}\
-    %{fcompare-debug-second:%:compare-debug-auxbase-opt(%b) -gnatd_A} \
-    %{!fcompare-debug-second:%{c|S:%{o*:-auxbase-strip %*}%{!o*:-auxbase 
%b}}%{!c:%{!S:-auxbase %b}}} \
-    %{O*} %{W*} %{w} %{p} %{pg:-p} %{d*} \
+    %{fcompare-debug-second:-gnatd_A} \
+    %{O*} %{W*} %{w} %{p} %{pg:-p} %{d*} %:dumps() \
     %{coverage:-fprofile-arcs -ftest-coverage} "
+/* -dumpbase %{.adb:%b.adb}%{.ads:%b.ads}%{!.adb:%{!.ads:%b.ada}} */
 #if defined(TARGET_VXWORKS_RTP)
    "%{fRTS=rtp|fRTS=rtp-smp|fRTS=ravenscar-cert-rtp:-mrtp} "
 #endif
diff --git a/gcc/ada/switch.adb b/gcc/ada/switch.adb
index 7cdaa196..b6f4e00 100644
--- a/gcc/ada/switch.adb
+++ b/gcc/ada/switch.adb
@@ -163,9 +163,9 @@ package body Switch is
       return Is_Switch (Switch_Chars)
         and then
           (Switch_Chars (First .. Last) = "-param"        or else
+           Switch_Chars (First .. Last) = "dumpdir"       or else
            Switch_Chars (First .. Last) = "dumpbase"      or else
-           Switch_Chars (First .. Last) = "auxbase-strip" or else
-           Switch_Chars (First .. Last) = "auxbase");
+           Switch_Chars (First .. Last) = "dumpbase-ext");
    end Is_Internal_GCC_Switch;
 
    ---------------
diff --git a/gcc/common.opt b/gcc/common.opt
index 404b6aa..e37e324 100644
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -188,6 +188,12 @@ const char *main_input_basename
 Variable
 int main_input_baselength
 
+; The base name used for auxiliary output files.
+; dump_base_name minus dump_base_ext.
+
+Variable
+const char *aux_base_name
+
 ; Which options have been printed by --help.
 Variable
 char *help_printed
@@ -254,6 +260,9 @@ Common Joined Alias(d)
 -dumpbase
 Common Separate Alias(dumpbase)
 
+-dumpbase-ext
+Common Separate Alias(dumpbase-ext)
+
 -dumpdir
 Common Separate Alias(dumpdir)
 
@@ -840,12 +849,6 @@ Common Separate Var(aux_info_file_name)
 aux-info=
 Common Joined Alias(aux-info)
 
-auxbase
-Common Separate RejectDriver Var(aux_base_name)
-
-auxbase-strip
-Common Separate RejectDriver
-
 coverage
 Driver
 
@@ -860,6 +863,10 @@ dumpbase
 Common Separate Var(dump_base_name)
 -dumpbase <file>       Set the file basename to be used for dumps.
 
+dumpbase-ext
+Common Separate Var(dump_base_ext)
+-dumpbase-ext .<ext>    Drop a trailing .<ext> from the dump basename to name 
auxiliary output files.
+
 dumpdir
 Common Separate Var(dump_dir_name)
 -dumpdir <dir> Set the directory name to be used for dumps.
diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
index 6fb345b..06154d9 100644
--- a/gcc/dwarf2out.c
+++ b/gcc/dwarf2out.c
@@ -24466,9 +24466,8 @@ gen_producer_string (void)
       case OPT_o:
       case OPT_d:
       case OPT_dumpbase:
+      case OPT_dumpbase_ext:
       case OPT_dumpdir:
-      case OPT_auxbase:
-      case OPT_auxbase_strip:
       case OPT_quiet:
       case OPT_version:
       case OPT_v:
diff --git a/gcc/fortran/options.c b/gcc/fortran/options.c
index f7a5299c..6a4b9eb 100644
--- a/gcc/fortran/options.c
+++ b/gcc/fortran/options.c
@@ -833,8 +833,8 @@ gfc_get_option_string (void)
         case OPT_o:
         case OPT_d:
         case OPT_dumpbase:
+        case OPT_dumpbase_ext:
         case OPT_dumpdir:
-        case OPT_auxbase:
         case OPT_quiet:
         case OPT_version:
         case OPT_fintrinsic_modules_path:
@@ -859,8 +859,8 @@ gfc_get_option_string (void)
         case OPT_o:
         case OPT_d:
         case OPT_dumpbase:
+        case OPT_dumpbase_ext:
         case OPT_dumpdir:
-        case OPT_auxbase:
         case OPT_quiet:
         case OPT_version:
         case OPT_fintrinsic_modules_path:
diff --git a/gcc/gcc.c b/gcc/gcc.c
index 4428d50..b284842 100644
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -402,8 +402,8 @@ static const char *find_plugindir_spec_function (int, const 
char **);
 static const char *print_asm_header_spec_function (int, const char **);
 static const char *compare_debug_dump_opt_spec_function (int, const char **);
 static const char *compare_debug_self_opt_spec_function (int, const char **);
-static const char *compare_debug_auxbase_opt_spec_function (int, const char 
**);
 static const char *pass_through_libs_spec_func (int, const char **);
+static const char *dumps_spec_func (int, const char **);
 static const char *replace_extension_spec_func (int, const char **);
 static const char *greater_than_spec_func (int, const char **);
 static const char *debug_level_greater_than_spec_func (int, const char **);
@@ -642,7 +642,7 @@ proper position among the other output files.  */
   "%{gsplit-dwarf: \n\
        objcopy --extract-dwo \
         %{c:%{o*:%*}%{!o*:%b%O}}%{!c:%U%O} \
-        %{c:%{o*:%:replace-extension(%{o*:%*} .dwo)}%{!o*:%b.dwo}}%{!c:%b.dwo} 
\n\
+        %{c:%{o*:%.dwo%*}%{!o*:%b.dwo}}%{!c:%b.dwo} \n\
        objcopy --strip-dwo \
         %{c:%{o*:%*}%{!o*:%b%O}}%{!c:%U%O} \
     }"
@@ -1145,9 +1145,7 @@ static const char *cpp_debug_options = "%{d*}";
 static const char *cc1_options =
 "%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
  %{!iplugindir*:%{fplugin*:%:find-plugindir()}}\
- %1 %{!Q:-quiet} %{!dumpbase:-dumpbase %B} %{d*} %{m*} %{aux-info*}\
- %{fcompare-debug-second:%:compare-debug-auxbase-opt(%b)} \
- %{!fcompare-debug-second:%{c|S:%{o*:-auxbase-strip %*}%{!o*:-auxbase 
%b}}}%{!c:%{!S:-auxbase %b}} \
+ %1 %{!Q:-quiet} %{d*} %{m*} %{aux-info*} %:dumps()\
  %{g*} %{O*} %{W*&pedantic*} %{w} %{std*&ansi&trigraphs}\
  %{v:-version} %{pg:-p} %{p} %{f*} %{undef}\
  %{Qn:-fno-ident} %{Qy:} %{-help:--help}\
@@ -1642,9 +1640,8 @@ static const struct spec_function static_spec_functions[] 
=
   { "print-asm-header",                print_asm_header_spec_function },
   { "compare-debug-dump-opt",  compare_debug_dump_opt_spec_function },
   { "compare-debug-self-opt",  compare_debug_self_opt_spec_function },
-  { "compare-debug-auxbase-opt", compare_debug_auxbase_opt_spec_function },
   { "pass-through-libs",       pass_through_libs_spec_func },
-  { "replace-extension",       replace_extension_spec_func },
+  { "dumps",                    dumps_spec_func },
   { "gt",                      greater_than_spec_func },
   { "debug-level-gt",          debug_level_greater_than_spec_func },
   { "fortran-preinclude-file", find_fortran_preinclude_file},
@@ -9787,8 +9784,6 @@ compare_debug_dump_opt_spec_function (int arg,
   return ret;
 }
 
-static const char *debug_auxbase_opt;
-
 /* %:compare-debug-self-opt spec function.  Expands to the options
     that are to be passed in the second compilation of
     compare-debug.  */
@@ -9807,13 +9802,6 @@ compare_debug_self_opt_spec_function (int arg,
   do_spec_2 ("%{c|S:%{o*:%*}}", NULL);
   do_spec_1 (" ", 0, NULL);
 
-  if (argbuf.length () > 0)
-    debug_auxbase_opt = concat ("-auxbase-strip ",
-                               argbuf.last (),
-                               NULL);
-  else
-    debug_auxbase_opt = NULL;
-
   return concat ("\
 %<o %<MD %<MMD %<MF* %<MG %<MP %<MQ* %<MT* \
 %<fdump-final-insns=* -w -S -o %j \
@@ -9821,50 +9809,6 @@ compare_debug_self_opt_spec_function (int arg,
 ", compare_debug_opt, NULL);
 }
 
-/* %:compare-debug-auxbase-opt spec function.  Expands to the auxbase
-    options that are to be passed in the second compilation of
-    compare-debug.  It expects, as an argument, the basename of the
-    current input file name, with the .gk suffix appended to it.  */
-
-static const char *
-compare_debug_auxbase_opt_spec_function (int arg,
-                                        const char **argv)
-{
-  char *name;
-  int len;
-
-  if (arg == 0)
-    fatal_error (input_location,
-                "too few arguments to %%:compare-debug-auxbase-opt");
-
-  if (arg != 1)
-    fatal_error (input_location,
-                "too many arguments to %%:compare-debug-auxbase-opt");
-
-  if (compare_debug >= 0)
-    return NULL;
-
-  len = strlen (argv[0]);
-  if (len < 3 || strcmp (argv[0] + len - 3, ".gk") != 0)
-    fatal_error (input_location, "argument to %%:compare-debug-auxbase-opt "
-                "does not end in %<.gk%>");
-
-  if (debug_auxbase_opt)
-    return debug_auxbase_opt;
-
-#define OPT "-auxbase "
-
-  len -= 3;
-  name = (char*) xmalloc (sizeof (OPT) + len);
-  memcpy (name, OPT, sizeof (OPT) - 1);
-  memcpy (name + sizeof (OPT) - 1, argv[0], len);
-  name[sizeof (OPT) - 1 + len] = '\0';
-
-#undef OPT
-
-  return name;
-}
-
 /* %:pass-through-libs spec function.  Finds all -l options and input
    file names in the lib spec passed to it, and makes a list of them
    prepended with the plugin option to cause them to be passed through
@@ -9908,34 +9852,143 @@ pass_through_libs_spec_func (int argc, const char 
**argv)
   return prepended;
 }
 
-/* %:replace-extension spec function.  Replaces the extension of the
-   first argument with the second argument.  */
+static bool
+not_actual_file_p (const char *name)
+{
+  return (strcmp (name, "-") == 0
+         || strcmp (output_file, HOST_BIT_BUCKET) == 0);
+}
 
+/* %:dumps spec function.  Take no arguments.
+    Return -dumpdir, -dumpbase and -dumpbase-ext, if needed.  */
 const char *
-replace_extension_spec_func (int argc, const char **argv)
+dumps_spec_func (int argc, const char **argv)
 {
-  char *name;
-  char *p;
-  char *result;
+  bool found_dumpdir = false;
+  const char *found_dumpbase = NULL;
+  bool found_dumpext = false;
+  bool found_cS = false;
+  const char *oname = NULL;
   int i;
 
-  if (argc != 2)
-    fatal_error (input_location, "too few arguments to %%:replace-extension");
+  char *args[3] = { NULL, NULL, NULL };
+  int nargs = 0;
 
-  name = xstrdup (argv[0]);
+  if (argc != 0)
+    fatal_error (input_location, "too few arguments for %%:dumps");
 
-  for (i = strlen (name) - 1; i >= 0; i--)
-    if (IS_DIR_SEPARATOR (name[i]))
-      break;
+  for (i = 0; i < n_switches; i++)
+    {
+      const char *s = switches[i].part1;
+      switch (s[0])
+       {
+       case 'c':
+         if (!s[1] && check_live_switch (i, 1))
+           found_cS = true;
+         break;
 
-  p = strrchr (name + i + 1, '.');
-  if (p != NULL)
-      *p = '\0';
+       case 'S':
+         if (!s[1] && check_live_switch (i, 1))
+           found_cS = true;
+         break;
 
-  result = concat (name, argv[1], NULL);
+       case 'o':
+         if (!s[1] && check_live_switch (i, 1))
+           oname = switches[i].args[0];
+         break;
 
-  free (name);
-  return result;
+       case 'd':
+         if (strncmp (s, "dump", 4) != 0)
+           break;
+         switch (s[4])
+           {
+           case 'd':
+             if (strcmp (s + 4, "dir") == 0
+                 && check_live_switch (i, 7))
+               found_dumpdir = true;
+             break;
+
+           case 'b':
+             if (strncmp (s + 4, "base", 4) == 0
+                 && check_live_switch (i, 8))
+               {
+                 if (!s[8])
+                   found_dumpbase = switches[i].args[0];
+                 else if (strcmp (s + 8, "-ext") == 0)
+                   found_dumpext = true;
+               }
+             break;
+
+           default:
+             break;
+           }
+
+       default:
+         break;
+       }
+    }
+
+  if (oname && not_actual_file_p (oname))
+    oname = NULL;
+
+  char *dir = NULL;
+  if (oname)
+    {
+      for (i = strlen (oname) - 1; i >= 0; i--)
+       if (IS_DIR_SEPARATOR (oname[i]))
+         break;
+
+      if (!found_dumpdir && i >= 0)
+       {
+         dir = xstrdup (oname);
+         int j = i + 1;
+
+         do
+           dir[j] = '\0';
+         while (j > 0 && IS_DIR_SEPARATOR (oname[j]));
+       }
+
+      oname += i + 1;
+    }
+
+  /* A "./" would be redundant, so omit -dumpdir for NULL dir.  */
+  if (!found_dumpdir && dir)
+    args[nargs++] = concat (" -dumpdir ",
+                           dir ? convert_white_space (dir) : "./",
+                           NULL);
+  free (dir);
+
+  char *ext = xstrdup (input_basename + basename_length);
+
+  if (!found_dumpbase || n_infiles > 1)
+    {
+      char *base = xstrdup (found_dumpbase ? found_dumpbase
+                           : oname ? oname : found_cS ? input_basename : "a");
+      char *p = *base ? strrchr (base + 1, '.') : NULL;
+      if (p)
+       *p = '\0';
+
+      if (!found_dumpbase && found_cS)
+       p = concat (base, ext, NULL);
+      else
+       p = concat (base, "-", input_basename, NULL);
+
+      free (base);
+      base = p;
+
+      args[nargs++] = concat (" -dumpbase ", convert_white_space (base), NULL);
+      free (base);
+    }
+
+  if (!found_dumpext && *ext)
+    args[nargs++] = concat (" -dumpbase-ext ", convert_white_space (ext), 
NULL);
+  free (ext);
+
+  const char *ret = concat (args[0], args[1], args[2], NULL);
+  while (nargs > 0)
+    free (args[--nargs]);
+
+  return ret;
 }
 
 /* Returns "" if ARGV[ARGC - 2] is greater than ARGV[ARGC-1].
@@ -10085,7 +10138,7 @@ convert_white_space (char *orig)
        }
       free (orig);
       return new_spec;
-  }
+    }
   else
     return orig;
 }
@@ -10264,8 +10317,6 @@ driver::finalize ()
   mdswitches = NULL;
   n_mdswitches = 0;
 
-  debug_auxbase_opt = NULL;
-
   used_arg.finalize ();
 }
 
diff --git a/gcc/lto-wrapper.c b/gcc/lto-wrapper.c
index 9a7bbd0..7099e6b 100644
--- a/gcc/lto-wrapper.c
+++ b/gcc/lto-wrapper.c
@@ -1250,6 +1250,7 @@ run_gcc (unsigned argc, char *argv[])
   const char **argv_ptr;
   char *list_option_full = NULL;
   const char *linker_output = NULL;
+  const char *linker_output_or_a = "a";
   const char *collect_gcc, *collect_gcc_options;
   int parallel = 0;
   int jobserver = 0;
@@ -1462,6 +1463,21 @@ run_gcc (unsigned argc, char *argv[])
          obstack_ptr_grow (&argv_obstack, output_dir);
        }
 
+      obstack_ptr_grow (&argv_obstack, "-dumpbase-ext");
+      obstack_ptr_grow (&argv_obstack, ".");
+
+      obstack_ptr_grow (&argv_obstack, "-dumpbase");
+      linker_output_or_a = linker_output;
+    }
+  else
+    {
+      static char current_dir[] = { '.', DIR_SEPARATOR, '\0' };
+      obstack_ptr_grow (&argv_obstack, "-dumpdir");
+      obstack_ptr_grow (&argv_obstack, current_dir);
+
+      obstack_ptr_grow (&argv_obstack, "-dumpbase-ext");
+      obstack_ptr_grow (&argv_obstack, ".");
+
       obstack_ptr_grow (&argv_obstack, "-dumpbase");
     }
 
@@ -1578,7 +1594,7 @@ cont1:
          strcat (flto_out, ".lto.o");
        }
       else
-       flto_out = make_temp_file (".lto.o");
+       flto_out = make_temp_file_with_prefix ("a.", ".lto.o");
       obstack_ptr_grow (&argv_obstack, "-o");
       obstack_ptr_grow (&argv_obstack, flto_out);
     }
@@ -1588,11 +1604,11 @@ cont1:
       size_t list_option_len = strlen (list_option);
       char *tmp;
 
-      if (linker_output)
+      if (linker_output_or_a)
        {
-         char *dumpbase = (char *) xmalloc (strlen (linker_output)
+         char *dumpbase = (char *) xmalloc (strlen (linker_output_or_a)
                                             + sizeof (".wpa") + 1);
-         strcpy (dumpbase, linker_output);
+         strcpy (dumpbase, linker_output_or_a);
          strcat (dumpbase, ".wpa");
          obstack_ptr_grow (&argv_obstack, dumpbase);
        }
@@ -1607,10 +1623,10 @@ cont1:
       else
        {
          char *prefix = NULL;
-         if (linker_output)
+         if (linker_output_or_a)
            {
-             prefix = (char *) xmalloc (strlen (linker_output) + 2);
-             strcpy (prefix, linker_output);
+             prefix = (char *) xmalloc (strlen (linker_output_or_a) + 2);
+             strcpy (prefix, linker_output_or_a);
              strcat (prefix, ".");
            }
 
@@ -1781,14 +1797,14 @@ cont:
          output_name = XOBFINISH (&env_obstack, char *);
 
          /* Adjust the dumpbase if the linker output file was seen.  */
-         if (linker_output)
+         if (linker_output_or_a)
            {
              char *dumpbase
-                 = (char *) xmalloc (strlen (linker_output)
+                 = (char *) xmalloc (strlen (linker_output_or_a)
                                      + sizeof (DUMPBASE_SUFFIX) + 1);
              snprintf (dumpbase,
-                       strlen (linker_output) + sizeof (DUMPBASE_SUFFIX),
-                       "%s.ltrans%u", linker_output, i);
+                       strlen (linker_output_or_a) + sizeof (DUMPBASE_SUFFIX),
+                       "%s.ltrans%u", linker_output_or_a, i);
              argv_ptr[0] = dumpbase;
            }
 
diff --git a/gcc/opts.c b/gcc/opts.c
index 3c53fbe..411652c 100644
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -845,30 +845,6 @@ finish_options (struct gcc_options *opts, struct 
gcc_options *opts_set,
        /* We have a DUMP_DIR_NAME, prepend that.  */
        opts->x_dump_base_name = opts_concat (opts->x_dump_dir_name,
                                              opts->x_dump_base_name, NULL);
-      else if (opts->x_aux_base_name
-              && strcmp (opts->x_aux_base_name, HOST_BIT_BUCKET) != 0)
-       /* AUX_BASE_NAME is set and is not the bit bucket.  If it
-          contains a directory component, prepend those directories.
-          Typically this places things in the same directory as the
-          object file.  */
-       {
-         const char *aux_base;
-
-         base_of_path (opts->x_aux_base_name, &aux_base);
-         if (opts->x_aux_base_name != aux_base)
-           {
-             int dir_len = aux_base - opts->x_aux_base_name;
-             char *new_dump_base_name
-               = XOBNEWVEC (&opts_obstack, char,
-                            strlen (opts->x_dump_base_name) + dir_len + 1);
-
-             /* Copy directory component from OPTS->X_AUX_BASE_NAME.  */
-             memcpy (new_dump_base_name, opts->x_aux_base_name, dir_len);
-             /* Append existing OPTS->X_DUMP_BASE_NAME.  */
-             strcpy (new_dump_base_name + dir_len, opts->x_dump_base_name);
-             opts->x_dump_base_name = new_dump_base_name;
-           }
-       }
 
       /* It is definitely prefixed now.  */
       opts->x_dump_base_name_prefixed = true;
@@ -2314,17 +2290,6 @@ common_handle_option (struct gcc_options *opts,
       opts->x_flag_gen_aux_info = 1;
       break;
 
-    case OPT_auxbase_strip:
-      {
-       char *tmp = xstrdup (arg);
-       strip_off_ending (tmp, strlen (tmp));
-       if (tmp[0])
-         opts->x_aux_base_name = tmp;
-       else
-         free (tmp);
-      }
-      break;
-
     case OPT_d:
       decode_d_option (arg, opts, loc, dc);
       break;
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 059046f..0c6e096 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -796,8 +796,8 @@ print_switch_values (print_switch_fn_type print_fn)
        case OPT_o:
        case OPT_d:
        case OPT_dumpbase:
+       case OPT_dumpbase_ext:
        case OPT_dumpdir:
-       case OPT_auxbase:
        case OPT_quiet:
        case OPT_version:
          /* Ignore these.  */
@@ -1401,18 +1401,44 @@ process_options (void)
   if (flag_short_enums == 2)
     flag_short_enums = targetm.default_short_enums ();
 
+  if (dump_base_ext)
+    ;
+  else if (main_input_filename)
+    {
+      const char *name = lbasename (main_input_filename);
+      const char *ext = strrchr (name, '.');
+      if (ext)
+       dump_base_ext = ext;
+      else
+       dump_base_ext = "";
+    }
+  else
+    dump_base_ext = "";
+
   /* Set aux_base_name if not already set.  */
   if (aux_base_name)
     ;
-  else if (main_input_filename)
+  else if (dump_base_name)
     {
-      char *name = xstrdup (lbasename (main_input_filename));
+      const char *name = dump_base_name;
+      int nlen, len;
+
+      if (dump_base_ext && (len = strlen (dump_base_ext))
+         && (nlen = strlen (name)) && nlen > len
+         && strcmp (name + nlen - len, dump_base_ext) == 0)
+       {
+         char *p = xstrdup (name);
+         p[nlen - len] = '\0';
+         name = (const char *) xrealloc (p, nlen - len + 1);
+       }
 
-      strip_off_ending (name, strlen (name));
       aux_base_name = name;
     }
   else
-    aux_base_name = "gccaux";
+    {
+      if (dump_dir_name)
+      aux_base_name = "gccaux";
+    }
 
 #ifndef HAVE_isl
   if (flag_graphite



-- 
Alexandre Oliva, freedom fighter   he/him   https://FSFLA.org/blogs/lxo
Free Software Evangelist           Stallman was right, but he's left :(
GNU Toolchain Engineer    FSMatrix: It was he who freed the first of us
FSF & FSFLA board member                The Savior shall return (true);

Reply via email to