Committed to branch dmalcolm/jit: gcc/jit/ * libgccjit.c (is_valid_cast): Permit casts between pointer types.
* internal-api.c (convert): Report more information if this ever occurs, and make the error occur on the playback context, so that it makes the gcc_jit_result be NULL. (gcc::jit::playback::context::build_cast): Handle pointers. Report more information if an unhandlable cast reaches here. gcc/testsuite/ * jit.dg/test-expressions.c (called_pointer_checking_function): New. (make_tests_of_casts): Add test of casting from array to pointer. (verify_casts): Likewise. --- gcc/jit/ChangeLog.jit | 10 ++++ gcc/jit/internal-api.c | 21 +++++-- gcc/jit/libgccjit.c | 6 ++ gcc/testsuite/ChangeLog.jit | 6 ++ gcc/testsuite/jit.dg/test-expressions.c | 98 +++++++++++++++++++++++++++++++++ 5 files changed, 137 insertions(+), 4 deletions(-) diff --git a/gcc/jit/ChangeLog.jit b/gcc/jit/ChangeLog.jit index 260273c..8244eba 100644 --- a/gcc/jit/ChangeLog.jit +++ b/gcc/jit/ChangeLog.jit @@ -1,3 +1,13 @@ +2014-03-14 David Malcolm <dmalc...@redhat.com> + + * libgccjit.c (is_valid_cast): Permit casts between pointer types. + + * internal-api.c (convert): Report more information if this ever + occurs, and make the error occur on the playback context, so that + it makes the gcc_jit_result be NULL. + (gcc::jit::playback::context::build_cast): Handle pointers. Report + more information if an unhandlable cast reaches here. + 2014-03-13 David Malcolm <dmalc...@redhat.com> * libgccjit.c (is_valid_cast): New. diff --git a/gcc/jit/internal-api.c b/gcc/jit/internal-api.c index 062095e..8e0395d 100644 --- a/gcc/jit/internal-api.c +++ b/gcc/jit/internal-api.c @@ -33,9 +33,14 @@ extern tree convert (tree type, tree expr); tree -convert (tree /*type*/, tree /*expr*/) -{ - error ("unhandled conversion"); +convert (tree dst_type, tree expr) +{ + gcc_assert (gcc::jit::active_playback_ctxt); + gcc::jit::active_playback_ctxt->add_error (NULL, "unhandled conversion"); + fprintf (stderr, "input expression:\n"); + debug_tree (expr); + fprintf (stderr, "requested type:\n"); + debug_tree (dst_type); return error_mark_node; } @@ -3095,8 +3100,16 @@ playback::context::build_cast (playback::location *loc, t_ret = convert_to_real (t_dst_type, t_expr); goto maybe_fold; + case POINTER_TYPE: + t_ret = build1 (NOP_EXPR, t_dst_type, t_expr); + goto maybe_fold; + default: - add_error (loc, "can't handle cast"); + add_error (loc, "couldn't handle cast during playback"); + fprintf (stderr, "input expression:\n"); + debug_tree (t_expr); + fprintf (stderr, "requested type:\n"); + debug_tree (t_dst_type); return error_mark_node; maybe_fold: diff --git a/gcc/jit/libgccjit.c b/gcc/jit/libgccjit.c index baab60d..5acb1bc 100644 --- a/gcc/jit/libgccjit.c +++ b/gcc/jit/libgccjit.c @@ -905,6 +905,12 @@ is_valid_cast (gcc::jit::recording::type *src_type, if (dst_is_int || dst_is_bool) return true; + /* Permit casts between pointer types. */ + gcc::jit::recording::type *deref_src_type = src_type->dereference (); + gcc::jit::recording::type *deref_dst_type = dst_type->dereference (); + if (deref_src_type && deref_dst_type) + return true; + return false; } diff --git a/gcc/testsuite/ChangeLog.jit b/gcc/testsuite/ChangeLog.jit index b8f1fa8..1d8c11c 100644 --- a/gcc/testsuite/ChangeLog.jit +++ b/gcc/testsuite/ChangeLog.jit @@ -1,3 +1,9 @@ +2014-03-14 David Malcolm <dmalc...@redhat.com> + + * jit.dg/test-expressions.c (called_pointer_checking_function): New. + (make_tests_of_casts): Add test of casting from array to pointer. + (verify_casts): Likewise. + 2014-03-13 David Malcolm <dmalc...@redhat.com> * jit.dg/test-error-bad-cast.c: New test case. diff --git a/gcc/testsuite/jit.dg/test-expressions.c b/gcc/testsuite/jit.dg/test-expressions.c index 07fe9d6..4873098 100644 --- a/gcc/testsuite/jit.dg/test-expressions.c +++ b/gcc/testsuite/jit.dg/test-expressions.c @@ -492,6 +492,14 @@ make_test_of_cast (gcc_jit_context *ctxt, gcc_jit_rvalue_as_object (cast)); } +/* For use by test_cast_from_array_of_ints_to_int_ptr. */ +extern int called_pointer_checking_function (int *ints) +{ + CHECK_VALUE (ints[0], 10); + CHECK_VALUE (ints[1], 4); + return ints[0] * ints[1]; +} + static void make_tests_of_casts (gcc_jit_context *ctxt) { @@ -501,6 +509,12 @@ make_tests_of_casts (gcc_jit_context *ctxt) gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT); gcc_jit_type *bool_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_BOOL); + gcc_jit_type *array_int_type = + gcc_jit_context_new_array_type (ctxt, NULL, + int_type, + 2); + gcc_jit_type *int_ptr_type = + gcc_jit_type_get_pointer (int_type); /* float/int conversions */ CHECK_STRING_VALUE ( @@ -529,6 +543,79 @@ make_tests_of_casts (gcc_jit_context *ctxt) bool_type, "test_cast_from_int_to_bool"), "(bool)a"); + + /* array/ptr conversions */ + { + gcc_jit_function *test_fn = + gcc_jit_context_new_function ( + ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + int_type, + "test_cast_from_array_of_ints_to_int_ptr", + 0, NULL, + 0); + /* Equivalent to: + int test_cast_from_array_of_ints_to_int_ptr (void) + { + int array[2]; + array[0] = 10; + array[1] = 4; + return called_pointer_checking_function (array); + } + */ + + gcc_jit_param *param_ints = + gcc_jit_context_new_param (ctxt, NULL, int_ptr_type, "ints"); + gcc_jit_function *called_fn = + gcc_jit_context_new_function ( + ctxt, NULL, + GCC_JIT_FUNCTION_IMPORTED, + int_type, + "called_pointer_checking_function", + 1, ¶m_ints, + 0); + + gcc_jit_lvalue *array = + gcc_jit_function_new_local (test_fn, NULL, + array_int_type, + "array"); + gcc_jit_block *block = + gcc_jit_function_new_block (test_fn, "block"); + /* array[0] = 10; */ + gcc_jit_block_add_assignment ( + block, NULL, + gcc_jit_context_new_array_access ( + ctxt, NULL, + gcc_jit_lvalue_as_rvalue (array), + gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 0)), + gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 10)); + /* array[1] = 4; */ + gcc_jit_block_add_assignment ( + block, NULL, + gcc_jit_context_new_array_access ( + ctxt, NULL, + gcc_jit_lvalue_as_rvalue (array), + gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 1)), + gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 4)); + gcc_jit_rvalue *cast = + gcc_jit_context_new_cast ( + ctxt, + NULL, + /* We need a get_address here. */ + gcc_jit_lvalue_get_address (array, NULL), + int_ptr_type); + gcc_jit_block_end_with_return ( + block, NULL, + gcc_jit_context_new_call ( + ctxt, NULL, + called_fn, + 1, &cast)); + + CHECK_STRING_VALUE ( + gcc_jit_object_get_debug_string ( + gcc_jit_rvalue_as_object (cast)), + "(int *)&array"); + } } static void @@ -575,6 +662,17 @@ verify_casts (gcc_jit_result *result) CHECK_VALUE (test_cast_from_int_to_bool (0), 0); CHECK_VALUE (test_cast_from_int_to_bool (1), 1); } + + /* array to ptr */ + { + typedef int (*fn_type) (void); + fn_type test_cast_from_array_of_ints_to_int_ptr = + (fn_type)gcc_jit_result_get_code ( + result, + "test_cast_from_array_of_ints_to_int_ptr"); + CHECK_NON_NULL (test_cast_from_array_of_ints_to_int_ptr); + CHECK_VALUE (test_cast_from_array_of_ints_to_int_ptr (), 40); + } } /********************************************************************** -- 1.8.5.3