From: Antoni Boucher <[email protected]>
gcc/jit/ChangeLog:
PR jit/105296
* jit-recording.cc: Use dyn_cast_compound_type instead of
reinterpret_cast.
* jit-recording.h (dyn_cast_compound_type, is_union): New methods.
* libgccjit.cc: Use correct cast method instead of
reinterpret_cast.
gcc/testsuite/ChangeLog:
PR jit/105296
* jit.dg/all-non-failing-tests.h: Mention new test.
* jit.dg/test-aligned-constructor.c: New test.
---
gcc/jit/jit-recording.cc | 2 +-
gcc/jit/jit-recording.h | 8 ++
gcc/jit/libgccjit.cc | 6 +-
gcc/testsuite/jit.dg/all-non-failing-tests.h | 10 ++
.../jit.dg/test-aligned-constructor.c | 120 ++++++++++++++++++
5 files changed, 142 insertions(+), 4 deletions(-)
create mode 100644 gcc/testsuite/jit.dg/test-aligned-constructor.c
diff --git a/gcc/jit/jit-recording.cc b/gcc/jit/jit-recording.cc
index f5ea37d96e9..ba6c981bf76 100644
--- a/gcc/jit/jit-recording.cc
+++ b/gcc/jit/jit-recording.cc
@@ -1256,7 +1256,7 @@ recording::context::new_ctor (recording::location *loc,
result->m_values.reserve (num_values, false);
result->m_fields.reserve (num_values, false);
- compound_type *ct = reinterpret_cast<compound_type *>(type);
+ compound_type *ct = type->dyn_cast_compound_type ();
recording::fields *fields = ct->get_fields ();
/* The entry point checks that num_values is not greater than
diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h
index 08de684653a..c9e8296173b 100644
--- a/gcc/jit/jit-recording.h
+++ b/gcc/jit/jit-recording.h
@@ -642,6 +642,7 @@ public:
virtual struct_ *dyn_cast_struct () { return NULL; }
virtual vector_type *dyn_cast_vector_type () { return NULL; }
virtual array_type *dyn_cast_array_type () { return NULL; }
+ virtual compound_type *dyn_cast_compound_type () { return NULL; }
virtual memento_of_get_aligned *dyn_cast_aligned_type () { return NULL; }
/* Is it typesafe to copy to this type from rtype? */
@@ -823,6 +824,7 @@ public:
type *is_pointer () final override { return m_other_type->is_pointer (); }
type *is_array () final override { return m_other_type->is_array (); }
struct_ *is_struct () final override { return m_other_type->is_struct (); }
+ bool is_union () const final override { return m_other_type->is_union (); }
bool is_signed () const final override { return m_other_type->is_signed (); }
protected:
@@ -977,6 +979,10 @@ public:
return m_other_type->dyn_cast_array_type ();
}
+ compound_type *dyn_cast_compound_type () final override {
+ return m_other_type->dyn_cast_compound_type ();
+ }
+
vector_type *dyn_cast_vector_type () final override {
return m_other_type->dyn_cast_vector_type ();
}
@@ -1245,6 +1251,8 @@ public:
type *is_array () final override { return NULL; }
bool is_signed () const final override { return false; }
+ compound_type *dyn_cast_compound_type () final override { return this; }
+
bool has_known_size () const final override { return m_fields != NULL; }
playback::compound_type *
diff --git a/gcc/jit/libgccjit.cc b/gcc/jit/libgccjit.cc
index 3fc96fb989a..89dc168b402 100644
--- a/gcc/jit/libgccjit.cc
+++ b/gcc/jit/libgccjit.cc
@@ -1477,7 +1477,7 @@ gcc_jit_context_new_struct_constructor (gcc_jit_context *ctxt,
"constructor type is not a struct: %s",
type->get_debug_string ());
- compound_type *ct = reinterpret_cast<compound_type *>(type);
+ compound_type *ct = type->dyn_cast_compound_type ();
gcc::jit::recording::fields *fields_struct = ct->get_fields ();
size_t n_fields = fields_struct->length ();
@@ -1628,7 +1628,7 @@ gcc_jit_context_new_union_constructor (gcc_jit_context *ctxt,
"constructor type is not an union: %s",
type->get_debug_string ());
- compound_type *ct = reinterpret_cast<compound_type *>(type);
+ compound_type *ct = type->dyn_cast_compound_type ();
gcc::jit::recording::fields *fields_union = ct->get_fields ();
size_t n_fields = fields_union->length ();
@@ -1725,7 +1725,7 @@ gcc_jit_context_new_array_constructor (gcc_jit_context *ctxt,
"'values' NULL with non-zero 'num_values'");
gcc::jit::recording::array_type *arr_type =
- reinterpret_cast<gcc::jit::recording::array_type*>(type);
+ type->dyn_cast_array_type ();
size_t n_el = arr_type->num_elements ();
RETURN_NULL_IF_FAIL_PRINTF2 (
diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h
index aa9d3434652..0c39394b1af 100644
--- a/gcc/testsuite/jit.dg/all-non-failing-tests.h
+++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h
@@ -52,6 +52,13 @@
#undef create_code
#undef verify_code
+/* test-aligned-constructor.c */
+#define create_code create_code_aligned_constructor
+#define verify_code verify_code_aligned_constructor
+#include "test-aligned-constructor.c"
+#undef create_code
+#undef verify_code
+
/* test-always_inline-attribute.c: This can't be in the testcases array as it needs
the `-O0` flag. */
@@ -522,6 +529,9 @@ const struct testcase testcases[] = {
{"alignof",
create_code_alignof,
verify_code_alignof},
+ {"aligned_constructor",
+ create_code_aligned_constructor,
+ verify_code_aligned_constructor},
{"alignment",
create_code_alignment,
verify_code_alignment},
diff --git a/gcc/testsuite/jit.dg/test-aligned-constructor.c b/gcc/testsuite/jit.dg/test-aligned-constructor.c
new file mode 100644
index 00000000000..403b39519f5
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-aligned-constructor.c
@@ -0,0 +1,120 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.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 my_struct {
+ int field;
+};
+
+union my_union {
+ int field;
+};
+
+int
+main (void)
+{
+ int array_value[4] = { 1 };
+ struct my_struct struct_value = { 1 };
+ union my_union union_value = { 1 };
+ int result = struct_value.field + union_value.field + array_value[0];
+ return result;
+}
+ */
+
+ gcc_jit_type *type_int = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+ gcc_jit_field *struct_field =
+
+ gcc_jit_context_new_field (ctxt, NULL, type_int, "my_field");
+ gcc_jit_struct *struct_type =
+ gcc_jit_context_new_opaque_struct (ctxt, NULL, "my_struct");
+ gcc_jit_field *struct_fields[1] = {
+ struct_field,
+ };
+ gcc_jit_struct_set_fields (struct_type, NULL, 1, struct_fields);
+ gcc_jit_type *aligned_struct_type =
+ gcc_jit_type_get_aligned (gcc_jit_struct_as_type (struct_type), 1);
+
+ gcc_jit_field *union_field =
+ gcc_jit_context_new_field (ctxt, NULL, type_int, "my_field");
+ gcc_jit_field *union_fields[1] = {
+ union_field,
+ };
+ gcc_jit_type *union_type =
+ gcc_jit_context_new_union_type (ctxt, NULL, "my_union", 1, union_fields);
+ gcc_jit_type *aligned_union_type =
+ gcc_jit_type_get_aligned (union_type, 1);
+
+ gcc_jit_type *array_type =
+ gcc_jit_context_new_array_type (ctxt, NULL, type_int, 4);
+ gcc_jit_type *aligned_array_type =
+ gcc_jit_type_get_aligned (array_type, 1);
+
+ gcc_jit_rvalue *one =
+ gcc_jit_context_new_rvalue_from_int (ctxt, type_int, 1);
+
+ gcc_jit_rvalue *struct_value;
+ {
+ gcc_jit_rvalue *values[] = {
+ one,
+ };
+ struct_value =
+ gcc_jit_context_new_struct_constructor (ctxt, NULL, aligned_struct_type,
+ 0, NULL, values);
+ }
+
+ gcc_jit_rvalue *union_value;
+ {
+ union_value =
+ gcc_jit_context_new_union_constructor (ctxt, NULL, aligned_union_type,
+ NULL, one);
+ }
+
+ gcc_jit_rvalue *array_value;
+ {
+ gcc_jit_rvalue *values[] = {
+ one,
+ };
+ array_value =
+ gcc_jit_context_new_array_constructor (ctxt, NULL, aligned_array_type,
+ 1, values);
+ }
+
+ gcc_jit_function *func_main =
+ gcc_jit_context_new_function (ctxt, NULL, GCC_JIT_FUNCTION_EXPORTED,
+ type_int, "main", 0, NULL,
+ 0);
+ gcc_jit_block *block_start =
+ gcc_jit_function_new_block (func_main, "start");
+
+ gcc_jit_rvalue *val1 =
+ gcc_jit_rvalue_access_field (struct_value, NULL, struct_field);
+ gcc_jit_lvalue *val2 =
+ gcc_jit_context_new_array_access (ctxt, NULL, array_value, one);
+ gcc_jit_rvalue *val3 =
+ gcc_jit_rvalue_access_field (union_value, NULL, union_field);
+
+ gcc_jit_rvalue *temp =
+ gcc_jit_context_new_binary_op (ctxt, NULL, GCC_JIT_BINARY_OP_PLUS,
+ type_int, val1,
+ gcc_jit_lvalue_as_rvalue (val2));
+
+ gcc_jit_rvalue *result =
+ gcc_jit_context_new_binary_op (ctxt, NULL, GCC_JIT_BINARY_OP_PLUS,
+ type_int, temp, val3);
+ gcc_jit_block_end_with_return (block_start, NULL, result);
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ CHECK_NON_NULL (result);
+}