Committed to branch dmalcolm/jit: gcc/jit/ * internal-api.c (gcc::jit::recording::memento_of_get_pointer:: accepts_writes_from): Avoid segfaulting when the argument is not of pointer type. * internal-api.h (gcc::jit::recording::accepts_writes_from): Add an assertion. * libgccjit.c (gcc_jit_context_new_comparison): Strip away const and volatile when comparing input types.
gcc/testsuite/ * jit.dg/test-error-mismatching-types-in-call.c: New test case, to ensure that a (struct foo *) vs (struct foo) type error is gracefully handled. --- gcc/jit/ChangeLog.jit | 10 +++ gcc/jit/internal-api.c | 7 +- gcc/jit/internal-api.h | 1 + gcc/jit/libgccjit.c | 2 +- gcc/testsuite/ChangeLog.jit | 6 ++ .../jit.dg/test-error-mismatching-types-in-call.c | 80 ++++++++++++++++++++++ 6 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/jit.dg/test-error-mismatching-types-in-call.c diff --git a/gcc/jit/ChangeLog.jit b/gcc/jit/ChangeLog.jit index 56f7b85..b9172a1 100644 --- a/gcc/jit/ChangeLog.jit +++ b/gcc/jit/ChangeLog.jit @@ -1,5 +1,15 @@ 2014-03-04 David Malcolm <dmalc...@redhat.com> + * internal-api.c (gcc::jit::recording::memento_of_get_pointer:: + accepts_writes_from): Avoid segfaulting when the argument is not + of pointer type. + * internal-api.h (gcc::jit::recording::accepts_writes_from): Add + an assertion. + * libgccjit.c (gcc_jit_context_new_comparison): Strip away const + and volatile when comparing input types. + +2014-03-04 David Malcolm <dmalc...@redhat.com> + * libgccjit.h (gcc_jit_type_get_volatile): New. * libgccjit.map (gcc_jit_type_get_volatile): New. * libgccjit.c (gcc_jit_type_get_volatile): New. diff --git a/gcc/jit/internal-api.c b/gcc/jit/internal-api.c index 539ba5e..835aa7f 100644 --- a/gcc/jit/internal-api.c +++ b/gcc/jit/internal-api.c @@ -891,9 +891,14 @@ recording::memento_of_get_type::make_debug_string () bool recording::memento_of_get_pointer::accepts_writes_from (type *rtype) { + /* Must be a pointer type: */ + type *rtype_points_to = rtype->dereference (); + if (!rtype_points_to) + return false; + /* It's OK to assign to a (const T *) from a (T *). */ return m_other_type->unqualified () - ->accepts_writes_from (rtype->dereference ()); + ->accepts_writes_from (rtype_points_to); } void diff --git a/gcc/jit/internal-api.h b/gcc/jit/internal-api.h index dd760c7..5c11085 100644 --- a/gcc/jit/internal-api.h +++ b/gcc/jit/internal-api.h @@ -480,6 +480,7 @@ public: /* Is it typesafe to copy to this type from rtype? */ virtual bool accepts_writes_from (type *rtype) { + gcc_assert (rtype); return this == rtype->unqualified (); } diff --git a/gcc/jit/libgccjit.c b/gcc/jit/libgccjit.c index b4c7d44..75fdfeb 100644 --- a/gcc/jit/libgccjit.c +++ b/gcc/jit/libgccjit.c @@ -784,7 +784,7 @@ gcc_jit_context_new_comparison (gcc_jit_context *ctxt, RETURN_NULL_IF_FAIL (a, ctxt, "NULL a"); RETURN_NULL_IF_FAIL (b, ctxt, "NULL b"); RETURN_NULL_IF_FAIL_PRINTF4 ( - a->get_type () == b->get_type (), + a->get_type ()->unqualified () == b->get_type ()->unqualified (), ctxt, "mismatching types for comparison:" " a: %s (type: %s) b: %s (type: %s)", diff --git a/gcc/testsuite/ChangeLog.jit b/gcc/testsuite/ChangeLog.jit index f0548f4..f66a844 100644 --- a/gcc/testsuite/ChangeLog.jit +++ b/gcc/testsuite/ChangeLog.jit @@ -1,5 +1,11 @@ 2014-03-04 David Malcolm <dmalc...@redhat.com> + * jit.dg/test-error-mismatching-types-in-call.c: New test case, + to ensure that a (struct foo *) vs (struct foo) type error is + gracefully handled. + +2014-03-04 David Malcolm <dmalc...@redhat.com> + * jit.dg/test-volatile.c: New testcase, to exercise gcc_jit_type_get_volatile, and show a way to work with pre-existing global variables. diff --git a/gcc/testsuite/jit.dg/test-error-mismatching-types-in-call.c b/gcc/testsuite/jit.dg/test-error-mismatching-types-in-call.c new file mode 100644 index 0000000..203c4ca --- /dev/null +++ b/gcc/testsuite/jit.dg/test-error-mismatching-types-in-call.c @@ -0,0 +1,80 @@ +#include <stdlib.h> +#include <stdio.h> + +#include "libgccjit.h" + +#include "harness.h" + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + /* Let's try to inject the equivalent of: + + struct foo; + + extern void called_function (struct foo *ptr); + + void + test_fn () + { + struct foo f; + called_function (f); + } + + and verify that we get a type error (foo * vs foo). + */ + gcc_jit_type *void_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID); + gcc_jit_struct *struct_foo = + gcc_jit_context_new_opaque_struct (ctxt, NULL, "foo"); + gcc_jit_type *foo_ptr = + gcc_jit_type_get_pointer (gcc_jit_struct_as_type (struct_foo)); + gcc_jit_param *param = + gcc_jit_context_new_param (ctxt, NULL, foo_ptr, "ptr"); + + gcc_jit_function *called_function = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_IMPORTED, + void_type, + "called_function", + 1, ¶m, + 0); + + gcc_jit_function *test_fn = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + void_type, + "test_fn", + 0, NULL, + 0); + gcc_jit_lvalue *f = + gcc_jit_function_new_local ( + test_fn, NULL, gcc_jit_struct_as_type (struct_foo), "f"); + + gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL); + + gcc_jit_rvalue *arg = gcc_jit_lvalue_as_rvalue (f); + + gcc_jit_block_add_eval ( + block, NULL, + gcc_jit_context_new_call ( + ctxt, NULL, + called_function, + 1, &arg)); + 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_call:" + " mismatching types for argument 1" + " of function \"called_function\":" + " assignment to param ptr (type: struct foo *)" + " from f (type: struct foo)"); +} + -- 1.7.11.7