drop -aux{dir,base}, revamp -dump{dir,base}

Richard Biener rguenther@suse.de
Mon Jan 20 10:38:00 GMT 2020


On Thu, 16 Jan 2020, Alexandre Oliva wrote:

> On Jan  9, 2020, Alexandre Oliva <oliva@adacore.com> wrote:
> 
> > On Jan  9, 2020, Richard Biener <rguenther@suse.de> wrote:
> >> Did I miss the actual (non-documentation) patch?
> 
> > No, I didn't post it.  It's kind of big, and only yesterday did I get it
> > to work as expected and now extensively documented, passing all of the
> > extensive testsuite I wrote for it.
> 
> Here it is, at last, regstrapped on x86_64-linux-gnu.  Ok to install?

I'm hesitant to approve it now since we're in stage4 and been too
permissive already.  So ...

OK for GCC 11.

And thanks alot for this work!

Thanks,
Richard.

> 
> revamp dump and aux output names
> 
> This patch simplifies (!!!) the logic governing the naming of dump
> files and auxiliary output files in the driver, in the compiler, and
> in the LTO wrapper.  No changes are made to the naming of primary
> outputs, there are often ways to restore past behavior, and a number
> of inconsistencies are fixed.  Some internal options are removed
> (-auxbase and -auxbase-strip), sensible existing uses of -dumpdir and
> -dumpbase options remain unchanged, additional useful cases are added,
> making for what is still admittedly quite complex.  Extensive
> documentation and testcases provide numerous examples, from normal to
> corner cases.
> 
> The most visible changes are:
> 
> - aux and dump files now always go in the same directory, that
> defaults to the directory of the primary output, but that can be
> overridden with -dumpdir, -save-temps=*, or, preserving past behavior,
> with a -dumpbase with a directory component.
> 
> - driver and compiler now have the same notion of naming of auxiliary
> outputs, e.g. .dwo files will no longer be in one location while the
> debug info suggests they are elsewhere, and -save-temps and .dwo
> auxiliary outputs now go in the same location as .su, .ci and
> coverage data, with consistent naming.
> 
> - explicitly-specified primary output names guide not only the
> location of aux and dump outputs: the output base name is also used in
> their base name, as a prefix when also linking (e.g. foo.c bar.c -o
> foobar creates foobar-foo.dwo and foobar-bar.dwo with -gsplit-dwarf),
> or as the base name instead of the input name (foo.c -c -o whatever.o
> creates whatever.su rather than foo.su with -fstack-usage).  The
> preference for the input file base name, quite useful for our
> testsuite, can be restored with -dumpbase "".
> 
> - naming a -dumpbase when compiling multiple sources used to cause
> dumps from later compiles to overwrite those of earlier ones; it is
> now used as a prefix when compiling multiple sources, like an
> executable name above.
> 
> - the dumpbase, explicitly specified or computed from output or input
> names, now also governs the naming of aux outputs; since aux outputs
> usually replaced the suffix from the input name, while dump outputs
> append their own additional suffixes, a -dumpbase-ext option is
> introduced to enable a chosen suffix to be dropped from dumpbase to
> form aux output names.
> 
> - LTO dump and aux outputs were quite a mess, sometimes leaking
> temporary output names into -save-temps output names, sometimes
> conversely generating desirable aux outputs in temporary locations.
> They now obey the same logic of compiler aux and dump outputs, landing
> in the expected location and taking the linker output name or an
> explicit dumpbase overrider into account.
> 
> - Naming of -fdump-final-insns outputs now follows the dump file
> naming logic for the .gkd files, and the .gk dump files generated in
> the second -fcompare-debug compilation get the .gk inserted before the
> suffix that -dumpbase-ext drops in aux outputs.
> 
> 
> for  gcc/ChangeLog
> 
> 	* common.opt (aux_base_name): Define.
> 	(dumpbase, dumpdir): Mark as Driver options.
> 	(-dumpbase, -dumpdir): Likewise.
> 	(dumpbase-ext, -dumpbase-ext): New.
> 	(auxbase, auxbase-strip): Drop.
> 	* doc/invoke.texi (-dumpbase, -dumpbase-ext, -dumpdir):
> 	Document.
> 	(-o): Introduce the notion of primary output, mention it
> 	influences auxiliary and dump output names as well, add
> 	examples.
> 	(-save-temps): Adjust, move examples into -dump*.
> 	(-save-temps=cwd, -save-temps=obj): Likewise.
> 	(-fdump-final-insns): Adjust.
> 	* dwarf2out.c (gen_producer_string): Drop auxbase and
> 	auxbase_strip; add dumpbase_ext.
> 	* gcc.c (enum save_temps): Add SAVE_TEMPS_DUMP.
> 	(save_temps_prefix, save_temps_length): Drop.
> 	(save_temps_overrides_dumpdir): New.
> 	(dumpdir, dumpbase, dumpbase_ext): New.
> 	(dumpdir_length, dumpdir_trailing_dash_added): New.
> 	(outbase, outbase_length): New.
> 	(The Specs Language): Introduce %".  Adjust %b and %B.
> 	(ASM_FINAL_SPEC): Use %b.dwo for an aux output name always.
> 	Precede object file with %w when it's the primary output.
> 	(cpp_debug_options): Do not pass on incoming -dumpdir,
> 	-dumpbase and -dumpbase-ext options; recompute them with
> 	%:dumps.
> 	(cc1_options): Drop auxbase with and without compare-debug;
> 	use cpp_debug_options instead of dumpbase.  Mark asm output
> 	with %w when it's the primary output.
> 	(static_spec_functions): Drop %:compare-debug-auxbase-opt and
> 	%:replace-exception.  Add %:dumps.
> 	(driver_handle_option): Implement -save-temps=*/-dumpdir
> 	mutual overriding logic.  Save dumpdir, dumpbase and
> 	dumpbase-ext options.  Do not save output_file in
> 	save_temps_prefix.
> 	(adds_single_suffix_p): New.
> 	(single_input_file_index): New.
> 	(process_command): Combine output dir, output base name, and
> 	dumpbase into dumpdir and outbase.
> 	(set_collect_gcc_options): Pass a possibly-adjusted -dumpdir.
> 	(do_spec_1): Optionally dumpdir instead of save_temps_prefix,
> 	and outbase instead of input_basename in %b, %B and in
> 	-save-temps aux files.  Handle empty argument %".
> 	(driver::maybe_run_linker): Adjust dumpdir and auxbase.
> 	(compare_debug_dump_opt_spec_function): Adjust gkd dump file
> 	naming.  Spec-quote the computed -fdump-final-insns file name.
> 	(debug_auxbase_opt): Drop.
> 	(compare_debug_self_opt_spec_function): Drop auxbase-strip
> 	computation.
> 	(compare_debug_auxbase_opt_spec_function): Drop.
> 	(not_actual_file_p): New.
> 	(replace_extension_spec_func): Drop.
> 	(dumps_spec_func): New.
> 	(convert_white_space): Split-out parts into...
> 	(quote_string, whitespace_to_convert_p): ... these.  New.
> 	(quote_spec_char_p, quote_spec, quote_spec_arg): New.
> 	(driver::finalize): Release and reset new variables; drop
> 	removed ones.
> 	* lto-wrapper.c (DUMPBASE_SUFFIX): Drop leading period.
> 	(debug_objcopy): Use concat.
> 	(run_gcc): Recognize -save-temps=* as -save-temps too.  Obey
> 	-dumpdir.  Pass on empty dumpdir and dumpbase with a directory
> 	component.  Simplify temp file names.
> 	* opts.c (finish_options): Drop aux base name handling.
> 	(common_handle_option): Drop auxbase-strip handling.
> 	* toplev.c (print_switch_values): Drop auxbase, add
> 	dumpbase-ext.
> 	(process_options): Derive aux_base_name from dump_base_name
> 	and dump_base_ext.
> 	(lang_dependent_init): Compute dump_base_ext along with
> 	dump_base_name.  Disable stack usage and callgraph-info	during
> 	lto generation and compare-debug recompilation.
> 
> for  gcc/fortran/ChangeLog
> 
> 	* options.c (gfc_get_option_string): Drop auxbase, add
> 	dumpbase_ext.
> 
> for  gcc/ada/ChangeLog
> 
> 	* gcc-interface/lang-specs.h: Drop auxbase and auxbase-strip.
> 	Use %:dumps instead of -dumpbase.  Add %w for implicit .s
> 	primary output.
> 	* switch.adb (Is_Internal_GCC_Switch): Recognize dumpdir and
> 	dumpbase-ext.  Drop auxbase and auxbase-strip.
> 
> for  lto-plugin/ChangeLog
> 
> 	* lto-plugin.c (skip_in_suffix): New.
> 	(exec_lto_wrapper): Use skip_in_suffix and concat to build
> 	non-temporary output names.
> 	(onload): Look for -dumpdir in COLLECT_GCC_OPTIONS, and
> 	override link_output_name with it.
> 
> for  contrib/ChangeLog
> 
> 	* compare-debug: Adjust for .gkd files named as dump files,
> 	with the source suffix rather than the object suffix.
> 
> for  gcc/testsuite/ChangeLog
> 
> 	* gcc.misc-tests/outputs.exp: New.
> 	* gcc.misc-tests/outputs-0.c: New.
> 	* gcc.misc-tests/outputs-1.c: New.
> 	* gcc.misc-tests/outputs-2.c: New.
> 	* lib/gcc-defs.exp (dg-additional-files-options): Pass
> 	-dumpbase "" when there are additional sources.
> 	* lib/profopt.exp (profopt-execute): Pass the executable
> 	suffix with -dumpbase-ext.
> 	* lib/scandump.exp (dump-base): Mention -dumpbase "" use.
> 	* lib/scanltranstree.exp: Adjust dump suffix expectation.
> 	* lib/scanwpaipa.exp: Likewise.
> ---
>  contrib/compare-debug                    |   26 +
>  gcc/ada/gcc-interface/lang-specs.h       |   16 -
>  gcc/ada/switch.adb                       |    4 
>  gcc/common.opt                           |   27 +
>  gcc/doc/invoke.texi                      |  385 +++++++++++-
>  gcc/dwarf2out.c                          |    3 
>  gcc/fortran/options.c                    |    4 
>  gcc/gcc.c                                |  938 ++++++++++++++++++++++++------
>  gcc/lto-wrapper.c                        |  153 ++---
>  gcc/opts.c                               |   35 -
>  gcc/testsuite/gcc.misc-tests/outputs-0.c |    1 
>  gcc/testsuite/gcc.misc-tests/outputs-1.c |    4 
>  gcc/testsuite/gcc.misc-tests/outputs-2.c |    2 
>  gcc/testsuite/gcc.misc-tests/outputs.exp |  655 +++++++++++++++++++++
>  gcc/testsuite/lib/gcc-defs.exp           |    4 
>  gcc/testsuite/lib/profopt.exp            |   10 
>  gcc/testsuite/lib/scandump.exp           |    3 
>  gcc/testsuite/lib/scanltranstree.exp     |   20 -
>  gcc/testsuite/lib/scanwpaipa.exp         |   20 -
>  gcc/toplev.c                             |   62 +-
>  lto-plugin/lto-plugin.c                  |   87 +++
>  21 files changed, 2040 insertions(+), 419 deletions(-)
>  create mode 100644 gcc/testsuite/gcc.misc-tests/outputs-0.c
>  create mode 100644 gcc/testsuite/gcc.misc-tests/outputs-1.c
>  create mode 100644 gcc/testsuite/gcc.misc-tests/outputs-2.c
>  create mode 100644 gcc/testsuite/gcc.misc-tests/outputs.exp
> 
> diff --git a/contrib/compare-debug b/contrib/compare-debug
> index 22870cf..cf80ae3 100755
> --- a/contrib/compare-debug
> +++ b/contrib/compare-debug
> @@ -2,7 +2,7 @@
>  
>  # Compare stripped copies of two given object files.
>  
> -# Copyright (C) 2007, 2008, 2009, 2010, 2012 Free Software Foundation
> +# Copyright (C) 2007, 2008, 2009, 2010, 2012, 2020 Free Software Foundation
>  # Originally by Alexandre Oliva <aoliva@redhat.com>
>  
>  # This file is part of GCC.
> @@ -183,8 +183,28 @@ $rm "$1.$suf1" "$2.$suf2"
>  
>  trap "exit $status; exit" 0 1 2 15
>  
> -if test -f "$1".gkd || test -f "$2".gkd; then
> -  if cmp "$1".gkd "$2".gkd; then
> +# Replace the suffix in $1 and $2 with .*.gkd, compare them if a
> +# single file is found by the globbing.
> +base1=`echo "$1" | sed '$s,\.[^.]*$,,'` gkd1=
> +for f in "$base1".*.gkd; do
> +  if test "x$gkd1" != x; then
> +    gkd1=
> +    break
> +  elif test -f "$f"; then
> +    gkd1=$f
> +  fi
> +done
> +base2=`echo "$2" | sed '$s,\.[^.]*$,,'` gkd2=
> +for f in "$base2".*.gkd; do
> +  if test "x$gkd2" != x; then
> +    gkd2=
> +    break
> +  elif test -f "$f"; then
> +    gkd2=$f
> +  fi
> +done
> +if test "x$gkd1" != x || test "x$gkd2" != x; then
> +  if cmp "${gkd1-/dev/null}" "${gkd2-/dev/null}"; then
>      :
>    else
>      status=$?
> diff --git a/gcc/ada/gcc-interface/lang-specs.h b/gcc/ada/gcc-interface/lang-specs.h
> index 374fc1e..5e65cf98 100644
> --- a/gcc/ada/gcc-interface/lang-specs.h
> +++ b/gcc/ada/gcc-interface/lang-specs.h
> @@ -34,17 +34,15 @@
>   %{!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(%{!.adb:%{!.ads:.ada}}) \
>      %{coverage:-fprofile-arcs -ftest-coverage} "
>  #if defined(TARGET_VXWORKS_RTP)
>     "%{fRTS=rtp|fRTS=rtp-smp|fRTS=ravenscar-cert-rtp:-mrtp} "
>  #endif
>     "%{gnatea:-gnatez} %{g*&m*&f*} "
>     "%1 %{!S:%{o*:%w%*-gnatO}} \
> -    %i %{S:%W{o*}%{!o*:-o %b.s}} \
> +    %i %{S:%W{o*}%{!o*:-o %w%b.s}} \
>      %{gnatc*|gnats*: -o %j} %{-param*} \
>      %{!gnatc*:%{!gnats*:%(invoke_as)}}", 0, 0, 0},
>  
> @@ -53,9 +51,7 @@
>   %{!c:%e-c required for gnat2why}\
>   gnat1why %{I*} %{k8:-gnatk8} %{!Q:-quiet}\
>      %{nostdinc*} %{nostdlib*}\
> -    -dumpbase %{.adb:%b.adb}%{.ads:%b.ads}%{!.adb:%{!.ads:%b.ada}}\
> -    %{o*:-auxbase-strip %*}%{!o*:-auxbase %b} \
> -    %{a} %{d*} \
> +    %{a} %{d*} %:dumps(%{!.adb:%{!.ads:.ada}}) \
>      %{gnatea:-gnatez} %{g*&m*&f*} \
>      %1 %{o*:%w%*-gnatO} \
>      %i \
> @@ -66,9 +62,7 @@
>   %{!c:%e-c required for gnat2scil}\
>   gnat1scil %{I*} %{k8:-gnatk8} %{!Q:-quiet}\
>      %{nostdinc*} %{nostdlib*}\
> -    -dumpbase %{.adb:%b.adb}%{.ads:%b.ads}%{!.adb:%{!.ads:%b.ada}}\
> -    %{o*:-auxbase-strip %*}%{!o*:-auxbase %b} \
> -    %{a} %{d*} \
> +    %{a} %{d*} %:dumps(%{!.adb:%{!.ads:.ada}}) \
>      %{gnatea:-gnatez} %{g*&m*&f*} \
>      %1 %{o*:%w%*-gnatO} \
>      %i \
> 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 e9b29fb..9c299cc 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
> @@ -252,10 +258,13 @@ Common Separate Alias(d)
>  Common Joined Alias(d)
>  
>  -dumpbase
> -Common Separate Alias(dumpbase)
> +Driver Common Separate Alias(dumpbase)
> +
> +-dumpbase-ext
> +Driver Common Separate Alias(dumpbase-ext)
>  
>  -dumpdir
> -Common Separate Alias(dumpdir)
> +Driver Common Separate Alias(dumpdir)
>  
>  -entry
>  Driver Separate Alias(e)
> @@ -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
>  
> @@ -857,11 +860,15 @@ Common Joined
>  -d<letters>	Enable dumps from specific passes of the compiler.
>  
>  dumpbase
> -Common Separate Var(dump_base_name)
> +Driver Common Separate Var(dump_base_name)
>  -dumpbase <file>	Set the file basename to be used for dumps.
>  
> +dumpbase-ext
> +Driver 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)
> +Driver Common Separate Var(dump_dir_name)
>  -dumpdir <dir>	Set the directory name to be used for dumps.
>  
>  dumpmachine
> diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> index f2c805c..c679cdf 100644
> --- a/gcc/doc/invoke.texi
> +++ b/gcc/doc/invoke.texi
> @@ -184,7 +184,9 @@ in the following sections.
>  @table @emph
>  @item Overall Options
>  @xref{Overall Options,,Options Controlling the Kind of Output}.
> -@gccoptlist{-c  -S  -E  -o @var{file}  -x @var{language}  @gol
> +@gccoptlist{-c  -S  -E  -o @var{file} @gol
> +-dumpbase @var{dumpbase}  -dumpbase-ext @var{auxdropsuf} @gol
> +-dumpdir @var{dumppfx}  -x @var{language}  @gol
>  -v  -###  --help@r{[}=@var{class}@r{[},@dots{}@r{]]}  --target-help  --version @gol
>  -pass-exit-codes  -pipe  -specs=@var{file}  -wrapper  @gol
>  @@@var{file}  -ffile-prefix-map=@var{old}=@var{new}  @gol
> @@ -1552,9 +1554,9 @@ Input files that don't require preprocessing are ignored.
>  @cindex output file option
>  @item -o @var{file}
>  @opindex o
> -Place output in file @var{file}.  This applies to whatever
> -sort of output is being produced, whether it be an executable file,
> -an object file, an assembler file or preprocessed C code.
> +Place the primary output in file @var{file}.  This applies to whatever
> +sort of output is being produced, whether it be an executable file, an
> +object file, an assembler file or preprocessed C code.
>  
>  If @option{-o} is not specified, the default is to put an executable
>  file in @file{a.out}, the object file for
> @@ -1563,6 +1565,314 @@ assembler file in @file{@var{source}.s}, a precompiled header file in
>  @file{@var{source}.@var{suffix}.gch}, and all preprocessed C source on
>  standard output.
>  
> +Though @option{-o} names only the primary output, it also affects the
> +naming of auxiliary and dump outputs.  See the examples below.  Unless
> +overridden, both auxiliary outputs and dump outputs are placed in the
> +same directory as the primary output.  In auxiliary outputs, the suffix
> +of the input file is replaced with that of the auxiliary output file
> +type; in dump outputs, the suffix of the dump file is appended to the
> +input file suffix.  In compilation commands, the base name of both
> +auxiliary and dump outputs is that of the primary output; in compile and
> +link commands, the primary output name, minus the executable suffix, is
> +combined with the input file name.  If both share the same base name,
> +disregarding the suffix, the result of the combination is that base
> +name, otherwise, they are concatenated, separated by a dash.
> +
> +@smallexample
> +gcc -c foo.c ...
> +@end smallexample
> +
> +will use @file{foo.o} as the primary output, and place aux outputs and
> +dumps next to it, e.g., aux file @file{foo.dwo} for
> +@option{-gsplit-dwarf}, and dump file @file{foo.c.???r.final} for
> +@option{-fdump-rtl-final}.
> +
> +If a non-linker output file is explicitly specified, aux and dump files
> +by default take the same base name:
> +
> +@smallexample
> +gcc -c foo.c -o dir/foobar.o ...
> +@end smallexample
> +
> +will name aux outputs @file{dir/foobar.*} and dump outputs
> +@file{dir/foobar.c.*}.
> +
> +A linker output will instead prefix aux and dump outputs:
> +
> +@smallexample
> +gcc foo.c bar.c -o dir/foobar ...
> +@end smallexample
> +
> +will generally name aux outputs @file{dir/foobar-foo.*} and
> +@file{dir/foobar-bar.*}, and dump outputs @file{dir/foobar-foo.c.*} and
> +@file{dir/foobar-bar.c.*}.
> +
> +The one exception to the above is when the executable shares the base
> +name with the single input:
> +
> +@smallexample
> +gcc foo.c -o dir/foo ...
> +@end smallexample
> +
> +in which case aux outputs are named @file{dir/foo.*} and dump outputs
> +named @file{dir/foo.c.*}.
> +
> +The location and the names of auxiliary and dump outputs can be adjusted
> +by the options @option{-dumpbase}, @option{-dumpbase-ext},
> +@option{-dumpdir}, @option{-save-temps=cwd}, and
> +@option{-save-temps=obj}.
> +
> +
> +@item -dumpbase @var{dumpbase}
> +@opindex dumpbase
> +This option sets the base name for auxiliary and dump output files.  It
> +does not affect the name of the primary output file.  Intermediate
> +outputs, when preserved, are not regarded as primary outputs, but as
> +auxiliary outputs:
> +
> +@smallexample
> +gcc -save-temps -S foo.c
> +@end smallexample
> +
> +saves the (no longer) temporary preprocessed file in @file{foo.i}, and
> +then compiles to the (implied) output file @file{foo.s}, whereas:
> +
> +@smallexample
> +gcc -save-temps -dumpbase save-foo -c foo.c
> +@end smallexample
> +
> +preprocesses to in @file{save-foo.i}, compiles to @file{save-foo.s} (now
> +an intermediate, thus auxiliary output), and then assembles to the
> +(implied) output file @file{foo.o}.
> +
> +Absent this option, dump and aux files take their names from the input
> +file, or from the (non-linker) output file, if one is explicitly
> +specified: dump output files (e.g. those requested by @option{-fdump-*}
> +options) with the input name suffix, and aux output files (those
> +requested by other non-dump options, e.g. @code{-save-temps},
> +@code{-gsplit-dwarf}, @code{-fcallgraph-info}) without it.
> +
> +Similar suffix differentiation of dump and aux outputs can be attained
> +for explicitly-given @option{-dumpbase basename.suf} by also specifying
> +@option{-dumpbase-ext .suf}.
> +
> +If @var{dumpbase} is explicitly specified with any directory component,
> +any @var{dumppfx} specification (e.g. @option{-dumpdir} or
> +@option{-save-temps=*}) is ignored, and instead of appending to it,
> +@var{dumpbase} fully overrides it:
> +
> +@smallexample
> +gcc foo.c -c -o dir/foo.o -dumpbase alt/foo \
> +  -dumpdir pfx- -save-temps=cwd ...
> +@end smallexample
> +
> +creates auxiliary and dump outputs named @file{alt/foo.*}, disregarding
> +@file{dir/} in @option{-o}, the @file{./} prefix implied by
> +@option{-save-temps=cwd}, and @file{pfx-} in @option{-dumpdir}.
> +
> +When @option{-dumpbase} is specified in a command that compiles multiple
> +inputs, or that compiles and then links, it may be combined with
> +@var{dumppfx}, as specified under @option{-dumpdir}.  Then, each input
> +file is compiled using the combined @var{dumppfx}, and default values
> +for @var{dumpbase} and @var{auxdropsuf} are computed for each input
> +file:
> +
> +@smallexample
> +gcc foo.c bar.c -c -dumpbase main ...
> +@end smallexample
> +
> +creates @file{foo.o} and @file{bar.o} as primary outputs, and avoids
> +overwriting the auxiliary and dump outputs by using the @var{dumpbase}
> +as a prefix, creating auxiliary and dump outputs named @file{main-foo.*}
> +and @file{main-bar.*}.
> +
> +An empty string specified as @var{dumpbase} avoids the influence of the
> +output basename in the naming of auxiliary and dump outputs during
> +compilation, computing default values :
> +
> +@smallexample
> +gcc -c foo.c -o dir/foobar.o -dumpbase '' ...
> +@end smallexample
> +
> +will name aux outputs @file{dir/foo.*} and dump outputs
> +@file{dir/foo.c.*}.  Note how their basenames are taken from the input
> +name, but the directory still defaults to that of the output.
> +
> +The empty-string dumpbase does not prevent the use of the output
> +basename for outputs during linking:
> +
> +@smallexample
> +gcc foo.c bar.c -o dir/foobar -dumpbase '' -flto ...
> +@end smallexample
> +
> +The compilation of the source files will name auxiliary outputs
> +@file{dir/foo.*} and @file{dir/bar.*}, and dump outputs
> +@file{dir/foo.c.*} and @file{dir/bar.c.*}.  LTO recompilation during
> +linking will use @file{dir/foobar.} as the prefix for dumps and
> +auxiliary files.
> +
> +
> +@item -dumpbase-ext @var{auxdropsuf}
> +@opindex dumpbase-ext
> +When forming the name of an auxiliary (but not a dump) output file, drop
> +trailing @var{auxdropsuf} from @var{dumpbase} before appending any
> +suffixes.  If not specified, this option defaults to the suffix of a
> +default @var{dumpbase}, i.e., the suffix of the input file when
> +@option{-dumpbase} is not present in the command line, or @var{dumpbase}
> +is combined with @var{dumppfx}.
> +
> +@smallexample
> +gcc foo.c -c -o dir/foo.o -dumpbase x-foo.c -dumpbase-ext .c ...
> +@end smallexample
> +
> +creates @file{dir/foo.o} as the main output, and generates auxiliary
> +outputs in @file{dir/x-foo.*}, taking the location of the primary
> +output, and dropping the @file{.c} suffix from the @var{dumpbase}.  Dump
> +outputs retain the suffix: @file{dir/x-foo.c.*}.
> +
> +This option is disregarded if it does not match the suffix of a
> +specified @var{dumpbase}, except as an alternative to the executable
> +suffix when appending the linker output base name to @var{dumppfx}, as
> +specified below:
> +
> +@smallexample
> +gcc foo.c bar.c -o main.out -dumpbase-ext .out ...
> +@end smallexample
> +
> +creates @file{main.out} as the primary output, and avoids overwriting
> +the auxiliary and dump outputs by using the executable name minus
> +@var{auxdropsuf} as a prefix, creating auxiliary outputs named
> +@file{main-foo.*} and @file{main-bar.*} and dump outputs named
> +@file{main-foo.c.*} and @file{main-bar.c.*}.
> +
> +
> +@item -dumpdir @var{dumppfx}
> +@opindex dumpdir
> +When forming the name of an auxiliary or dump output file, use
> +@var{dumppfx} as a prefix:
> +
> +@smallexample
> +gcc -dumpdir pfx- -c foo.c ...
> +@end smallexample
> +
> +creates @file{foo.o} as the primary output, and auxiliary outputs named
> +@file{pfx-foo.*}, combining the given @var{dumppfx} with the default
> +@var{dumpbase} derived from the default primary output, derived in turn
> +from the input name.  Dump outputs also take the input name suffix:
> +@file{pfx-foo.c.*}.
> +
> +If @var{dumppfx} is to be used as a directory name, it must end with a
> +directory separator:
> +
> +@smallexample
> +gcc -dumpdir dir/ -c foo.c -o obj/bar.o ...
> +@end smallexample
> +
> +creates @file{obj/bar.o} as the primary output, and auxiliary outputs
> +named @file{dir/bar.*}, combining the given @var{dumppfx} with the
> +default @var{dumpbase} derived from the primary output name.  Dump
> +outputs also take the input name suffix: @file{dir/bar.c.*}.
> +
> +It defaults to the location of the output file; options
> +@option{-save-temps=cwd} and @option{-save-temps=obj} override this
> +default, just like an explicit @option{-dumpdir} option.  In case
> +multiple such options are given, the last one prevails:
> +
> +@smallexample
> +gcc -dumpdir pfx- -c foo.c -save-temps=obj ...
> +@end smallexample
> +
> +outputs @file{foo.o}, with auxiliary outputs named @file{foo.*} because
> +@option{-save-temps=*} overrides the @var{dumppfx} given by the earlier
> +@option{-dumpdir} option.  It does not matter that @option{=obj} is the
> +default for @option{-save-temps}, nor that the output directory is
> +implicitly the current directory.  Dump outputs are named
> +@file{foo.c.*}.
> +
> +When compiling from multiple input files, if @option{-dumpbase} is
> +specified, @var{dumpbase}, minus a @var{auxdropsuf} suffix, and a dash
> +are appended to (or override, if containing any directory components) an
> +explicit or defaulted @var{dumppfx}, so that each of the multiple
> +compilations gets differently-named aux and dump outputs.
> +
> +@smallexample
> +gcc foo.c bar.c -c -dumpdir dir/pfx- -dumpbase main ...
> +@end smallexample
> +
> +outputs auxiliary dumps to @file{dir/pfx-main-foo.*} and
> +@file{dir/pfx-main-bar.*}, appending @var{dumpbase}- to @var{dumppfx}.
> +Dump outputs retain the input file suffix: @file{dir/pfx-main-foo.c.*}
> +and @file{dir/pfx-main-bar.c.*}, respectively.  Contrast with the
> +single-input compilation:
> +
> +@smallexample
> +gcc foo.c -c -dumpdir dir/pfx- -dumpbase main ...
> +@end smallexample
> +
> +that, applying @option{-dumpbase} to a single source, does not compute
> +and append a separate @var{dumpbase} per input file.  Its auxiliary and
> +dump outputs go in @file{dir/pfx-main.*}.
> +
> +When compiling and then linking from multiple input files, a defaulted
> +or explicitly specified @var{dumppfx} also undergoes the @var{dumpbase}-
> +transformation above (e.g. the compilation of @file{foo.c} and
> +@file{bar.c} above, but without @option{-c}).  If neither
> +@option{-dumpdir} nor @option{-dumpbase} are given, the linker output
> +base name, minus @var{auxdropsuf}, if specified, or the executable
> +suffix otherwise, plus a dash is appended to the default @var{dumppfx}
> +instead.  Note, however, that unlike earlier cases of linking:
> +
> +@smallexample
> +gcc foo.c bar.c -dumpdir dir/pfx- -o main ...
> +@end smallexample
> +
> +does not append the output name @file{main} to @var{dumppfx}, because
> +@option{-dumpdir} is explicitly specified.  The goal is that the
> +explicitly-specified @var{dumppfx} may contain the specified output name
> +as part of the prefix, if desired; only an explicitly-specified
> +@option{-dumpbase} would be combined with it, in order to avoid simply
> +discarding a meaningful option.
> +
> +When compiling and then linking from a single input file, the linker
> +output base name will only be appended to the default @var{dumppfx} as
> +above if it does not share the base name with the single input file
> +name.  This has been covered in single-input linking cases above, but
> +not with an explicit @option{-dumpdir} that inhibits the combination,
> +even if overridden by @option{-save-temps=*}:
> +
> +@smallexample
> +gcc foo.c -dumpdir alt/pfx- -o dir/main.exe -save-temps=cwd ...
> +@end smallexample
> +
> +Auxiliary outputs are named @file{foo.*}, and dump outputs
> +@file{foo.c.*}, in the current working directory as ultimately requested
> +by @option{-save-temps=cwd}.
> +
> +Summing it all up for an intuitive though slightly imprecise data flow:
> +the primary output name is broken into a directory part and a basename
> +part; @var{dumppfx} is set to the former, unless overridden by
> +@option{-dumpdir} or @option{-save-temps=*}, and @var{dumpbase} is set
> +to the latter, unless overriden by @option{-dumpbase}.  If there are
> +multiple inputs or linking, this @var{dumpbase} may be combined with
> +@var{dumppfx} and taken from each input file.  Auxiliary output names
> +for each input are formed by combining @var{dumppfx}, @var{dumpbase}
> +minus suffix, and the auxiliary output suffix; dump output names are
> +only different in that the suffix from @var{dumpbase} is retained.
> +
> +When it comes to auxiliary and dump outputs created during LTO
> +recompilation, a combination of @var{dumppfx} and @var{dumpbase}, as
> +given or as derived from the linker output name but not from inputs,
> +even in cases in which this combination would not otherwise be used as
> +such, is passed down with a trailing period replacing the compiler-added
> +dash, if any, as a @option{-dumpdir} option to @command{lto-wrapper};
> +being involved in linking, this program does not normally get any
> +@option{-dumpbase} and @option{-dumpbase-ext}, and it ignores them.
> +
> +When running sub-compilers, @command{lto-wrapper} appends LTO stage
> +names to the received @var{dumppfx}, ensures it contains a directory
> +component so that it overrides any @option{-dumpdir}, and passes that as
> +@option{-dumpbase} to sub-compilers.
> +
>  @item -v
>  @opindex v
>  Print (on standard error output) the commands executed to run the stages
> @@ -15644,54 +15954,28 @@ computing CRC32).
>  The @var{string} should be different for every file you compile.
>  
>  @item -save-temps
> -@itemx -save-temps=cwd
>  @opindex save-temps
> -Store the usual ``temporary'' intermediate files permanently; place them
> -in the current directory and name them based on the source file.  Thus,
> -compiling @file{foo.c} with @option{-c -save-temps} produces files
> -@file{foo.i} and @file{foo.s}, as well as @file{foo.o}.  This creates a
> -preprocessed @file{foo.i} output file even though the compiler now
> -normally uses an integrated preprocessor.
> +Store the usual ``temporary'' intermediate files permanently; name them
> +as auxiliary output files, as specified described under
> +@option{-dumpbase} and @option{-dumpdir}.
>  
>  When used in combination with the @option{-x} command-line option,
> -@option{-save-temps} is sensible enough to avoid over writing an
> +@option{-save-temps} is sensible enough to avoid overwriting an
>  input source file with the same extension as an intermediate file.
>  The corresponding intermediate file may be obtained by renaming the
>  source file before using @option{-save-temps}.
>  
> -If you invoke GCC in parallel, compiling several different source
> -files that share a common base name in different subdirectories or the
> -same source file compiled for multiple output destinations, it is
> -likely that the different parallel compilers will interfere with each
> -other, and overwrite the temporary files.  For instance:
> -
> -@smallexample
> -gcc -save-temps -o outdir1/foo.o indir1/foo.c&
> -gcc -save-temps -o outdir2/foo.o indir2/foo.c&
> -@end smallexample
> -
> -may result in @file{foo.i} and @file{foo.o} being written to
> -simultaneously by both compilers.
> +@item -save-temps=cwd
> +@opindex save-temps=cwd
> +Equivalent to @option{-save-temps -dumpdir ./}.
>  
>  @item -save-temps=obj
>  @opindex save-temps=obj
> -Store the usual ``temporary'' intermediate files permanently.  If the
> -@option{-o} option is used, the temporary files are based on the
> -object file.  If the @option{-o} option is not used, the
> -@option{-save-temps=obj} switch behaves like @option{-save-temps}.
> -
> -For example:
> -
> -@smallexample
> -gcc -save-temps=obj -c foo.c
> -gcc -save-temps=obj -c bar.c -o dir/xbar.o
> -gcc -save-temps=obj foobar.c -o dir2/yfoobar
> -@end smallexample
> -
> -@noindent
> -creates @file{foo.i}, @file{foo.s}, @file{dir/xbar.i},
> -@file{dir/xbar.s}, @file{dir2/yfoobar.i}, @file{dir2/yfoobar.s}, and
> -@file{dir2/yfoobar.o}.
> +Equivalent to @option{-save-temps -dumpdir @file{outdir/}}, where
> +@file{outdir/} is the directory of the output file specified after the
> +@option{-o} option, including any directory separators.  If the
> +@option{-o} option is not used, the @option{-save-temps=obj} switch
> +behaves like @option{-save-temps=cwd}.
>  
>  @item -time@r{[}=@var{file}@r{]}
>  @opindex time
> @@ -15728,7 +16012,7 @@ can later tell what file was being compiled, and with which options.
>  Dump the final internal representation (RTL) to @var{file}.  If the
>  optional argument is omitted (or if @var{file} is @code{.}), the name
>  of the dump file is determined by appending @code{.gkd} to the
> -compilation output file name.
> +dump base name, see @option{-dumpbase}.
>  
>  @item -fcompare-debug@r{[}=@var{opts}@r{]}
>  @opindex fcompare-debug
> @@ -29903,17 +30187,24 @@ together or combine them with constant text in a single argument.
>  @item %%
>  Substitute one @samp{%} into the program name or argument.
>  
> +@item %"
> +Substitute an empty argument.
> +
>  @item %i
>  Substitute the name of the input file being processed.
>  
>  @item %b
> -Substitute the basename of the input file being processed.
> -This is the substring up to (and not including) the last period
> -and not including the directory.
> +Substitute the basename for outputs related with the input file being
> +processed.  This is often the substring up to (and not including) the
> +last period and not including the directory but, unless %w is active, it
> +expands to the basename for auxiliary outputs, which may be influenced
> +by an explicit output name, and by various other options that control
> +how auxiliary outputs are named.
>  
>  @item %B
>  This is the same as @samp{%b}, but include the file suffix (text after
> -the last period).
> +the last period).  Without %w, it expands to the basename for dump
> +outputs.
>  
>  @item %d
>  Marks the argument containing or following the @samp{%d} as a
> diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c
> index 70b3fad..1882116 100644
> --- a/gcc/dwarf2out.c
> +++ b/gcc/dwarf2out.c
> @@ -24333,9 +24333,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 4cc8a90..d844fa9 100644
> --- a/gcc/fortran/options.c
> +++ b/gcc/fortran/options.c
> @@ -838,8 +838,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:
> @@ -864,8 +864,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 effc384f..cc04a20 100644
> --- a/gcc/gcc.c
> +++ b/gcc/gcc.c
> @@ -270,12 +270,36 @@ static const char *target_sysroot_hdrs_suffix = 0;
>  static enum save_temps {
>    SAVE_TEMPS_NONE,		/* no -save-temps */
>    SAVE_TEMPS_CWD,		/* -save-temps in current directory */
> +  SAVE_TEMPS_DUMP,              /* -save-temps in dumpdir */
>    SAVE_TEMPS_OBJ		/* -save-temps in object directory */
>  } save_temps_flag;
>  
> -/* Output file to use to get the object directory for -save-temps=obj  */
> -static char *save_temps_prefix = 0;
> -static size_t save_temps_length = 0;
> +/* Set this iff the dumppfx implied by a -save-temps=* option is to
> +   override a -dumpdir option, if any.  */
> +static bool save_temps_overrides_dumpdir = false;
> +
> +/* -dumpdir, -dumpbase and -dumpbase-ext flags passed in, possibly
> +   rearranged as they are to be passed down, e.g., dumpbase and
> +   dumpbase_ext may be cleared if integrated with dumpdir or
> +   dropped.  */
> +static char *dumpdir, *dumpbase, *dumpbase_ext;
> +
> +/* Usually the length of the string in dumpdir.  However, during
> +   linking, it may be shortened to omit a driver-added trailing dash,
> +   by then replaced with a trailing period, that is still to be passed
> +   to sub-processes in -dumpdir, but not to be generally used in spec
> +   filename expansions.  See maybe_run_linker.  */
> +static size_t dumpdir_length = 0;
> +
> +/* Set if the last character in dumpdir is (or was) a dash that the
> +   driver added to dumpdir after dumpbase or linker output name.  */
> +static bool dumpdir_trailing_dash_added = false;
> +
> +/* Basename of dump and aux outputs, computed from dumpbase (given or
> +   derived from output name), to override input_basename in non-%w %b
> +   et al.  */
> +static char *outbase;
> +static size_t outbase_length = 0;
>  
>  /* The compiler version.  */
>  
> @@ -402,13 +426,16 @@ 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 *replace_extension_spec_func (int, const char **);
> +static const char *dumps_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 **);
>  static const char *find_fortran_preinclude_file (int, const char **);
>  static char *convert_white_space (char *);
> +static char *quote_spec (char *);
> +static char *quote_spec_arg (char *);
> +static bool not_actual_file_p (const char *);
> +
>  

