From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 29934 invoked by alias); 19 Mar 2014 17:01:49 -0000 Mailing-List: contact jit-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Post: List-Help: List-Subscribe: Sender: jit-owner@gcc.gnu.org Received: (qmail 29904 invoked by uid 89); 19 Mar 2014 17:01:48 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Checked: by ClamAV 0.98.1 on sourceware.org X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL,BAYES_00,SPF_HELO_PASS,SPF_PASS,T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-Spam-Status: No, score=-2.3 required=5.0 tests=AWL,BAYES_00,SPF_HELO_PASS,SPF_PASS,T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on sourceware.org X-Spam-Level: X-Spam-User: qpsmtpd, 2 recipients X-HELO: mx1.redhat.com From: David Malcolm To: jit@gcc.gnu.org, gcc-patches@gcc.gnu.org Cc: David Malcolm Subject: [jit] Tighten up the distinction between pointers and arrays Date: Wed, 01 Jan 2014 00:00:00 -0000 Message-Id: <1395248564-11235-1-git-send-email-dmalcolm@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.12 X-SW-Source: 2014-q1/txt/msg00085.txt.bz2 Committed to branch dmalcolm/jit: https://github.com/davidmalcolm/pygccjit/pull/3#issuecomment-37883129 showed a problem where a parameter expecting a (char *) was passed a char[1024] cast to a (char *) as its argument, leading to an ICE: libgccjit.so: internal compiler error: in convert_move, at expr.c:320 0x7fffebea98ad convert_move(rtx_def*, rtx_def*, int) ../../src/gcc/expr.c:320 0x7fffebec31cb expand_expr_real_2(separate_ops*, rtx_def*, machine_mode, expand_modifier) ../../src/gcc/expr.c:8105 0x7fffec88d768 expand_gimple_stmt_1 ../../src/gcc/cfgexpand.c:2321 0x7fffec88d9cc expand_gimple_stmt ../../src/gcc/cfgexpand.c:2381 The issue was that the recording::type::dereference method is used for both pointers and for arrays, leading to sloppiness about where lvalues and rvalues can be pointers vs arrays. This commit introduces is_pointer and is_array methods, using them to tighten up type-checking, converting the above ICE into an type-check error when the cast is attempted: libgccjit.so: error: gcc_jit_context_new_cast: cannot cast buffer from type: char[1024] to type: char * The correct way to use an array as a pointer in the JIT API is to use gcc_jit_lvalue_get_address on the array, which gives you an rvalue representing the address of the initial element, and then to cast that rvalue as necessary. gcc/jit * internal-api.c (gcc::jit::recording::memento_of_get_pointer:: accepts_writes_from): Accept writes from pointers, but not arrays. * internal-api.h (gcc::jit::recording::type::is_pointer): New. (gcc::jit::recording::type::is_array): New. (gcc::jit::recording::memento_of_get_type::accepts_writes_from): Allow (void *) to accept writes of pointers, but not arrays. (gcc::jit::recording::memento_of_get_type::is_pointer): New. (gcc::jit::recording::memento_of_get_type::is_array): New. (gcc::jit::recording::memento_of_get_pointer::is_pointer): New. (gcc::jit::recording::memento_of_get_pointer::is_array): New. (gcc::jit::recording::memento_of_get_const::is_pointer): New. (gcc::jit::recording::memento_of_get_const::is_array): New. (gcc::jit::recording::memento_of_get_volatile::is_pointer): New. (gcc::jit::recording::memento_of_get_volatile::is_array): New. (gcc::jit::recording::array_type::is_pointer): New. (gcc::jit::recording::array_type::is_array): New. (gcc::jit::recording::function_type::is_pointer): New. (gcc::jit::recording::function_type::is_array): New. (gcc::jit::recording::struct_::is_pointer): New. (gcc::jit::recording::struct_::is_array): New. * libgccjit.c (gcc_jit_context_new_rvalue_from_ptr): Require the pointer_type to be a pointer, not an array. (gcc_jit_context_null): Likewise. (is_valid_cast): Require pointer casts to be between pointer types, not arrays. (gcc_jit_context_new_array_access): Update error message from "not a pointer" to "not a pointer or array". (gcc_jit_rvalue_dereference_field): Require the pointer arg to be of pointer type, not an array. (gcc_jit_rvalue_dereference): Likewise. gcc/testsuite/ * jit.dg/test-array-as-pointer.c: New test case, verifying that there's a way to treat arrays as pointers. * jit.dg/test-combination.c: Add test-array-as-pointer.c... (create_code): ...here and... (verify_code): ...here. * jit.dg/test-error-array-as-pointer.c: New test case, verifying that bogus casts from array to pointer are caught by the type system, rather than leading to ICEs seen in: https://github.com/davidmalcolm/pygccjit/pull/3#issuecomment-37883129 --- gcc/jit/ChangeLog.jit | 35 +++++++ gcc/jit/internal-api.c | 2 +- gcc/jit/internal-api.h | 18 +++- gcc/jit/libgccjit.c | 14 +-- gcc/testsuite/ChangeLog.jit | 13 +++ gcc/testsuite/jit.dg/test-array-as-pointer.c | 101 +++++++++++++++++++++ gcc/testsuite/jit.dg/test-combination.c | 9 ++ gcc/testsuite/jit.dg/test-error-array-as-pointer.c | 99 ++++++++++++++++++++ 8 files changed, 282 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/jit.dg/test-array-as-pointer.c create mode 100644 gcc/testsuite/jit.dg/test-error-array-as-pointer.c diff --git a/gcc/jit/ChangeLog.jit b/gcc/jit/ChangeLog.jit index 8244eba..efb1931 100644 --- a/gcc/jit/ChangeLog.jit +++ b/gcc/jit/ChangeLog.jit @@ -1,3 +1,38 @@ +2014-03-19 David Malcolm + + * internal-api.c (gcc::jit::recording::memento_of_get_pointer:: + accepts_writes_from): Accept writes from pointers, but not arrays. + + * internal-api.h (gcc::jit::recording::type::is_pointer): New. + (gcc::jit::recording::type::is_array): New. + (gcc::jit::recording::memento_of_get_type::accepts_writes_from): + Allow (void *) to accept writes of pointers, but not arrays. + (gcc::jit::recording::memento_of_get_type::is_pointer): New. + (gcc::jit::recording::memento_of_get_type::is_array): New. + (gcc::jit::recording::memento_of_get_pointer::is_pointer): New. + (gcc::jit::recording::memento_of_get_pointer::is_array): New. + (gcc::jit::recording::memento_of_get_const::is_pointer): New. + (gcc::jit::recording::memento_of_get_const::is_array): New. + (gcc::jit::recording::memento_of_get_volatile::is_pointer): New. + (gcc::jit::recording::memento_of_get_volatile::is_array): New. + (gcc::jit::recording::array_type::is_pointer): New. + (gcc::jit::recording::array_type::is_array): New. + (gcc::jit::recording::function_type::is_pointer): New. + (gcc::jit::recording::function_type::is_array): New. + (gcc::jit::recording::struct_::is_pointer): New. + (gcc::jit::recording::struct_::is_array): New. + + * libgccjit.c (gcc_jit_context_new_rvalue_from_ptr): Require the + pointer_type to be a pointer, not an array. + (gcc_jit_context_null): Likewise. + (is_valid_cast): Require pointer casts to be between pointer types, + not arrays. + (gcc_jit_context_new_array_access): Update error message from "not + a pointer" to "not a pointer or array". + (gcc_jit_rvalue_dereference_field): Require the pointer arg to be + of pointer type, not an array. + (gcc_jit_rvalue_dereference): Likewise. + 2014-03-14 David Malcolm * libgccjit.c (is_valid_cast): Permit casts between pointer types. diff --git a/gcc/jit/internal-api.c b/gcc/jit/internal-api.c index 8e0395d..e3ddc4d 100644 --- a/gcc/jit/internal-api.c +++ b/gcc/jit/internal-api.c @@ -1048,7 +1048,7 @@ bool recording::memento_of_get_pointer::accepts_writes_from (type *rtype) { /* Must be a pointer type: */ - type *rtype_points_to = rtype->dereference (); + type *rtype_points_to = rtype->is_pointer (); if (!rtype_points_to) return false; diff --git a/gcc/jit/internal-api.h b/gcc/jit/internal-api.h index 772f828..34c1de3 100644 --- a/gcc/jit/internal-api.h +++ b/gcc/jit/internal-api.h @@ -496,6 +496,8 @@ public: virtual bool is_int () const = 0; virtual bool is_float () const = 0; virtual bool is_bool () const = 0; + virtual type *is_pointer () = 0; + virtual type *is_array () = 0; playback::type * playback_type () @@ -527,7 +529,7 @@ public: bool accepts_writes_from (type *rtype) { if (m_kind == GCC_JIT_TYPE_VOID_PTR) - if (rtype->dereference ()) + if (rtype->is_pointer ()) { /* LHS (this) is type (void *), and the RHS is a pointer: accept it: */ @@ -540,6 +542,8 @@ public: bool is_int () const; bool is_float () const; bool is_bool () const; + type *is_pointer () { return dereference (); } + type *is_array () { return NULL; } public: void replay_into (replayer *r); @@ -568,6 +572,8 @@ public: bool is_int () const { return false; } bool is_float () const { return false; } bool is_bool () const { return false; } + type *is_pointer () { return m_other_type; } + type *is_array () { return NULL; } private: string * make_debug_string (); @@ -598,6 +604,8 @@ public: bool is_int () const { return m_other_type->is_int (); } bool is_float () const { return m_other_type->is_float (); } bool is_bool () const { return m_other_type->is_bool (); } + type *is_pointer () { return m_other_type->is_pointer (); } + type *is_array () { return m_other_type->is_array (); } void replay_into (replayer *); @@ -624,6 +632,8 @@ public: bool is_int () const { return m_other_type->is_int (); } bool is_float () const { return m_other_type->is_float (); } bool is_bool () const { return m_other_type->is_bool (); } + type *is_pointer () { return m_other_type->is_pointer (); } + type *is_array () { return m_other_type->is_array (); } void replay_into (replayer *); @@ -652,6 +662,8 @@ class array_type : public type bool is_int () const { return false; } bool is_float () const { return false; } bool is_bool () const { return false; } + type *is_pointer () { return NULL; } + type *is_array () { return m_element_type; } void replay_into (replayer *); @@ -679,6 +691,8 @@ public: bool is_int () const { return false; } bool is_float () const { return false; } bool is_bool () const { return false; } + type *is_pointer () { return NULL; } + type *is_array () { return NULL; } void replay_into (replayer *); @@ -756,6 +770,8 @@ public: bool is_int () const { return false; } bool is_float () const { return false; } bool is_bool () const { return false; } + type *is_pointer () { return NULL; } + type *is_array () { return NULL; } void replay_into (replayer *r); diff --git a/gcc/jit/libgccjit.c b/gcc/jit/libgccjit.c index 5acb1bc..c9805de 100644 --- a/gcc/jit/libgccjit.c +++ b/gcc/jit/libgccjit.c @@ -721,7 +721,7 @@ gcc_jit_context_new_rvalue_from_ptr (gcc_jit_context *ctxt, RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context"); RETURN_NULL_IF_FAIL (pointer_type, ctxt, NULL, "NULL type"); RETURN_NULL_IF_FAIL_PRINTF1 ( - pointer_type->dereference (), + pointer_type->is_pointer (), ctxt, NULL, "not a pointer type (type: %s)", pointer_type->get_debug_string ()); @@ -736,7 +736,7 @@ gcc_jit_context_null (gcc_jit_context *ctxt, RETURN_NULL_IF_FAIL (ctxt, NULL, NULL, "NULL context"); RETURN_NULL_IF_FAIL (pointer_type, ctxt, NULL, "NULL type"); RETURN_NULL_IF_FAIL_PRINTF1 ( - pointer_type->dereference (), + pointer_type->is_pointer (), ctxt, NULL, "not a pointer type (type: %s)", pointer_type->get_debug_string ()); @@ -906,8 +906,8 @@ is_valid_cast (gcc::jit::recording::type *src_type, 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 (); + gcc::jit::recording::type *deref_src_type = src_type->is_pointer (); + gcc::jit::recording::type *deref_dst_type = dst_type->is_pointer (); if (deref_src_type && deref_dst_type) return true; @@ -946,7 +946,7 @@ gcc_jit_context_new_array_access (gcc_jit_context *ctxt, RETURN_NULL_IF_FAIL_PRINTF2 ( ptr->get_type ()->dereference (), ctxt, loc, - "%s (type: %s) is not a pointer", + "%s (type: %s) is not a pointer or array", ptr->get_debug_string (), ptr->get_type ()->get_debug_string ()); @@ -1007,7 +1007,7 @@ gcc_jit_rvalue_dereference_field (gcc_jit_rvalue *ptr, RETURN_NULL_IF_FAIL (ptr, NULL, loc, "NULL ptr"); RETURN_NULL_IF_FAIL (field, NULL, loc, "NULL field"); gcc::jit::recording::type *underlying_type = - ptr->get_type ()->dereference (); + ptr->get_type ()->is_pointer (); RETURN_NULL_IF_FAIL_PRINTF1 (field->get_container (), field->m_ctxt, loc, "field %s has not been placed in a struct", field->get_debug_string ()); @@ -1036,7 +1036,7 @@ gcc_jit_rvalue_dereference (gcc_jit_rvalue *rvalue, RETURN_NULL_IF_FAIL (rvalue, NULL, loc, "NULL rvalue"); gcc::jit::recording::type *underlying_type = - rvalue->get_type ()->dereference (); + rvalue->get_type ()->is_pointer (); RETURN_NULL_IF_FAIL_PRINTF2 ( underlying_type, diff --git a/gcc/testsuite/ChangeLog.jit b/gcc/testsuite/ChangeLog.jit index e07ba87..393bd8f 100644 --- a/gcc/testsuite/ChangeLog.jit +++ b/gcc/testsuite/ChangeLog.jit @@ -1,3 +1,16 @@ +2014-03-19 David Malcolm + + * jit.dg/test-array-as-pointer.c: New test case, verifying that + there's a way to treat arrays as pointers. + * jit.dg/test-combination.c: Add test-array-as-pointer.c... + (create_code): ...here and... + (verify_code): ...here. + + * jit.dg/test-error-array-as-pointer.c: New test case, verifying + that bogus casts from array to pointer are caught by the type + system, rather than leading to ICEs seen in: + https://github.com/davidmalcolm/pygccjit/pull/3#issuecomment-37883129 + 2014-03-18 David Malcolm * jit.dg/test-combination.c: Add test-arrays.c and test-volatile.c. diff --git a/gcc/testsuite/jit.dg/test-array-as-pointer.c b/gcc/testsuite/jit.dg/test-array-as-pointer.c new file mode 100644 index 0000000..1a240ac --- /dev/null +++ b/gcc/testsuite/jit.dg/test-array-as-pointer.c @@ -0,0 +1,101 @@ +#include +#include +#include + +#include "libgccjit.h" + +#include "harness.h" + +#define BUFFER_SIZE (1024) + +char test_buffer[1024]; + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + /* Let's try to inject the equivalent of: + void test_of_array_as_pointer (const char *name) + { + snprintf (test_buffer, sizeof (test_buffer), + "hello %s", 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_type *char_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CHAR); + gcc_jit_type *char_ptr_type = + gcc_jit_type_get_pointer (char_type); + gcc_jit_type *int_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + gcc_jit_type *size_t_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_SIZE_T); + gcc_jit_type *buf_type = + gcc_jit_context_new_array_type (ctxt, NULL, char_type, BUFFER_SIZE); + + /* extern int snprintf(char *str, size_t size, const char *format, ...); */ + gcc_jit_param *param_s = + gcc_jit_context_new_param (ctxt, NULL, char_ptr_type, "s"); + gcc_jit_param *param_n = + gcc_jit_context_new_param (ctxt, NULL, size_t_type, "n"); + gcc_jit_param *param_format = + gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "format"); + gcc_jit_param *snprintf_params[3] = {param_s, param_n, param_format}; + gcc_jit_function *snprintf = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_IMPORTED, + int_type, + "snprintf", + 3, snprintf_params, + 1); + + gcc_jit_param *param_name = + gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "name"); + gcc_jit_function *test_fn = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + void_type, + "test_of_array_as_pointer", + 1, ¶m_name, + 0); + + gcc_jit_lvalue *buffer = + gcc_jit_context_new_global (ctxt, NULL, buf_type, "test_buffer"); + + gcc_jit_block *block = gcc_jit_function_new_block(test_fn, "entry"); + + /* snprintf(buffer, sizeof(buffer), "hello %s", name); */ + gcc_jit_rvalue *args[4]; + args[0] = gcc_jit_context_new_cast ( + ctxt, NULL, + /* Here's the difference with test-error-array-as-pointer.c: */ + gcc_jit_lvalue_get_address (buffer, + NULL), + char_ptr_type); + args[1] = gcc_jit_context_new_rvalue_from_int (ctxt, + size_t_type, + BUFFER_SIZE); + args[2] = gcc_jit_context_new_string_literal (ctxt, "hello %s"); + args[3] = gcc_jit_param_as_rvalue (param_name); + + gcc_jit_block_add_eval ( + block, NULL, + gcc_jit_context_new_call (ctxt, NULL, snprintf, 4, args)); + gcc_jit_block_end_with_void_return (block, NULL); +} + +void +verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) +{ + CHECK_NON_NULL (result); + + typedef void (*fn_type) (const char *); + fn_type test_of_array_as_pointer = + (fn_type)gcc_jit_result_get_code (result, "test_of_array_as_pointer"); + CHECK_NON_NULL (test_of_array_as_pointer); + + test_of_array_as_pointer ("world"); + CHECK_STRING_VALUE (test_buffer, "hello world"); +} diff --git a/gcc/testsuite/jit.dg/test-combination.c b/gcc/testsuite/jit.dg/test-combination.c index 72b8602..6f65592 100644 --- a/gcc/testsuite/jit.dg/test-combination.c +++ b/gcc/testsuite/jit.dg/test-combination.c @@ -14,6 +14,13 @@ #undef create_code #undef verify_code +/* test-array-as-pointer.c */ +#define create_code create_code_array_as_pointer +#define verify_code verify_code_array_as_pointer +#include "test-array-as-pointer.c" +#undef create_code +#undef verify_code + /* test-arrays.c */ #define create_code create_code_arrays #define verify_code verify_code_arrays @@ -141,6 +148,7 @@ void create_code (gcc_jit_context *ctxt, void * user_data) { create_code_accessing_struct (ctxt, user_data); + create_code_array_as_pointer (ctxt, user_data); create_code_arrays (ctxt, user_data); create_code_calling_external_function (ctxt, user_data); create_code_dot_product (ctxt, user_data); @@ -161,6 +169,7 @@ void verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) { verify_code_accessing_struct (ctxt, result); + verify_code_array_as_pointer (ctxt, result); verify_code_arrays (ctxt, result); verify_code_calling_external_function (ctxt, result); verify_code_dot_product (ctxt, result); diff --git a/gcc/testsuite/jit.dg/test-error-array-as-pointer.c b/gcc/testsuite/jit.dg/test-error-array-as-pointer.c new file mode 100644 index 0000000..cd2b7f8 --- /dev/null +++ b/gcc/testsuite/jit.dg/test-error-array-as-pointer.c @@ -0,0 +1,99 @@ +#include +#include +#include + +#include "libgccjit.h" + +#include "harness.h" + +#define BUFFER_SIZE (1024) + +char test_buffer[1024]; + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + /* Let's try to inject the equivalent of: + void test_of_array_as_pointer (const char *name) + { + snprintf (test_buffer, sizeof (test_buffer), + "hello %s", 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_type *char_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CHAR); + gcc_jit_type *char_ptr_type = + gcc_jit_type_get_pointer (char_type); + gcc_jit_type *int_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + gcc_jit_type *size_t_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_SIZE_T); + gcc_jit_type *buf_type = + gcc_jit_context_new_array_type (ctxt, NULL, char_type, BUFFER_SIZE); + + /* extern int snprintf(char *str, size_t size, const char *format, ...); */ + gcc_jit_param *param_s = + gcc_jit_context_new_param (ctxt, NULL, char_ptr_type, "s"); + gcc_jit_param *param_n = + gcc_jit_context_new_param (ctxt, NULL, size_t_type, "n"); + gcc_jit_param *param_format = + gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "format"); + gcc_jit_param *snprintf_params[3] = {param_s, param_n, param_format}; + gcc_jit_function *snprintf = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_IMPORTED, + int_type, + "snprintf", + 3, snprintf_params, + 1); + + gcc_jit_param *param_name = + gcc_jit_context_new_param (ctxt, NULL, const_char_ptr_type, "name"); + gcc_jit_function *test_fn = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + void_type, + "test_of_array_as_pointer", + 1, ¶m_name, + 0); + + gcc_jit_lvalue *buffer = + gcc_jit_context_new_global (ctxt, NULL, buf_type, "test_buffer"); + + gcc_jit_block *block = gcc_jit_function_new_block(test_fn, "entry"); + + /* snprintf(buffer, sizeof(buffer), "hello %s", name); */ + gcc_jit_rvalue *args[4]; + args[0] = gcc_jit_context_new_cast ( + ctxt, NULL, + /* Here's the difference with test-array-as-pointer.c: */ + gcc_jit_lvalue_as_rvalue (buffer), + char_ptr_type); + args[1] = gcc_jit_context_new_rvalue_from_int (ctxt, + size_t_type, + BUFFER_SIZE); + args[2] = gcc_jit_context_new_string_literal (ctxt, "hello %s"); + args[3] = gcc_jit_param_as_rvalue (param_name); + + gcc_jit_block_add_eval ( + block, NULL, + gcc_jit_context_new_call (ctxt, NULL, snprintf, 4, args)); + gcc_jit_block_end_with_void_return (block, NULL); +} + +void +verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) +{ + CHECK_VALUE (result, NULL); + + /* Verify that the correct error message was emitted. */ + CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt), + "gcc_jit_context_new_cast:" + " cannot cast test_buffer" + " from type: char[1024]" + " to type: char *"); +} -- 1.8.5.3