blob: 8e202a6c09288357dc02f5a9f2be71fd771fda16 [file]
# Test code for libgdiagnostics.so
#
# We will compile each of libgdiagnostics.dg/test-*.{c,cc} into an executable
# dynamically linked against libgdiagnostics.so, and then run each
# such executable.
#
# These executables call into the libgdiagnostics.so API to emit diagnostics,
# sometimes in text form, and other times in SARIF form.
# Kludge alert:
# We need g++_init so that it can find the stdlib include path.
#
# g++_init (in lib/g++.exp) uses g++_maybe_build_wrapper,
# which normally comes from the definition of
# ${tool}_maybe_build_wrapper within lib/wrapper.exp.
#
# However, for us, ${tool} is "libgdiagnostics".
# Hence we load wrapper.exp with tool == "g++", so that
# g++_maybe_build_wrapper is defined.
set tool g++
load_lib wrapper.exp
set tool libgdiagnostics
load_lib dg.exp
load_lib prune.exp
load_lib target-supports.exp
load_lib gcc-defs.exp
load_lib timeout.exp
load_lib target-libpath.exp
load_lib gcc.exp
load_lib g++.exp
load_lib dejagnu.exp
load_lib target-supports-dg.exp
load_lib valgrind.exp
load_lib scansarif.exp
load_lib dg-test-cleanup.exp
# The default do-what keyword.
set dg-do-what-default compile
# Adapted from jit.exp.
#
# Execute the executable file.
# Returns:
# A "" (empty) string if everything worked, or an error message
# if there was a problem.
#
proc fixed_host_execute {args} {
global env
global text
global spawn_id
verbose "fixed_host_execute: $args"
set timeoutmsg "Timed out: Never got started, "
set timeout 100
set file all
set timetol 0
set arguments ""
if { [llength $args] == 0} {
set executable $args
} else {
set executable [lindex $args 0]
set params [lindex $args 1]
}
verbose "The executable is $executable" 2
if {![file exists ${executable}]} {
perror "The executable, \"$executable\" is missing" 0
return "No source file found"
} elseif {![file executable ${executable}]} {
perror "The executable, \"$executable\" is not usable" 0
return "Bad executable found"
}
verbose "params: $params" 2
# spawn the executable and look for the DejaGnu output messages from the
# test case.
# spawn -noecho -open [open "|./${executable}" "r"]
# Run under valgrind if RUN_UNDER_VALGRIND is present in the environment.
# Note that it's best to configure gcc with --enable-valgrind-annotations
# when testing under valgrind.
set run_under_valgrind [info exists env(RUN_UNDER_VALGRIND)]
if $run_under_valgrind {
set valgrind_logfile "${executable}.valgrind.txt"
set valgrind_params {"valgrind"}
lappend valgrind_params "--leak-check=full"
lappend valgrind_params "--log-file=${valgrind_logfile}"
} else {
set valgrind_params {}
}
verbose "valgrind_params: $valgrind_params" 2
set args ${valgrind_params}
lappend args "./${executable}"
set args [concat $args ${params}]
verbose "args: $args" 2
set status [catch "exec -keepnewline $args" exe_output]
verbose "Test program returned $exe_output" 2
if $run_under_valgrind {
upvar 2 name name
parse_valgrind_logfile $name $valgrind_logfile fail
}
# We don't do prune_gcc_output here, as we want
# to check *exactly* what we get from libgdiagnostics
return $exe_output
}
# (end of code from dejagnu.exp)
# GCC_UNDER_TEST is needed by gcc_target_compile
global GCC_UNDER_TEST
if ![info exists GCC_UNDER_TEST] {
set GCC_UNDER_TEST "[find_gcc]"
}
g++_init
# Initialize dg.
dg-init
# Gather a list of all tests.
# C and C++ tests within the testsuite: gcc/testsuite/libgdiagnostics.dg/test-*.{c,c++}
set c_tests [find $srcdir/$subdir test-*.c]
set cxx_tests [find $srcdir/$subdir test-*.cc]
set tests [concat $c_tests $cxx_tests]
verbose "tests: $tests"
# Expand "SRCDIR" within ARG to the location of the top-level
# src directory
proc diagnostics-expand-vars {arg} {
verbose "diagnostics-expand-vars: $arg"
global srcdir
verbose " srcdir: $srcdir"
# "srcdir" is that of the gcc/testsuite directory, so
# we need to go up two levels.
set arg [string map [list "SRCDIR" $srcdir/../..] $arg]
verbose " new arg: $arg"
return $arg
}
# Parameters used when invoking the executables built from the test cases.
global diagnostics-exe-params
set diagnostics-exe-params {}
# Set "diagnostics-exe-params", expanding "SRCDIR" in each arg to the location of
# the top-level srcdir.
proc dg-diagnostics-set-exe-params { args } {
verbose "dg-diagnostics-set-exe-params: $args"
global diagnostics-exe-params
set diagnostics-exe-params {}
# Skip initial arg (line number)
foreach arg [lrange $args 1 [llength $args] ] {
lappend diagnostics-exe-params [diagnostics-expand-vars $arg]
}
}
proc libgdiagnostics-dg-test { prog do_what extra_tool_flags } {
verbose "within libgdiagnostics-dg-test..."
verbose " prog: $prog"
verbose " do_what: $do_what"
verbose " extra_tool_flags: $extra_tool_flags"
global dg-do-what-default
set dg-do-what [list ${dg-do-what-default} "" P]
# If we're not supposed to try this test on this target, we're done.
if { [lindex ${dg-do-what} 1] == "N" } {
unsupported "$name"
verbose "$name not supported on this target, skipping it" 3
return
}
# Determine what to name the built executable.
#
# We simply append .exe to the filename, e.g.
# "test-foo.c.exe"
# since some testcases exist in both
# "test-foo.c" and
# "test-foo.cc"
# variants, and we don't want them to clobber each other's
# executables.
#
# This also ensures that the source name makes it into the
# pass/fail output, so that we can distinguish e.g. which test-foo
# is failing.
set output_file "[file tail $prog].exe"
verbose "output_file: $output_file"
# Create the test executable:
set extension [file extension $prog]
if {$extension == ".cc"} {
set compilation_function "g++_target_compile"
} else {
set compilation_function "gcc_target_compile"
}
set options "{additional_flags=$extra_tool_flags}"
verbose "compilation_function=$compilation_function"
verbose "options=$options"
set comp_output [$compilation_function $prog $output_file \
"executable" $options]
upvar 1 name name
if ![libgdiagnostics_check_compile "$name" "initial compilation" \
$output_file $comp_output] then {
return
}
# Run the test executable.
# We need to set LD_LIBRARY_PATH so that the test files can find
# libgdiagnostics.so
# Do this using set_ld_library_path_env_vars from target-libpath.exp
# We will restore the old value later using
# restore_ld_library_path_env_vars.
# Unfortunately this API only supports a single saved value, rather
# than a stack, and g++_init has already called into this API,
# injecting the appropriate value for LD_LIBRARY_PATH for finding
# the built copy of libstdc++.
# Hence the call to restore_ld_library_path_env_vars would restore
# the *initial* value of LD_LIBRARY_PATH, and attempts to run
# a C++ testcase after running any prior testcases would thus look
# in the wrong place for libstdc++. This led to failures at startup
# of the form:
# ./tut01-hello-world.cc.exe: /lib64/libstdc++.so.6: version `GLIBCXX_3.4.21' not found (required by ./tut01-hello-world.cc.exe)
# when the built libstdc++ is more recent that the system libstdc++.
#
# As a workaround, reset the variable "orig_environment_saved" within
# target-libpath.exp, so that the {set|restore}_ld_library_path_env_vars
# API saves/restores the current value of LD_LIBRARY_PATH (as set up
# by g++_init).
global orig_environment_saved
set orig_environment_saved 0
global ld_library_path
global base_dir
set ld_library_path "$base_dir/../../"
set_ld_library_path_env_vars
global diagnostics-exe-params
set args ${diagnostics-exe-params}
set diagnostics-exe-params {}
set exe_output [fixed_host_execute $output_file $args ]
verbose "exe_output: $exe_output"
restore_ld_library_path_env_vars
# Analyze the output from the executable. To some what extent this
# is duplicating prune_gcc_output, but we're looking for *precise*
# output, so we can't reuse prune_gcc_output.
global testname_with_flags
set testname_with_flags $name
# Handle any freeform regexps.
set exe_output [handle-dg-regexps $exe_output]
# Call into multiline.exp to handle any multiline output directives.
set exe_output [handle-multiline-outputs $exe_output]
# Normally we would return $exe_output and $output_file to the
# caller, which would delete $output_file, the generated executable.
# If we need to debug, it's handy to be able to suppress this behavior,
# keeping the executable around.
global env
set preserve_executables [info exists env(PRESERVE_EXECUTABLES)]
if $preserve_executables {
set output_file ""
}
return [list $exe_output $output_file]
}
set DEFAULT_CFLAGS "-I$srcdir/.. -lgdiagnostics -g -Wall -Werror"
# Main loop. This will invoke jig-dg-test on each test-*.c file.
dg-runtest $tests "" $DEFAULT_CFLAGS
# All done.
dg-finish