>  /* The Specs Language
>  
> @@ -426,12 +453,19 @@ expanding these sequences; therefore, you can concatenate them together
>  or with constant text in a single argument.
>  
>   %%	substitute one % into the program name or argument.
> + %"     substitute an empty argument.
>   %i     substitute the name of the input file being processed.
> - %b     substitute the basename of the input file being processed.
> -	This is the substring up to (and not including) the last period
> -	and not including the directory unless -save-temps was specified
> -	to put temporaries in a different location.
> - %B	same as %b, but include the file suffix (text after the last period).
> + %b     substitute the basename for outputs related with the input file
> +	being processed.  This is often a substring of the input file name,
> +	up to (and not including) the last period but, unless %w is active,
> +	it is affected by the directory selected by -save-temps=*, by
> +	-dumpdir, and, in case of multiple compilations, even by -dumpbase
> +	and -dumpbase-ext and, in case of linking, by the linker output
> +	name.  When %w is active, it derives the main output name only from
> +	the input file base name; when it is not, it names aux/dump output
> +	file.
> + %B	same as %b, but include the input file suffix (text after the last
> +	period).
>   %gSUFFIX
>  	substitute a file name that has suffix SUFFIX and is chosen
>  	once per compilation, and mark the argument a la %d.  To reduce
> @@ -641,10 +675,10 @@ proper position among the other output files.  */
>  #define ASM_FINAL_SPEC \
>    "%{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*:%*}%{!o*:%w%b%O}}%{!c:%U%O} \
> +	 %b.dwo \n\
>         objcopy --strip-dwo \
> -	 %{c:%{o*:%*}%{!o*:%b%O}}%{!c:%U%O} \
> +	 %{c:%{o*:%*}%{!o*:%w%b%O}}%{!c:%U%O} \
>      }"
>  #endif
>  
> @@ -1139,22 +1173,20 @@ static const char *cpp_options =
>  
>  /* This contains cpp options which are not passed when the preprocessor
>     output will be used by another program.  */
> -static const char *cpp_debug_options = "%{d*}";
> +static const char *cpp_debug_options = "%<dumpdir %<dumpbase %<dumpbase-ext %{d*} %:dumps()";
>  
>  /* NB: This is shared amongst all front-ends, except for Ada.  */
>  static const char *cc1_options =
>  "%{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\
>   %{!iplugindir*:%{fplugin*:%: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} %(cpp_debug_options) %{m*} %{aux-info*}\
>   %{g*} %{O*} %{W*&pedantic*} %{w} %{std*&ansi&trigraphs}\
>   %{v:-version} %{pg:-p} %{p} %{f*} %{undef}\
>   %{Qn:-fno-ident} %{Qy:} %{-help:--help}\
>   %{-target-help:--target-help}\
>   %{-version:--version}\
>   %{-help=*:--help=%*}\
> - %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %b.s}}}\
> + %{!fsyntax-only:%{S:%W{o*}%{!o*:-o %w%b.s}}}\
>   %{fsyntax-only:-o %j} %{-param*}\
>   %{coverage:-fprofile-arcs -ftest-coverage}\
>   %{fprofile-arcs|fprofile-generate*|coverage:\
> @@ -1642,9 +1674,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},
> @@ -4140,7 +4171,8 @@ driver_handle_option (struct gcc_options *opts,
>        return true;
>  
>      case OPT_save_temps:
> -      save_temps_flag = SAVE_TEMPS_CWD;
> +      if (!save_temps_flag)
> +	save_temps_flag = SAVE_TEMPS_DUMP;
>        validated = true;
>        break;
>  
> @@ -4153,6 +4185,23 @@ driver_handle_option (struct gcc_options *opts,
>        else
>  	fatal_error (input_location, "%qs is an unknown %<-save-temps%> option",
>  		     decoded->orig_option_with_args_text);
> +      save_temps_overrides_dumpdir = true;
> +      break;
> +
> +    case OPT_dumpdir:
> +      free (dumpdir);
> +      dumpdir = xstrdup (arg);
> +      save_temps_overrides_dumpdir = false;
> +      break;
> +
> +    case OPT_dumpbase:
> +      free (dumpbase);
> +      dumpbase = xstrdup (arg);
> +      break;
> +
> +    case OPT_dumpbase_ext:
> +      free (dumpbase_ext);
> +      dumpbase_ext = xstrdup (arg);
>        break;
>  
>      case OPT_no_canonical_prefixes:
> @@ -4259,8 +4308,6 @@ driver_handle_option (struct gcc_options *opts,
>        arg = convert_filename (arg, ! have_c, 0);
>  #endif
>        output_file = arg;
> -      /* Save the output name in case -save-temps=obj was used.  */
> -      save_temps_prefix = xstrdup (arg);
>        /* On some systems, ld cannot handle "-o" without a space.  So
>  	 split the option from its argument.  */
>        save_switch ("-o", 1, &arg, validated, true);
> @@ -4303,6 +4350,19 @@ driver_handle_option (struct gcc_options *opts,
>    return true;
>  }
>  
> +/* Return true if F2 is F1 followed by a single suffix, i.e., by a
> +   period and additional characters other than a period.  */
> +
> +static inline bool
> +adds_single_suffix_p (const char *f2, const char *f1)
> +{
> +  size_t len = strlen (f1);
> +
> +  return (strncmp (f1, f2, len) == 0
> +	  && f2[len] == '.'
> +	  && strchr (f2 + len + 1, '.') == NULL);
> +}
> +
>  /* Put the driver's standard set of option handlers in *HANDLERS.  */
>  
>  static void
> @@ -4319,6 +4379,32 @@ set_option_handlers (struct cl_option_handlers *handlers)
>    handlers->handlers[2].mask = CL_TARGET;
>  }
>  
> +
> +/* Return the index into infiles for the single non-library
> +   non-lto-wpa input file, -1 if there isn't any, or -2 if there is
> +   more than one.  */
> +static inline int
> +single_input_file_index ()
> +{
> +  int ret = -1;
> +
> +  for (int i = 0; i < n_infiles; i++)
> +    {
> +      if (infiles[i].language
> +	  && (infiles[i].language[0] == '*'
> +	      || (flag_wpa
> +		  && strcmp (infiles[i].language, "lto") == 0)))
> +	continue;
> +
> +      if (ret != -1)
> +	return -2;
> +
> +      ret = i;
> +    }
> +
> +  return ret;
> +}
> +
>  /* Create the vector `switches' and its contents.
>     Store its length in `n_switches'.  */
>  
> @@ -4631,23 +4717,371 @@ process_command (unsigned int decoded_options_count,
>    if (output_file != NULL && output_file[0] == '\0')
>      fatal_error (input_location, "output filename may not be empty");
>  
> +  /* -dumpdir and -save-temps=* both specify the location of aux/dump
> +     outputs; the one that appears last prevails.  When compiling
> +     multiple sources, an explicit dumpbase (minus -ext) may be
> +     combined with an explicit or implicit dumpdir, whereas when
> +     linking, a specified or implied link output name (minus
> +     extension) may be combined with a prevailing -save-temps=* or an
> +     otherwise implied dumpdir, but not override a prevailing
> +     -dumpdir.  Primary outputs (e.g., linker output when linking
> +     without -o, or .i, .s or .o outputs when processing multiple
> +     inputs with -E, -S or -c, respectively) are NOT affected by these
> +     -save-temps=/-dump* options, always landing in the current
> +     directory and with the same basename as the input when an output
> +     name is not given, but when they're intermediate outputs, they
> +     are named like other aux outputs, so the options affect their
> +     location and name.
> +
> +     Here are some examples.  There are several more in the
> +     documentation of -o and -dump*, and some quite exhaustive tests
> +     in gcc.misc-tests/outputs.exp.
> +
> +     When compiling any number of sources, no -dump* nor
> +     -save-temps=*, all outputs in cwd without prefix:
> +
> +     # gcc -c b.c -gsplit-dwarf
> +     -> cc1 [-dumpdir ./] -dumpbase b.c -dumpbase-ext .c # b.o b.dwo
> +
> +     # gcc -c b.c d.c -gsplit-dwarf
> +     -> cc1 [-dumpdir ./] -dumpbase b.c -dumpbase-ext .c # b.o b.dwo
> +     && cc1 [-dumpdir ./] -dumpbase d.c -dumpbase-ext .c # d.o d.dwo
> +
> +     When compiling and linking, no -dump* nor -save-temps=*, .o
> +     outputs are temporary, aux outputs land in the dir of the output,
> +     prefixed with the basename of the linker output:
> +
> +     # gcc b.c d.c -o ab -gsplit-dwarf
> +     -> cc1 -dumpdir ab- -dumpbase b.c -dumpbase-ext .c # ab-b.dwo
> +     && cc1 -dumpdir ab- -dumpbase d.c -dumpbase-ext .c # ab-d.dwo
> +     && link ... -o ab
> +
> +     # gcc b.c d.c [-o a.out] -gsplit-dwarf
> +     -> cc1 -dumpdir a- -dumpbase b.c -dumpbase-ext .c # a-b.dwo
> +     && cc1 -dumpdir a- -dumpbase d.c -dumpbase-ext .c # a-d.dwo
> +     && link ... [-o a.out]
> +
> +     When compiling and linking, a prevailing -dumpdir fully overrides
> +     the prefix of aux outputs given by the output name:
> +
> +     # gcc -dumpdir f b.c d.c -gsplit-dwarf [-o [dir/]whatever]
> +     -> cc1 -dumpdir f -dumpbase b.c -dumpbase-ext .c # fb.dwo
> +     && cc1 -dumpdir f -dumpbase d.c -dumpbase-ext .c # fd.dwo
> +     && link ... [-o whatever]
> +
> +     When compiling multiple inputs, an explicit -dumpbase is combined
> +     with -dumpdir, affecting aux outputs, but not the .o outputs:
> +
> +     # gcc -dumpdir f -dumpbase g- b.c d.c -gsplit-dwarf -c
> +     -> cc1 -dumpdir fg- -dumpbase b.c -dumpbase-ext .c # b.o fg-b.dwo
> +     && cc1 -dumpdir fg- -dumpbase d.c -dumpbase-ext .c # d.o fg-d.dwo
> +
> +     When compiling and linking with -save-temps, the .o outputs that
> +     would have been temporary become aux outputs, so they get
> +     affected by -dump* flags:
> +
> +     # gcc -dumpdir f -dumpbase g- -save-temps b.c d.c
> +     -> cc1 -dumpdir fg- -dumpbase b.c -dumpbase-ext .c # fg-b.o
> +     && cc1 -dumpdir fg- -dumpbase d.c -dumpbase-ext .c # fg-d.o
> +     && link
> +
> +     If -save-temps=* prevails over -dumpdir, however, the explicit
> +     -dumpdir is discarded, as if it wasn't there.  The basename of
> +     the implicit linker output, a.out or a.exe, becomes a- as the aux
> +     output prefix for all compilations:
> +
> +     # gcc [-dumpdir f] -save-temps=cwd b.c d.c
> +     -> cc1 -dumpdir a- -dumpbase b.c -dumpbase-ext .c # a-b.o
> +     && cc1 -dumpdir a- -dumpbase d.c -dumpbase-ext .c # a-d.o
> +     && link
> +
> +     A single -dumpbase, applying to multiple inputs, overrides the
> +     linker output name, implied or explicit, as the aux output prefix:
> +
> +     # gcc [-dumpdir f] -dumpbase g- -save-temps=cwd b.c d.c
> +     -> cc1 -dumpdir g- -dumpbase b.c -dumpbase-ext .c # g-b.o
> +     && cc1 -dumpdir g- -dumpbase d.c -dumpbase-ext .c # g-d.o
> +     && link
> +
> +     # gcc [-dumpdir f] -dumpbase g- -save-temps=cwd b.c d.c -o dir/h.out
> +     -> cc1 -dumpdir g- -dumpbase b.c -dumpbase-ext .c # g-b.o
> +     && cc1 -dumpdir g- -dumpbase d.c -dumpbase-ext .c # g-d.o
> +     && link -o dir/h.out
> +
> +     Now, if the linker output is NOT overridden as a prefix, but
> +     -save-temps=* overrides implicit or explicit -dumpdir, the
> +     effective dump dir combines the dir selected by the -save-temps=*
> +     option with the basename of the specified or implied link output:
> +
> +     # gcc [-dumpdir f] -save-temps=cwd b.c d.c -o dir/h.out
> +     -> cc1 -dumpdir h- -dumpbase b.c -dumpbase-ext .c # h-b.o
> +     && cc1 -dumpdir h- -dumpbase d.c -dumpbase-ext .c # h-d.o
> +     && link -o dir/h.out
> +
> +     # gcc [-dumpdir f] -save-temps=obj b.c d.c -o dir/h.out
> +     -> cc1 -dumpdir dir/h- -dumpbase b.c -dumpbase-ext .c # dir/h-b.o
> +     && cc1 -dumpdir dir/h- -dumpbase d.c -dumpbase-ext .c # dir/h-d.o
> +     && link -o dir/h.out
> +
> +     But then again, a single -dumpbase applying to multiple inputs
> +     gets used instead of the linker output basename in the combined
> +     dumpdir:
> +
> +     # gcc [-dumpdir f] -dumpbase g- -save-temps=obj b.c d.c -o dir/h.out
> +     -> cc1 -dumpdir dir/g- -dumpbase b.c -dumpbase-ext .c # dir/g-b.o
> +     && cc1 -dumpdir dir/g- -dumpbase d.c -dumpbase-ext .c # dir/g-d.o
> +     && link -o dir/h.out
> +
> +     With a single input being compiled, the output basename does NOT
> +     affect the dumpdir prefix.
> +
> +     # gcc -save-temps=obj b.c -gsplit-dwarf -c -o dir/b.o
> +     -> cc1 -dumpdir dir/ -dumpbase b.c -dumpbase-ext .c # dir/b.o dir/b.dwo
> +
> +     but when compiling and linking even a single file, it does:
> +
> +     # gcc -save-temps=obj b.c -o dir/h.out
> +     -> cc1 -dumpdir dir/h- -dumpbase b.c -dumpbase-ext .c # dir/h-b.o
> +
> +     unless an explicit -dumpdir prevails:
> +
> +     # gcc -save-temps[=obj] -dumpdir g- b.c -o dir/h.out
> +     -> cc1 -dumpdir g- -dumpbase b.c -dumpbase-ext .c # g-b.o
> +
> +  */
> +
> +  bool explicit_dumpdir = dumpdir;
> +
> +  if (!save_temps_overrides_dumpdir && explicit_dumpdir)
> +    {
> +      /* Do nothing.  */
> +    }
> +
>    /* If -save-temps=obj and -o name, create the prefix to use for %b.
>       Otherwise just make -save-temps=obj the same as -save-temps=cwd.  */
> -  if (save_temps_flag == SAVE_TEMPS_OBJ && save_temps_prefix != NULL)
> +  else if (save_temps_flag != SAVE_TEMPS_CWD && output_file != NULL)
> +    {
> +      free (dumpdir);
> +      dumpdir = NULL;
> +      temp = lbasename (output_file);
> +      if (temp != output_file)
> +	dumpdir = xstrndup (output_file,
> +			    strlen (output_file) - strlen (temp));
> +    }
> +  else if (dumpdir)
> +    {
> +      free (dumpdir);
> +      dumpdir = NULL;
> +    }
> +
> +  if (save_temps_flag)
> +    save_temps_flag = SAVE_TEMPS_DUMP;
> +
> +  /* If there is any pathname component in an explicit -dumpbase, it
> +     overrides dumpdir entirely, so discard it right away.  Although
> +     the presence of an explicit -dumpdir matters for the driver, it
> +     shouldn't matter for other processes, that get all that's needed
> +     from the -dumpdir and -dumpbase always passed to them.  */
> +  if (dumpdir && dumpbase && lbasename (dumpbase) != dumpbase)
> +    {
> +      free (dumpdir);
> +      dumpdir = NULL;
> +    }
> +
> +  /* Check that dumpbase_ext matches the end of dumpbase, drop it
> +     otherwise.  */
> +  if (dumpbase_ext && dumpbase && *dumpbase)
> +    {
> +      int lendb = strlen (dumpbase);
> +      int lendbx = strlen (dumpbase_ext);
> +
> +      if (lendbx >= lendb
> +	  || strcmp (dumpbase + lendb - lendbx, dumpbase_ext) != 0)
> +	{
> +	  free (dumpbase_ext);
> +	  dumpbase_ext = NULL;
> +	}
> +    }
> +
> +  /* -dumpbase with multiple sources goes into dumpdir.  With a single
> +     source, it does only if linking and if dumpdir was not explicitly
> +     specified.  */
> +  if (dumpbase && *dumpbase
> +      && (single_input_file_index () == -2
> +	  || (!have_c && !explicit_dumpdir)))
> +    {
> +      char *prefix;
> +
> +      if (dumpbase_ext)
> +	/* We checked that they match above.  */
> +	dumpbase[strlen (dumpbase) - strlen (dumpbase_ext)] = '\0';
> +
> +      if (dumpdir)
> +	prefix = concat (dumpdir, dumpbase, "-", NULL);
> +      else
> +	prefix = concat (dumpbase, "-", NULL);
> +
> +      free (dumpdir);
> +      free (dumpbase);
> +      free (dumpbase_ext);
> +      dumpbase = dumpbase_ext = NULL;
> +      dumpdir = prefix;
> +      dumpdir_trailing_dash_added = true;
> +    }
> +
> +  /* If dumpbase was not brought into dumpdir but we're linking, bring
> +     output_file into dumpdir unless dumpdir was explicitly specified.
> +     The test for !explicit_dumpdir is further below, because we want
> +     to use the obase computation for a ghost outbase, passed to
> +     GCC_COLLECT_OPTIONS.  */
> +  else if (!have_c && (!explicit_dumpdir || (dumpbase && !*dumpbase)))
> +    {
> +      /* If we get here, we know dumpbase was not specified, or it was
> +	 specified as an empty string.  If it was anything else, it
> +	 would have combined with dumpdir above, because the condition
> +	 for dumpbase to be used when present is broader than the
> +	 condition that gets us here.  */
> +      gcc_assert (!dumpbase || !*dumpbase);
> +
> +      const char *obase;
> +      char *tofree = NULL;
> +      if (!output_file || not_actual_file_p (output_file))
> +	obase = "a";
> +      else
> +	{
> +	  obase = lbasename (output_file);
> +	  size_t blen = strlen (obase), xlen;
> +	  /* Drop the suffix if it's dumpbase_ext, if given,
> +	     otherwise .exe or the target executable suffix, or if the
> +	     output was explicitly named a.out, but not otherwise.  */
> +	  if (dumpbase_ext
> +	      ? (blen > (xlen = strlen (dumpbase_ext))
> +		 && strcmp ((temp = (obase + blen - xlen)),
> +			    dumpbase_ext) == 0)
> +	      : ((temp = strrchr (obase + 1, '.'))
> +		 && (xlen = strlen (temp))
> +		 && (strcmp (temp, ".exe") == 0
> +#if HAVE_TARGET_EXECUTABLE_SUFFIX
> +		     || strcmp (temp, TARGET_EXECUTABLE_SUFFIX) == 0
> +#endif
> +		     || strcmp (obase, "a.out") == 0)))
> +	    {
> +	      tofree = xstrndup (obase, blen - xlen);
> +	      obase = tofree;
> +	    }
> +	}
> +
> +      /* We wish to save this basename to the -dumpdir passed through
> +	 GCC_COLLECT_OPTIONS within maybe_run_linker, for e.g. LTO,
> +	 but we do NOT wish to add it to e.g. %b, so we keep
> +	 outbase_length as zero.  */
> +      gcc_assert (!outbase);
> +      outbase_length = 0;
> +
> +      /* If we're building [dir1/]foo[.exe] out of a single input
> +	 [dir2/]foo.c that shares the same basename, dump to
> +	 [dir2/]foo.c.* rather than duplicating the basename into
> +	 [dir2/]foo-foo.c.*.  */
> +      int idxin;
> +      if (dumpbase
> +	  || ((idxin = single_input_file_index ()) >= 0
> +	      && adds_single_suffix_p (lbasename (infiles[idxin].name),
> +				       obase)))
> +	{
> +	  if (obase == tofree)
> +	    outbase = tofree;
> +	  else
> +	    {
> +	      outbase = xstrdup (obase);
> +	      free (tofree);
> +	    }
> +	  obase = tofree = NULL;
> +	}
> +      else
> +	{
> +	  if (dumpdir)
> +	    {
> +	      char *p = concat (dumpdir, obase, "-", NULL);
> +	      free (dumpdir);
> +	      dumpdir = p;
> +	    }
> +	  else
> +	    dumpdir = concat (obase, "-", NULL);
> +
> +	  dumpdir_trailing_dash_added = true;
> +
> +	  free (tofree);
> +	  obase = tofree = NULL;
> +	}
> +
> +      if (!explicit_dumpdir || dumpbase)
> +	{
> +	  /* Absent -dumpbase and present -dumpbase-ext have been applied
> +	     to the linker output name, so compute fresh defaults for each
> +	     compilation.  */
> +	  free (dumpbase_ext);
> +	  dumpbase_ext = NULL;
> +	}
> +    }
> +
> +  /* Now, if we're compiling, or if we haven't used the dumpbase
> +     above, then outbase (%B) is derived from dumpbase, if given, or
> +     from the output name, given or implied.  We can't precompute
> +     implied output names, but that's ok, since they're derived from
> +     input names.  Just make sure we skip this if dumpbase is the
> +     empty string: we want to use input names then, so don't set
> +     outbase.  */
> +  if ((dumpbase || have_c)
> +      && !(dumpbase && !*dumpbase))
>      {
> -      save_temps_length = strlen (save_temps_prefix);
> -      temp = strrchr (lbasename (save_temps_prefix), '.');
> -      if (temp)
> +      gcc_assert (!outbase);
> +
> +      if (dumpbase)
> +	{
> +	  gcc_assert (single_input_file_index () != -2);
> +	  /* We do not want lbasename here; dumpbase with dirnames
> +	     overrides dumpdir entirely, even if dumpdir is
> +	     specified.  */
> +	  if (dumpbase_ext)
> +	    /* We've already checked above that the suffix matches.  */
> +	    outbase = xstrndup (dumpbase,
> +				strlen (dumpbase) - strlen (dumpbase_ext));
> +	  else
> +	    outbase = xstrdup (dumpbase);
> +	}
> +      else if (output_file && !not_actual_file_p (output_file))
>  	{
> -	  save_temps_length -= strlen (temp);
> -	  save_temps_prefix[save_temps_length] = '\0';
> +	  outbase = xstrdup (lbasename (output_file));
> +	  char *p = strrchr (outbase + 1, '.');
> +	  if (p)
> +	    *p = '\0';
>  	}
>  
> +      if (outbase)
> +	outbase_length = strlen (outbase);
>      }
> -  else if (save_temps_prefix != NULL)
> +
> +  /* If there is any pathname component in an explicit -dumpbase, do
> +     not use dumpdir, but retain it to pass it on to the compiler.  */
> +  if (dumpdir)
> +    dumpdir_length = strlen (dumpdir);
> +  else
> +    dumpdir_length = 0;
> +
> +  /* Check that dumpbase_ext, if still present, still matches the end
> +     of dumpbase, if present, and drop it otherwise.  We only retained
> +     it above when dumpbase was absent to maybe use it to drop the
> +     extension from output_name before combining it with dumpdir.  */
> +  if (dumpbase_ext)
>      {
> -      free (save_temps_prefix);
> -      save_temps_prefix = NULL;
> +      if (!dumpbase)
> +	{
> +	  free (dumpbase_ext);
> +	  dumpbase_ext = NULL;
> +	}
> +      else
> +	gcc_assert (strcmp (dumpbase + strlen (dumpbase)
> +			    - strlen (dumpbase_ext), dumpbase_ext) == 0);
>      }
>  
>    if (save_temps_flag && use_pipes)
> @@ -4843,6 +5277,28 @@ set_collect_gcc_options (void)
>  	  obstack_grow (&collect_obstack, "'", 1);
>  	}
>      }
> +
> +  if (dumpdir)
> +    {
> +      if (!first_time)
> +	obstack_grow (&collect_obstack, " ", 1);
> +      first_time = FALSE;
> +
> +      obstack_grow (&collect_obstack, "'-dumpdir' '", 12);
> +      const char *p, *q;
> +
> +      q = dumpdir;
> +      while ((p = strchr (q, '\'')))
> +	{
> +	  obstack_grow (&collect_obstack, q, p - q);
> +	  obstack_grow (&collect_obstack, "'\\''", 4);
> +	  q = ++p;
> +	}
> +      obstack_grow (&collect_obstack, q, strlen (q));
> +
> +      obstack_grow (&collect_obstack, "'", 1);
> +    }
> +
>    obstack_grow (&collect_obstack, "\0", 1);
>    xputenv (XOBFINISH (&collect_obstack, char *));
>  }
> @@ -5333,22 +5789,33 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
>  	    fatal_error (input_location, "spec %qs invalid", spec);
>  
>  	  case 'b':
> -	    if (save_temps_length)
> -	      obstack_grow (&obstack, save_temps_prefix, save_temps_length);
> -	    else
> +	    /* Don't use %b in the linker command.  */
> +	    gcc_assert (suffixed_basename_length);
> +	    if (!this_is_output_file && dumpdir_length)
> +	      obstack_grow (&obstack, dumpdir, dumpdir_length);
> +	    if (this_is_output_file || !outbase_length)
>  	      obstack_grow (&obstack, input_basename, basename_length);
> +	    else
> +	      obstack_grow (&obstack, outbase, outbase_length);
>  	    if (compare_debug < 0)
>  	      obstack_grow (&obstack, ".gk", 3);
>  	    arg_going = 1;
>  	    break;
>  
>  	  case 'B':
> -	    if (save_temps_length)
> -	      obstack_grow (&obstack, save_temps_prefix, save_temps_length);
> +	    /* Don't use %B in the linker command.  */
> +	    gcc_assert (suffixed_basename_length);
> +	    if (!this_is_output_file && dumpdir_length)
> +	      obstack_grow (&obstack, dumpdir, dumpdir_length);
> +	    if (this_is_output_file || !outbase_length)
> +	      obstack_grow (&obstack, input_basename, basename_length);
>  	    else
> -	      obstack_grow (&obstack, input_basename, suffixed_basename_length);
> +	      obstack_grow (&obstack, outbase, outbase_length);
>  	    if (compare_debug < 0)
>  	      obstack_grow (&obstack, ".gk", 3);
> +	    obstack_grow (&obstack, input_basename + basename_length,
> +			  suffixed_basename_length - basename_length);
> +
>  	    arg_going = 1;
>  	    break;
>  
> @@ -5501,42 +5968,44 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
>  		    suffix_length += 3;
>  		  }
>  
> -		/* If -save-temps=obj and -o were specified, use that for the
> +		/* If -save-temps was specified, use that for the
>  		   temp file.  */
> -		if (save_temps_length)
> -		  {
> -		    char *tmp;
> -		    temp_filename_length
> -		      = save_temps_length + suffix_length + 1;
> -		    tmp = (char *) alloca (temp_filename_length);
> -		    memcpy (tmp, save_temps_prefix, save_temps_length);
> -		    memcpy (tmp + save_temps_length, suffix, suffix_length);
> -		    tmp[save_temps_length + suffix_length] = '\0';
> -		    temp_filename = save_string (tmp, save_temps_length
> -						      + suffix_length);
> -		    obstack_grow (&obstack, temp_filename,
> -				  temp_filename_length);
> -		    arg_going = 1;
> -		    delete_this_arg = 0;
> -		    break;
> -		  }
> -
> -		/* If the gcc_input_filename has the same suffix specified
> -		   for the %g, %u, or %U, and -save-temps is specified,
> -		   we could end up using that file as an intermediate
> -		   thus clobbering the user's source file (.e.g.,
> -		   gcc -save-temps foo.s would clobber foo.s with the
> -		   output of cpp0).  So check for this condition and
> -		   generate a temp file as the intermediate.  */
> -
>  		if (save_temps_flag)
>  		  {
>  		    char *tmp;
> -		    temp_filename_length = basename_length + suffix_length + 1;
> +		    bool adjusted_suffix = false;
> +		    if (suffix_length
> +			&& !outbase_length && !basename_length
> +			&& !dumpdir_trailing_dash_added)
> +		      {
> +			adjusted_suffix = true;
> +			suffix++;
> +			suffix_length--;
> +		      }
> +		    temp_filename_length
> +		      = dumpdir_length + suffix_length + 1;
> +		    if (!outbase_length)
> +		      temp_filename_length += basename_length;
> +		    else
> +		      temp_filename_length += outbase_length;
>  		    tmp = (char *) alloca (temp_filename_length);
> -		    memcpy (tmp, input_basename, basename_length);
> -		    memcpy (tmp + basename_length, suffix, suffix_length);
> -		    tmp[basename_length + suffix_length] = '\0';
> +		    if (dumpdir_length)
> +		      memcpy (tmp, dumpdir, dumpdir_length);
> +		    if (!outbase_length)
> +		      memcpy (tmp + dumpdir_length, input_basename,
> +			      basename_length);
> +		    else
> +		      memcpy (tmp + dumpdir_length, outbase,
> +			      outbase_length);
> +		    memcpy (tmp + temp_filename_length - suffix_length - 1,
> +			    suffix, suffix_length);
> +		    if (adjusted_suffix)
> +		      {
> +			adjusted_suffix = false;
> +			suffix--;
> +			suffix_length++;
> +		      }
> +		    tmp[temp_filename_length - 1] = '\0';
>  		    temp_filename = tmp;
>  
>  		    if (filename_cmp (temp_filename, gcc_input_filename) != 0)
> @@ -6047,6 +6516,14 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
>  	    }
>  	    break;
>  
> +	  case '"':
> +	    /* End a previous argument, if there is one, then issue an
> +	       empty argument.  */
> +	    end_going_arg ();
> +	    arg_going = 1;
> +	    end_going_arg ();
> +	    break;
> +
>  	  default:
>  	    error ("spec failure: unrecognized spec option %qc", c);
>  	    break;
> @@ -6057,6 +6534,9 @@ do_spec_1 (const char *spec, int inswitch, const char *soft_matched_part)
>  	/* Backslash: treat next character as ordinary.  */
>  	c = *p++;
>  
> +	/* When adding more cases that previously matched default, make
> +	   sure to adjust quote_spec_char_p as well.  */
> +
>  	/* Fall through.  */
>        default:
>  	/* Ordinary character: put it into the current argument.  */
> @@ -8262,6 +8742,40 @@ driver::maybe_run_linker (const char *argv0) const
>      if (explicit_link_files[i] || outfiles[i] != NULL)
>        num_linker_inputs++;
>  
> +  /* Arrange for temporary file names created during linking to take
> +     on names related with the linker output rather than with the
> +     inputs when appropriate.  */
> +  if (outbase && *outbase)
> +    {
> +      if (dumpdir)
> +	{
> +	  char *tofree = dumpdir;
> +	  gcc_checking_assert (strlen (dumpdir) == dumpdir_length);
> +	  dumpdir = concat (dumpdir, outbase, ".", NULL);
> +	  free (tofree);
> +	}
> +      else
> +	dumpdir = concat (outbase, ".", NULL);
> +      dumpdir_length += strlen (outbase) + 1;
> +      dumpdir_trailing_dash_added = true;
> +    }
> +  else if (dumpdir_trailing_dash_added)
> +    {
> +      gcc_assert (dumpdir[dumpdir_length - 1] == '-');
> +      dumpdir[dumpdir_length - 1] = '.';
> +    }
> +
> +  if (dumpdir_trailing_dash_added)
> +    {
> +      gcc_assert (dumpdir_length > 0);
> +      gcc_assert (dumpdir[dumpdir_length - 1] == '.');
> +      dumpdir_length--;
> +    }
> +
> +  free (outbase);
> +  input_basename = outbase = NULL;
> +  outbase_length = suffixed_basename_length = basename_length = 0;
> +
>    /* Run ld to link all the compiler output files.  */
>  
>    if (num_linker_inputs > 0 && !seen_error () && print_subprocess_help < 2)
> @@ -9732,7 +10246,7 @@ compare_debug_dump_opt_spec_function (int arg,
>    do_spec_1 (" ", 0, NULL);
>  
>    if (argbuf.length () > 0
> -      && strcmp (argv[argbuf.length () - 1], "."))
> +      && strcmp (argv[argbuf.length () - 1], ".") != 0)
>      {
>        if (!compare_debug)
>  	return NULL;
> @@ -9742,25 +10256,22 @@ compare_debug_dump_opt_spec_function (int arg,
>      }
>    else
>      {
> -      const char *ext = NULL;
> -
>        if (argbuf.length () > 0)
> -	{
> -	  do_spec_2 ("%{o*:%*}%{!o:%{!S:%b%O}%{S:%b.s}}", NULL);
> -	  ext = ".gkd";
> -	}
> +	do_spec_2 ("%B.gkd", NULL);
>        else if (!compare_debug)
>  	return NULL;
>        else
> -	do_spec_2 ("%g.gkd", NULL);
> +	do_spec_2 ("%{!save-temps*:%g.gkd}%{save-temps*:%B.gkd}", NULL);
>  
>        do_spec_1 (" ", 0, NULL);
>  
>        gcc_assert (argbuf.length () > 0);
>  
> -      name = concat (argbuf.last (), ext, NULL);
> +      name = xstrdup (argbuf.last ());
>  
> -      ret = concat ("-fdump-final-insns=", name, NULL);
> +      char *arg = quote_spec (xstrdup (name));
> +      ret = concat ("-fdump-final-insns=", arg, NULL);
> +      free (arg);
>      }
>  
>    which = compare_debug < 0;
> @@ -9787,8 +10298,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.  */
> @@ -9804,16 +10313,6 @@ compare_debug_self_opt_spec_function (int arg,
>    if (compare_debug >= 0)
>      return NULL;
>  
> -  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 +10320,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 +10363,105 @@ 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 an optional argument that overrides
> +   the default extension for -dumpbase and -dumpbase-ext.
> +   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 ATTRIBUTE_UNUSED)
>  {
> -  char *name;
> +  const char *ext = dumpbase_ext;
>    char *p;
> -  char *result;
> -  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]);
> +  /* Do not compute a default for -dumpbase-ext when -dumpbase was
> +     given explicitly.  */
> +  if (dumpbase && *dumpbase && !ext)
> +    ext = "";
>  
> -  for (i = strlen (name) - 1; i >= 0; i--)
> -    if (IS_DIR_SEPARATOR (name[i]))
> -      break;
> +  if (argc == 1)
> +    {
> +      /* Do not override the explicitly-specified -dumpbase-ext with
> +	 the specs-provided overrider.  */
> +      if (!ext)
> +	ext = argv[0];
> +    }
> +  else if (argc != 0)
> +    fatal_error (input_location, "too many arguments for %%:dumps");
>  
> -  p = strrchr (name + i + 1, '.');
> -  if (p != NULL)
> -      *p = '\0';
> +  if (dumpdir)
> +    {
> +      p = quote_spec_arg (xstrdup (dumpdir));
> +      args[nargs++] = concat (" -dumpdir ", p, NULL);
> +      free (p);
> +    }
>  
> -  result = concat (name, argv[1], NULL);
> +  if (!ext)
> +    ext = input_basename + basename_length;
>  
> -  free (name);
> -  return result;
> +  /* Use the precomputed outbase, or compute dumpbase from
> +     input_basename, just like %b would.  */
> +  char *base;
> +
> +  if (dumpbase && *dumpbase)
> +    {
> +      base = xstrdup (dumpbase);
> +      p = base + outbase_length;
> +      gcc_checking_assert (strncmp (base, outbase, outbase_length) == 0);
> +      gcc_checking_assert (strcmp (p, ext) == 0);
> +    }
> +  else if (outbase_length)
> +    {
> +      base = xstrndup (outbase, outbase_length);
> +      p = NULL;
> +    }
> +  else
> +    {
> +      base = xstrndup (input_basename, suffixed_basename_length);
> +      p = base + basename_length;
> +    }
> +
> +  if (compare_debug < 0 || !p || strcmp (p, ext) != 0)
> +    {
> +      if (p)
> +	*p = '\0';
> +
> +      const char *gk;
> +      if (compare_debug < 0)
> +	gk = ".gk";
> +      else
> +	gk = "";
> +
> +      p = concat (base, gk, ext, NULL);
> +
> +      free (base);
> +      base = p;
> +    }
> +
> +  base = quote_spec_arg (base);
> +  args[nargs++] = concat (" -dumpbase ", base, NULL);
> +  free (base);
> +
> +  if (*ext)
> +    {
> +      p = quote_spec_arg (xstrdup (ext));
> +      args[nargs++] = concat (" -dumpbase-ext ", p, NULL);
> +      free (p);
> +    }
> +
> +  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].
> @@ -10041,6 +10567,44 @@ find_fortran_preinclude_file (int argc, const char **argv)
>    return result;
>  }
>  
> +/* If any character in ORIG fits QUOTE_P (_, P), reallocate the string
> +   so as to precede every one of them with a backslash.  Return the
> +   original string or the reallocated one.  */
> +
> +static inline char *
> +quote_string (char *orig, bool (*quote_p)(char, void *), void *p)
> +{
> +  int len, number_of_space = 0;
> +
> +  for (len = 0; orig[len]; len++)
> +    if (quote_p (orig[len], p))
> +      number_of_space++;
> +
> +  if (number_of_space)
> +    {
> +      char *new_spec = (char *) xmalloc (len + number_of_space + 1);
> +      int j, k;
> +      for (j = 0, k = 0; j <= len; j++, k++)
> +	{
> +	  if (quote_p (orig[j], p))
> +	    new_spec[k++] = '\\';
> +	  new_spec[k] = orig[j];
> +	}
> +      free (orig);
> +      return new_spec;
> +    }
> +  else
> +    return orig;
> +}
> +
> +/* Return true iff C is any of the characters convert_white_space
> +   should quote.  */
> +
> +static inline bool
> +whitespace_to_convert_p (char c, void *)
> +{
> +  return (c == ' ' || c == '\t');
> +}
>  
>  /* Insert backslash before spaces in ORIG (usually a file path), to 
>     avoid being broken by spec parser.
> @@ -10068,26 +10632,50 @@ find_fortran_preinclude_file (int argc, const char **argv)
>  static char *
>  convert_white_space (char *orig)
>  {
> -  int len, number_of_space = 0;
> +  return quote_string (orig, whitespace_to_convert_p, NULL);
> +}
>  
> -  for (len = 0; orig[len]; len++)
> -    if (orig[len] == ' ' || orig[len] == '\t') number_of_space++;
> +/* Return true iff C matches any of the spec active characters.  */
> +static inline bool
> +quote_spec_char_p (char c, void *)
> +{
> +  switch (c)
> +    {
> +    case ' ':
> +    case '\t':
> +    case '\n':
> +    case '|':
> +    case '%':
> +    case '\\':
> +      return true;
>  
> -  if (number_of_space)
> +    default:
> +      return false;
> +    }
> +}
> +
> +/* Like convert_white_space, but deactivate all active spec chars by
> +   quoting them.  */
> +
> +static inline char *
> +quote_spec (char *orig)
> +{
> +  return quote_string (orig, quote_spec_char_p, NULL);
> +}
> +
> +/* Like quote_spec, but also turn an empty string into the spec for an
> +   empty argument.  */
> +
> +static inline char *
> +quote_spec_arg (char *orig)
> +{
> +  if (!*orig)
>      {
> -      char *new_spec = (char *) xmalloc (len + number_of_space + 1);
> -      int j, k;
> -      for (j = 0, k = 0; j <= len; j++, k++)
> -	{
> -	  if (orig[j] == ' ' || orig[j] == '\t')
> -	    new_spec[k++] = '\\';
> -	  new_spec[k] = orig[j];
> -	}
>        free (orig);
> -      return new_spec;
> -  }
> -  else
> -    return orig;
> +      return xstrdup ("%\"");
> +    }
> +
> +  return quote_spec (orig);
>  }
>  
>  /* Restore all state within gcc.c to the initial state, so that the driver
> @@ -10124,8 +10712,14 @@ driver::finalize ()
>    target_sysroot_suffix = 0;
>    target_sysroot_hdrs_suffix = 0;
>    save_temps_flag = SAVE_TEMPS_NONE;
> -  save_temps_prefix = 0;
> -  save_temps_length = 0;
> +  save_temps_overrides_dumpdir = false;
> +  dumpdir_trailing_dash_added = false;
> +  free (dumpdir);
> +  free (dumpbase);
> +  free (dumpbase_ext);
> +  free (outbase);
> +  dumpdir = dumpbase = dumpbase_ext = outbase = NULL;
> +  dumpdir_length = outbase_length = 0;
>    spec_machine = DEFAULT_TARGET_MACHINE;
>    greatest_status = 1;
>  
> @@ -10264,8 +10858,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 fe8f292..ed076e3 100644
> --- a/gcc/lto-wrapper.c
> +++ b/gcc/lto-wrapper.c
> @@ -125,7 +125,7 @@ maybe_unlink (const char *file)
>  }
>  
>  /* Template of LTRANS dumpbase suffix.  */
> -#define DUMPBASE_SUFFIX ".ltrans18446744073709551615"
> +#define DUMPBASE_SUFFIX "ltrans18446744073709551615"
>  
>  /* Create decoded options from the COLLECT_GCC and COLLECT_GCC_OPTIONS
>     environment.  */
> @@ -1081,12 +1081,7 @@ debug_objcopy (const char *infile, bool rename)
>      }
>  
>    if (save_temps)
> -    {
> -      outfile = (char *) xmalloc (strlen (orig_infile)
> -				  + sizeof (".debug.temp.o") + 1);
> -      strcpy (outfile, orig_infile);
> -      strcat (outfile, ".debug.temp.o");
> -    }
> +    outfile = concat (orig_infile, ".debug.temp.o", NULL);
>    else
>      outfile = make_temp_file (".debug.temp.o");
>    errmsg = simple_object_copy_lto_debug_sections (inobj, outfile, &err, rename);
> @@ -1271,6 +1266,8 @@ run_gcc (unsigned argc, char *argv[])
>    bool linker_output_rel = false;
>    bool skip_debug = false;
>    unsigned n_debugobj;
> +  const char *dumppfx = NULL, *incoming_dumppfx = NULL;
> +  static char current_dir[] = { '.', DIR_SEPARATOR, '\0' };
>  
>    /* Get the driver and options.  */
>    collect_gcc = getenv ("COLLECT_GCC");
> @@ -1362,6 +1359,10 @@ run_gcc (unsigned argc, char *argv[])
>  	  linker_output = option->arg;
>  	  break;
>  
> +	  /* We don't have to distinguish between -save-temps=* and
> +	     -save-temps, -dumpdir already carries that
> +	     information.  */
> +	case OPT_save_temps_:
>  	case OPT_save_temps:
>  	  save_temps = 1;
>  	  break;
> @@ -1407,6 +1408,10 @@ run_gcc (unsigned argc, char *argv[])
>  	  skip_debug = option->arg && !strcmp (option->arg, "0");
>  	  break;
>  
> +	case OPT_dumpdir:
> +	  incoming_dumppfx = dumppfx = option->arg;
> +	  break;
> +
>  	default:
>  	  break;
>  	}
> @@ -1439,32 +1444,50 @@ run_gcc (unsigned argc, char *argv[])
>        jobserver = 1;
>      }
>  
> -  if (linker_output)
> +  if (!dumppfx)
>      {
> -      char *output_dir, *base, *name;
> -      bool bit_bucket = strcmp (linker_output, HOST_BIT_BUCKET) == 0;
> -
> -      output_dir = xstrdup (linker_output);
> -      base = output_dir;
> -      for (name = base; *name; name++)
> -	if (IS_DIR_SEPARATOR (*name))
> -	  base = name + 1;
> -      *base = '\0';
> -
> -      linker_output = &linker_output[base - output_dir];
> -      if (*output_dir == '\0')
> -	{
> -	  static char current_dir[] = { '.', DIR_SEPARATOR, '\0' };
> -	  output_dir = current_dir;
> -	}
> -      if (!bit_bucket)
> +      if (!linker_output
> +	  || strcmp (linker_output, HOST_BIT_BUCKET) == 0)
> +	dumppfx = "a.";
> +      else
>  	{
> -	  obstack_ptr_grow (&argv_obstack, "-dumpdir");
> -	  obstack_ptr_grow (&argv_obstack, output_dir);
> +	  const char *obase = lbasename (linker_output), *temp;
> +
> +	  /* Strip the executable extension.  */
> +	  size_t blen = strlen (obase), xlen;
> +	  if ((temp = strrchr (obase + 1, '.'))
> +	      && (xlen = strlen (temp))
> +	      && (strcmp (temp, ".exe") == 0
> +#if HAVE_TARGET_EXECUTABLE_SUFFIX
> +		  || strcmp (temp, TARGET_EXECUTABLE_SUFFIX) == 0
> +#endif
> +		  || strcmp (obase, "a.out") == 0))
> +	    dumppfx = xstrndup (linker_output,
> +				obase - linker_output + blen - xlen + 1);
> +	  else
> +	    dumppfx = concat (linker_output, ".", NULL);
>  	}
> +    }
>  
> -      obstack_ptr_grow (&argv_obstack, "-dumpbase");
> +  /* If there's no directory component in the dumppfx, add one, so
> +     that, when it is used as -dumpbase, it overrides any occurrence
> +     of -dumpdir that might have been passed in.  */
> +  if (!dumppfx || lbasename (dumppfx) == dumppfx)
> +    dumppfx = concat (current_dir, dumppfx, NULL);
> +
> +  /* Make sure some -dumpdir is passed, so as to get predictable
> +     -dumpbase overriding semantics.  If we got an incoming -dumpdir
> +     argument, we'll pass it on, so don't bother with another one
> +     then.  */
> +  if (!incoming_dumppfx)
> +    {
> +      obstack_ptr_grow (&argv_obstack, "-dumpdir");
> +      /* An empty string would do, if only writeargv would write it
> +	 out in a way that would not be skipped by expandargv and
> +	 buildargv.  */
> +      obstack_ptr_grow (&argv_obstack, current_dir);
>      }
> +  obstack_ptr_grow (&argv_obstack, "-dumpbase");
>  
>    /* Remember at which point we can scrub args to re-use the commons.  */
>    new_head_argc = obstack_object_size (&argv_obstack) / sizeof (void *);
> @@ -1570,15 +1593,11 @@ cont1:
>  
>    if (lto_mode == LTO_MODE_LTO)
>      {
> -      if (linker_output)
> -	{
> -	  obstack_ptr_grow (&argv_obstack, linker_output);
> -	  flto_out = (char *) xmalloc (strlen (linker_output)
> -				       + sizeof (".lto.o") + 1);
> -	  strcpy (flto_out, linker_output);
> -	  strcat (flto_out, ".lto.o");
> -	}
> -      else
> +      /* -dumpbase argument for LTO.  */
> +      flto_out = concat (dumppfx, "lto.o", NULL);
> +      obstack_ptr_grow (&argv_obstack, flto_out);
> +
> +      if (!save_temps)
>  	flto_out = make_temp_file (".lto.o");
>        obstack_ptr_grow (&argv_obstack, "-o");
>        obstack_ptr_grow (&argv_obstack, flto_out);
> @@ -1586,47 +1605,17 @@ cont1:
>    else 
>      {
>        const char *list_option = "-fltrans-output-list=";
> -      size_t list_option_len = strlen (list_option);
> -      char *tmp;
>  
> -      if (linker_output)
> -	{
> -	  char *dumpbase = (char *) xmalloc (strlen (linker_output)
> -					     + sizeof (".wpa") + 1);
> -	  strcpy (dumpbase, linker_output);
> -	  strcat (dumpbase, ".wpa");
> -	  obstack_ptr_grow (&argv_obstack, dumpbase);
> -	}
> +      /* -dumpbase argument for WPA.  */
> +      char *dumpbase = concat (dumppfx, "wpa", NULL);
> +      obstack_ptr_grow (&argv_obstack, dumpbase);
>  
> -      if (linker_output && save_temps)
> -	{
> -	  ltrans_output_file = (char *) xmalloc (strlen (linker_output)
> -						 + sizeof (".ltrans.out") + 1);
> -	  strcpy (ltrans_output_file, linker_output);
> -	  strcat (ltrans_output_file, ".ltrans.out");
> -	}
> +      if (save_temps)
> +	ltrans_output_file = concat (dumppfx, "ltrans.out", NULL);
>        else
> -	{
> -	  char *prefix = NULL;
> -	  if (linker_output)
> -	    {
> -	      prefix = (char *) xmalloc (strlen (linker_output) + 2);
> -	      strcpy (prefix, linker_output);
> -	      strcat (prefix, ".");
> -	    }
> -
> -	  ltrans_output_file = make_temp_file_with_prefix (prefix,
> -							   ".ltrans.out");
> -	  free (prefix);
> -	}
> -      list_option_full = (char *) xmalloc (sizeof (char) *
> -		         (strlen (ltrans_output_file) + list_option_len + 1));
> -      tmp = list_option_full;
> -
> -      obstack_ptr_grow (&argv_obstack, tmp);
> -      strcpy (tmp, list_option);
> -      tmp += list_option_len;
> -      strcpy (tmp, ltrans_output_file);
> +	ltrans_output_file = make_temp_file (".ltrans.out");
> +      list_option_full = concat (list_option, ltrans_output_file, NULL);
> +      obstack_ptr_grow (&argv_obstack, list_option_full);
>  
>        if (jobserver)
>  	{
> @@ -1782,16 +1771,10 @@ cont:
>  	  output_name = XOBFINISH (&env_obstack, char *);
>  
>  	  /* Adjust the dumpbase if the linker output file was seen.  */
> -	  if (linker_output)
> -	    {
> -	      char *dumpbase
> -		  = (char *) xmalloc (strlen (linker_output)
> -				      + sizeof (DUMPBASE_SUFFIX) + 1);
> -	      snprintf (dumpbase,
> -			strlen (linker_output) + sizeof (DUMPBASE_SUFFIX),
> -			"%s.ltrans%u", linker_output, i);
> -	      argv_ptr[0] = dumpbase;
> -	    }
> +	  int dumpbase_len = (strlen (dumppfx) + sizeof (DUMPBASE_SUFFIX));
> +	  char *dumpbase = (char *) xmalloc (dumpbase_len + 1);
> +	  snprintf (dumpbase, dumpbase_len, "%sltrans%u.ltrans", dumppfx, i);
> +	  argv_ptr[0] = dumpbase;
>  
>  	  argv_ptr[1] = "-fltrans";
>  	  argv_ptr[2] = "-o";
> diff --git a/gcc/opts.c b/gcc/opts.c
> index fa4804c..5b29b98 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/testsuite/gcc.misc-tests/outputs-0.c b/gcc/testsuite/gcc.misc-tests/outputs-0.c
> new file mode 100644
> index 00000000..ca2ac4a
> --- /dev/null
> +++ b/gcc/testsuite/gcc.misc-tests/outputs-0.c
> @@ -0,0 +1 @@
> +int main () {}
> diff --git a/gcc/testsuite/gcc.misc-tests/outputs-1.c b/gcc/testsuite/gcc.misc-tests/outputs-1.c
> new file mode 100644
> index 00000000..35f19cf
> --- /dev/null
> +++ b/gcc/testsuite/gcc.misc-tests/outputs-1.c
> @@ -0,0 +1,4 @@
> +extern void f();
> +int main() {
> +  f();
> +}
> diff --git a/gcc/testsuite/gcc.misc-tests/outputs-2.c b/gcc/testsuite/gcc.misc-tests/outputs-2.c
> new file mode 100644
> index 00000000..109733d
> --- /dev/null
> +++ b/gcc/testsuite/gcc.misc-tests/outputs-2.c
> @@ -0,0 +1,2 @@
> +void f() {
> +}
> diff --git a/gcc/testsuite/gcc.misc-tests/outputs.exp b/gcc/testsuite/gcc.misc-tests/outputs.exp
> new file mode 100644
> index 00000000..a37e978
> --- /dev/null
> +++ b/gcc/testsuite/gcc.misc-tests/outputs.exp
> @@ -0,0 +1,655 @@
> +# Copyright (C) 2005-2020 Free Software Foundation, Inc.
> +
> +# 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 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
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with GCC; see the file COPYING3.  If not see
> +# <http://www.gnu.org/licenses/>.
> +
> +# This file contains a set of test that check that options intended to
> +# control the location and name of GCC outputs behave as expected.
> +
> +load_lib gcc-defs.exp
> +
> +set b "outputs"
> +
> +# These tests don't run runtest_file_p consistently if it
> +# doesn't return the same values, so disable parallelization
> +# of this *.exp file.  The first parallel runtest to reach
> +# this will run all the tests serially.
> +if ![gcc_parallel_test_run_p $b] {
> +    return
> +}
> +gcc_parallel_test_enable 0
> +
> +# For the test named TEST, run the compiler with SOURCES and OPTS, and
> +# look in DIRS for OUTPUTS.  SOURCES is a list of suffixes for source
> +# files starting with $b in $srcdir/$subdir, OPTS is a string with
> +# options to be passed to the compiler, DIRS and OUTPUTS are lists.
> +# DIRS is a list of output directories, children before parent, and
> +# for each element of DIRS, there should be a corresponding sublist in
> +# OUTPUTS.  If OUTPUTS has an additional trailing sublist, that's the
> +# output list for the current directory.  Each element of the sublists
> +# in OUTPUT is a file name or glob pattern to be checked for; a name
> +# starting with a dash or a period is taken as a suffix for $b; with a
> +# double dash, or a dash followed by a period, the first dash is
> +# replaced with $b-$b; names starting with "a--" or "a-." have "$b"
> +# inserted after the first dash.  The glob pattern may expand to more
> +# than one file, but then the test will pass when there any number of
> +# matches.  So, it's safe to use for a.{out,exe}, but .{i,s,o} and
> +# .[iso] will pass even if only the .o is present.
> +proc outest { test sources opts dirs outputs } {
> +    global b
> +    global srcdir
> +    global subdir
> +    set src {}
> +    foreach s $sources {
> +	lappend src $srcdir/$subdir/$b$s
> +    }
> +    foreach f [glob -nocomplain -path $b -- *] {
> +	file delete $f
> +    }
> +    foreach d $dirs {
> +	file mkdir $d
> +	foreach f [glob -nocomplain -path $d -- *] {
> +	    file delete $d$f
> +	}
> +    }
> +    set options ""
> +    foreach opt [split $opts " "] {
> +	set options "$options additional_flags=$opt"
> +    }
> +    set gcc_output [gcc_target_compile $src "" none "$options"]
> +    set outs {}
> +    foreach d $dirs olist $outputs {
> +	foreach og $olist {
> +	    if { [string index $og 0] == "-" } then {
> +		if { [string index $og 1] == "-" || \
> +			 [string index $og 1] == "." } then {
> +		    set o "$b-$b[string range $og 1 end]"
> +		} else {
> +		    set o "$b$og"
> +		}
> +	    } elseif { [string index $og 0] == "." } then {
> +		set o "$b$og"
> +	    } elseif { [string range $og 0 2] == "a--" } then {
> +		set o "a-$b-[string range $og 3 end]"
> +	    } elseif { [string range $og 0 2] == "a-." } then {
> +		set o "a-$b.[string range $og 3 end]"
> +	    } else {
> +		set o "$og"
> +	    }
> +	    if { [file exists $d$o] } then {
> +		pass "$test: $d$o"
> +		file delete $d$o
> +	    } else {
> +	        set ogl [glob -nocomplain -path $d -- $o]
> +		if { $ogl != {} } {
> +		    pass "$test: $d$o"
> +		    file delete $ogl
> +		} else {
> +		    fail "$test: $d$o"
> +		}
> +	    }
> +	}
> +	foreach ol [glob -nocomplain -path $d$b -- *] {
> +	    lappend outs $ol
> +	}
> +	foreach ol [glob -nocomplain -path $d -- a{-,.}*] {
> +	    lappend outs $ol
> +	}
> +    }
> +
> +    foreach f $outs {
> +	file delete $f
> +    }
> +    foreach d $dirs {
> +	file delete -force $d
> +    }
> +
> +    if { [llength $outs] == 0 } then {
> +	pass "$test: extra"
> +    } else {
> +	fail "$test: extra $outs"
> +    }
> +
> +    if { [string equal "$gcc_output" ""] } then {
> +	pass "$test: std out"
> +    } else {
> +	fail "$test: std out $gcc_output"
> +    }
> +
> +}
> +
> +set sing {-0.c}
> +set mult {-1.c -2.c}
> +
> +# Driver-chosen outputs.
> +outest "$b asm default 1" $sing "-S" {} {{-0.s}}
> +outest "$b asm default 2" $mult "-S" {} {{-1.s -2.s}}
> +
> +outest "$b obj default 1" $sing "-c" {} {{-0.o}}
> +outest "$b obj default 2" $mult "-c" {} {{-1.o -2.o}}
> +
> +outest "$b exe default 1" $sing "" {} {{a.{out,exe}}}
> +outest "$b exe default 2" $mult "" {} {{a.{out,exe}}}
> +
> +# Driver-chosen aux outputs.
> +outest "$b asm savetmp 1" $sing "-S -save-temps" {} {{-0.i -0.s}}
> +outest "$b asm savetmp 2" $mult "-S -save-temps" {} {{-1.i -1.s -2.i -2.s}}
> +outest "$b obj savetmp unnamed1" $sing "-c -save-temps" {} {{-0.i -0.s -0.o}}
> +outest "$b obj savetmp unnamed2" $mult "-c -save-temps" {} {{-1.i -1.s -1.o -2.i -2.s -2.o}}
> +
> +# Aux outputs computed within the driver, based on output name (and
> +# input).
> +outest "$b cpp savetmp named0" $sing "-E -o $b-0.i -save-temps" {} {{-0.i}}
> +outest "$b asm savetmp named0" $sing "-S -o $b-0.s -save-temps" {} {{-0.i -0.s}}
> +outest "$b obj savetmp named0" $sing "-c -o $b-0.o -save-temps" {} {{-0.i -0.s -0.o}}
> +outest "$b cpp savetmp namedb" $sing "-E -o $b.i -save-temps" {} {{.i}}
> +outest "$b asm savetmp namedb" $sing "-S -o $b.s -save-temps" {} {{.i .s}}
> +outest "$b obj savetmp namedb" $sing "-c -o $b.o -save-temps" {} {{.i .s .o}}
> +
> +# When linking, the executable name gets prepended to aux output
> +# basenames, except when executable and single input share the same
> +# basename.
> +outest "$b exe savetmp unnamed1" $sing "-save-temps" {} {{a--0.i a--0.s a--0.o a.{out,exe}}}
> +outest "$b exe savetmp unnamed2" $mult "-save-temps" {} {{a--1.i a--1.s a--1.o a--2.i a--2.s a--2.o a.{out,exe}}}
> +outest "$b exe savetmp named0" $sing "-o $b-0.exe -save-temps" {} {{-0.i -0.s -0.o -0.exe}}
> +outest "$b exe savetmp namedb" $sing "-o $b.exe -save-temps" {} {{--0.i --0.s --0.o .exe}}
> +outest "$b exe savetmp named2" $mult "-o $b.exe -save-temps" {} {{--1.i --1.s --1.o --2.i --2.s --2.o .exe}}
> +
> +# Setting the main output to a dir selects it as the default aux&dump
> +# location.
> +outest "$b cpp savetmp namedir0" $sing "-E -o o/$b-0.i -save-temps" {o/} {{-0.i} {}}
> +outest "$b asm savetmp namedir0" $sing "-S -o o/$b-0.s -save-temps" {o/} {{-0.i -0.s} {}}
> +outest "$b obj savetmp namedir0" $sing "-c -o o/$b-0.o -save-temps" {o/} {{-0.i -0.s -0.o} {}}
> +outest "$b cpp savetmp namedir" $sing "-E -o o/$b.i -save-temps" {o/} {{.i} {}}
> +outest "$b asm savetmp namedir" $sing "-S -o o/$b.s -save-temps" {o/} {{.i .s} {}}
> +outest "$b obj savetmp namedir" $sing "-c -o o/$b.o -save-temps" {o/} {{.i .s .o} {}}
> +outest "$b exe savetmp namedir0" $sing "-o o/$b-0.exe -save-temps" {o/} {{-0.i -0.s -0.o -0.exe} {}}
> +outest "$b exe savetmp namedirb" $sing "-o o/$b.exe -save-temps" {o/} {{--0.i --0.s --0.o .exe} {}}
> +outest "$b exe savetmp namedir2" $mult "-o o/$b.exe -save-temps" {o/} {{--1.i --1.s --1.o --2.i --2.s --2.o .exe} {}}
> +
> +# -save-temps=cwd overrides the aux output location to the current dir.
> +outest "$b obj savecwd unnamed1" $sing "-c -save-temps=cwd" {} {{-0.i -0.s -0.o}}
> +outest "$b obj savecwd unnamed2" $mult "-c -save-temps=cwd" {} {{-1.i -1.s -1.o -2.i -2.s -2.o}}
> +outest "$b cpp savecwd named0" $sing "-E -o $b-0.i -save-temps=cwd" {} {{-0.i}}
> +outest "$b asm savecwd named0" $sing "-S -o $b-0.s -save-temps=cwd" {} {{-0.i -0.s}}
> +outest "$b obj savecwd named0" $sing "-c -o $b-0.o -save-temps=cwd" {} {{-0.i -0.s -0.o}}
> +outest "$b cpp savecwd namedb" $sing "-E -o $b.i -save-temps=cwd" {} {{.i}}
> +outest "$b asm savecwd namedb" $sing "-S -o $b.s -save-temps=cwd" {} {{.i .s}}
> +outest "$b obj savecwd namedb" $sing "-c -o $b.o -save-temps=cwd" {} {{.i .s .o}}
> +outest "$b exe savecwd unnamed1" $sing "-save-temps=cwd" {} {{a--0.i a--0.s a--0.o a.{out,exe}}}
> +outest "$b exe savecwd unnamed2" $mult "-save-temps=cwd" {} {{a--1.i a--1.s a--1.o a--2.i a--2.s a--2.o a.{out,exe}}}
> +outest "$b exe savecwd named0" $sing "-o $b-0.exe -save-temps=cwd" {} {{-0.i -0.s -0.o -0.exe}}
> +outest "$b exe savecwd namedb" $sing "-o $b.exe -save-temps=cwd" {} {{--0.i --0.s --0.o .exe}}
> +outest "$b exe savecwd named2" $mult "-o $b.exe -save-temps=cwd" {} {{--1.i --1.s --1.o --2.i --2.s --2.o .exe}}
> +
> +outest "$b cpp savecwd namedir0" $sing "-E -o o/$b-0.i -save-temps=cwd" {o/} {{-0.i} {}}
> +outest "$b asm savecwd namedir0" $sing "-S -o o/$b-0.s -save-temps=cwd" {o/} {{-0.s} {-0.i}}
> +outest "$b obj savecwd namedir0" $sing "-c -o o/$b-0.o -save-temps=cwd" {o/} {{-0.o} {-0.i -0.s}}
> +outest "$b cpp savecwd namedir" $sing "-E -o o/$b.i -save-temps=cwd" {o/} {{.i} {}}
> +outest "$b asm savecwd namedir" $sing "-S -o o/$b.s -save-temps=cwd" {o/} {{.s} {.i}}
> +outest "$b obj savecwd namedir" $sing "-c -o o/$b.o -save-temps=cwd" {o/} {{.o} {.i .s}}
> +outest "$b exe savecwd namedir0" $sing "-o o/$b-0.exe -save-temps=cwd" {o/} {{-0.exe} {-0.i -0.s -0.o}}
> +outest "$b exe savecwd namedirb" $sing "-o o/$b.exe -save-temps=cwd" {o/} {{.exe} {--0.i --0.s --0.o}}
> +outest "$b exe savecwd namedir2" $mult "-o o/$b.exe -save-temps=cwd" {o/} {{.exe} {--1.i --1.s --1.o --2.i --2.s --2.o}}
> +
> +# -save-temps=obj overrides the aux output location to that of the
> +# main output
> +outest "$b obj saveobj unnamed1" $sing "-c -save-temps=obj" {} {{-0.i -0.s -0.o}}
> +outest "$b obj saveobj unnamed2" $mult "-c -save-temps=obj" {} {{-1.i -1.s -1.o -2.i -2.s -2.o}}
> +outest "$b cpp saveobj named0" $sing "-E -o $b-0.i -save-temps=obj" {} {{-0.i}}
> +outest "$b asm saveobj named0" $sing "-S -o $b-0.s -save-temps=obj" {} {{-0.i -0.s}}
> +outest "$b obj saveobj named0" $sing "-c -o $b-0.o -save-temps=obj" {} {{-0.i -0.s -0.o}}
> +outest "$b cpp saveobj namedb" $sing "-E -o $b.i -save-temps=obj" {} {{.i}}
> +outest "$b asm saveobj namedb" $sing "-S -o $b.s -save-temps=obj" {} {{.i .s}}
> +outest "$b obj saveobj namedb" $sing "-c -o $b.o -save-temps=obj" {} {{.i .s .o}}
> +outest "$b exe saveobj unnamed1" $sing "-save-temps=obj" {} {{a--0.i a--0.s a--0.o a.{out,exe}}}
> +outest "$b exe saveobj unnamed2" $mult "-save-temps=obj" {} {{a--1.i a--1.s a--1.o a--2.i a--2.s a--2.o a.{out,exe}}}
> +outest "$b exe saveobj named0" $sing "-o $b-0.exe -save-temps=obj" {} {{-0.i -0.s -0.o -0.exe}}
> +outest "$b exe saveobj namedb" $sing "-o $b.exe -save-temps=obj" {} {{--0.i --0.s --0.o .exe}}
> +outest "$b exe saveobj named2" $mult "-o $b.exe -save-temps=obj" {} {{--1.i --1.s --1.o --2.i --2.s --2.o .exe}}
> +
> +outest "$b cpp saveobj namedir0" $sing "-E -o o/$b-0.i -save-temps=obj" {o/} {{-0.i} {}}
> +outest "$b asm saveobj namedir0" $sing "-S -o o/$b-0.s -save-temps=obj" {o/} {{-0.i -0.s} {}}
> +outest "$b obj saveobj namedir0" $sing "-c -o o/$b-0.o -save-temps=obj" {o/} {{-0.i -0.s -0.o} {}}
> +outest "$b cpp saveobj namedir" $sing "-E -o o/$b.i -save-temps=obj" {o/} {{.i} {}}
> +outest "$b asm saveobj namedir" $sing "-S -o o/$b.s -save-temps=obj" {o/} {{.i .s} {}}
> +outest "$b obj saveobj namedir" $sing "-c -o o/$b.o -save-temps=obj" {o/} {{.i .s .o} {}}
> +outest "$b exe saveobj namedir0" $sing "-o o/$b-0.exe -save-temps=obj" {o/} {{-0.i -0.s -0.o -0.exe} {}}
> +outest "$b exe saveobj namedirb" $sing "-o o/$b.exe -save-temps=obj" {o/} {{--0.i --0.s --0.o .exe} {}}
> +outest "$b exe saveobj namedir2" $mult "-o o/$b.exe -save-temps=obj" {o/} {{--1.i --1.s --1.o --2.i --2.s --2.o .exe} {}}
> +
> +# Check -dumpdir overriding by -save-temps=*, and -save-temps
> +# non-overriding, with one catch: the presence of a given dumpdir,
> +# even if ultimately overridden, still disables the prepending of the
> +# executable basename to the aux&dump output basenames (or rather the
> +# appending of the executable basename to the dumpdir).
> +outest "$b exe sobjovr namedir0" $sing "-o o/$b-0.exe -dumpdir no/ -save-temps=obj -save-temps" {o/} {{-0.i -0.s -0.o -0.exe} {}}
> +outest "$b exe sobjovr namedirb" $sing "-o o/$b.exe -dumpdir no/ -save-temps=obj -save-temps" {o/} {{-0.i -0.s -0.o .exe} {}}
> +outest "$b exe sobjovr namedir2" $mult "-o o/$b.exe -dumpdir no/ -save-temps=obj -save-temps" {o/} {{-1.i -1.s -1.o -2.i -2.s -2.o .exe} {}}
> +outest "$b exe scwdovr namedir0" $sing "-o o/$b-0.exe -dumpdir o/ -save-temps=cwd -save-temps" {o/} {{-0.exe} {-0.i -0.s -0.o}}
> +outest "$b exe scwdovr namedirb" $sing "-o o/$b.exe -dumpdir o/ -save-temps=cwd -save-temps" {o/} {{.exe} {-0.i -0.s -0.o}}
> +outest "$b exe scwdovr namedir2" $mult "-o o/$b.exe -dumpdir o/ -save-temps=cwd -save-temps" {o/} {{.exe} {-1.i -1.s -1.o -2.i -2.s -2.o}}
> +outest "$b exe ddstovr namedir0" $sing "-o $b-0.exe -dumpdir o/ -save-temps" {o/} {{-0.i -0.s -0.o} {-0.exe}}
> +outest "$b exe ddstovr namedirb" $sing "-o $b.exe -dumpdir o/ -save-temps" {o/} {{-0.i -0.s -0.o} {.exe}}
> +outest "$b exe ddstovr namedir2" $mult "-o $b.exe -dumpdir o/ -save-temps" {o/} {{-1.i -1.s -1.o -2.i -2.s -2.o} {.exe}}
> +
> +# Check -dumpdir prevailing over -save-temps*.  Even though -dumpdir
> +# overrides the -save-temps=* directory selection, -save-temps remains
> +# enabled.
> +outest "$b exe soddovr namedir0" $sing "-o o/$b-0.exe -save-temps=obj -dumpdir ./" {o/} {{-0.exe} {-0.i -0.s -0.o}}
> +outest "$b exe soddovr namedirb" $sing "-o o/$b.exe -save-temps=obj -dumpdir ./" {o/} {{.exe} {-0.i -0.s -0.o}}
> +outest "$b exe soddovr namedir2" $mult "-o o/$b.exe -save-temps=obj -dumpdir ./" {o/} {{.exe} {-1.i -1.s -1.o -2.i -2.s -2.o}}
> +outest "$b exe scddovr namedir0" $sing "-o o/$b-0.exe -save-temps=cwd -dumpdir o/" {o/} {{-0.i -0.s -0.o -0.exe} {}}
> +outest "$b exe scddovr namedirb" $sing "-o o/$b.exe -save-temps=cwd -dumpdir o/" {o/} {{-0.i -0.s -0.o .exe} {}}
> +outest "$b exe scddovr namedir2" $mult "-o o/$b.exe -save-temps=cwd -dumpdir o/" {o/} {{-1.i -1.s -1.o -2.i -2.s -2.o .exe} {}}
> +outest "$b exe ddstovr namedir0" $sing "-o $b-0.exe -save-temps -dumpdir o/" {o/} {{-0.i -0.s -0.o} {-0.exe}}
> +outest "$b exe ddstovr namedirb" $sing "-o $b.exe -save-temps -dumpdir o/" {o/} {{-0.i -0.s -0.o} {.exe}}
> +outest "$b exe ddstovr namedir2" $mult "-o $b.exe -save-temps -dumpdir o/" {o/} {{-1.i -1.s -1.o -2.i -2.s -2.o} {.exe}}
> +
> +
> +# Compiler- and driver-generated aux and dump outputs.
> +# -fdump-rtl-final creates a .c.???r.final dump in the compiler.
> +# -fstack-usage creates a .su aux output in the compiler.
> +# -gsplit-dwarf extracts a .dwo aux output from the .o in the driver.
> +outest "$b asm auxdump 1" $sing "-S -g -fdump-rtl-final -fstack-usage -gsplit-dwarf" {} {{-0.c.???r.final -0.su -0.s}}
> +outest "$b asm auxdump 2" $mult "-S -g -fdump-rtl-final -fstack-usage -gsplit-dwarf" {} {{-1.c.???r.final -1.su -1.s -2.c.???r.final -2.su -2.s}}
> +outest "$b obj auxdump unnamed1" $sing "-c -g -fdump-rtl-final -fstack-usage -gsplit-dwarf" {} {{-0.c.???r.final -0.su -0.dwo -0.o}}
> +outest "$b obj auxdump unnamed2" $mult "-c -g -fdump-rtl-final -fstack-usage -gsplit-dwarf" {} {{-1.c.???r.final -1.su -1.dwo -1.o -2.c.???r.final -2.su -2.dwo -2.o}}
> +
> +outest "$b cpp auxdump named0" $sing "-E -o $b-0.i -g -fdump-rtl-final -fstack-usage -gsplit-dwarf" {} {{-0.i}}
> +outest "$b asm auxdump named0" $sing "-S -o $b-0.s -g -fdump-rtl-final -fstack-usage -gsplit-dwarf" {} {{-0.c.???r.final -0.su -0.s}}
> +outest "$b obj auxdump named0" $sing "-c -o $b-0.o -g -fdump-rtl-final -fstack-usage -gsplit-dwarf" {} {{-0.c.???r.final -0.su -0.dwo -0.o}}
> +outest "$b cpp auxdump namedb" $sing "-E -o $b.i -g -fdump-rtl-final -fstack-usage -gsplit-dwarf" {} {{.i}}
> +outest "$b asm auxdump namedb" $sing "-S -o $b.s -g -fdump-rtl-final -fstack-usage -gsplit-dwarf" {} {{.c.???r.final .su .s}}
> +outest "$b obj auxdump namedb" $sing "-c -o $b.o -g -fdump-rtl-final -fstack-usage -gsplit-dwarf" {} {{.c.???r.final .su .dwo .o}}
> +
> +outest "$b exe auxdump unnamed1" $sing "-g -fdump-rtl-final -fstack-usage -gsplit-dwarf" {} {{a--0.c.???r.final a--0.su a--0.dwo a.{out,exe}}}
> +outest "$b exe auxdump unnamed2" $mult "-g -fdump-rtl-final -fstack-usage -gsplit-dwarf" {} {{a--1.c.???r.final a--1.su a--1.dwo a--2.c.???r.final a--2.su a--2.dwo a.{out,exe}}}
> +outest "$b exe auxdump named0" $sing "-o $b-0.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf" {} {{-0.c.???r.final -0.su -0.dwo -0.exe}}
> +outest "$b exe auxdump namedb" $sing "-o $b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf" {} {{--0.c.???r.final --0.su --0.dwo .exe}}
> +outest "$b exe auxdump named2" $mult "-o $b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf" {} {{--1.c.???r.final --1.su --1.dwo --2.c.???r.final --2.su --2.dwo .exe}}
> +
> +outest "$b cpp auxdump namedir0" $sing "-E -o o/$b-0.i -g -fdump-rtl-final -fstack-usage -gsplit-dwarf" {o/} {{-0.i} {}}
> +outest "$b asm auxdump namedir0" $sing "-S -o o/$b-0.s -g -fdump-rtl-final -fstack-usage -gsplit-dwarf" {o/} {{-0.c.???r.final -0.su -0.s} {}}
> +outest "$b obj auxdump namedir0" $sing "-c -o o/$b-0.o -g -fdump-rtl-final -fstack-usage -gsplit-dwarf" {o/} {{-0.c.???r.final -0.su -0.dwo -0.o} {}}
> +outest "$b cpp auxdump namedir" $sing "-E -o o/$b.i -g -fdump-rtl-final -fstack-usage -gsplit-dwarf" {o/} {{.i} {}}
> +outest "$b asm auxdump namedir" $sing "-S -o o/$b.s -g -fdump-rtl-final -fstack-usage -gsplit-dwarf" {o/} {{.c.???r.final .su .s} {}}
> +outest "$b obj auxdump namedir" $sing "-c -o o/$b.o -g -fdump-rtl-final -fstack-usage -gsplit-dwarf" {o/} {{.c.???r.final .su .dwo .o} {}}
> +outest "$b exe auxdump namedir0" $sing "-o o/$b-0.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf" {o/} {{-0.c.???r.final -0.su -0.dwo -0.exe} {}}
> +outest "$b exe auxdump namedirb" $sing "-o o/$b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf" {o/} {{--0.c.???r.final --0.su --0.dwo .exe} {}}
> +outest "$b exe auxdump namedir2" $mult "-o o/$b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf" {o/} {{--1.c.???r.final --1.su --1.dwo --2.c.???r.final --2.su --2.dwo .exe} {}}
> +
> +# Check that -save-temps doesn't break compiler aux or dumps as it
> +# changes temp file names.
> +outest "$b asm auxdmps 1" $sing "-S -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -save-temps" {} {{-0.i -0.c.???r.final -0.su -0.s}}
> +outest "$b asm auxdmps 2" $mult "-S -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -save-temps" {} {{-1.i -1.c.???r.final -1.su -1.s -2.i -2.c.???r.final -2.su -2.s}}
> +outest "$b obj auxdmps unnamed1" $sing "-c -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -save-temps" {} {{-0.i -0.c.???r.final -0.su -0.s -0.dwo -0.o}}
> +outest "$b obj auxdmps unnamed2" $mult "-c -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -save-temps" {} {{-1.i -1.c.???r.final -1.su -1.s -1.dwo -1.o -2.i -2.c.???r.final -2.su -2.s -2.dwo -2.o}}
> +
> +outest "$b cpp auxdmps named0" $sing "-E -o $b-0.i -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -save-temps" {} {{-0.i}}
> +outest "$b asm auxdmps named0" $sing "-S -o $b-0.s -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -save-temps" {} {{-0.i -0.c.???r.final -0.su -0.s}}
> +outest "$b obj auxdmps named0" $sing "-c -o $b-0.o -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -save-temps" {} {{-0.i -0.c.???r.final -0.su -0.s -0.dwo -0.o}}
> +outest "$b cpp auxdmps namedb" $sing "-E -o $b.i -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -save-temps" {} {{.i}}
> +outest "$b asm auxdmps namedb" $sing "-S -o $b.s -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -save-temps" {} {{.i .c.???r.final .su .s}}
> +outest "$b obj auxdmps namedb" $sing "-c -o $b.o -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -save-temps" {} {{.i .c.???r.final .su .s .dwo .o}}
> +
> +outest "$b exe auxdmps unnamed1" $sing "-g -fdump-rtl-final -fstack-usage -gsplit-dwarf -save-temps" {} {{a--0.i a--0.c.???r.final a--0.su a--0.s a--0.dwo a--0.o a.{out,exe}}}
> +outest "$b exe auxdmps unnamed2" $mult "-g -fdump-rtl-final -fstack-usage -gsplit-dwarf -save-temps" {} {{a--1.i a--1.c.???r.final a--1.su a--1.s a--1.dwo a--1.o a--2.i a--2.c.???r.final a--2.su a--2.s a--2.dwo a--2.o a.{out,exe}}}
> +outest "$b exe auxdmps named0" $sing "-o $b-0.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -save-temps" {} {{-0.i -0.c.???r.final -0.su -0.s -0.dwo -0.o -0.exe}}
> +outest "$b exe auxdmps namedb" $sing "-o $b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -save-temps" {} {{--0.i --0.c.???r.final --0.su --0.s --0.dwo --0.o .exe}}
> +outest "$b exe auxdmps named2" $mult "-o $b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -save-temps" {} {{--1.i --1.c.???r.final --1.su --1.s --1.dwo --1.o --2.i --2.c.???r.final --2.su --2.s --2.dwo --2.o .exe}}
> +
> +outest "$b cpp auxdmps namedir0" $sing "-E -o o/$b-0.i -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -save-temps" {o/} {{-0.i} {}}
> +outest "$b asm auxdmps namedir0" $sing "-S -o o/$b-0.s -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -save-temps" {o/} {{-0.i -0.c.???r.final -0.su -0.s} {}}
> +outest "$b obj auxdmps namedir0" $sing "-c -o o/$b-0.o -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -save-temps" {o/} {{-0.i -0.c.???r.final -0.su -0.s -0.dwo -0.o} {}}
> +outest "$b cpp auxdmps namedir" $sing "-E -o o/$b.i -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -save-temps" {o/} {{.i} {}}
> +outest "$b asm auxdmps namedir" $sing "-S -o o/$b.s -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -save-temps" {o/} {{.i .c.???r.final .su .s} {}}
> +outest "$b obj auxdmps namedir" $sing "-c -o o/$b.o -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -save-temps" {o/} {{.i .c.???r.final .su .s .dwo .o} {}}
> +outest "$b exe auxdmps namedir0" $sing "-o o/$b-0.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -save-temps" {o/} {{-0.i -0.c.???r.final -0.su -0.s -0.dwo -0.o -0.exe} {}}
> +outest "$b exe auxdmps namedirb" $sing "-o o/$b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -save-temps" {o/} {{--0.i --0.c.???r.final --0.su --0.s --0.dwo --0.o .exe} {}}
> +outest "$b exe auxdmps namedir2" $mult "-o o/$b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -save-temps" {o/} {{--1.i --1.c.???r.final --1.su --1.s --1.dwo --1.o --2.i --2.c.???r.final --2.su --2.s --2.dwo --2.o .exe} {}}
> +
> +
> +# Check that dumpdir changes the location of non-primary outputs
> +outest "$b asm dumpdir 1" $sing "-S -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/" {od/} {{-0.c.???r.final -0.su} {-0.s}}
> +outest "$b asm dumpdir 2" $mult "-S -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/" {od/} {{-1.c.???r.final -1.su -2.c.???r.final -2.su} {-1.s -2.s}}
> +outest "$b obj dumpdir unnamed1" $sing "-c -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/" {od/} {{-0.c.???r.final -0.su -0.dwo} {-0.o}}
> +outest "$b obj dumpdir unnamed2" $mult "-c -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/" {od/} {{-1.c.???r.final -1.su -1.dwo -2.c.???r.final -2.su -2.dwo} {-1.o -2.o}}
> +
> +outest "$b cpp dumpdir named0" $sing "-E -o $b-0.i -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/" {od/} {{} {-0.i}}
> +outest "$b asm dumpdir named0" $sing "-S -o $b-0.s -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/" {od/} {{-0.c.???r.final -0.su} {-0.s}}
> +outest "$b obj dumpdir named0" $sing "-c -o $b-0.o -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/" {od/} {{-0.c.???r.final -0.su -0.dwo} {-0.o}}
> +outest "$b cpp dumpdir namedb" $sing "-E -o $b.i -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/" {od/} {{} {.i}}
> +outest "$b asm dumpdir namedb" $sing "-S -o $b.s -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/" {od/} {{.c.???r.final .su} {.s}}
> +outest "$b obj dumpdir namedb" $sing "-c -o $b.o -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/" {od/} {{.c.???r.final .su .dwo} {.o}}
> +
> +outest "$b exe dumpdir unnamed1" $sing "-g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/a-" {od/} {{a--0.c.???r.final a--0.su a--0.dwo} {a.{out,exe}}}
> +outest "$b exe dumpdir unnamed2" $mult "-g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/a-" {od/} {{a--1.c.???r.final a--1.su a--1.dwo a--2.c.???r.final a--2.su a--2.dwo} {a.{out,exe}}}
> +outest "$b exe dumpdir named0" $sing "-o $b-0.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/" {od/} {{-0.c.???r.final -0.su -0.dwo} {-0.exe}}
> +outest "$b exe dumpdir namedb" $sing "-o $b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/" {od/} {{-0.c.???r.final -0.su -0.dwo} {.exe}}
> +outest "$b exe dumpdir named2" $mult "-o $b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/" {od/} {{-1.c.???r.final -1.su -1.dwo -2.c.???r.final -2.su -2.dwo} {.exe}}
> +outest "$b exe dumpdira namedb" $sing "-o $b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/a-" {od/} {{a--0.c.???r.final a--0.su a--0.dwo} {.exe}}
> +outest "$b exe dumpdira named2" $mult "-o $b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/a-" {od/} {{a--1.c.???r.final a--1.su a--1.dwo a--2.c.???r.final a--2.su a--2.dwo} {.exe}}
> +outest "$b exe dumpdirb namedb" $sing "-o $b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/$b-" {od/} {{--0.c.???r.final --0.su --0.dwo} {.exe}}
> +outest "$b exe dumpdirb named2" $mult "-o $b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/$b-" {od/} {{--1.c.???r.final --1.su --1.dwo --2.c.???r.final --2.su --2.dwo} {.exe}}
> +
> +outest "$b cpp dumpdir namedir0" $sing "-E -o o/$b-0.i -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/" {od/ o/} {{} {-0.i} {}}
> +outest "$b asm dumpdir namedir0" $sing "-S -o o/$b-0.s -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/" {od/ o/} {{-0.c.???r.final -0.su} {-0.s} {}}
> +outest "$b obj dumpdir namedir0" $sing "-c -o o/$b-0.o -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/" {od/ o/} {{-0.c.???r.final -0.su -0.dwo} {-0.o} {}}
> +outest "$b cpp dumpdir namedir" $sing "-E -o o/$b.i -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/" {od/ o/} {{} {.i} {}}
> +outest "$b asm dumpdir namedir" $sing "-S -o o/$b.s -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/" {od/ o/} {{.c.???r.final .su} {.s} {}}
> +outest "$b obj dumpdir namedir" $sing "-c -o o/$b.o -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/" {od/ o/} {{.c.???r.final .su .dwo} {.o} {}}
> +outest "$b exe dumpdir namedir0" $sing "-o o/$b-0.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/" {od/ o/} {{-0.c.???r.final -0.su -0.dwo} {-0.exe} {}}
> +outest "$b exe dumpdir namedirb" $sing "-o o/$b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/" {od/ o/} {{-0.c.???r.final -0.su -0.dwo} {.exe} {}}
> +outest "$b exe dumpdir namedir2" $mult "-o o/$b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/" {od/ o/} {{-1.c.???r.final -1.su -1.dwo -2.c.???r.final -2.su -2.dwo} {.exe} {}}
> +outest "$b exe dumpdira namedirb" $sing "-o o/$b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/a-" {od/ o/} {{a--0.c.???r.final a--0.su a--0.dwo} {.exe} {}}
> +outest "$b exe dumpdira namedir2" $mult "-o o/$b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/a-" {od/ o/} {{a--1.c.???r.final a--1.su a--1.dwo a--2.c.???r.final a--2.su a--2.dwo} {.exe} {}}
> +outest "$b exe dumpdirb namedirb" $sing "-o o/$b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/$b-" {od/ o/} {{--0.c.???r.final --0.su --0.dwo} {.exe} {}}
> +outest "$b exe dumpdirb namedir2" $mult "-o o/$b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/$b-" {od/ o/} {{--1.c.???r.final --1.su --1.dwo --2.c.???r.final --2.su --2.dwo} {.exe} {}}
> +
> +# Check that a -dumpbase with a dir component disregards the -dumpdir
> +# prefix.  Also, start testing -dumpbase-ext to distinguish between
> +# aux and dump files: only the latter retain the named extension.
> +# -dumpbase-ext, if absent or used in combination with -dumpbase for
> +# an executable name, defaults to the extension of the source file.
> +# The specified dumpbase is combined with the dumpdir prefix when
> +# processing more than one input (we couldn't use the same dumpbase
> +# for them all), or when linking (the specified dumpbase is then used
> +# as prefix instead of the linker output, and a new dumpbase is
> +# computed per source).
> +outest "$b asm dbsovrdd 1" $sing "-S -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir ./ -dumpbase od/$b" {od/} {{.???r.final .su} {-0.s}}
> +outest "$b asm dbsovrddx 1" $sing "-S -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir ./ -dumpbase od/$b.c -dumpbase-ext .c" {od/} {{.c.???r.final .su} {-0.s}}
> +outest "$b asm dbsovrdd-x 1" $sing "-S -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir ./ -dumpbase od/$b.c" {od/} {{.c.???r.final .c.su} {-0.s}}
> +outest "$b asm dbsovrdd.x 1" $sing "-S -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir ./ -dumpbase od/$b.x" {od/} {{.x.???r.final .x.su} {-0.s}}
> +outest "$b asm dbsovrdd 2" $mult "-S -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir ./ -dumpbase od/$b" {od/} {{--1.c.???r.final --1.su --2.c.???r.final --2.su} {-1.s -2.s}}
> +outest "$b asm dbsovrddx 2" $mult "-S -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir ./ -dumpbase od/$b.x -dumpbase-ext .x" {od/} {{--1.c.???r.final --1.su --2.c.???r.final --2.su} {-1.s -2.s}}
> +outest "$b obj dbsovrdd unnamed1" $sing "-c -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir ./ -dumpbase od/$b" {od/} {{.???r.final .su .dwo} {-0.o}}
> +outest "$b obj dbsovrddx unnamed1" $sing "-c -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir ./ -dumpbase od/$b.c -dumpbase-ext .c" {od/} {{.c.???r.final .su .dwo} {-0.o}}
> +outest "$b obj dbsovrdd unnamed2" $mult "-c -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir ./ -dumpbase od/$b" {od/} {{--1.c.???r.final --1.su --1.dwo --2.c.???r.final --2.su --2.dwo} {-1.o -2.o}}
> +
> +outest "$b cpp dbsovrdd named0" $sing "-E -o $b-0.i -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir ./ -dumpbase od/$b" {od/} {{} {-0.i}}
> +outest "$b asm dbsovrdd named0" $sing "-S -o $b-0.s -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir ./ -dumpbase od/$b" {od/} {{.???r.final .su} {-0.s}}
> +outest "$b obj dbsovrdd named0" $sing "-c -o $b-0.o -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir ./ -dumpbase od/$b" {od/} {{.???r.final .su .dwo} {-0.o}}
> +outest "$b cpp dbsovrdd namedb" $sing "-E -o $b.i -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir ./ -dumpbase od/$b" {od/} {{} {.i}}
> +outest "$b asm dbsovrdd namedb" $sing "-S -o $b.s -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir ./ -dumpbase od/$b" {od/} {{.???r.final .su} {.s}}
> +outest "$b obj dbsovrdd namedb" $sing "-c -o $b.o -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir ./ -dumpbase od/$b" {od/} {{.???r.final .su .dwo} {.o}}
> +
> +# Nit: -dumpdir affects whether the specified dumpbase is combined
> +# into dumpdir or taken as the output basename, even if dumpbase will
> +# ultimately override it.
> +outest "$b exe dbsovrdd unnamed1" $sing "-g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir ./ -dumpbase od/$b" {od/} {{.???r.final .su .dwo} {a.{out,exe}}}
> +outest "$b exe dbsovrdd unnamed2" $mult "-g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir ./ -dumpbase od/a" {od/} {{a--1.c.???r.final a--1.su a--1.dwo a--2.c.???r.final a--2.su a--2.dwo} {a.{out,exe}}}
> +outest "$b exe dbsovrdd named0" $sing "-o $b-0.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir ./ -dumpbase od/$b" {od/} {{.???r.final .su .dwo} {-0.exe}}
> +outest "$b exe dbsovrdd namedb" $sing "-o $b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir ./ -dumpbase od/$b.exe -dumpbase-ext .exe" {od/} {{.exe.???r.final .su .dwo} {.exe}}
> +outest "$b exe dbsovrdd named2" $mult "-o $b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir ./ -dumpbase od/$b" {od/} {{--1.c.???r.final --1.su --1.dwo --2.c.???r.final --2.su --2.dwo} {.exe}}
> +outest "$b exe dbsovrdda namedb" $sing "-o $b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir ./ -dumpbase od/a" {od/} {{a.???r.final a.su a.dwo} {.exe}}
> +outest "$b exe dbsovrddac namedb" $sing "-o $b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir ./ -dumpbase od/a.c -dumpbase-ext .c" {od/} {{a.c.???r.final a.su a.dwo} {.exe}}
> +outest "$b exe dbsovrdda named2" $mult "-o $b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir ./ -dumpbase od/a" {od/} {{a--1.c.???r.final a--1.su a--1.dwo a--2.c.???r.final a--2.su a--2.dwo} {.exe}}
> +
> +outest "$b cpp dbsovrdd namedir0" $sing "-E -o o/$b-0.i -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir ./ -dumpbase od/$b" {od/ o/} {{} {-0.i} {}}
> +outest "$b asm dbsovrdd namedir0" $sing "-S -o o/$b-0.s -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir ./ -dumpbase od/$b" {od/ o/} {{.???r.final .su} {-0.s} {}}
> +outest "$b obj dbsovrdd namedir0" $sing "-c -o o/$b-0.o -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir ./ -dumpbase od/$b" {od/ o/} {{.???r.final .su .dwo} {-0.o} {}}
> +outest "$b cpp dbsovrdd namedir" $sing "-E -o o/$b.i -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir ./ -dumpbase od/$b" {od/ o/} {{} {.i} {}}
> +outest "$b asm dbsovrdd namedir" $sing "-S -o o/$b.s -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir ./ -dumpbase od/$b" {od/ o/} {{.???r.final .su} {.s} {}}
> +outest "$b obj dbsovrdd namedir" $sing "-c -o o/$b.o -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir ./ -dumpbase od/$b" {od/ o/} {{.???r.final .su .dwo} {.o} {}}
> +outest "$b exe dbsovrdd namedir0" $sing "-o o/$b-0.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir ./ -dumpbase od/$b" {od/ o/} {{.???r.final .su .dwo} {-0.exe} {}}
> +outest "$b exe dbsovrdd namedirb" $sing "-o o/$b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir ./ -dumpbase od/$b.exe -dumpbase-ext .exe" {od/ o/} {{.exe.???r.final .su .dwo} {.exe} {}}
> +outest "$b exe dbsovrdd namedir2" $mult "-o o/$b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir ./ -dumpbase od/$b" {od/ o/} {{--1.c.???r.final --1.su --1.dwo --2.c.???r.final --2.su --2.dwo} {.exe} {}}
> +outest "$b exe dbsovrdda namedirb" $sing "-o o/$b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir ./ -dumpbase od/a" {od/ o/} {{a.???r.final a.su a.dwo} {.exe} {}}
> +outest "$b exe dbsovrdda namedir2" $mult "-o o/$b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir ./ -dumpbase od/a" {od/ o/} {{a--1.c.???r.final a--1.su a--1.dwo a--2.c.???r.final a--2.su a--2.dwo} {.exe} {}}
> +
> +
> +# Check that a -dumpbase without a dir component adds to the -dumpdir
> +# prefix.
> +outest "$b asm dbswthdd 1" $sing "-S -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/ -dumpbase $b" {od/} {{.???r.final .su} {-0.s}}
> +outest "$b asm dbswthddx 1" $sing "-S -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/ -dumpbase $b.c -dumpbase-ext .c" {od/} {{.c.???r.final .su} {-0.s}}
> +outest "$b asm dbswthdd-x 1" $sing "-S -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/ -dumpbase $b.c" {od/} {{.c.???r.final .c.su} {-0.s}}
> +outest "$b asm dbswthdd.x 1" $sing "-S -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/ -dumpbase $b.x" {od/} {{.x.???r.final .x.su} {-0.s}}
> +outest "$b asm dbswthdd 2" $mult "-S -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/ -dumpbase $b" {od/} {{--1.c.???r.final --1.su --2.c.???r.final --2.su} {-1.s -2.s}}
> +outest "$b asm dbswthddx 2" $mult "-S -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/ -dumpbase $b.x -dumpbase-ext .x" {od/} {{--1.c.???r.final --1.su --2.c.???r.final --2.su} {-1.s -2.s}}
> +outest "$b obj dbswthdd unnamed1" $sing "-c -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/ -dumpbase $b" {od/} {{.???r.final .su .dwo} {-0.o}}
> +outest "$b obj dbswthddx unnamed1" $sing "-c -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/ -dumpbase $b.c -dumpbase-ext .c" {od/} {{.c.???r.final .su .dwo} {-0.o}}
> +outest "$b obj dbswthdd unnamed2" $mult "-c -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/ -dumpbase $b" {od/} {{--1.c.???r.final --1.su --1.dwo --2.c.???r.final --2.su --2.dwo} {-1.o -2.o}}
> +
> +outest "$b cpp dbswthdd named0" $sing "-E -o $b-0.i -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/ -dumpbase $b" {od/} {{} {-0.i}}
> +outest "$b asm dbswthdd named0" $sing "-S -o $b-0.s -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/ -dumpbase $b" {od/} {{.???r.final .su} {-0.s}}
> +outest "$b obj dbswthdd named0" $sing "-c -o $b-0.o -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/ -dumpbase $b" {od/} {{.???r.final .su .dwo} {-0.o}}
> +outest "$b cpp dbswthdd namedb" $sing "-E -o $b.i -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/ -dumpbase $b" {od/} {{} {.i}}
> +outest "$b asm dbswthdd namedb" $sing "-S -o $b.s -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/ -dumpbase $b" {od/} {{.???r.final .su} {.s}}
> +outest "$b obj dbswthdd namedb" $sing "-c -o $b.o -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/ -dumpbase $b" {od/} {{.???r.final .su .dwo} {.o}}
> +
> +# Nitty details: -dumpdir affects whether the specified dumpbase is
> +# combined into dumpdir or taken as the output basename, even if
> +# dumpbase will ultimately override it.
> +outest "$b exe dbswthdd unnamed1" $sing "-g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/ -dumpbase $b" {od/} {{.???r.final .su .dwo} {a.{out,exe}}}
> +outest "$b exe dbswthdd unnamed2" $mult "-g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/ -dumpbase a" {od/} {{a--1.c.???r.final a--1.su a--1.dwo a--2.c.???r.final a--2.su a--2.dwo} {a.{out,exe}}}
> +outest "$b exe dbswthdd named0" $sing "-o $b-0.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/ -dumpbase $b" {od/} {{.???r.final .su .dwo} {-0.exe}}
> +outest "$b exe dbswthdd namedb" $sing "-o $b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/ -dumpbase $b.exe -dumpbase-ext .exe" {od/} {{.exe.???r.final .su .dwo} {.exe}}
> +outest "$b exe dbswthdd named2" $mult "-o $b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/ -dumpbase $b" {od/} {{--1.c.???r.final --1.su --1.dwo --2.c.???r.final --2.su --2.dwo} {.exe}}
> +outest "$b exe dbswthdda namedb" $sing "-o $b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/ -dumpbase a" {od/} {{a.???r.final a.su a.dwo} {.exe}}
> +outest "$b exe dbswthddac namedb" $sing "-o $b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/ -dumpbase a.c -dumpbase-ext .c" {od/} {{a.c.???r.final a.su a.dwo} {.exe}}
> +outest "$b exe dbswthdda named2" $mult "-o $b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/ -dumpbase a" {od/} {{a--1.c.???r.final a--1.su a--1.dwo a--2.c.???r.final a--2.su a--2.dwo} {.exe}}
> +
> +outest "$b cpp dbswthdd namedir0" $sing "-E -o o/$b-0.i -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/ -dumpbase $b" {od/ o/} {{} {-0.i} {}}
> +outest "$b asm dbswthdd namedir0" $sing "-S -o o/$b-0.s -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/ -dumpbase $b" {od/ o/} {{.???r.final .su} {-0.s} {}}
> +outest "$b obj dbswthdd namedir0" $sing "-c -o o/$b-0.o -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/ -dumpbase $b" {od/ o/} {{.???r.final .su .dwo} {-0.o} {}}
> +outest "$b cpp dbswthdd namedir" $sing "-E -o o/$b.i -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/ -dumpbase $b" {od/ o/} {{} {.i} {}}
> +outest "$b asm dbswthdd namedir" $sing "-S -o o/$b.s -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/ -dumpbase $b" {od/ o/} {{.???r.final .su} {.s} {}}
> +outest "$b obj dbswthdd namedir" $sing "-c -o o/$b.o -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/ -dumpbase $b" {od/ o/} {{.???r.final .su .dwo} {.o} {}}
> +outest "$b exe dbswthdd namedir0" $sing "-o o/$b-0.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/ -dumpbase $b" {od/ o/} {{.???r.final .su .dwo} {-0.exe} {}}
> +outest "$b exe dbswthdd namedirb" $sing "-o o/$b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/ -dumpbase $b.exe -dumpbase-ext .exe" {od/ o/} {{.exe.???r.final .su .dwo} {.exe} {}}
> +outest "$b exe dbswthdd namedir2" $mult "-o o/$b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/ -dumpbase $b" {od/ o/} {{--1.c.???r.final --1.su --1.dwo --2.c.???r.final --2.su --2.dwo} {.exe} {}}
> +outest "$b exe dbswthdda namedirb" $sing "-o o/$b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/ -dumpbase a" {od/ o/} {{a.???r.final a.su a.dwo} {.exe} {}}
> +outest "$b exe dbswthdda namedir2" $mult "-o o/$b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpdir od/ -dumpbase a" {od/ o/} {{a--1.c.???r.final a--1.su a--1.dwo a--2.c.???r.final a--2.su a--2.dwo} {.exe} {}}
> +
> +
> +# Check for the minor differences when -dumpbase is used without
> +# -dumpdir.  The main difference between dbwoutdd and dbswthdd tests
> +# is in the single-input link tests: with the dump dir/ prefix moved
> +# to dumpbase, and without -dumpdir we end up using -dumpbase as the
> +# executable prefix rather than as the dumpbase for the single input.
> +outest "$b asm dbwoutdd 1" $sing "-S -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpbase od/$b" {od/} {{.???r.final .su} {-0.s}}
> +outest "$b asm dbwoutddx 1" $sing "-S -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpbase od/$b.c -dumpbase-ext .c" {od/} {{.c.???r.final .su} {-0.s}}
> +outest "$b asm dbwoutdd-x 1" $sing "-S -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpbase od/$b.c" {od/} {{.c.???r.final .c.su} {-0.s}}
> +outest "$b asm dbwoutdd.x 1" $sing "-S -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpbase od/$b.x" {od/} {{.x.???r.final .x.su} {-0.s}}
> +outest "$b asm dbwoutdd 2" $mult "-S -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpbase od/$b" {od/} {{--1.c.???r.final --1.su --2.c.???r.final --2.su} {-1.s -2.s}}
> +outest "$b asm dbwoutddx 2" $mult "-S -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpbase od/$b.x -dumpbase-ext .x" {od/} {{--1.c.???r.final --1.su --2.c.???r.final --2.su} {-1.s -2.s}}
> +outest "$b obj dbwoutdd unnamed1" $sing "-c -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpbase od/$b" {od/} {{.???r.final .su .dwo} {-0.o}}
> +outest "$b obj dbwoutddx unnamed1" $sing "-c -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpbase od/$b.c -dumpbase-ext .c" {od/} {{.c.???r.final .su .dwo} {-0.o}}
> +outest "$b obj dbwoutdd unnamed2" $mult "-c -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpbase od/$b" {od/} {{--1.c.???r.final --1.su --1.dwo --2.c.???r.final --2.su --2.dwo} {-1.o -2.o}}
> +
> +outest "$b cpp dbwoutdd named0" $sing "-E -o $b-0.i -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpbase od/$b" {od/} {{} {-0.i}}
> +outest "$b asm dbwoutdd named0" $sing "-S -o $b-0.s -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpbase od/$b" {od/} {{.???r.final .su} {-0.s}}
> +outest "$b obj dbwoutdd named0" $sing "-c -o $b-0.o -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpbase od/$b" {od/} {{.???r.final .su .dwo} {-0.o}}
> +outest "$b cpp dbwoutdd namedb" $sing "-E -o $b.i -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpbase od/$b" {od/} {{} {.i}}
> +outest "$b asm dbwoutdd namedb" $sing "-S -o $b.s -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpbase od/$b" {od/} {{.???r.final .su} {.s}}
> +outest "$b obj dbwoutdd namedb" $sing "-c -o $b.o -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpbase od/$b" {od/} {{.???r.final .su .dwo} {.o}}
> +
> +outest "$b exe dbwoutdd unnamed1" $sing "-g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpbase od/$b" {od/} {{--0.c.???r.final --0.su --0.dwo} {a.{out,exe}}}
> +outest "$b exe dbwoutdd unnamed2" $mult "-g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpbase od/a" {od/} {{a--1.c.???r.final a--1.su a--1.dwo a--2.c.???r.final a--2.su a--2.dwo} {a.{out,exe}}}
> +outest "$b exe dbwoutdd named0" $sing "-o $b-0.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpbase od/$b" {od/} {{--0.c.???r.final --0.su --0.dwo} {-0.exe}}
> +outest "$b exe dbwoutdd named0d" $sing "-o od/$b-0.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpbase $b" {od/} {{--0.c.???r.final --0.su --0.dwo -0.exe} {}}
> +outest "$b exe dbwoutdd namedb" $sing "-o $b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpbase od/$b.exe -dumpbase-ext .exe" {od/} {{--0.c.???r.final --0.su --0.dwo} {.exe}}
> +outest "$b exe dbwoutdd named2" $mult "-o $b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpbase od/$b" {od/} {{--1.c.???r.final --1.su --1.dwo --2.c.???r.final --2.su --2.dwo} {.exe}}
> +outest "$b exe dbwoutdda namedb" $sing "-o $b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpbase od/a" {od/} {{a--0.c.???r.final a--0.su a--0.dwo} {.exe}}
> +outest "$b exe dbwoutddac namedb" $sing "-o $b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpbase od/a.c -dumpbase-ext .c" {od/} {{a--0.c.???r.final a--0.su a--0.dwo} {.exe}}
> +outest "$b exe dbwoutdda named2" $mult "-o $b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpbase od/a" {od/} {{a--1.c.???r.final a--1.su a--1.dwo a--2.c.???r.final a--2.su a--2.dwo} {.exe}}
> +
> +outest "$b cpp dbwoutdd namedir0" $sing "-E -o o/$b-0.i -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpbase od/$b" {od/ o/} {{} {-0.i} {}}
> +outest "$b asm dbwoutdd namedir0" $sing "-S -o o/$b-0.s -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpbase od/$b" {od/ o/} {{.???r.final .su} {-0.s} {}}
> +outest "$b obj dbwoutdd namedir0" $sing "-c -o o/$b-0.o -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpbase od/$b" {od/ o/} {{.???r.final .su .dwo} {-0.o} {}}
> +outest "$b cpp dbwoutdd namedir" $sing "-E -o o/$b.i -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpbase od/$b" {od/ o/} {{} {.i} {}}
> +outest "$b asm dbwoutdd namedir" $sing "-S -o o/$b.s -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpbase od/$b" {od/ o/} {{.???r.final .su} {.s} {}}
> +outest "$b obj dbwoutdd namedir" $sing "-c -o o/$b.o -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpbase od/$b" {od/ o/} {{.???r.final .su .dwo} {.o} {}}
> +outest "$b exe dbwoutdd namedir0" $sing "-o o/$b-0.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpbase od/$b" {od/ o/} {{--0.c.???r.final --0.su --0.dwo} {-0.exe} {}}
> +outest "$b exe dbwoutdd namedirb" $sing "-o o/$b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpbase od/$b.exe -dumpbase-ext .exe" {od/ o/} {{--0.c.???r.final --0.su --0.dwo} {.exe} {}}
> +outest "$b exe dbwoutdd namedir2" $mult "-o o/$b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpbase od/$b" {od/ o/} {{--1.c.???r.final --1.su --1.dwo --2.c.???r.final --2.su --2.dwo} {.exe} {}}
> +outest "$b exe dbwoutdda namedirb" $sing "-o o/$b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpbase od/a" {od/ o/} {{a--0.c.???r.final a--0.su a--0.dwo} {.exe} {}}
> +outest "$b exe dbwoutdda namedir2" $mult "-o o/$b.exe -g -fdump-rtl-final -fstack-usage -gsplit-dwarf -dumpbase od/a" {od/ o/} {{a--1.c.???r.final a--1.su a--1.dwo a--2.c.???r.final a--2.su a--2.dwo} {.exe} {}}
> +
> +# -fcompare-debug
> +outest "$b obj compare-debug" $sing "-c -fcompare-debug -fdump-rtl-final -fstack-usage -gsplit-dwarf -fdump-final-insns" {} {{-0.c.???r.final -0.su -0.c.gkd -0.gk.c.???r.final -0.dwo -0.o}}
> +outest "$b obj compare-debug save-temps" $sing "-c -fcompare-debug -save-temps -fdump-rtl-final -fstack-usage -gsplit-dwarf -fdump-final-insns" {} {{-0.c.???r.final -0.su -0.i -0.c.gkd -0.s -0.gk.i -0.gk.c.???r.final -0.gk.c.gkd -0.dwo -0.o}}
> +
> +# -flto
> +outest "$b lto sing unnamed" $sing "-O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {} {{a--0.c.???i.icf a.wpa.???i.icf a.ltrans0.ltrans.???r.final a.ltrans0.ltrans.su a.{out,exe}}}
> +outest "$b lto mult unnamed" $mult "-O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {} {{a--1.c.???i.icf a--2.c.???i.icf  a.wpa.???i.icf a.ltrans0.ltrans.???r.final a.ltrans0.ltrans.su a.{out,exe}}}
> +outest "$b lto sing named" $sing "-o $b.exe -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {} {{--0.c.???i.icf .wpa.???i.icf .ltrans0.ltrans.???r.final .ltrans0.ltrans.su .exe}}
> +outest "$b lto mult named" $mult "-o $b.exe -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {} {{--1.c.???i.icf --2.c.???i.icf .wpa.???i.icf .ltrans0.ltrans.???r.final .ltrans0.ltrans.su .exe}}
> +outest "$b lto sing nameddir" $sing "-o dir/$b.exe -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{--0.c.???i.icf .wpa.???i.icf .ltrans0.ltrans.???r.final .ltrans0.ltrans.su .exe} {}}
> +outest "$b lto mult nameddir" $mult "-o dir/$b.exe -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{--1.c.???i.icf --2.c.???i.icf .wpa.???i.icf .ltrans0.ltrans.???r.final .ltrans0.ltrans.su .exe} {}}
> +
> +# -dumpbase without -dumpdir.  The trailing dumppfx dash after it is
> +# combined with dumpbase turns into a period when passed to lto as
> +# -dumpdir, because the dash is introduced by the compiler driver.
> +outest "$b lto sing dumpbase unnamed" $sing "-dumpbase dir/$b -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{--0.c.???i.icf .wpa.???i.icf .ltrans0.ltrans.???r.final .ltrans0.ltrans.su} {a.{out,exe}}}
> +outest "$b lto mult dumpbase unnamed" $mult "-dumpbase dir/$b -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{--1.c.???i.icf --2.c.???i.icf .wpa.???i.icf .ltrans0.ltrans.???r.final .ltrans0.ltrans.su} {a.{out,exe}}}
> +outest "$b lto sing dumpbase named" $sing "-dumpbase dir/$b -o $b-0.exe -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{--0.c.???i.icf .wpa.???i.icf .ltrans0.ltrans.???r.final .ltrans0.ltrans.su} {-0.exe}}
> +outest "$b lto mult dumpbase named" $mult "-dumpbase dir/$b -o $b-1.exe -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{--1.c.???i.icf --2.c.???i.icf .wpa.???i.icf .ltrans0.ltrans.???r.final .ltrans0.ltrans.su} {-1.exe}}
> +outest "$b lto sing dumpbase namedb" $sing "-dumpbase dir/$b -o $b.exe -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{--0.c.???i.icf .wpa.???i.icf .ltrans0.ltrans.???r.final .ltrans0.ltrans.su} {.exe}}
> +outest "$b lto mult dumpbase namedb" $mult "-dumpbase dir/$b -o $b.exe -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{--1.c.???i.icf --2.c.???i.icf .wpa.???i.icf .ltrans0.ltrans.???r.final .ltrans0.ltrans.su} {.exe}}
> +
> +# -dumpdir without -dumpbase.  The trailing dash in -dumpdir is given
> +# by the user, thus not replaced with a dot.
> +outest "$b lto sing dumpdir unnamed" $sing "-dumpdir dir/$b- -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{--0.c.???i.icf -wpa.???i.icf -ltrans0.ltrans.???r.final -ltrans0.ltrans.su} {a.{out,exe}}}
> +outest "$b lto mult dumpdir unnamed" $mult "-dumpdir dir/$b- -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{--1.c.???i.icf --2.c.???i.icf -wpa.???i.icf -ltrans0.ltrans.???r.final -ltrans0.ltrans.su} {a.{out,exe}}}
> +outest "$b lto sing dumpdir named" $sing "-dumpdir dir/$b- -o $b-0.exe -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{--0.c.???i.icf -wpa.???i.icf -ltrans0.ltrans.???r.final -ltrans0.ltrans.su} {-0.exe}}
> +outest "$b lto mult dumpdir named" $mult "-dumpdir dir/$b- -o $b-1.exe -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{--1.c.???i.icf --2.c.???i.icf -wpa.???i.icf -ltrans0.ltrans.???r.final -ltrans0.ltrans.su} {-1.exe}}
> +outest "$b lto sing dumpdir namedb" $sing "-dumpdir dir/$b- -o $b.exe -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{--0.c.???i.icf -wpa.???i.icf -ltrans0.ltrans.???r.final -ltrans0.ltrans.su} {.exe}}
> +outest "$b lto mult dumpdir namedb" $mult "-dumpdir dir/$b- -o $b.exe -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{--1.c.???i.icf --2.c.???i.icf -wpa.???i.icf -ltrans0.ltrans.???r.final -ltrans0.ltrans.su} {.exe}}
> +
> +# -dumpdir and non-overriding -dumpbase.
> +outest "$b lto dbswthdd sing unnamed" $sing "-dumpdir dir/ -dumpbase $b -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{.???i.icf .wpa.???i.icf .ltrans0.ltrans.???r.final .ltrans0.ltrans.su} {a.{out,exe}}}
> +outest "$b lto dbswthdd mult unnamed" $mult "-dumpdir dir/ -dumpbase $b -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{--1.c.???i.icf --2.c.???i.icf .wpa.???i.icf .ltrans0.ltrans.???r.final .ltrans0.ltrans.su} {a.{out,exe}}}
> +outest "$b lto dbswthdd sing named" $sing "-dumpdir dir/ -dumpbase $b -o $b-0.exe -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{.???i.icf .wpa.???i.icf .ltrans0.ltrans.???r.final .ltrans0.ltrans.su} {-0.exe}}
> +outest "$b lto dbswthdd mult named" $mult "-dumpdir dir/ -dumpbase $b -o $b-1.exe -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{--1.c.???i.icf --2.c.???i.icf .wpa.???i.icf .ltrans0.ltrans.???r.final .ltrans0.ltrans.su} {-1.exe}}
> +outest "$b lto dbswthdd sing namedb" $sing "-dumpdir dir/ -dumpbase $b -o $b.exe -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{.???i.icf .wpa.???i.icf .ltrans0.ltrans.???r.final .ltrans0.ltrans.su} {.exe}}
> +outest "$b lto dbswthdd mult namedb" $mult "-dumpdir dir/ -dumpbase $b -o $b.exe -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{--1.c.???i.icf --2.c.???i.icf .wpa.???i.icf .ltrans0.ltrans.???r.final .ltrans0.ltrans.su} {.exe}}
> +
> +# -dumpdir and an overriding -dumpbase.
> +outest "$b lto dbsovrdd sing unnamed" $sing "-dumpdir ignore/ -dumpbase dir/$b -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{.???i.icf .wpa.???i.icf .ltrans0.ltrans.???r.final .ltrans0.ltrans.su} {a.{out,exe}}}
> +outest "$b lto dbsovrdd mult unnamed" $mult "-dumpdir ignore/ -dumpbase dir/$b -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{--1.c.???i.icf --2.c.???i.icf .wpa.???i.icf .ltrans0.ltrans.???r.final .ltrans0.ltrans.su} {a.{out,exe}}}
> +outest "$b lto dbsovrdd sing named" $sing "-dumpdir ignore/ -dumpbase dir/$b -o $b-0.exe -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{.???i.icf .wpa.???i.icf .ltrans0.ltrans.???r.final .ltrans0.ltrans.su} {-0.exe}}
> +outest "$b lto dbsovrdd mult named" $mult "-dumpdir ignore/ -dumpbase dir/$b -o $b-1.exe -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{--1.c.???i.icf --2.c.???i.icf .wpa.???i.icf .ltrans0.ltrans.???r.final .ltrans0.ltrans.su} {-1.exe}}
> +outest "$b lto dbsovrdd sing namedb" $sing "-dumpdir ignore/ -dumpbase dir/$b -o $b.exe -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{.???i.icf .wpa.???i.icf .ltrans0.ltrans.???r.final .ltrans0.ltrans.su} {.exe}}
> +outest "$b lto dbsovrdd mult namedb" $mult "-dumpdir ignore/ -dumpbase dir/$b -o $b.exe -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{--1.c.???i.icf --2.c.???i.icf .wpa.???i.icf .ltrans0.ltrans.???r.final .ltrans0.ltrans.su} {.exe}}
> +
> +# Check that -dumpbase '' gets source names as dumpbases for
> +# compilation, and output name as dumpbase for linking, regardless of
> +# how many source files.
> +outest "$b lto sing empty dumpbase unnamed" $sing "-dumpbase \"\" -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {} {{-0.c.???i.icf a.wpa.???i.icf a.ltrans0.ltrans.???r.final a.ltrans0.ltrans.su a.{out,exe}}}
> +outest "$b lto mult empty dumpbase unnamed" $mult "-dumpbase \"\" -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {} {{-1.c.???i.icf -2.c.???i.icf a.wpa.???i.icf a.ltrans0.ltrans.???r.final a.ltrans0.ltrans.su a.{out,exe}}}
> +outest "$b lto sing empty dumpbase named" $sing "-dumpbase \"\" -o dir/$b-0.exe -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{-0.c.???i.icf -0.wpa.???i.icf -0.ltrans0.ltrans.???r.final -0.ltrans0.ltrans.su -0.exe} {}}
> +outest "$b lto mult empty dumpbase named" $mult "-dumpbase \"\" -o dir/$b-1.exe -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{-1.c.???i.icf -2.c.???i.icf -1.wpa.???i.icf -1.ltrans0.ltrans.???r.final -1.ltrans0.ltrans.su -1.exe} {}}
> +outest "$b lto sing empty dumpbase namedb" $sing "-dumpbase \"\" -o $b.exe -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {} {{-0.c.???i.icf .wpa.???i.icf .ltrans0.ltrans.???r.final .ltrans0.ltrans.su .exe}}
> +outest "$b lto mult empty dumpbase namedb" $mult "-dumpbase \"\" -o $b.exe -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {} {{-1.c.???i.icf -2.c.???i.icf .wpa.???i.icf .ltrans0.ltrans.???r.final .ltrans0.ltrans.su .exe}}
> +
> +# Now with -dumpdir too.
> +outest "$b lto sing empty dumpbase dumpdir unnamed" $sing "-dumpdir dir/$b- -dumpbase \"\" -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{--0.c.???i.icf -a.wpa.???i.icf -a.ltrans0.ltrans.???r.final -a.ltrans0.ltrans.su} {a.{out,exe}}}
> +outest "$b lto mult empty dumpbase dumpdir unnamed" $mult "-dumpdir dir/$b- -dumpbase \"\" -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{--1.c.???i.icf --2.c.???i.icf -a.wpa.???i.icf -a.ltrans0.ltrans.???r.final -a.ltrans0.ltrans.su} {a.{out,exe}}}
> +outest "$b lto sing empty dumpbase dumpdir named" $sing "-dumpdir dir/$b- -dumpbase \"\" -o $b-0.exe -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{--0.c.???i.icf --0.wpa.???i.icf --0.ltrans0.ltrans.???r.final --0.ltrans0.ltrans.su} {-0.exe}}
> +outest "$b lto mult empty dumpbase dumpdir named" $mult "-dumpdir dir/$b- -dumpbase \"\" -o $b-1.exe -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{--1.c.???i.icf --2.c.???i.icf --1.wpa.???i.icf --1.ltrans0.ltrans.???r.final --1.ltrans0.ltrans.su} {-1.exe}}
> +outest "$b lto sing empty dumpbase dumpdir namedb" $sing "-dumpdir dir/$b- -dumpbase \"\" -o $b.exe -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{--0.c.???i.icf -.wpa.???i.icf -.ltrans0.ltrans.???r.final -.ltrans0.ltrans.su} {.exe}}
> +outest "$b lto mult empty dumpbase dumpdir namedb" $mult "-dumpdir dir/$b- -dumpbase \"\" -o $b.exe -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{--1.c.???i.icf --2.c.???i.icf -.wpa.???i.icf -.ltrans0.ltrans.???r.final -.ltrans0.ltrans.su} {.exe}}
> +
> +# And also with an empty -dumpdir.  That's equivalent to -dumpdir ./,
> +# overriding any dumpdir implied by the output.
> +outest "$b lto sing empty dumpdir empty dumpbase unnamed" $sing "-dumpdir \"\" -dumpbase \"\" -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {} {{-0.c.???i.icf a.wpa.???i.icf a.ltrans0.ltrans.???r.final a.ltrans0.ltrans.su a.{out,exe}}}
> +outest "$b lto mult empty dumpdir empty dumpbase unnamed" $mult "-dumpdir \"\" -dumpbase \"\" -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {} {{-1.c.???i.icf -2.c.???i.icf a.wpa.???i.icf a.ltrans0.ltrans.???r.final a.ltrans0.ltrans.su a.{out,exe}}}
> +outest "$b lto sing empty dumpdir empty dumpbase named" $sing "-dumpdir \"\" -dumpbase \"\" -o dir/$b-0.exe -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{-0.exe} {-0.c.???i.icf -0.wpa.???i.icf -0.ltrans0.ltrans.???r.final -0.ltrans0.ltrans.su}}
> +outest "$b lto mult empty dumpdir empty dumpbase named" $mult "-dumpdir \"\" -dumpbase \"\" -o dir/$b-1.exe -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{-1.exe} {-1.c.???i.icf -2.c.???i.icf -1.wpa.???i.icf -1.ltrans0.ltrans.???r.final -1.ltrans0.ltrans.su}}
> +outest "$b lto sing empty dumpdir empty dumpbase namedb" $sing "-dumpdir \"\" -dumpbase \"\" -o dir/$b.exe -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{.exe} {-0.c.???i.icf .wpa.???i.icf .ltrans0.ltrans.???r.final .ltrans0.ltrans.su}}
> +outest "$b lto mult empty dumpdir empty dumpbase namedb" $mult "-dumpdir \"\" -dumpbase \"\" -o dir/$b.exe -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{.exe} {-1.c.???i.icf -2.c.???i.icf .wpa.???i.icf .ltrans0.ltrans.???r.final .ltrans0.ltrans.su}}
> +
> +# Now -flto with -save-temps, not exhaustive.
> +outest "$b lto st sing empty dumpbase unnamed" $sing "-dumpbase \"\" -save-temps -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {} {{-0.i -0.s -0.o -0.c.???i.icf a.lto_wrapper_args a.wpa.???i.icf a.ltrans.out a.res a.ltrans0.o a.ltrans0.ltrans.???r.final a.ltrans0.ltrans.su a.ltrans0.ltrans.s a.ltrans0.ltrans.o a.{out,exe}}}
> +outest "$b lto st mult empty dumpbase unnamed" $mult "-dumpbase \"\" -save-temps -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {} {{-1.i -1.s -1.o -1.c.???i.icf -2.i -2.s -2.o -2.c.???i.icf a.lto_wrapper_args a.wpa.???i.icf a.ltrans.out a.res a.ltrans0.o a.ltrans0.ltrans.???r.final a.ltrans0.ltrans.su a.ltrans0.ltrans.s a.ltrans0.ltrans.o a.{out,exe}}}
> +outest "$b lto st sing dumpdir empty dumpbase named" $sing "-dumpdir dir/ -dumpbase \"\" -o $b-0.exe -save-temps -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{-0.i -0.s -0.o -0.c.???i.icf -0.lto_wrapper_args -0.wpa.???i.icf -0.ltrans.out -0.res -0.ltrans0.o -0.ltrans0.ltrans.???r.final -0.ltrans0.ltrans.su -0.ltrans0.ltrans.s -0.ltrans0.ltrans.o} {-0.exe}}
> +outest "$b lto st mult dumpdir empty dumpbase named" $mult "-dumpdir dir/ -dumpbase \"\" -o $b-1.exe -save-temps -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{-1.i -1.s -1.o -1.c.???i.icf -2.i -2.s -2.o -2.c.???i.icf -1.lto_wrapper_args -1.wpa.???i.icf -1.ltrans.out -1.res -1.ltrans0.o -1.ltrans0.ltrans.???r.final -1.ltrans0.ltrans.su -1.ltrans0.ltrans.s -1.ltrans0.ltrans.o} {-1.exe}}
> +outest "$b lto st sing empty dumpbase namedb" $sing "-dumpbase \"\" -o dir/$b.exe -save-temps -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{-0.i -0.s -0.o -0.c.???i.icf .lto_wrapper_args .wpa.???i.icf .ltrans.out .res .ltrans0.o .ltrans0.ltrans.???r.final .ltrans0.ltrans.su .ltrans0.ltrans.s .ltrans0.ltrans.o .exe} {}}
> +outest "$b lto st mult empty dumpbase namedb" $mult "-dumpbase \"\" -o dir/$b.exe -save-temps -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{-1.i -1.s -1.o -1.c.???i.icf -2.i -2.s -2.o -2.c.???i.icf .lto_wrapper_args .wpa.???i.icf .ltrans.out .res .ltrans0.o .ltrans0.ltrans.???r.final .ltrans0.ltrans.su .ltrans0.ltrans.s .ltrans0.ltrans.o .exe} {}}
> +
> +# lto save-temps without -dumpbase.
> +outest "$b lto st sing unnamed" $sing "-save-temps -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {} {{a--0.i a--0.s a--0.o a--0.c.???i.icf a.lto_wrapper_args a.wpa.???i.icf a.ltrans.out a.res a.ltrans0.o a.ltrans0.ltrans.???r.final a.ltrans0.ltrans.su a.ltrans0.ltrans.s a.ltrans0.ltrans.o a.{out,exe}}}
> +outest "$b lto st mult unnamed" $mult "-save-temps -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {} {{a--1.i a--1.s a--1.o a--1.c.???i.icf a--2.i a--2.s a--2.o a--2.c.???i.icf a.lto_wrapper_args a.wpa.???i.icf a.ltrans.out a.res a.ltrans0.o a.ltrans0.ltrans.???r.final a.ltrans0.ltrans.su a.ltrans0.ltrans.s a.ltrans0.ltrans.o a.{out,exe}}}
> +outest "$b lto st sing dumpdir named" $sing "-dumpdir dir/$b- -o $b-0.exe -save-temps -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{--0.i --0.s --0.o --0.c.???i.icf -lto_wrapper_args -wpa.???i.icf -ltrans.out -res -ltrans0.o -ltrans0.ltrans.???r.final -ltrans0.ltrans.su -ltrans0.ltrans.s -ltrans0.ltrans.o} {-0.exe}}
> +outest "$b lto st mult dumpdir named" $mult "-dumpdir dir/$b- -o $b-1.exe -save-temps -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{--1.i --1.s --1.o --1.c.???i.icf --2.i --2.s --2.o --2.c.???i.icf -lto_wrapper_args -wpa.???i.icf -ltrans.out -res -ltrans0.o -ltrans0.ltrans.???r.final -ltrans0.ltrans.su -ltrans0.ltrans.s -ltrans0.ltrans.o} {-1.exe}}
> +outest "$b lto st sing namedb" $sing "-o dir/$b.exe -save-temps -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{--0.i --0.s --0.o --0.c.???i.icf .lto_wrapper_args .wpa.???i.icf .ltrans.out .res .ltrans0.o .ltrans0.ltrans.???r.final .ltrans0.ltrans.su .ltrans0.ltrans.s .ltrans0.ltrans.o .exe} {}}
> +outest "$b lto st mult namedb" $mult "-o dir/$b.exe -save-temps -O2 -flto -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{--1.i --1.s --1.o --1.c.???i.icf --2.i --2.s --2.o --2.c.???i.icf .lto_wrapper_args .wpa.???i.icf .ltrans.out .res .ltrans0.o .ltrans0.ltrans.???r.final .ltrans0.ltrans.su .ltrans0.ltrans.s .ltrans0.ltrans.o .exe} {}}
> +
> +# Below are examples taken from the documentation.
> +# They are likely redundant with earlier test,
> +# but we want to make sure behavior matches the docs.
> +
> +# gcc -c foo.c ...
> +outest "$b doc single  -c !-o" $sing "-c -fdump-rtl-final -fstack-usage -gsplit-dwarf" {} {{-0.c.???r.final -0.su -0.dwo -0.o}}
> +
> +# gcc -c foo.c -o dir/foobar.o ...
> +outest "$b doc single  -c +-o" $sing "-c -o dir/$b.o -fdump-rtl-final -fstack-usage -gsplit-dwarf" {dir/} {{.c.???r.final .su .dwo .o} {}}
> +
> +# gcc foo.c bar.c -o dir/foobar ...
> +outest "$b doc double !-c  -o" $mult "-o dir/$b.exe -fdump-rtl-final -fstack-usage -gsplit-dwarf" {dir/} {{--1.c.???r.final --1.su --1.dwo --2.c.???r.final --2.su --2.dwo .exe} {}}
> +
> +# gcc foo.c -o dir/foo ...
> +outest "$b doc single !-c  -o" $sing "-o dir/$b-0 -fdump-rtl-final -fstack-usage -gsplit-dwarf" {dir/} {{-0.c.???r.final -0.su -0.dwo -0} {}}
> +
> +# gcc -save-temps -S foo.c
> +outest "$b doc single  -S -st" $sing "-save-temps -S" {} {{-0.i -0.s}}
> +
> +# gcc -save-temps -dumpbase save-foo -c foo.c
> +outest "$b doc single  -c -st -db" $sing "-save-temps -dumpbase $b -c" {} {{.i .s -0.o}}
> +
> +# gcc foo.c -c -o dir/foo.o -dumpbase alt/foo \
> +#   -dumpdir pfx- -save-temps=cwd ...
> +outest "$b doc single  -c  -o -db" $sing "-c -o dir/$b.o -dumpbase alt/$b -dumpdir pfx- -save-temps=cwd -fdump-rtl-final -fstack-usage -gsplit-dwarf" {alt/ dir/} {{.i .s .???r.final .su .dwo} {.o} {}}
> +
> +# gcc foo.c bar.c -c -dumpbase main ...
> +outest "$b doc double  -c !-o -db" $mult "-c -dumpbase $b -fdump-rtl-final -fstack-usage -gsplit-dwarf" {} {{--1.c.???r.final --1.su --1.dwo -1.o --2.c.???r.final --2.su --2.dwo -2.o}}
> +
> +# gcc -c foo.c -o dir/foobar.o -dumpbase '' ...
> +outest "$b doc single  -c  -o -db''" $sing "-c -o dir/$b.o -dumpbase \"\" -fdump-rtl-final -fstack-usage -gsplit-dwarf" {dir/} {{-0.c.???r.final -0.su -0.dwo .o} {}}
> +
> +# gcc foo.c bar.c -o dir/foobar -dumpbase '' -flto ...
> +outest "$b doc double !-c  -o -db'' -flto" $mult "-o dir/$b.exe -dumpbase \"\" -flto -O2 -flto-partition=one -fdump-ipa-icf-optimized -fdump-rtl-final -fstack-usage" {dir/} {{-1.c.???i.icf -2.c.???i.icf .wpa.???i.icf .ltrans0.ltrans.???r.final .ltrans0.ltrans.su .exe} {}}
> +
> +
> +# gcc foo.c -c -o dir/foo.o -dumpbase x-foo.c -dumpbase-ext .c ...
> +outest "$b doc single  -c  -o -dbx" $sing "-c -o dir/$b-0.o -dumpbase $b.c -dumpbase-ext .c -fdump-rtl-final -fstack-usage -gsplit-dwarf" {dir/} {{.c.???r.final .su .dwo -0.o} {}}
> +
> +# gcc foo.c bar.c -o main.out -dumpbase-ext .out ...
> +outest "$b doc double !-c  -o -dbx" $mult "-o $b.out -dumpbase-ext .out -fdump-rtl-final -fstack-usage -gsplit-dwarf" {} {{--1.c.???r.final --1.su --1.dwo --2.c.???r.final --2.su --2.dwo .out}}
> +
> +# gcc -dumpdir pfx- -c foo.c ...
> +outest "$b doc single  -c !-o -dd" $sing "-dumpdir $b- -c -fdump-rtl-final -fstack-usage -gsplit-dwarf" {} {{--0.c.???r.final --0.su --0.dwo -0.o}}
> +
> +# gcc -dumpdir dir/ -c foo.c -o obj/bar.o ...
> +outest "$b doc single  -c  -o -dd" $sing "-dumpdir dir/ -c -o obj/$b.o -fdump-rtl-final -fstack-usage -gsplit-dwarf" {dir/ obj/} {{.c.???r.final .su .dwo} {.o} {}}
> +
> +# gcc -dumpdir pfx- -c foo.c -save-temps=obj ...
> +outest "$b doc single  -c  -o -dd -st=" $sing "-dumpdir $b- -c -save-temps=obj -fdump-rtl-final -fstack-usage -gsplit-dwarf" {} {{-0.c.???r.final -0.su -0.dwo -0.i -0.s -0.o}}
> +
> +# gcc foo.c bar.c -c -dumpdir dir/pfx- -dumpbase main ...
> +outest "$b doc double  -c !-o -dd -db" $mult "-c -dumpdir dir/ -dumpbase $b -fdump-rtl-final -fstack-usage -gsplit-dwarf" {dir/} {{--1.c.???r.final --1.su --1.dwo --2.c.???r.final --2.su --2.dwo} {-1.o -2.o}}
> +
> +# gcc foo.c -c -dumpdir dir/pfx- -dumpbase main ...
> +outest "$b doc single  -c !-o -dd -db" $sing "-c -dumpdir dir/ -dumpbase $b -fdump-rtl-final -fstack-usage -gsplit-dwarf" {dir/} {{.???r.final .su .dwo} {-0.o}}
> +
> +# gcc foo.c bar.c -dumpdir dir/pfx- -o main ...
> +outest "$b doc double !-c  -o -dd" $mult "-dumpdir dir/ -o $b.exe -fdump-rtl-final -fstack-usage -gsplit-dwarf" {dir/} {{-1.c.???r.final -1.su -1.dwo -2.c.???r.final -2.su -2.dwo} {.exe}}
> +
> +# gcc foo.c -dumpdir alt/pfx- -o dir/main.exe -save-temps=cwd ...
> +outest "$b doc single !-c  -o -dd -st=" $sing "-c -dumpdir dir/ -dumpbase $b -fdump-rtl-final -fstack-usage -gsplit-dwarf" {dir/} {{.???r.final .su .dwo} {-0.o}}
> +
> +
> +gcc_parallel_test_enable 1
> diff --git a/gcc/testsuite/lib/gcc-defs.exp b/gcc/testsuite/lib/gcc-defs.exp
> index da0d1bc..e656e27 100644
> --- a/gcc/testsuite/lib/gcc-defs.exp
> +++ b/gcc/testsuite/lib/gcc-defs.exp
> @@ -305,6 +305,10 @@ proc dg-additional-files-options { options source } {
>  	set to_download [concat $to_download $additional_sources]
>  	set additional_sources_used "$additional_sources"
>  	set additional_sources ""
> +	# This option restores naming of aux and dump output files
> +	# after input files when multiple input files are named,
> +	# instead of getting them combined with the output name.
> +	lappend options "additional_flags=-dumpbase \"\""
>      }
>      if { $additional_files != "" } then { 
>  	regsub -all "^| " $additional_files " [file dirname $source]/" additional_files
> diff --git a/gcc/testsuite/lib/profopt.exp b/gcc/testsuite/lib/profopt.exp
> index 0b853a1..af1fd62f 100644
> --- a/gcc/testsuite/lib/profopt.exp
> +++ b/gcc/testsuite/lib/profopt.exp
> @@ -353,6 +353,10 @@ proc profopt-execute { src } {
>  
>      set count 0
>      foreach option $prof_option_list {
> +	# We pass -dumpbase-ext ${execext}[123] to the compile&link
> +	# commands so as to avoid the combination of the executable
> +	# with the source name in the aux outputs.
> +	set execext ".x${count}"
>  	set execname1 "${executable}${count}1"
>  	set execname2 "${executable}${count}2"
>  	set execname3 "${executable}${count}3"
> @@ -402,7 +406,7 @@ proc profopt-execute { src } {
>  	# Compile for profiling.
>  
>  	set options "$extra_options"
> -	lappend options "additional_flags=$option $extra_flags $profile_option"
> +	lappend options "additional_flags=$option $extra_flags $profile_option -dumpbase-ext ${execext}1"
>  	set optstr "$option $profile_option"
>  	set comp_output [${tool}_target_compile "$src" "$execname1" executable $options]
>  	if ![${tool}_check_compile "$testcase compilation" $optstr $execname1 $comp_output] {
> @@ -491,7 +495,7 @@ proc profopt-execute { src } {
>  	# Compile with feedback-directed optimizations.
>  
>  	set options "$extra_options"
> -	lappend options "additional_flags=$option $extra_flags $feedback_option"
> +	lappend options "additional_flags=$option $extra_flags $feedback_option -dumpbase-ext ${execext}2"
>  	set optstr "$option $feedback_option"
>  	if { [string first "-fauto-profile" $options] >= 0} {
>  	    set options [regsub -- "-fauto-profile" $options "-fauto-profile=$tmpdir/$bprefix$base.$ext"]
> @@ -548,7 +552,7 @@ proc profopt-execute { src } {
>  	# Compile with normal optimizations.
>  
>  	set options "$extra_options"
> -	lappend options "additional_flags=$option"
> +	lappend options "additional_flags=$option -dumpbase-ext ${execext}3"
>  	set optstr "$option"
>  	set comp_output [${tool}_target_compile "$src" "$execname3" "executable" $options]
>  	if ![${tool}_check_compile "$testcase compilation" $optstr $execname3 $comp_output] {
> diff --git a/gcc/testsuite/lib/scandump.exp b/gcc/testsuite/lib/scandump.exp
> index 4c7d904..b29a95a 100644
> --- a/gcc/testsuite/lib/scandump.exp
> +++ b/gcc/testsuite/lib/scandump.exp
> @@ -32,6 +32,9 @@ proc dump-suffix { arg } {
>  proc dump-base { args } {
>      set src [lindex $args 0]
>      set dumpbase_suf [lindex $args 1]
> +    # The dump basename may vary depending on the output name, on
> +    # whether there are multiple sources.  We use -dumpbase "" in
> +    # gcc-defs to base compilation dumps only on the source basename.
>      set dumpbase $src
>      if { [string length $dumpbase_suf] != 0 } {
>  	regsub {[.][^.]*$} $src $dumpbase_suf dumpbase
> diff --git a/gcc/testsuite/lib/scanltranstree.exp b/gcc/testsuite/lib/scanltranstree.exp
> index cff956b..6d35bef 100644
> --- a/gcc/testsuite/lib/scanltranstree.exp
> +++ b/gcc/testsuite/lib/scanltranstree.exp
> @@ -37,11 +37,11 @@ proc scan-ltrans-tree-dump { args } {
>      }
>      if { [llength $args] >= 3 } {
>  	scan-dump "ltrans-tree" [lindex $args 0] \
> -		  "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" ".exe.ltrans0" \
> +		  "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" ".ltrans0.ltrans" \
>  		  [lindex $args 2]
>      } else {
>  	scan-dump "ltrans-tree" [lindex $args 0] \
> -		  "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" ".exe.ltrans0"
> +		  "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" ".ltrans0.ltrans"
>      }
>  }
>  
> @@ -63,10 +63,10 @@ proc scan-ltrans-tree-dump-times { args } {
>      if { [llength $args] >= 4 } {
>  	scan-dump-times "ltrans-tree" [lindex $args 0] [lindex $args 1] \
>  			"\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 2]" \
> -			".exe.ltrans0" [lindex $args 3]
> +			".ltrans0.ltrans" [lindex $args 3]
>      } else {
>  	scan-dump-times "ltrans-tree" [lindex $args 0] [lindex $args 1] \
> -			"\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 2]" ".exe.ltrans0"
> +			"\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 2]" ".ltrans0.ltrans"
>      }
>  }
>  
> @@ -87,11 +87,11 @@ proc scan-ltrans-tree-dump-not { args } {
>      }
>      if { [llength $args] >= 3 } {
>  	scan-dump-not "ltrans-tree" [lindex $args 0] \
> -		      "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" ".exe.ltrans0" \
> +		      "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" ".ltrans0.ltrans" \
>  		      [lindex $args 2]
>      } else {
>  	scan-dump-not "ltrans-tree" [lindex $args 0] \
> -		      "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" ".exe.ltrans0"
> +		      "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" ".ltrans0.ltrans"
>      }
>  }
>  
> @@ -113,11 +113,11 @@ proc scan-ltrans-tree-dump-dem { args } {
>      }
>      if { [llength $args] >= 3 } {
>  	scan-dump-dem "ltrans-tree" [lindex $args 0] \
> -		      "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" ".exe.ltrans0" \
> +		      "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" ".ltrans0.ltrans" \
>  		      [lindex $args 2]
>      } else {
>  	scan-dump-dem "ltrans-tree" [lindex $args 0] \
> -		      "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" ".exe.ltrans0"
> +		      "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" ".ltrans0.ltrans"
>      }
>  }
>  
> @@ -139,10 +139,10 @@ proc scan-ltrans-tree-dump-dem-not { args } {
>      if { [llength $args] >= 3 } {
>  	scan-dump-dem-not "ltrans-tree" [lindex $args 0] \
>  			  "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" \
> -			  ".exe.ltrans0" [lindex $args 2]
> +			  ".ltrans0.ltrans" [lindex $args 2]
>      } else {
>  	scan-dump-dem-not "ltrans-tree" [lindex $args 0] \
>  			  "\[0-9\]\[0-9\]\[0-9\]t.[lindex $args 1]" \
> -			  ".exe.ltrans0"
> +			  ".ltrans0.ltrans"
>      }
>  }
> diff --git a/gcc/testsuite/lib/scanwpaipa.exp b/gcc/testsuite/lib/scanwpaipa.exp
> index d00b400..39e95b8 100644
> --- a/gcc/testsuite/lib/scanwpaipa.exp
> +++ b/gcc/testsuite/lib/scanwpaipa.exp
> @@ -37,11 +37,11 @@ proc scan-wpa-ipa-dump { args } {
>      }
>      if { [llength $args] >= 3 } {
>  	scan-dump "wpa-ipa" [lindex $args 0] \
> -		  "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".exe.wpa" \
> +		  "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".wpa" \
>  		  [lindex $args 2]
>      } else {
>  	scan-dump "wpa-ipa" [lindex $args 0] \
> -		  "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".exe.wpa"
> +		  "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".wpa"
>      }
>  }
>  
> @@ -62,11 +62,11 @@ proc scan-wpa-ipa-dump-times { args } {
>      }
>      if { [llength $args] >= 4 } {
>  	scan-dump-times "wpa-ipa" [lindex $args 0] [lindex $args 1] \
> -			"\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 2]" ".exe.wpa" \
> +			"\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 2]" ".wpa" \
>  			[lindex $args 3]
>      } else {
>  	scan-dump-times "wpa-ipa" [lindex $args 0] [lindex $args 1] \
> -			"\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 2]" ".exe.wpa"
> +			"\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 2]" ".wpa"
>      }
>  }
>  
> @@ -87,11 +87,11 @@ proc scan-wpa-ipa-dump-not { args } {
>      }
>      if { [llength $args] >= 3 } {
>  	scan-dump-not "wpa-ipa" [lindex $args 0] \
> -		      "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".exe.wpa" \
> +		      "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".wpa" \
>  		      [lindex $args 2]
>      } else {
>  	scan-dump-not "wpa-ipa" [lindex $args 0] \
> -		      "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".exe.wpa"
> +		      "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".wpa"
>      }
>  }
>  
> @@ -113,11 +113,11 @@ proc scan-wpa-ipa-dump-dem { args } {
>      }
>      if { [llength $args] >= 3 } {
>  	scan-dump-dem "wpa-ipa" [lindex $args 0] \
> -		      "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".exe.wpa" \
> +		      "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".wpa" \
>  		      [lindex $args 2]
>      } else {
>  	scan-dump-dem "wpa-ipa" [lindex $args 0] \
> -		      "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".exe.wpa"
> +		      "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".wpa"
>      }
>  }
>  
> @@ -138,10 +138,10 @@ proc scan-wpa-ipa-dump-dem-not { args } {
>      }
>      if { [llength $args] >= 3 } {
>  	scan-dump-dem-not "wpa-ipa" [lindex $args 0] \
> -			  "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".exe.wpa" \
> +			  "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".wpa" \
>  			  [lindex $args 2]
>      } else {
>  	scan-dump-dem-not "wpa-ipa" [lindex $args 0] \
> -			  "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".exe.wpa"
> +			  "\[0-9\]\[0-9\]\[0-9\]i.[lindex $args 1]" ".wpa"
>      }
>  }
> diff --git a/gcc/toplev.c b/gcc/toplev.c
> index 4c8be50..04f8938 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.  */
> @@ -1410,11 +1410,19 @@ process_options (void)
>    /* 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 = xstrndup (name, nlen - len);
> +	  name = p;
> +	}
>  
> -      strip_off_ending (name, strlen (name));
>        aux_base_name = name;
>      }
>    else
> @@ -1961,8 +1969,21 @@ static int
>  lang_dependent_init (const char *name)
>  {
>    location_t save_loc = input_location;
> -  if (dump_base_name == 0)
> -    dump_base_name = name && name[0] ? name : "gccdump";
> +  if (!dump_base_name)
> +    {
> +      dump_base_name = name && name[0] ? name : "gccdump";
> +
> +      /* We do not want to derive a non-empty dumpbase-ext from an
> +	 explicit -dumpbase argument, only from a defaulted
> +	 dumpbase.  */
> +      if (!dump_base_ext)
> +	{
> +	  const char *base = lbasename (dump_base_name);
> +	  const char *ext = strrchr (base, '.');
> +	  if (ext)
> +	    dump_base_ext = ext;
> +	}
> +    }
>  
>    /* Other front-end initialization.  */
>    input_location = BUILTINS_LOCATION;
> @@ -1974,20 +1995,25 @@ lang_dependent_init (const char *name)
>      {
>        init_asm_output (name);
>  
> -      /* If stack usage information is desired, open the output file.  */
> -      if (flag_stack_usage && !flag_generate_lto)
> -	stack_usage_file = open_auxiliary_file ("su");
> -
> -      /* If call graph information is desired, open the output file.  */
> -      if (flag_callgraph_info && !flag_generate_lto)
> +      if (!flag_generate_lto && !flag_compare_debug)
>  	{
> -	  callgraph_info_file = open_auxiliary_file ("ci");
> -	  /* Write the file header.  */
> -	  fprintf (callgraph_info_file,
> -		   "graph: { title: \"%s\"\n", main_input_filename);
> -	  bitmap_obstack_initialize (NULL);
> -	  callgraph_info_external_printed = BITMAP_ALLOC (NULL);
> +	  /* If stack usage information is desired, open the output file.  */
> +	  if (flag_stack_usage)
> +	    stack_usage_file = open_auxiliary_file ("su");
> +
> +	  /* If call graph information is desired, open the output file.  */
> +	  if (flag_callgraph_info)
> +	    {
> +	      callgraph_info_file = open_auxiliary_file ("ci");
> +	      /* Write the file header.  */
> +	      fprintf (callgraph_info_file,
> +		       "graph: { title: \"%s\"\n", main_input_filename);
> +	      bitmap_obstack_initialize (NULL);
> +	      callgraph_info_external_printed = BITMAP_ALLOC (NULL);
> +	    }
>  	}
> +      else
> +	flag_stack_usage = flag_callgraph_info = false;
>      }
>  
>    /* This creates various _DECL nodes, so needs to be called after the
> diff --git a/lto-plugin/lto-plugin.c b/lto-plugin/lto-plugin.c
> index c307fc8..30f9cca 100644
> --- a/lto-plugin/lto-plugin.c
> +++ b/lto-plugin/lto-plugin.c
> @@ -195,6 +195,10 @@ static int linker_output_set;
>  static int linker_output_known;
>  static const char *link_output_name = NULL;
>  
> +/* This indicates link_output_name already contains the dot of the
> +   suffix, so we can skip it in extensions.  */
> +static int skip_in_suffix = 0;
> +
>  /* The version of gold being used, or -1 if not gold.  The number is
>     MAJOR * 100 + MINOR.  */
>  static int gold_version = -1;
> @@ -567,14 +571,11 @@ exec_lto_wrapper (char *argv[])
>    /* Write argv to a file to avoid a command line that is too long
>       Save the file locally on save-temps.  */
>    if (save_temps && link_output_name)
> -    {
> -      arguments_file_name = (char *) xmalloc (strlen (link_output_name)
> -				  + sizeof (".lto_wrapper_args") + 1);
> -      strcpy (arguments_file_name, link_output_name);
> -      strcat (arguments_file_name, ".lto_wrapper_args");
> -    }
> +    arguments_file_name = concat (link_output_name,
> +				  ".lto_wrapper_args"
> +				  + skip_in_suffix, NULL);
>    else
> -     arguments_file_name = make_temp_file (".lto_wrapper_args");
> +    arguments_file_name = make_temp_file (".lto_wrapper_args");
>    check (arguments_file_name, LDPL_FATAL,
>           "Failed to generate a temorary file name");
>  
> @@ -1312,12 +1313,82 @@ onload (struct ld_plugin_tv *tv)
>        if (strstr (collect_gcc_options, "'-fno-use-linker-plugin'"))
>  	return LDPS_ERR;
>  
> -      if ( strstr (collect_gcc_options, "'-save-temps'"))
> +      if (strstr (collect_gcc_options, "'-save-temps'"))
>  	save_temps = true;
>  
>        if (strstr (collect_gcc_options, "'-v'")
>            || strstr (collect_gcc_options, "'--verbose'"))
>  	verbose = true;
> +
> +      const char *p;
> +      if ((p = strstr (collect_gcc_options, "'-dumpdir'")))
> +	{
> +	  p += sizeof ("'-dumpdir'");
> +	  while (*p == ' ')
> +	    p++;
> +	  const char *start = p;
> +	  int ticks = 0, escapes = 0;
> +	  /* Count ticks (') and escaped (\.) characters.  Stop at the
> +	     end of the options or at a blank after an even number of
> +	     ticks (not counting escaped ones.  */
> +	  for (p = start; *p; p++)
> +	    {
> +	      if (*p == '\'')
> +		{
> +		  ticks++;
> +		  continue;
> +		}
> +	      else if ((ticks % 2) != 0)
> +		{
> +		  if (*p == ' ')
> +		    break;
> +		  if (*p == '\\')
> +		    {
> +		      if (*++p)
> +			escapes++;
> +		      else
> +			p--;
> +		    }
> +		}
> +	    }
> +
> +	  /* Now allocate a new link_output_name and decode dumpdir
> +	     into it.  The loop uses the same logic, except it counts
> +	     ticks and escapes backwards (so ticks is adjusted if we
> +	     find an odd number of them), and it copies characters
> +	     that are escaped or not otherwise skipped.  */
> +	  int len = p - start - ticks - escapes + 1;
> +	  char *q = xmalloc (len);
> +	  link_output_name = q;
> +	  int oddticks = (ticks % 2);
> +	  ticks += oddticks;
> +	  for (p = start; *p; p++)
> +	    {
> +	      if (*p == '\'')
> +		{
> +		  ticks--;
> +		  continue;
> +		}
> +	      else if ((ticks % 2) != 0)
> +		{
> +		  if (*p == ' ')
> +		    break;
> +		  if (*p == '\\')
> +		    {
> +		      if (*++p)
> +			escapes--;
> +		      else
> +			p--;
> +		    }
> +		}
> +	      *q++ = *p;
> +	    }
> +	  *q = '\0';
> +	  assert (escapes == 0);
> +	  assert (ticks == oddticks);
> +	  assert (q - link_output_name == len - 1);
> +	  skip_in_suffix = 1;
> +	}
>      }
>  
>    return LDPS_OK;
> 
> 

-- 
Richard Biener <rguenther@suse.de>
SUSE Software Solutions Germany GmbH, Maxfeldstrasse 5, 90409 Nuernberg,
Germany; GF: Felix Imendörffer; HRB 36809 (AG Nuernberg)


More information about the Gcc-patches mailing list