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);
+}

Reply via email to