From: David Malcolm Date: Wed, 17 Jun 2015 16:04:18 +0000 (+0000) Subject: jit: Add missing type-checking to gcc_jit_{l|r}value_access_field X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=41571b55b1c023158fda594eafa431e943c87819;p=gcc.git 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 --- 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-accessing-field-in-other-struct.c b/gcc/testsuite/jit.dg/test-error-accessing-field-in-other-struct.c deleted file mode 100644 index f10954b434c..00000000000 --- a/gcc/testsuite/jit.dg/test-error-accessing-field-in-other-struct.c +++ /dev/null @@ -1,114 +0,0 @@ -#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->q; - } - i.e. using the wrong struct. - */ - 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); - - gcc_jit_type *foo_ptr = - gcc_jit_type_get_pointer (gcc_jit_struct_as_type (struct_foo)); - - /* Build the test function. */ - gcc_jit_param *param_f = - gcc_jit_context_new_param (ctxt, NULL, foo_ptr, "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_rvalue_dereference_field ( - gcc_jit_param_as_rvalue (param_f), - NULL, - p); - - /* Erroneous: ... = f->q; */ - gcc_jit_rvalue *rvalue = - gcc_jit_lvalue_as_rvalue ( - gcc_jit_rvalue_dereference_field ( - gcc_jit_param_as_rvalue (param_f), - NULL, - q)); - - 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_dereference_field:" - " p is not a field of struct foo"); -} - 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-gcc_jit_rvalue_dereference_field-wrong-struct.c b/gcc/testsuite/jit.dg/test-error-gcc_jit_rvalue_dereference_field-wrong-struct.c new file mode 100644 index 00000000000..f10954b434c --- /dev/null +++ b/gcc/testsuite/jit.dg/test-error-gcc_jit_rvalue_dereference_field-wrong-struct.c @@ -0,0 +1,114 @@ +#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->q; + } + i.e. using the wrong struct. + */ + 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); + + gcc_jit_type *foo_ptr = + gcc_jit_type_get_pointer (gcc_jit_struct_as_type (struct_foo)); + + /* Build the test function. */ + gcc_jit_param *param_f = + gcc_jit_context_new_param (ctxt, NULL, foo_ptr, "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_rvalue_dereference_field ( + gcc_jit_param_as_rvalue (param_f), + NULL, + p); + + /* Erroneous: ... = f->q; */ + gcc_jit_rvalue *rvalue = + gcc_jit_lvalue_as_rvalue ( + gcc_jit_rvalue_dereference_field ( + gcc_jit_param_as_rvalue (param_f), + NULL, + q)); + + 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_dereference_field:" + " p is not a field of struct foo"); +} +