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, &param_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

Reply via email to