The jit testsuite attempted to test the gcc_jit_context_compile_to_file API entrypoint by running "file" on the generated file, and comparing the result against a regexp.
This approach is unfixable: some hosts won't have "file" installed, and the output of "file" seems to vary enough from host to host that this test can never be made sane. For example, on i686 Fedora I get: FAIL: 'file' output on output-of-test-compile-to-assembler.c.s did not match: assembler source text since the output was: output-of-test-compile-to-assembler.c.s: assembler source, ASCII text and I've seen output (on ppc iirc) that read just "ASCII text" The tests also weren't performing a functional verification. The attached patch eliminates this use of "file", in favor of sanity-checking the output more directly, introducing functions to jit.exp: jit-verify-assembler jit-verify-object jit-verify-dynamic-library alongside the existing jit-verify-executable, to verify that the .s, .o or .so file generated by the test executable (via libgccjit) can be used as expected. For .s and .o it attempts to run the driver again to build an executable, and then run it. For .so it attempts to build a simple executable that dlopens the .so file. This presumably adds further host==target assumptions into the jit testsuite, but that's already assumed, and I don't plan to tackle that until GCC 6. The patch also some extra checking to ensure that no errors occur when calling gcc_jit_context_compile_to_file. Tested via "make check-jit" on 3 architectures: x86_64-unknown-linux-gnu: Before: 7571 passes, no failures After: 7602 passes, no failures powerpc64-unknown-linux-gnu: Before: 7570 passes and 1 failure (PR jit/64752) After: 7602 passes, no failures. s390x-ibm-linux-gnu: Before: 7570 passes and 1 failure (PR jit/64752) After: 7602 passes, no failures Committed to trunk as r220494. gcc/testsuite/ChangeLog: PR jit/64752 * jit.dg/create-code-for-hello-world-executable.h: New file, taken from jit.dg/test-compile-to-executable.c's create_code, with a clarification of the output message. * jit.dg/harness.h (CHECK_NO_ERRORS): Add test and __func__ to the pass/fail message. (test_jit): Use CHECK_NO_ERRORS when calling gcc_jit_context_compile_to_file. * jit.dg/jit.exp (jit-dg-test): Update grep for rename of jit-verify-compile-to-file to jit-verify-output-file-was-created. (jit-setup-compile-to-file): Likewise. Add a verbose comment about deletions that are attempted. (jit-verify-compile-to-file): Rename to... (jit-verify-output-file-was-created): ...this, and drop the attempt to run "file" and verify the output. (jit-verify-assembler): New function. (jit-verify-object): New function. (jit-verify-dynamic-library): New function. * jit.dg/test-compile-to-assembler.c (create_code): Eliminate in favor of an implementation from new file create-code-for-hello-world-executable.h, which also adds a "main". (dg-final): Replace jit-verify-compile-to-file with jit-verify-output-file-was-created, and invoke new function jit-verify-assembler. * jit.dg/test-compile-to-dynamic-library.c (create_code): Clarify the output message. (dg-final): Replace jit-verify-compile-to-file with jit-verify-output-file-was-created, and invoke new function jit-verify-dynamic-library. * jit.dg/test-compile-to-executable.c (create_code): Eliminate in favor of an implementation from new file create-code-for-hello-world-executable.h, which also adds a "main". (dg-final): Replace jit-verify-compile-to-file with jit-verify-output-file-was-created. Strengthen the expected stdout from the built executable. * jit.dg/test-compile-to-object.c (create_code): Eliminate in favor of an implementation from new file create-code-for-hello-world-executable.h, which also adds a "main". (dg-final): Replace jit-verify-compile-to-file with jit-verify-output-file-was-created, and invoke new function jit-verify-object. * jit.dg/verify-dynamic-library.c: New source file. --- .../create-code-for-hello-world-executable.h | 101 +++++++++++ gcc/testsuite/jit.dg/harness.h | 5 +- gcc/testsuite/jit.dg/jit.exp | 187 +++++++++++++++++---- gcc/testsuite/jit.dg/test-compile-to-assembler.c | 58 +------ .../jit.dg/test-compile-to-dynamic-library.c | 7 +- gcc/testsuite/jit.dg/test-compile-to-executable.c | 103 +----------- gcc/testsuite/jit.dg/test-compile-to-object.c | 58 +------ gcc/testsuite/jit.dg/verify-dynamic-library.c | 41 +++++ 8 files changed, 312 insertions(+), 248 deletions(-) create mode 100644 gcc/testsuite/jit.dg/create-code-for-hello-world-executable.h create mode 100644 gcc/testsuite/jit.dg/verify-dynamic-library.c diff --git a/gcc/testsuite/jit.dg/create-code-for-hello-world-executable.h b/gcc/testsuite/jit.dg/create-code-for-hello-world-executable.h new file mode 100644 index 0000000..363171f --- /dev/null +++ b/gcc/testsuite/jit.dg/create-code-for-hello-world-executable.h @@ -0,0 +1,101 @@ +/* This code is shared by various test-compile-to-*.c test cases + that ultimately generate a standalone executable + (all of them apart from test-compile-to-dynamic-library.c). */ + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + /* Let's try to inject the equivalent of: + static void + hello_world (const char *name) + { + // a test comment + printf ("hello from %s\n", name); + } + + extern int + main (int argc, char **argv) + { + hello_world (argv[0]); + return 0; + } + */ + gcc_jit_type *void_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID); + gcc_jit_type *const_char_ptr_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CONST_CHAR_PTR); + gcc_jit_param *param_name = + gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "name"); + gcc_jit_function *func = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_INTERNAL, + void_type, + "hello_world", + 1, ¶m_name, + 0); + + gcc_jit_param *param_format = + gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "format"); + gcc_jit_function *printf_func = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_IMPORTED, + gcc_jit_context_get_type ( + ctxt, GCC_JIT_TYPE_INT), + "printf", + 1, ¶m_format, + 1); + gcc_jit_rvalue *args[2]; + args[0] = gcc_jit_context_new_string_literal (ctxt, "hello from %s\n"); + args[1] = gcc_jit_param_as_rvalue (param_name); + + gcc_jit_block *block = gcc_jit_function_new_block (func, NULL); + + gcc_jit_block_add_comment ( + block, NULL, + "a test comment"); + + gcc_jit_block_add_eval ( + block, NULL, + gcc_jit_context_new_call (ctxt, + NULL, + printf_func, + 2, args)); + gcc_jit_block_end_with_void_return (block, NULL); + + gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + gcc_jit_param *param_argc = + gcc_jit_context_new_param (ctxt, NULL, int_type, "argc"); + gcc_jit_type *char_ptr_ptr_type = + gcc_jit_type_get_pointer ( + gcc_jit_type_get_pointer ( + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CHAR))); + gcc_jit_param *param_argv = + gcc_jit_context_new_param (ctxt, NULL, char_ptr_ptr_type, "argv"); + gcc_jit_param *params[2] = {param_argc, param_argv}; + gcc_jit_function *func_main = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + int_type, + "main", + 2, params, + 0); + block = gcc_jit_function_new_block (func_main, NULL); + gcc_jit_rvalue *zero = gcc_jit_context_zero (ctxt, int_type); + args[0] = gcc_jit_context_new_cast ( + ctxt, + NULL, + gcc_jit_lvalue_as_rvalue ( + gcc_jit_context_new_array_access ( + ctxt, + NULL, + gcc_jit_param_as_rvalue (param_argv), + zero)), + const_char_ptr_type); + gcc_jit_block_add_eval ( + block, NULL, + gcc_jit_context_new_call (ctxt, + NULL, + func, + 1, args)); + gcc_jit_block_end_with_return (block, NULL, zero); +} diff --git a/gcc/testsuite/jit.dg/harness.h b/gcc/testsuite/jit.dg/harness.h index a702a23..907da56 100644 --- a/gcc/testsuite/jit.dg/harness.h +++ b/gcc/testsuite/jit.dg/harness.h @@ -112,9 +112,9 @@ static char test[1024]; do { \ const char *err = gcc_jit_context_get_first_error (CTXT); \ if (err) \ - fail ("error unexpectedly occurred: %s", err); \ + fail ("%s: %s: error unexpectedly occurred: %s", test, __func__, err); \ else \ - pass ("no errors occurred"); \ + pass ("%s: %s: no errors occurred", test, __func__); \ } while (0) /* Hooks that testcases should provide. */ @@ -362,6 +362,7 @@ test_jit (const char *argv0, void *user_data) gcc_jit_context_compile_to_file (ctxt, (OUTPUT_KIND), (OUTPUT_FILENAME)); + CHECK_NO_ERRORS (ctxt); #else /* #ifdef TEST_COMPILING_TO_FILE */ /* This actually calls into GCC and runs the build, all in a mutex for now. */ diff --git a/gcc/testsuite/jit.dg/jit.exp b/gcc/testsuite/jit.dg/jit.exp index c853f22..d13f6b5 100644 --- a/gcc/testsuite/jit.dg/jit.exp +++ b/gcc/testsuite/jit.dg/jit.exp @@ -375,11 +375,10 @@ proc jit-dg-test { prog do_what extra_tool_flags } { append extra_tool_flags " -lpthread" } - # Any test case that uses - # { dg-final { jit-verify-compile-to-file FOO } } + # 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-compile-to-file"] + set tmp [grep $prog "jit-verify-output-file-was-created"] if {![string match "" $tmp]} { jit-setup-compile-to-file $prog } @@ -601,7 +600,7 @@ proc jit-get-output-filename {prog} { return "" } -# For testcases that use jit-verify-compile-to-file, +# For testcases that use jit-verify-output-file-was-created # delete OUTPUT_FILENAME beforehand, to ensure that the # testcase is indeed creating it. @@ -610,21 +609,13 @@ proc 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" } } -# Locate OUTPUT_FILENAME within the testcase. Verify -# that a file with that name was created, and that -# the output of running the "file" utility on it -# matches the given regex. -# For use by the various test-compile-to-*.c testcases. - -proc jit-verify-compile-to-file {args} { - verbose "jit-verify-compile-to-file: $args" - - set file_regex [lindex $args 0] - verbose "file_regex: $file_regex" +proc jit-verify-output-file-was-created { args } { + verbose "jit-verify-output-file-was-created: $args" upvar 2 prog prog verbose "prog: $prog" @@ -636,25 +627,7 @@ proc jit-verify-compile-to-file {args} { pass "$output_filename exists" } else { fail "$output_filename does not exist" - return - } - - # Run "file" on OUTPUT_FILENAME, and verify that the output - # matches $file_regex. - spawn -noecho "file" $output_filename - set file_id $spawn_id - expect "\n" { - verbose "got newline: $expect_out(buffer)" - set classification $expect_out(buffer) - verbose "classification: $classification" - if { [regexp $file_regex $classification] } { - pass "'file' output on $output_filename matched: $file_regex" - } else { - fail "'file' output on $output_filename did not match: $file_regex" - } } - set $spawn_id $file_id - close } # Verify that the given file exists, and is executable. @@ -709,6 +682,154 @@ proc jit-run-executable { args } { } } +# 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. diff --git a/gcc/testsuite/jit.dg/test-compile-to-assembler.c b/gcc/testsuite/jit.dg/test-compile-to-assembler.c index c5b282c..e3a6d2e 100644 --- a/gcc/testsuite/jit.dg/test-compile-to-assembler.c +++ b/gcc/testsuite/jit.dg/test-compile-to-assembler.c @@ -7,59 +7,7 @@ #define OUTPUT_KIND GCC_JIT_OUTPUT_KIND_ASSEMBLER #define OUTPUT_FILENAME "output-of-test-compile-to-assembler.c.s" #include "harness.h" +#include "create-code-for-hello-world-executable.h" -void -create_code (gcc_jit_context *ctxt, void *user_data) -{ - /* Let's try to inject the equivalent of: - void - hello_world (const char *name) - { - // a test comment - printf ("hello %s\n", name); - } - */ - gcc_jit_type *void_type = - gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID); - gcc_jit_type *const_char_ptr_type = - gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CONST_CHAR_PTR); - gcc_jit_param *param_name = - gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "name"); - gcc_jit_function *func = - gcc_jit_context_new_function (ctxt, NULL, - GCC_JIT_FUNCTION_EXPORTED, - void_type, - "hello_world", - 1, ¶m_name, - 0); - - gcc_jit_param *param_format = - gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "format"); - gcc_jit_function *printf_func = - gcc_jit_context_new_function (ctxt, NULL, - GCC_JIT_FUNCTION_IMPORTED, - gcc_jit_context_get_type ( - ctxt, GCC_JIT_TYPE_INT), - "printf", - 1, ¶m_format, - 1); - gcc_jit_rvalue *args[2]; - args[0] = gcc_jit_context_new_string_literal (ctxt, "hello %s\n"); - args[1] = gcc_jit_param_as_rvalue (param_name); - - gcc_jit_block *block = gcc_jit_function_new_block (func, NULL); - - gcc_jit_block_add_comment ( - block, NULL, - "a test comment"); - - gcc_jit_block_add_eval ( - block, NULL, - gcc_jit_context_new_call (ctxt, - NULL, - printf_func, - 2, args)); - gcc_jit_block_end_with_void_return (block, NULL); -} - -/* { dg-final { jit-verify-compile-to-file "assembler source text" } } */ +/* { dg-final { jit-verify-output-file-was-created "" } } */ +/* { dg-final { jit-verify-assembler "hello from ./output-of-test-compile-to-assembler.c.s.exe" } } */ diff --git a/gcc/testsuite/jit.dg/test-compile-to-dynamic-library.c b/gcc/testsuite/jit.dg/test-compile-to-dynamic-library.c index 095f751..c29e6f6 100644 --- a/gcc/testsuite/jit.dg/test-compile-to-dynamic-library.c +++ b/gcc/testsuite/jit.dg/test-compile-to-dynamic-library.c @@ -16,7 +16,7 @@ create_code (gcc_jit_context *ctxt, void *user_data) hello_world (const char *name) { // a test comment - printf ("hello %s\n", name); + printf ("hello from %s\n", name); } */ gcc_jit_type *void_type = @@ -44,7 +44,7 @@ create_code (gcc_jit_context *ctxt, void *user_data) 1, ¶m_format, 1); gcc_jit_rvalue *args[2]; - args[0] = gcc_jit_context_new_string_literal (ctxt, "hello %s\n"); + args[0] = gcc_jit_context_new_string_literal (ctxt, "hello from %s\n"); args[1] = gcc_jit_param_as_rvalue (param_name); gcc_jit_block *block = gcc_jit_function_new_block (func, NULL); @@ -62,4 +62,5 @@ create_code (gcc_jit_context *ctxt, void *user_data) gcc_jit_block_end_with_void_return (block, NULL); } -/* { dg-final { jit-verify-compile-to-file "shared object.+dynamically linked" } } */ +/* { dg-final { jit-verify-output-file-was-created "" } } */ +/* { dg-final { jit-verify-dynamic-library "hello from ./verify-dynamic-library.c.exe" } } */ diff --git a/gcc/testsuite/jit.dg/test-compile-to-executable.c b/gcc/testsuite/jit.dg/test-compile-to-executable.c index 8d7b428..2fb0bd9 100644 --- a/gcc/testsuite/jit.dg/test-compile-to-executable.c +++ b/gcc/testsuite/jit.dg/test-compile-to-executable.c @@ -7,104 +7,7 @@ #define OUTPUT_KIND GCC_JIT_OUTPUT_KIND_EXECUTABLE #define OUTPUT_FILENAME "output-of-test-compile-to-executable.c.exe" #include "harness.h" +#include "create-code-for-hello-world-executable.h" -void -create_code (gcc_jit_context *ctxt, void *user_data) -{ - /* Let's try to inject the equivalent of: - static void - hello_world (const char *name) - { - // a test comment - printf ("hello %s\n", name); - } - - extern int - main (int argc, char **argv) - { - hello_world (argv[0]); - return 0; - } - */ - gcc_jit_type *void_type = - gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID); - gcc_jit_type *const_char_ptr_type = - gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CONST_CHAR_PTR); - gcc_jit_param *param_name = - gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "name"); - gcc_jit_function *func = - gcc_jit_context_new_function (ctxt, NULL, - GCC_JIT_FUNCTION_INTERNAL, - void_type, - "hello_world", - 1, ¶m_name, - 0); - - gcc_jit_param *param_format = - gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "format"); - gcc_jit_function *printf_func = - gcc_jit_context_new_function (ctxt, NULL, - GCC_JIT_FUNCTION_IMPORTED, - gcc_jit_context_get_type ( - ctxt, GCC_JIT_TYPE_INT), - "printf", - 1, ¶m_format, - 1); - gcc_jit_rvalue *args[2]; - args[0] = gcc_jit_context_new_string_literal (ctxt, "hello %s\n"); - args[1] = gcc_jit_param_as_rvalue (param_name); - - gcc_jit_block *block = gcc_jit_function_new_block (func, NULL); - - gcc_jit_block_add_comment ( - block, NULL, - "a test comment"); - - gcc_jit_block_add_eval ( - block, NULL, - gcc_jit_context_new_call (ctxt, - NULL, - printf_func, - 2, args)); - gcc_jit_block_end_with_void_return (block, NULL); - - gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); - gcc_jit_param *param_argc = - gcc_jit_context_new_param (ctxt, NULL, int_type, "argc"); - gcc_jit_type *char_ptr_ptr_type = - gcc_jit_type_get_pointer ( - gcc_jit_type_get_pointer ( - gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CHAR))); - gcc_jit_param *param_argv = - gcc_jit_context_new_param (ctxt, NULL, char_ptr_ptr_type, "argv"); - gcc_jit_param *params[2] = {param_argc, param_argv}; - gcc_jit_function *func_main = - gcc_jit_context_new_function (ctxt, NULL, - GCC_JIT_FUNCTION_EXPORTED, - int_type, - "main", - 2, params, - 0); - block = gcc_jit_function_new_block (func_main, NULL); - gcc_jit_rvalue *zero = gcc_jit_context_zero (ctxt, int_type); - args[0] = gcc_jit_context_new_cast ( - ctxt, - NULL, - gcc_jit_lvalue_as_rvalue ( - gcc_jit_context_new_array_access ( - ctxt, - NULL, - gcc_jit_param_as_rvalue (param_argv), - zero)), - const_char_ptr_type); - gcc_jit_block_add_eval ( - block, NULL, - gcc_jit_context_new_call (ctxt, - NULL, - func, - 1, args)); - gcc_jit_block_end_with_return (block, NULL, zero); -} - -/* { dg-final { jit-verify-compile-to-file "executable" } } */ -/* { dg-final { jit-verify-executable "hello .*" } } */ +/* { dg-final { jit-verify-output-file-was-created "" } } */ +/* { dg-final { jit-verify-executable "hello from ./output-of-test-compile-to-executable.c.exe" } } */ diff --git a/gcc/testsuite/jit.dg/test-compile-to-object.c b/gcc/testsuite/jit.dg/test-compile-to-object.c index 1f7fcc6..81d41c2 100644 --- a/gcc/testsuite/jit.dg/test-compile-to-object.c +++ b/gcc/testsuite/jit.dg/test-compile-to-object.c @@ -7,59 +7,7 @@ #define OUTPUT_KIND GCC_JIT_OUTPUT_KIND_OBJECT_FILE #define OUTPUT_FILENAME "output-of-test-compile-to-object.c.o" #include "harness.h" +#include "create-code-for-hello-world-executable.h" -void -create_code (gcc_jit_context *ctxt, void *user_data) -{ - /* Let's try to inject the equivalent of: - void - hello_world (const char *name) - { - // a test comment - printf ("hello %s\n", name); - } - */ - gcc_jit_type *void_type = - gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID); - gcc_jit_type *const_char_ptr_type = - gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CONST_CHAR_PTR); - gcc_jit_param *param_name = - gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "name"); - gcc_jit_function *func = - gcc_jit_context_new_function (ctxt, NULL, - GCC_JIT_FUNCTION_EXPORTED, - void_type, - "hello_world", - 1, ¶m_name, - 0); - - gcc_jit_param *param_format = - gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "format"); - gcc_jit_function *printf_func = - gcc_jit_context_new_function (ctxt, NULL, - GCC_JIT_FUNCTION_IMPORTED, - gcc_jit_context_get_type ( - ctxt, GCC_JIT_TYPE_INT), - "printf", - 1, ¶m_format, - 1); - gcc_jit_rvalue *args[2]; - args[0] = gcc_jit_context_new_string_literal (ctxt, "hello %s\n"); - args[1] = gcc_jit_param_as_rvalue (param_name); - - gcc_jit_block *block = gcc_jit_function_new_block (func, NULL); - - gcc_jit_block_add_comment ( - block, NULL, - "a test comment"); - - gcc_jit_block_add_eval ( - block, NULL, - gcc_jit_context_new_call (ctxt, - NULL, - printf_func, - 2, args)); - gcc_jit_block_end_with_void_return (block, NULL); -} - -/* { dg-final { jit-verify-compile-to-file "relocatable" } } */ +/* { dg-final { jit-verify-output-file-was-created "" } } */ +/* { dg-final { jit-verify-object "hello from ./output-of-test-compile-to-object.c.o.exe" } } */ diff --git a/gcc/testsuite/jit.dg/verify-dynamic-library.c b/gcc/testsuite/jit.dg/verify-dynamic-library.c new file mode 100644 index 0000000..99f9128 --- /dev/null +++ b/gcc/testsuite/jit.dg/verify-dynamic-library.c @@ -0,0 +1,41 @@ +/* For use by jit-verify-dynamic-library, used by + test-compile-to-dynamic-library.c. */ +#include <dlfcn.h> +#include <stdio.h> +#include <stdlib.h> + +int +main (int argc, char **argv) +{ + void *handle; + void (*hello_world) (const char *name); + char *error; + + handle = dlopen ("./output-of-test-compile-to-dynamic-library.c.so", + RTLD_NOW | RTLD_LOCAL); + if (!handle) + { + fprintf (stderr, "dlopen failed: %s\n", dlerror()); + exit (1); + } + + /* Clear any existing error */ + dlerror (); + + /* This symbol is from the DSO built by + test-compile-to-dynamic-library.c. */ + *(void **) (&hello_world) = dlsym (handle, "hello_world"); + + if ((error = dlerror()) != NULL) + { + fprintf (stderr, "dlsym failed: %s\n", error); + exit (2); + } + + /* Call the function from the generated DSO. */ + hello_world (argv[0]); + + dlclose (handle); + + return 0; +} -- 1.8.5.3