8sa1-gcc/gcc/testsuite/lib/gcc-defs.exp
Alexandre Oliva 1dedc12d18 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 "".  When compiling and
linking tests in the testsuite with additional inputs, we now use this
flag.  Files named in dejagnu board ldflags, libs, and ldscripts are
now quoted in the gcc testsuite with -Wl, so that they are not counted
as additional inputs by the compiler driver.

- 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.


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 (HAVE_TARGET_EXECUTABLE_SUFFIX): Define if...
	(TARGET_EXECUTABLE_SUFFIX): ... is defined; define this to the
	empty string otherwise.
	(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.

gcc/fortran/ChangeLog:

	* options.c (gfc_get_option_string): Drop auxbase, add
	dumpbase_ext.

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.

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.

contrib/ChangeLog:

	* compare-debug: Adjust for .gkd files named as dump files,
	with the source suffix rather than the object suffix.

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 (gcc_adjusted_linker_flags): New.
	(gcc_adjust_linker_flags): New.
	(dg-additional-files-options): Call it.  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.
2020-05-26 04:30:15 -03:00

488 lines
13 KiB
Plaintext

# Copyright (C) 2001-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/>.
load_lib target-libpath.exp
load_lib wrapper.exp
load_lib target-utils.exp
#
# ${tool}_check_compile -- Reports and returns pass/fail for a compilation
#
proc ${tool}_check_compile {testcase option objname gcc_output} {
global tool
set fatal_signal "*cc: Internal compiler error: program*got fatal signal"
if [string match "$fatal_signal 6" $gcc_output] then {
${tool}_fail $testcase "Got Signal 6, $option"
return 0
}
if [string match "$fatal_signal 11" $gcc_output] then {
${tool}_fail $testcase "Got Signal 11, $option"
return 0
}
if [string match "*internal compiler error*" $gcc_output] then {
${tool}_fail $testcase "$option (internal compiler error)"
return 0
}
# We shouldn't get these because of -w, but just in case.
if [string match "*cc:*warning:*" $gcc_output] then {
warning "$testcase: (with warnings) $option"
send_log "$gcc_output\n"
unresolved "$testcase, $option"
return 0
}
set gcc_output [prune_warnings $gcc_output]
if { [info proc ${tool}-dg-prune] != "" } {
global target_triplet
set gcc_output [${tool}-dg-prune $target_triplet $gcc_output]
if [string match "*::unsupported::*" $gcc_output] then {
regsub -- "::unsupported::" $gcc_output "" gcc_output
unsupported "$testcase: $gcc_output"
return 0
}
} else {
set unsupported_message [${tool}_check_unsupported_p $gcc_output]
if { $unsupported_message != "" } {
unsupported "$testcase: $unsupported_message"
return 0
}
}
# remove any leftover LF/CR to make sure any output is legit
regsub -all -- "\[\r\n\]*" $gcc_output "" gcc_output
# If any message remains, we fail.
if ![string match "" $gcc_output] then {
${tool}_fail $testcase $option
return 0
}
# fail if the desired object file doesn't exist.
# FIXME: there's no way of checking for existence on a remote host.
if {$objname != "" && ![is3way] && ![file exists $objname]} {
${tool}_fail $testcase $option
return 0
}
${tool}_pass $testcase $option
return 1
}
#
# ${tool}_pass -- utility to record a testcase passed
#
proc ${tool}_pass { testcase cflags } {
if { "$cflags" == "" } {
pass "$testcase"
} else {
pass "$testcase, $cflags"
}
}
#
# ${tool}_fail -- utility to record a testcase failed
#
proc ${tool}_fail { testcase cflags } {
if { "$cflags" == "" } {
fail "$testcase"
} else {
fail "$testcase, $cflags"
}
}
#
# ${tool}_finish -- called at the end of every script that calls ${tool}_init
#
# Hide all quirks of the testing environment from the testsuites. Also
# undo anything that ${tool}_init did that needs undoing.
#
proc ${tool}_finish { } {
# The testing harness apparently requires this.
global errorInfo
if [info exists errorInfo] then {
unset errorInfo
}
# Might as well reset these (keeps our caller from wondering whether
# s/he has to or not).
global prms_id bug_id
set prms_id 0
set bug_id 0
}
#
# ${tool}_exit -- Does final cleanup when testing is complete
#
proc ${tool}_exit { } {
global gluefile
if [info exists gluefile] {
file_on_build delete $gluefile
unset gluefile
}
}
#
# runtest_file_p -- Provide a definition for older dejagnu releases
# and assume the old syntax: foo1.exp bar1.c foo2.exp bar2.c.
# (delete after next dejagnu release).
#
if { [info procs runtest_file_p] == "" } then {
proc runtest_file_p { runtests testcase } {
if { $runtests != "" && [regexp "\[.\]\[cC\]" $runtests] } then {
if { [lsearch $runtests [file tail $testcase]] >= 0 } then {
return 1
} else {
return 0
}
}
return 1
}
}
if { [info exists env(GCC_RUNTEST_PARALLELIZE_DIR)] \
&& [info procs runtest_file_p] != [list] \
&& [info procs gcc_parallelize_saved_runtest_file_p] == [list] } then {
global gcc_runtest_parallelize_counter
global gcc_runtest_parallelize_counter_minor
global gcc_runtest_parallelize_enable
global gcc_runtest_parallelize_dir
global gcc_runtest_parallelize_last
set gcc_runtest_parallelize_counter 0
set gcc_runtest_parallelize_counter_minor 0
set gcc_runtest_parallelize_enable 1
set gcc_runtest_parallelize_dir [getenv GCC_RUNTEST_PARALLELIZE_DIR]
set gcc_runtest_parallelize_last 0
proc gcc_parallel_test_run_p { testcase } {
global gcc_runtest_parallelize_counter
global gcc_runtest_parallelize_counter_minor
global gcc_runtest_parallelize_enable
global gcc_runtest_parallelize_dir
global gcc_runtest_parallelize_last
if { $gcc_runtest_parallelize_enable == 0 } {
return 1
}
# Only test the filesystem every 10th iteration
incr gcc_runtest_parallelize_counter_minor
if { $gcc_runtest_parallelize_counter_minor == 10 } {
set gcc_runtest_parallelize_counter_minor 0
}
if { $gcc_runtest_parallelize_counter_minor != 1 } {
#verbose -log "gcc_parallel_test_run_p $testcase $gcc_runtest_parallelize_counter $gcc_runtest_parallelize_last"
return $gcc_runtest_parallelize_last
}
set path $gcc_runtest_parallelize_dir/$gcc_runtest_parallelize_counter
if {![catch {open $path {RDWR CREAT EXCL} 0600} fd]} {
close $fd
set gcc_runtest_parallelize_last 1
#verbose -log "gcc_parallel_test_run_p $testcase $gcc_runtest_parallelize_counter 1"
incr gcc_runtest_parallelize_counter
return 1
}
set gcc_runtest_parallelize_last 0
#verbose -log "gcc_parallel_test_run_p $testcase $gcc_runtest_parallelize_counter 0"
incr gcc_runtest_parallelize_counter
return 0
}
proc gcc_parallel_test_enable { val } {
global gcc_runtest_parallelize_enable
set gcc_runtest_parallelize_enable $val
}
rename runtest_file_p gcc_parallelize_saved_runtest_file_p
proc runtest_file_p { runtests testcase } {
if ![gcc_parallelize_saved_runtest_file_p $runtests $testcase] {
return 0
}
return [gcc_parallel_test_run_p $testcase]
}
} else {
proc gcc_parallel_test_run_p { testcase } {
return 1
}
proc gcc_parallel_test_enable { val } {
}
}
# Like dg-options, but adds to the default options rather than replacing them.
proc dg-additional-options { args } {
upvar dg-extra-tool-flags extra-tool-flags
if { [llength $args] > 3 } {
error "[lindex $args 0]: too many arguments"
return
}
if { [llength $args] >= 3 } {
switch [dg-process-target [lindex $args 2]] {
"S" { eval lappend extra-tool-flags [lindex $args 1] }
"N" { }
"F" { error "[lindex $args 0]: `xfail' not allowed here" }
"P" { error "[lindex $args 0]: `xfail' not allowed here" }
}
} else {
eval lappend extra-tool-flags [lindex $args 1]
}
}
# Record additional sources files that must be compiled along with the
# main source file.
set additional_sources ""
set additional_sources_used ""
proc dg-additional-sources { args } {
global additional_sources
set additional_sources [lindex $args 1]
}
# Record additional files -- other than source files -- that must be
# present on the system where the compiler runs.
set additional_files ""
proc dg-additional-files { args } {
global additional_files
set additional_files [lindex $args 1]
}
set gcc_adjusted_linker_flags 0
# Add -Wl, before any file names in ldflags, libs, and ldscripts, so
# that default object files or libraries do not change the names of
# gcc auxiliary outputs.
proc gcc_adjust_linker_flags {} {
global gcc_adjusted_linker_flags
if {$gcc_adjusted_linker_flags} {
return
}
set gcc_adjusted_linker_flags 1
if {![is_remote host]} {
set dest [target_info name]
foreach i { ldflags libs ldscripts } {
if {[board_info $dest exists $i]} {
set opts [board_info $dest $i]
set nopts {}
set skip ""
foreach opt [split $opts] {
if { $skip != "" } then {
set skip ""
} elseif { $opt == "-Xlinker" } then {
set skip $opt
} elseif { ![string match "-*" $opt] \
&& [file isfile $opt] } {
set opt "-Wl,$opt"
}
lappend nopts $opt
}
if { $nopts != $opts } {
unset_currtarget_info $i
set_currtarget_info $i "$nopts"
}
}
}
}
}
# Return an updated version of OPTIONS that mentions any additional
# source files registered with dg-additional-sources. SOURCE is the
# name of the test case.
proc dg-additional-files-options { options source } {
gcc_adjust_linker_flags
global additional_sources
global additional_sources_used
global additional_files
set to_download [list]
if { $additional_sources != "" } then {
if [is_remote host] {
lappend options "additional_flags=$additional_sources"
}
regsub -all "^| " $additional_sources " [file dirname $source]/" additional_sources
if ![is_remote host] {
lappend options "additional_flags=$additional_sources"
}
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
set to_download [concat $to_download $additional_files]
set additional_files ""
}
if [is_remote host] {
foreach file $to_download {
remote_download host $file
}
}
return $options
}
# Return a colon-separate list of directories to search for libraries
# for COMPILER, including multilib directories.
proc gcc-set-multilib-library-path { compiler } {
set shlib_ext [get_shlib_extension]
set options [lrange $compiler 1 end]
set compiler [lindex $compiler 0]
set libgcc_s_x [remote_exec host "$compiler" \
"$options -print-file-name=libgcc_s.${shlib_ext}"]
if { [lindex $libgcc_s_x 0] == 0 \
&& [set libgcc_s_dir [file dirname [lindex $libgcc_s_x 1]]] != "" } {
set libpath ":${libgcc_s_dir}"
} else {
return ""
}
set multi_dir_x [remote_exec host "$compiler" \
"$options -print-multi-directory"]
set multi_lib_x [remote_exec host "$compiler" \
"$options -print-multi-lib"]
if { [lindex $multi_dir_x 0] == 0 && [lindex $multi_lib_x 0] == 0 } {
set multi_dir [string trim [lindex $multi_dir_x 1]]
set multi_lib [string trim [lindex $multi_lib_x 1]]
if { "$multi_dir" == "." } {
set multi_root "$libgcc_s_dir"
} else {
set multi_match [string last "/$multi_dir" "$libgcc_s_dir"]
if { "$multi_match" < 0 } {
return $libpath
}
set multi_root [string range "$libgcc_s_dir" \
0 [expr $multi_match - 1]]
}
foreach i "$multi_lib" {
set mldir ""
regexp -- "\[a-z0-9=_/\.-\]*;" $i mldir
set mldir [string trimright $mldir "\;@"]
if { "$mldir" == "$multi_dir" } {
continue
}
append libpath ":${multi_root}/${mldir}"
}
}
return $libpath
}
# A list of all uses of dg-regexp, each entry of the form:
# line-number regexp
# This is cleared at the end of each test by gcc-dg.exp's wrapper for dg-test.
set freeform_regexps []
# Directive for looking for a regexp, without any line numbers or other
# prefixes.
proc dg-regexp { args } {
verbose "dg-regexp: args: $args" 2
global freeform_regexps
lappend freeform_regexps $args
}
# Hook to be called by prune.exp's prune_gcc_output to
# look for the expected dg-regexp expressions, pruning them,
# reporting PASS for those that are found, and FAIL for
# those that weren't found.
#
# It returns a pruned version of its output.
proc handle-dg-regexps { text } {
global freeform_regexps
global testname_with_flags
foreach entry $freeform_regexps {
verbose " entry: $entry" 3
set linenum [lindex $entry 0]
set rexp [lindex $entry 1]
# Escape newlines in $rexp so that we can print them in
# pass/fail results.
set escaped_regex [string map {"\n" "\\n"} $rexp]
verbose "escaped_regex: ${escaped_regex}" 4
set title "$testname_with_flags dg-regexp $linenum"
# Use "regsub" to attempt to prune the pattern from $text
if {[regsub -line $rexp $text "" text]} {
# Success; the multiline pattern was pruned.
pass "$title was found: \"$escaped_regex\""
} else {
fail "$title not found: \"$escaped_regex\""
}
}
return $text
}
# Verify that the initial arg is a valid .dot file
# (by running dot -Tpng on it, and verifying the exit code is 0).
proc dg-check-dot { args } {
verbose "dg-check-dot: args: $args" 2
set testcase [testname-for-summary]
set dotfile [lindex $args 0]
verbose " dotfile: $dotfile" 2
set status [remote_exec host "dot" "-O -Tpng $dotfile"]
verbose " status: $status" 2
if { [lindex $status 0] != 0 } {
fail "$testcase dg-check-dot $dotfile"
return 0
}
pass "$testcase dg-check-dot $dotfile"
}