Prevent use of opaque structs for fields, globals and locals. Tested with "make check-jit"; jit.sum goes from 8434 to 8494 passes.
Committed to trunk as r225523. gcc/jit/ChangeLog: PR jit/66783 * jit-recording.h: Within namespace gcc:jit::recording... (type::has_known_size): New virtual function. (struct_has_known_size): New function. * libgccjit.c (gcc_jit_context_new_field): Verify that the type has a known size. (gcc_jit_context_new_global): Likewise. (gcc_jit_function_new_local): Likewise. gcc/testsuite/ChangeLog: PR jit/66783 * jit.dg/test-error-gcc_jit_context_new_field-opaque-struct.c: New test case. * jit.dg/test-error-gcc_jit_context_new_global-opaque-struct.c: New test case. * jit.dg/test-error-gcc_jit_function_new_local-opaque-struct.c: New test case. * jit.dg/test-error-mismatching-types-in-call.c (create_code): Avoid using an opaque struct for local "f". --- gcc/jit/jit-recording.h | 3 ++ gcc/jit/libgccjit.c | 15 ++++++++ ...error-gcc_jit_context_new_field-opaque-struct.c | 31 ++++++++++++++++ ...rror-gcc_jit_context_new_global-opaque-struct.c | 32 +++++++++++++++++ ...rror-gcc_jit_function_new_local-opaque-struct.c | 42 ++++++++++++++++++++++ .../jit.dg/test-error-mismatching-types-in-call.c | 2 +- 6 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_field-opaque-struct.c create mode 100644 gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_global-opaque-struct.c create mode 100644 gcc/testsuite/jit.dg/test-error-gcc_jit_function_new_local-opaque-struct.c diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h index acd69e9..884304b 100644 --- a/gcc/jit/jit-recording.h +++ b/gcc/jit/jit-recording.h @@ -497,6 +497,7 @@ public: virtual type *is_pointer () = 0; virtual type *is_array () = 0; virtual bool is_void () const { return false; } + virtual bool has_known_size () const { return true; } bool is_numeric () const { @@ -795,6 +796,8 @@ public: type *is_pointer () { return NULL; } type *is_array () { return NULL; } + bool has_known_size () const { return m_fields != NULL; } + playback::compound_type * playback_compound_type () { diff --git a/gcc/jit/libgccjit.c b/gcc/jit/libgccjit.c index 4d7dd8c..85d9f62 100644 --- a/gcc/jit/libgccjit.c +++ b/gcc/jit/libgccjit.c @@ -543,6 +543,11 @@ gcc_jit_context_new_field (gcc_jit_context *ctxt, /* LOC can be NULL. */ RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type"); RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name"); + RETURN_NULL_IF_FAIL_PRINTF1 ( + type->has_known_size (), + ctxt, loc, + "type has unknown size (type: %s)", + type->get_debug_string ()); return (gcc_jit_field *)ctxt->new_field (loc, type, name); } @@ -1033,6 +1038,11 @@ gcc_jit_context_new_global (gcc_jit_context *ctxt, kind); RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type"); RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name"); + RETURN_NULL_IF_FAIL_PRINTF1 ( + type->has_known_size (), + ctxt, loc, + "type has unknown size (type: %s)", + type->get_debug_string ()); return (gcc_jit_lvalue *)ctxt->new_global (loc, kind, type, name); } @@ -1829,6 +1839,11 @@ gcc_jit_function_new_local (gcc_jit_function *func, "Cannot add locals to an imported function"); RETURN_NULL_IF_FAIL (type, ctxt, loc, "NULL type"); RETURN_NULL_IF_FAIL (name, ctxt, loc, "NULL name"); + RETURN_NULL_IF_FAIL_PRINTF1 ( + type->has_known_size (), + ctxt, loc, + "type has unknown size (type: %s)", + type->get_debug_string ()); return (gcc_jit_lvalue *)func->new_local (loc, type, name); } diff --git a/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_field-opaque-struct.c b/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_field-opaque-struct.c new file mode 100644 index 0000000..c4e1448 --- /dev/null +++ b/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_field-opaque-struct.c @@ -0,0 +1,31 @@ +#include <stdlib.h> +#include <stdio.h> + +#include "libgccjit.h" + +#include "harness.h" + +/* Try to put an opaque struct inside another struct + (or union); the API ought to complain. */ + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + gcc_jit_struct *t_opaque = + gcc_jit_context_new_opaque_struct (ctxt, NULL, "opaque"); + + (void)gcc_jit_context_new_field (ctxt, NULL, + gcc_jit_struct_as_type (t_opaque), + "f_opaque"); +} + +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_field:" + " type has unknown size (type: struct opaque)"); +} diff --git a/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_global-opaque-struct.c b/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_global-opaque-struct.c new file mode 100644 index 0000000..5f096af --- /dev/null +++ b/gcc/testsuite/jit.dg/test-error-gcc_jit_context_new_global-opaque-struct.c @@ -0,0 +1,32 @@ +#include <stdlib.h> +#include <stdio.h> + +#include "libgccjit.h" + +#include "harness.h" + +/* Try to create a global of an opaque struct; + the API ought to complain. */ + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + gcc_jit_struct *t_opaque = + gcc_jit_context_new_opaque_struct (ctxt, NULL, "opaque"); + + (void)gcc_jit_context_new_global (ctxt, NULL, + GCC_JIT_GLOBAL_EXPORTED, + gcc_jit_struct_as_type (t_opaque), + "instance_of_opaque"); +} + +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_global:" + " type has unknown size (type: struct opaque)"); +} diff --git a/gcc/testsuite/jit.dg/test-error-gcc_jit_function_new_local-opaque-struct.c b/gcc/testsuite/jit.dg/test-error-gcc_jit_function_new_local-opaque-struct.c new file mode 100644 index 0000000..f263d67 --- /dev/null +++ b/gcc/testsuite/jit.dg/test-error-gcc_jit_function_new_local-opaque-struct.c @@ -0,0 +1,42 @@ +#include <stdlib.h> +#include <stdio.h> + +#include "libgccjit.h" + +#include "harness.h" + +/* Try to create a local of an opaque struct; + the API ought to complain. */ + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + gcc_jit_type *t_void = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID); + + gcc_jit_struct *t_opaque = + gcc_jit_context_new_opaque_struct (ctxt, NULL, "opaque"); + + gcc_jit_function *func = + gcc_jit_context_new_function (ctxt, NULL, + GCC_JIT_FUNCTION_EXPORTED, + t_void, + "test_fn", + 0, NULL, + 0); + + (void)gcc_jit_function_new_local (func, NULL, + gcc_jit_struct_as_type (t_opaque), + "i"); +} + +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_function_new_local:" + " type has unknown size (type: struct opaque)"); +} 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 index 203c4ca..e89c281 100644 --- a/gcc/testsuite/jit.dg/test-error-mismatching-types-in-call.c +++ b/gcc/testsuite/jit.dg/test-error-mismatching-types-in-call.c @@ -26,7 +26,7 @@ create_code (gcc_jit_context *ctxt, void *user_data) 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_context_new_struct_type (ctxt, NULL, "foo", 0, NULL); gcc_jit_type *foo_ptr = gcc_jit_type_get_pointer (gcc_jit_struct_as_type (struct_foo)); gcc_jit_param *param = -- 1.8.5.3