From 41571b55b1c023158fda594eafa431e943c87819 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Wed, 17 Jun 2015 16:04:18 +0000 Subject: [PATCH] jit: Add missing type-checking to gcc_jit_{l|r}value_access_field gcc/jit/ChangeLog: * libgccjit.c (gcc_jit_lvalue_access_field): Verify that the field is for the correct struct. (gcc_jit_rvalue_access_field): Likewise. gcc/testsuite/ChangeLog: * jit.dg/test-error-accessing-field-in-other-struct.c: Rename to... * jit.dg/test-error-gcc_jit_rvalue_dereference_field-wrong-struct.c: ...this. * jit.dg/test-error-gcc_jit_lvalue_access_field-wrong-struct.c: New testcase. * jit.dg/test-error-gcc_jit_rvalue_access_field-wrong-struct.c: New testcase. From-SVN: r224565 --- gcc/jit/ChangeLog | 6 + gcc/jit/libgccjit.c | 18 +++ gcc/testsuite/ChangeLog | 10 ++ ...gcc_jit_lvalue_access_field-wrong-struct.c | 111 ++++++++++++++++++ ...gcc_jit_rvalue_access_field-wrong-struct.c | 110 +++++++++++++++++ ...t_rvalue_dereference_field-wrong-struct.c} | 0 6 files changed, 255 insertions(+) create mode 100644 gcc/testsuite/jit.dg/test-error-gcc_jit_lvalue_access_field-wrong-struct.c create mode 100644 gcc/testsuite/jit.dg/test-error-gcc_jit_rvalue_access_field-wrong-struct.c rename gcc/testsuite/jit.dg/{test-error-accessing-field-in-other-struct.c => test-error-gcc_jit_rvalue_dereference_field-wrong-struct.c} (100%) diff --git a/gcc/jit/ChangeLog b/gcc/jit/ChangeLog index d9e61b657a3..a131171a342 100644 --- a/gcc/jit/ChangeLog +++ b/gcc/jit/ChangeLog @@ -1,3 +1,9 @@ +2015-06-17 David Malcolm + + * libgccjit.c (gcc_jit_lvalue_access_field): Verify that the field + is for the correct struct. + (gcc_jit_rvalue_access_field): Likewise. + 2015-06-17 Andrew MacLeod * dummy-frontend.c: Do not include input.h, line-map.h or is-a.h. diff --git a/gcc/jit/libgccjit.c b/gcc/jit/libgccjit.c index 7eb66bdae50..dedf942ebaa 100644 --- a/gcc/jit/libgccjit.c +++ b/gcc/jit/libgccjit.c @@ -1671,6 +1671,15 @@ gcc_jit_lvalue_access_field (gcc_jit_lvalue *struct_, 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 ()); + gcc::jit::recording::type *underlying_type = + struct_->get_type (); + RETURN_NULL_IF_FAIL_PRINTF2 ( + (field->get_container ()->unqualified () + == underlying_type->unqualified ()), + struct_->m_ctxt, loc, + "%s is not a field of %s", + field->get_debug_string (), + underlying_type->get_debug_string ()); return (gcc_jit_lvalue *)struct_->access_field (loc, field); } @@ -1694,6 +1703,15 @@ gcc_jit_rvalue_access_field (gcc_jit_rvalue *struct_, 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 ()); + gcc::jit::recording::type *underlying_type = + struct_->get_type (); + RETURN_NULL_IF_FAIL_PRINTF2 ( + (field->get_container ()->unqualified () + == underlying_type->unqualified ()), + struct_->m_ctxt, loc, + "%s is not a field of %s", + field->get_debug_string (), + underlying_type->get_debug_string ()); return (gcc_jit_rvalue *)struct_->access_field (loc, field); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index af0e2c2e8e8..bc86c88e1e0 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,13 @@ +2015-06-17 David Malcolm + + * jit.dg/test-error-accessing-field-in-other-struct.c: Rename to... + * jit.dg/test-error-gcc_jit_rvalue_dereference_field-wrong-struct.c: + ...this. + * jit.dg/test-error-gcc_jit_lvalue_access_field-wrong-struct.c: + New testcase. + * jit.dg/test-error-gcc_jit_rvalue_access_field-wrong-struct.c: + New testcase. + 2015-06-17 Uros Bizjak PR testsuite/65944 diff --git a/gcc/testsuite/jit.dg/test-error-gcc_jit_lvalue_access_field-wrong-struct.c b/gcc/testsuite/jit.dg/test-error-gcc_jit_lvalue_access_field-wrong-struct.c new file mode 100644 index 00000000000..b47571e4917 --- /dev/null +++ b/gcc/testsuite/jit.dg/test-error-gcc_jit_lvalue_access_field-wrong-struct.c @@ -0,0 +1,111 @@ +#include +#include + +#include "libgccjit.h" + +#include "harness.h" + +struct foo +{ + int x; + int y; +}; + +struct bar +{ + int p; + int q; +}; + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + /* Let's try to inject the equivalent of: + void + test_bogus_access (struct foo f) + { + f.p = f.x; + } + i.e. using the wrong struct for the LHS. + */ + gcc_jit_type *void_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID); + gcc_jit_type *int_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + + /* Map "struct foo". */ + gcc_jit_field *x = + gcc_jit_context_new_field (ctxt, + NULL, + int_type, + "x"); + gcc_jit_field *y = + gcc_jit_context_new_field (ctxt, + NULL, + int_type, + "y"); + gcc_jit_field *foo_fields[] = {x, y}; + gcc_jit_struct *struct_foo = + gcc_jit_context_new_struct_type (ctxt, NULL, "foo", 2, foo_fields); + + /* Map "struct bar". */ + gcc_jit_field *p = + gcc_jit_context_new_field (ctxt, + NULL, + int_type, + "p"); + gcc_jit_field *q = + gcc_jit_context_new_field (ctxt, + NULL, + int_type, + "q"); + /* We don't actually need a gcc_jit_type for "struct bar" for the test. */ + gcc_jit_field *bar_fields[] = {p, q}; + (void)gcc_jit_context_new_struct_type (ctxt, NULL, "foo", 2, bar_fields); + + /* Build the test function. */ + gcc_jit_param *param_f = + gcc_jit_context_new_param (ctxt, NULL, + gcc_jit_struct_as_type (struct_foo), "f"); + gcc_jit_function *test_fn = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + void_type, + "test_bogus_access", + 1, ¶m_f, + 0); + + /* Erroneous: f.p = ... */ + gcc_jit_lvalue *lvalue = + gcc_jit_lvalue_access_field ( + gcc_jit_param_as_lvalue (param_f), + NULL, + p); + + /* OK: ... = f.x; */ + gcc_jit_rvalue *rvalue = + gcc_jit_lvalue_as_rvalue ( + gcc_jit_lvalue_access_field ( + gcc_jit_param_as_lvalue (param_f), + NULL, + x)); + + gcc_jit_block *block = + gcc_jit_function_new_block (test_fn, NULL); + gcc_jit_block_add_assignment ( + block, + NULL, + lvalue, rvalue); + 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_lvalue_access_field:" + " p is not a field of struct foo"); +} diff --git a/gcc/testsuite/jit.dg/test-error-gcc_jit_rvalue_access_field-wrong-struct.c b/gcc/testsuite/jit.dg/test-error-gcc_jit_rvalue_access_field-wrong-struct.c new file mode 100644 index 00000000000..c09acfb52ca --- /dev/null +++ b/gcc/testsuite/jit.dg/test-error-gcc_jit_rvalue_access_field-wrong-struct.c @@ -0,0 +1,110 @@ +#include +#include + +#include "libgccjit.h" + +#include "harness.h" + +struct foo +{ + int x; + int y; +}; + +struct bar +{ + int p; + int q; +}; + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + /* Let's try to inject the equivalent of: + void + test_bogus_access (struct foo f) + { + f.x = f.p; + } + i.e. using the wrong struct for the RHS. + */ + gcc_jit_type *void_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID); + gcc_jit_type *int_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + + /* Map "struct foo". */ + gcc_jit_field *x = + gcc_jit_context_new_field (ctxt, + NULL, + int_type, + "x"); + gcc_jit_field *y = + gcc_jit_context_new_field (ctxt, + NULL, + int_type, + "y"); + gcc_jit_field *foo_fields[] = {x, y}; + gcc_jit_struct *struct_foo = + gcc_jit_context_new_struct_type (ctxt, NULL, "foo", 2, foo_fields); + + /* Map "struct bar". */ + gcc_jit_field *p = + gcc_jit_context_new_field (ctxt, + NULL, + int_type, + "p"); + gcc_jit_field *q = + gcc_jit_context_new_field (ctxt, + NULL, + int_type, + "q"); + /* We don't actually need a gcc_jit_type for "struct bar" for the test. */ + gcc_jit_field *bar_fields[] = {p, q}; + (void)gcc_jit_context_new_struct_type (ctxt, NULL, "foo", 2, bar_fields); + + /* Build the test function. */ + gcc_jit_param *param_f = + gcc_jit_context_new_param (ctxt, NULL, + gcc_jit_struct_as_type (struct_foo), "f"); + gcc_jit_function *test_fn = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + void_type, + "test_bogus_access", + 1, ¶m_f, + 0); + + /* OK: f.x = ... */ + gcc_jit_lvalue *lvalue = + gcc_jit_lvalue_access_field ( + gcc_jit_param_as_lvalue (param_f), + NULL, + x); + + /* Erroneous: ... = f.p; */ + gcc_jit_rvalue *rvalue = + gcc_jit_rvalue_access_field ( + gcc_jit_param_as_rvalue (param_f), + NULL, + p); + + gcc_jit_block *block = + gcc_jit_function_new_block (test_fn, NULL); + gcc_jit_block_add_assignment ( + block, + NULL, + lvalue, rvalue); + 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_rvalue_access_field:" + " p is not a field of struct foo"); +} diff --git a/gcc/testsuite/jit.dg/test-error-accessing-field-in-other-struct.c b/gcc/testsuite/jit.dg/test-error-gcc_jit_rvalue_dereference_field-wrong-struct.c similarity index 100% rename from gcc/testsuite/jit.dg/test-error-accessing-field-in-other-struct.c rename to gcc/testsuite/jit.dg/test-error-gcc_jit_rvalue_dereference_field-wrong-struct.c -- 2.30.2