123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868 |
- # Test code for libgccjit.so
- #
- # We will compile each of jit.dg/test-*.c into an executable
- # dynamically linked against libgccjit.so, and then run each
- # such executable.
- #
- # These executables call into the libgccjit.so API to create
- # code, compile it, and run it, verifying that the results
- # are as expected. See harness.h for shared code used by all
- # such executables.
- #
- # The executables call into DejaGnu's unit testing C API to
- # report PASS/FAIL results, which this script gathers back
- # up into the Tcl world, reporting a summary of all results
- # across all of the executables.
- # 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 "jit".
- # 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 jit
- 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
- # Look for lines of the form:
- # definitely lost: 11,316 bytes in 235 blocks
- # indirectly lost: 352 bytes in 4 blocks
- # Ideally these would report zero bytes lost (which is a PASS);
- # for now, report non-zero leaks as XFAILs.
- proc report_leak {kind name logfile line} {
- set match [regexp "$kind lost: .*" $line result]
- if $match {
- verbose "Saw \"$result\" within \"$line\"" 4
- # Extract bytes and blocks.
- # These can contain commas as well as numerals,
- # but we only care about whether we have zero.
- regexp "$kind lost: (.+) bytes in (.+) blocks" \
- $result -> bytes blocks
- verbose "bytes: '$bytes'" 4
- verbose "blocks: '$blocks'" 4
- if { $bytes == 0 } {
- pass "$name: $logfile: $result"
- } else {
- xfail "$name: $logfile: $result"
- }
- }
- }
- proc parse_valgrind_logfile {name logfile} {
- verbose "parse_valgrind_logfile: $logfile" 2
- if [catch {set f [open $logfile]}] {
- fail "$name: unable to read $logfile"
- return
- }
- while { [gets $f line] >= 0 } {
- # Strip off the PID prefix e.g. ==7675==
- set line [regsub "==\[0-9\]*== " $line ""]
- verbose $line 2
- report_leak "definitely" $name $logfile $line
- report_leak "indirectly" $name $logfile $line
- }
- close $f
- }
- # Given WRES, the result from "wait", issue a PASS
- # if the spawnee exited cleanly, or a FAIL for various kinds of
- # unexpected exits.
- proc verify_exit_status { executable wres } {
- lassign $wres pid spawnid os_error_flag value
- verbose "pid: $pid" 3
- verbose "spawnid: $spawnid" 3
- verbose "os_error_flag: $os_error_flag" 3
- verbose "value: $value" 3
- # Detect segfaults etc:
- if { [llength $wres] > 4 } {
- if { [lindex $wres 4] == "CHILDKILLED" } {
- fail "$executable killed: $wres"
- return
- }
- }
- if { $os_error_flag != 0 } {
- fail "$executable: OS error: $wres"
- return
- }
- if { $value != 0 } {
- fail "$executable: non-zero exit code: $wres"
- return
- }
- pass "$executable exited cleanly"
- }
- # This is host_execute from dejagnu.exp commit
- # 126a089777158a7891ff975473939f08c0e31a1c
- # with the following patch applied, and renaming to "fixed_host_execute".
- # See the discussion at
- # http://lists.gnu.org/archive/html/dejagnu/2014-10/msg00000.html
- #
- # --- /usr/share/dejagnu/dejagnu.exp.old 2014-10-08 13:38:57.274068541 -0400
- # +++ /usr/share/dejagnu/dejagnu.exp 2014-10-10 12:27:51.113813659 -0400
- # @@ -113,8 +113,6 @@ proc host_execute {args} {
- # set timetol 0
- # set arguments ""
- #
- # - expect_before buffer_full { perror "Buffer full" }
- # -
- # if { [llength $args] == 0} {
- # set executable $args
- # } else {
- # Execute the executable file, and anaylyse the output for the
- # test state keywords.
- # 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"
- }
- 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
- eval spawn -noecho $args
- expect_after full_buffer { error "got full_buffer" }
- set prefix "\[^\r\n\]*"
- expect {
- -re "^$prefix\[0-9\]\[0-9\]:..:..:${text}*\r\n" {
- regsub "\[\n\r\t\]*NOTE: $text\r\n" $expect_out(0,string) "" output
- verbose "$output" 3
- set timetol 0
- exp_continue
- }
- -re "^$prefix\tNOTE:${text}*" {
- regsub "\[\n\r\t\]*NOTE: $text\r\n" $expect_out(0,string) "" output
- set output [string range $output 6 end]
- verbose "$output" 2
- set timetol 0
- exp_continue
- }
- -re "^$prefix\tPASSED:${text}*" {
- regsub "\[\n\r\t\]*PASSED: $text\r\n" $expect_out(0,string) "" output
- set output [string range $output 8 end]
- pass "$output"
- set timetol 0
- exp_continue
- }
- -re "^$prefix\tFAILED:${text}*" {
- regsub "\[\n\r\t\]*FAILED: $text\r\n" $expect_out(0,string) "" output
- set output [string range $output 8 end]
- fail "$output"
- set timetol 0
- exp_continue
- }
- -re "^$prefix\tUNTESTED:${text}*" {
- regsub "\[\n\r\t\]*TESTED: $text\r\n" $expect_out(0,string) "" output
- set output [string range $output 8 end]
- untested "$output"
- set timetol 0
- exp_continue
- }
- -re "^$prefix\tUNRESOLVED:${text}*" {
- regsub "\[\n\r\t\]*UNRESOLVED: $text\r\n" $expect_out(0,string) "" output
- set output [string range $output 8 end]
- unresolved "$output"
- set timetol 0
- exp_continue
- }
- -re "^Totals" {
- verbose "All done" 2
- }
- eof {
- # unresolved "${executable} died prematurely"
- # catch close
- # return "${executable} died prematurely"
- }
- timeout {
- warning "Timed out executing test case"
- if { $timetol <= 2 } {
- incr timetol
- exp_continue
- } else {
- catch close
- return "Timed out executing test case"
- }
- }
- -re "^$prefix\r\n" {
- exp_continue
- }
- }
- # Use "wait" before "close": valgrind might not have finished
- # writing the log out before we parse it, so we need to wait for
- # the spawnee to finish.
- catch wait wres
- verbose "wres: $wres" 2
- verify_exit_status $executable $wres
- if $run_under_valgrind {
- upvar 2 name name
- parse_valgrind_logfile $name $valgrind_logfile
- }
- # force a close of the executable to be safe.
- catch close
- return ""
- }
- # (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 tests within the testsuite: gcc/testsuite/jit.dg/test-*.c
- set tests [find $srcdir/$subdir test-*.c]
- # C++ tests within the testsuite: gcc/testsuite/jit.dg/test-*.cc
- set tests [concat $tests [find $srcdir/$subdir test-*.cc]]
- # We also test the examples within the documentation, to ensure that
- # they compile:
- set tests [concat $tests [find $srcdir/../jit/docs/examples *.c]]
- set tests [concat $tests [find $srcdir/../jit/docs/examples *.cc]]
- set tests [lsort $tests]
- verbose "tests: $tests"
- # Is testcase NAME meant to generate a reproducer?
- proc is_testcase_meant_to_generate_a_reproducer {name} {
- # We expect most testcases to generate a reproducer.
- # The exceptions are the tutorials (which don't have a "test-"
- # prefix), and test-threads.c and test-benchmark.c (which are each
- # unique).
- verbose "is_testcase_meant_to_generate_a_reproducer: $name"
- if { [string match "*test-*" $name] } {
- if { [string match "*test-threads.c" $name] } {
- return 0
- }
- if { [string match "*test-benchmark.c" $name] } {
- return 0
- }
- return 1
- }
- return 0
- }
- # libgloss has found the driver (as "xgcc" or "gcc) and stored
- # its full path as GCC_UNDER_TEST.
- proc get_path_of_driver {} {
- global GCC_UNDER_TEST
- verbose "GCC_UNDER_TEST: $GCC_UNDER_TEST"
- set binary [lindex $GCC_UNDER_TEST 0]
- verbose "binary: $binary"
- return [file dirname $binary]
- }
- # Expand "SRCDIR" within ARG to the location of the top-level
- # src directory
- proc jit-expand-vars {arg} {
- verbose "jit-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 jit-exe-params
- set jit-exe-params {}
- # Set "jit-exe-params", expanding "SRCDIR" in each arg to the location of
- # the top-level srcdir.
- proc dg-jit-set-exe-params { args } {
- verbose "dg-jit-set-exe-params: $args"
- global jit-exe-params
- set jit-exe-params {}
- # Skip initial arg (line number)
- foreach arg [lrange $args 1 [llength $args] ] {
- lappend jit-exe-params [jit-expand-vars $arg]
- }
- }
- proc jit-dg-test { prog do_what extra_tool_flags } {
- verbose "within jit-dg-test..."
- verbose " prog: $prog"
- verbose " do_what: $do_what"
- verbose " extra_tool_flags: $extra_tool_flags"
- # test-threads.c needs to be linked against pthreads
- if {[string match "*test-threads.c" $prog]} {
- append extra_tool_flags " -lpthread"
- }
- # Any test case that uses jit-verify-output-file-was-created
- # needs to call jit-setup-compile-to-file here.
- # (is there a better way to handle setup/finish pairs in dg?)
- set tmp [grep $prog "jit-verify-output-file-was-created"]
- if {![string match "" $tmp]} {
- jit-setup-compile-to-file $prog
- }
- # 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"
- set options "{additional_flags=$extra_tool_flags}"
- } else {
- set compilation_function "gcc_target_compile"
- # Until recently, <dejagnu.h> assumed -fgnu89-inline
- # Ideally we should fixincludes it (PR other/63613), but
- # for now add -fgnu89-inline when compiling C JIT testcases.
- # See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63613
- # and http://lists.gnu.org/archive/html/dejagnu/2014-10/msg00011.html
- set options "{additional_flags=$extra_tool_flags -fgnu89-inline}"
- }
- verbose "compilation_function=$compilation_function"
- verbose "options=$options"
- set comp_output [$compilation_function $prog $output_file \
- "executable" $options]
- upvar 1 name name
- if ![jit_check_compile "$name" "initial compilation" \
- $output_file $comp_output] then {
- return
- }
- # Most of the test cases use gcc_jit_context_dump_reproducer_to_file
- # as they run to write out a .c file that reproduces their behavior,
- # exercising that API.
- set generated_reproducer "${output_file}.reproducer.c"
- # Delete any such generated .c file from a previous run.
- catch "exec rm -f $generated_reproducer"
- # Run the test executable, capturing the PASS/FAIL textual output
- # from the C API, converting it into the Tcl API.
- # We need to set LD_LIBRARY_PATH so that the test files can find
- # libgccjit.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
- # libgccjit uses the driver to convert .s files to .so libraries
- # via its *installed* name, FULL_DRIVER_NAME
- # ${target_noncanonical}-gcc-${gcc_BASEVER}${exeext}
- # e.g. "x86_64-unknown-linux-gnu-gcc-5.0.0"
- # looking for it on PATH. Hence we need to prepend the location of
- # that executable to PATH when running the tests
- set dir_containing_driver [get_path_of_driver ]
- verbose "dir_containing_driver: $dir_containing_driver"
- global env
- set old_path $env(PATH)
- setenv "PATH" $dir_containing_driver:$old_path
- verbose -log "PATH=[getenv PATH]"
- # We have:
- # test-executables
- # linked to -> libgccjit.so
- # -> invokes driver:
- # -> invokes the assembler
- # -> invokes the linker
- # We want to be able to run this from the builddir without installing
- # but the linker needs to be able to locate various libraries, or we
- # get:
- # ld: cannot find crtbeginS.o: No such file or directory
- # ld: cannot find -lgcc
- # ld: cannot find -lgcc_s
- # These can be found in the "gcc" subdir of the build.
- # Hence to be able to run the testsuite without installing, we need
- # to set or prepend the "gcc" subdir of the build to LIBRARY_PATH:
- if { [info exists env(LIBRARY_PATH) ] } {
- set old_library_path $env(LIBRARY_PATH)
- setenv "LIBRARY_PATH" $dir_containing_driver:$old_library_path
- } else {
- setenv "LIBRARY_PATH" $dir_containing_driver
- }
- verbose -log "LIBRARY_PATH=[getenv LIBRARY_PATH]"
- # dejagnu.exp's host_execute has code to scrape out test results
- # from the DejaGnu C API and bring back into the tcl world, so we
- # use that to invoke the built code.
- # However, it appears to be buggy; see:
- # http://lists.gnu.org/archive/html/dejagnu/2014-10/msg00000.html
- # We instead call a patched local copy, "fixed_host_execute", defined
- # above.
- global jit-exe-params
- set args ${jit-exe-params}
- set jit-exe-params {}
- set result [fixed_host_execute $output_file $args ]
- verbose "result: $result"
- # Restore PATH
- setenv "PATH" $old_path
- # Restore LIBRARY_PATH
- if { [info exists old_library_path] } {
- setenv "LIBRARY_PATH" $old_library_path
- } else {
- unsetenv "LIBRARY_PATH"
- }
- restore_ld_library_path_env_vars
- # Most of the test cases use gcc_jit_context_dump_reproducer_to_file
- # as they run to write out a .c file that reproduces their behavior,
- # exercising that API.
- if { [is_testcase_meant_to_generate_a_reproducer $name] } {
- verbose "$name is meant to generate a reproducer"
- # Verify that a reproducer was generated
- if { [file exists $generated_reproducer] == 1} {
- pass "found generated reproducer: $generated_reproducer"
- set output_file "${generated_reproducer}.exe"
- # (this overwrites output_file)
- # Try to compile the generated reproducer
- verbose "compilation_function=$compilation_function"
- # The .c file written by gcc_jit_context_dump_reproducer_to_file
- # assigns the result of each API call to a unique variable, and not
- # all are necessarily used, so we need -Wno-unused-variable.
- set options \
- "{additional_flags=$extra_tool_flags -Wno-unused-variable}"
- verbose "options=$options"
- set comp_output2 [$compilation_function $generated_reproducer \
- $output_file "executable" $options]
- if ![jit_check_compile "generated reproducer from $name" "initial compilation" \
- $output_file $comp_output2] then {
- return
- }
- # The caller, dg-test, will verify comp_output, which contains
- # the output from compiling the testcase and will issue a fail
- # if it's non-empty (e.g. containing warnings, the
- # "test for excess errors").
- #
- # Append the output from compiling the reproducer, so that this is also
- # verified:
- append comp_output $comp_output2
- # TODO: we should try to run the built executable
- # It's not quite a quine, since it embeds ptrs which could change
- # from run to run.
- } else {
- fail "did not find a generated reproducer: $generated_reproducer"
- }
- } else {
- verbose "$name is not meant to generate a reproducer"
- }
- return [list $comp_output $output_file]
- }
- # Given source file PROG, scrape out the value of
- # #define OUTPUT_FILENAME
- # failing if it's not found.
- proc jit-get-output-filename {prog} {
- set tmp [grep $prog "#define OUTPUT_FILENAME (.*)"]
- if {![string match "" $tmp]} {
- foreach i $tmp {
- verbose "i: $i"
- if {[regexp "^\#define OUTPUT_FILENAME\[ \t\]\+\"(.*)\"$" $i i group] } {
- verbose "group: '$group'"
- return $group
- } else {
- fail "Unable to parse line: $i"
- }
- }
- }
- fail "Unable to locate OUTPUT_FILENAME"
- return ""
- }
- # For testcases that use jit-verify-output-file-was-created
- # delete OUTPUT_FILENAME beforehand, to ensure that the
- # testcase is indeed creating it.
- proc jit-setup-compile-to-file { prog } {
- verbose "jit-setup-compile-to-file: $prog"
- set output_filename [jit-get-output-filename $prog]
- verbose " output_filename: $output_filename"
- if {![string match "" $output_filename]} {
- verbose " deleting any $output_filename"
- catch "exec rm -f $output_filename"
- }
- }
- proc jit-verify-output-file-was-created { args } {
- verbose "jit-verify-output-file-was-created: $args"
- upvar 2 prog prog
- verbose "prog: $prog"
- set output_filename [jit-get-output-filename $prog]
- verbose " output_filename: $output_filename"
- # Verify that the expected file was written out
- if { [file exists $output_filename] == 1} {
- pass "$output_filename exists"
- } else {
- fail "$output_filename does not exist"
- }
- }
- # Verify that the given file exists, and is executable.
- # Attempt to execute it, and verify that its stdout matches
- # the given regex.
- proc jit-run-executable { args } {
- verbose "jit-run-executable: $args"
- set executable-name [lindex $args 0]
- verbose "executable-name: ${executable-name}"
- set dg-output-text [lindex $args 1]
- verbose "dg-output-text: ${dg-output-text}"
- if { [file executable ${executable-name}] } {
- pass "${executable-name} has executable bit set"
- } else {
- fail "${executable-name} does not have executable bit set"
- }
- # Attempt to run the executable; adapted from dg.exp's dg-test
- set status -1
- set result [jit_load ./${executable-name}]
- set status [lindex $result 0]
- set output [lindex $result 1]
- verbose " status: $status"
- verbose " output: $output"
- # send_user "After exec, status: $status\n"
- if { "$status" == "pass" } {
- pass "${executable-name} execution test"
- verbose "Exec succeeded." 3
- set texttmp ${dg-output-text}
- if { ![regexp $texttmp ${output}] } {
- fail "${executable-name} output pattern test, is ${output}, should match $texttmp"
- verbose "Failed test for output pattern $texttmp" 3
- } else {
- pass "${executable-name} output pattern test, $texttmp"
- verbose "Passed test for output pattern $texttmp" 3
- }
- unset texttmp
- } elseif { "$status" == "fail" } {
- # It would be nice to get some info out of errorCode.
- if {[info exists errorCode]} {
- verbose "Exec failed, errorCode: $errorCode" 3
- } else {
- verbose "Exec failed, errorCode not defined!" 3
- }
- fail "${executable-name} execution test"
- } else {
- $status "${executable-name} execution test"
- }
- }
- # Assuming that a .s file has been written out named
- # OUTPUT_FILENAME, invoke the driver to try to turn it into
- # an executable, and try to run the result.
- # For use by the test-compile-to-assembler.c testcase.
- proc jit-verify-assembler { args } {
- verbose "jit-verify-assembler: $args"
- set dg-output-text [lindex $args 0]
- verbose "dg-output-text: ${dg-output-text}"
- upvar 2 name name
- verbose "name: $name"
- upvar 2 prog prog
- verbose "prog: $prog"
- set asm_filename [jit-get-output-filename $prog]
- verbose " asm_filename: ${asm_filename}"
- # Name the built executable as OUTPUT_FILENAME with
- # ".exe" appended.
- set executable_from_asm ${asm_filename}.exe
- verbose " executable_from_asm: ${executable_from_asm}"
- # Invoke the driver to assemble/link the .s file to the .exe
- set comp_output [gcc_target_compile \
- ${asm_filename} \
- ${executable_from_asm} \
- "executable" \
- "{}"]
- if ![jit_check_compile \
- "$name" \
- "assemble/link of ${asm_filename}" \
- ${executable_from_asm} \
- $comp_output] then {
- return
- }
- # Verify that the executable was created.
- if { [file exists $executable_from_asm] == 1} {
- pass "$executable_from_asm exists"
- } else {
- fail "$executable_from_asm does not exist"
- }
- # Run it and verify that the output matches the regex.
- jit-run-executable ${executable_from_asm} ${dg-output-text}
- }
- # Assuming that a .o file has been written out named
- # OUTPUT_FILENAME, invoke the driver to try to turn it into
- # an executable, and try to run the result.
- # For use by the test-compile-to-object.c testcase.
- proc jit-verify-object { args } {
- verbose "jit-verify-object: $args"
- set dg-output-text [lindex $args 0]
- verbose "dg-output-text: ${dg-output-text}"
- upvar 2 name name
- verbose "name: $name"
- upvar 2 prog prog
- verbose "prog: $prog"
- set obj_filename [jit-get-output-filename $prog]
- verbose " obj_filename: ${obj_filename}"
- # Name the linked executable as OUTPUT_FILENAME with
- # ".exe" appended.
- set executable_from_obj ${obj_filename}.exe
- verbose " executable_from_obj: ${executable_from_obj}"
- # Invoke the driver to link the .o file to the .exe
- set comp_output [gcc_target_compile \
- ${obj_filename} \
- ${executable_from_obj} \
- "executable" \
- "{}"]
- if ![jit_check_compile \
- "$name" \
- "link of ${obj_filename}" \
- ${executable_from_obj} \
- $comp_output] then {
- return
- }
- # Verify that the executable was created.
- if { [file exists $executable_from_obj] == 1} {
- pass "$executable_from_obj exists"
- } else {
- fail "$executable_from_obj does not exist"
- }
- # Run it and verify that the output matches the regex.
- jit-run-executable ${executable_from_obj} ${dg-output-text}
- }
- # Assuming that a .so file has been written out named
- # OUTPUT_FILENAME, build a test executable to use it,
- # and try to run the result.
- # For use by the test-compile-to-dynamic-library.c testcase.
- proc jit-verify-dynamic-library { args } {
- verbose "jit-verify-object: $args"
- global srcdir
- global subdir
- set dg-output-text [lindex $args 0]
- verbose "dg-output-text: ${dg-output-text}"
- upvar 2 name name
- verbose "name: $name"
- upvar 2 prog prog
- verbose "prog: $prog"
- set obj_filename [jit-get-output-filename $prog]
- verbose " obj_filename: ${obj_filename}"
- # Build a test executable from
- # verify-dynamic-library.c
- set test_src "verify-dynamic-library.c"
- set test_executable ${test_src}.exe
- verbose " test_executable: ${test_executable}"
- # Invoke the driver to build the test executable
- set comp_output [gcc_target_compile \
- $srcdir/$subdir/${test_src} \
- ${test_executable} \
- "executable" \
- "{additional_flags=-ldl}"]
- if ![jit_check_compile \
- "$name" \
- "build of ${test_executable}" \
- ${test_executable} \
- $comp_output] then {
- return
- }
- # Verify that the test executable was created.
- if { [file exists $test_executable] == 1} {
- pass "$test_executable exists"
- } else {
- fail "$test_executable does not exist"
- }
- # Run it and verify that the output matches the regex.
- jit-run-executable ${test_executable} ${dg-output-text}
- }
- # A way to invoke "jit-run-executable" with the given regex,
- # using OUTPUT_FILENAME within the testcase to determine
- # the name of the executable to run.
- # For use by the test-compile-to-executable.c testcase.
- proc jit-verify-executable { args } {
- verbose "jit-verify-executable: $args"
- set dg-output-text [lindex $args 0]
- verbose "dg-output-text: ${dg-output-text}"
- upvar 2 name name
- verbose "name: $name"
- upvar 2 prog prog
- verbose "prog: $prog"
- set output_filename [jit-get-output-filename $prog]
- verbose " output_filename: $output_filename"
- jit-run-executable $output_filename ${dg-output-text}
- }
- # We need to link with --export-dynamic for test-calling-external-function.c
- # so that the JIT-built code can call into functions from the main program.
- set DEFAULT_CFLAGS "-I$srcdir/../jit -lgccjit -g -Wall -Werror -Wl,--export-dynamic"
- # Main loop. This will invoke jig-dg-test on each test-*.c file.
- dg-runtest $tests "" $DEFAULT_CFLAGS
- # All done.
- dg-finish
|