aboutsummaryrefslogtreecommitdiff
path: root/gcc/testsuite/jit.dg
diff options
context:
space:
mode:
authorPetter Tomner <tomner@kth.se>2021-11-29 20:44:07 +0100
committerPetter Tomner <tomner@kth.se>2021-12-14 18:18:07 +0100
commit3736837806fdb26daa51300bee1554bef89db9fe (patch)
tree874865030ed635b65e50b15bc717891b8047afd6 /gcc/testsuite/jit.dg
parent1c613165a55b212c59a83796b20a1d555e096504 (diff)
downloadgcc-3736837806fdb26daa51300bee1554bef89db9fe.zip
gcc-3736837806fdb26daa51300bee1554bef89db9fe.tar.gz
gcc-3736837806fdb26daa51300bee1554bef89db9fe.tar.bz2
Add support for global rvalue initialization and constructors
This patch adds support for initialization of global variables with rvalues and creating constructors for array, struct and union types which can be used as rvalues. Signed-off-by: 2021-12-14 Petter Tomner <tomner@kth.se> gcc/jit/ * jit-common.h: New enum * jit-playback.c : Folding an setting intitial (global_new_decl) : Handle const global generation (new_global) : New flag (global_set_init_rvalue) : New (new_ctor) : New (new_global_initialized) : Flag (as_truth_value) : Fold (new_unary_op) : Fold (new_binary_op) : Fold (new_comparison) : Fold (new_array_access) : Fold (new_dereference) : Fold (get_address) : Fold * jit-playback.h : (global_set_init_rvalue) : New (new_ctor) : New * jit-recording.c : * jit-recording.h : (new_global_init_rvalue) : New (new_ctor) : New (ctor) : New, inherits rvalue (global_init_rvalue) : New, inherits memento (type::is_union) : New * libgccjit++.h : New entrypoints, see C-header * libgccjit.c : See .h * libgccjit.h : New entrypoints (gcc_jit_context_new_array_constructor) : New (gcc_jit_context_new_struct_constructor) : New (gcc_jit_context_new_union_constructor) : New (gcc_jit_global_set_initializer_rvalue) : New (LIBGCCJIT_HAVE_CTORS) : New feuture macro * libgccjit.map : New entrypoints added to ABI 19 * docs/topics/expressions.rst : Updated docs gcc/testsuite/ * jit.dg/all-non-failing-tests.h: Added two tests * jit.dg/test-error-ctor-array-wrong-obj.c: New * jit.dg/test-error-ctor-struct-too-big.c: New * jit.dg/test-error-ctor-struct-wrong-field-obj.c: New * jit.dg/test-error-ctor-struct-wrong-type.c: New * jit.dg/test-error-ctor-struct-wrong-type2.c * jit.dg/test-error-ctor-union-wrong-field-name.c: New * jit.dg/test-error-global-already-init.c: New * jit.dg/test-error-global-common-section.c: New * jit.dg/test-error-global-init-too-small-array.c: New * jit.dg/test-error-global-lvalue-init.c: New * jit.dg/test-error-global-nonconst-init.c: New * jit.dg/test-global-init-rvalue.c: New * jit.dg/test-local-init-rvalue.c: New
Diffstat (limited to 'gcc/testsuite/jit.dg')
-rw-r--r--gcc/testsuite/jit.dg/all-non-failing-tests.h20
-rw-r--r--gcc/testsuite/jit.dg/test-error-ctor-array-wrong-obj.c54
-rw-r--r--gcc/testsuite/jit.dg/test-error-ctor-struct-too-big.c71
-rw-r--r--gcc/testsuite/jit.dg/test-error-ctor-struct-wrong-field-obj.c86
-rw-r--r--gcc/testsuite/jit.dg/test-error-ctor-struct-wrong-type.c76
-rw-r--r--gcc/testsuite/jit.dg/test-error-ctor-struct-wrong-type2.c77
-rw-r--r--gcc/testsuite/jit.dg/test-error-ctor-union-wrong-field-name.c76
-rw-r--r--gcc/testsuite/jit.dg/test-error-global-already-init.c46
-rw-r--r--gcc/testsuite/jit.dg/test-error-global-common-section.c54
-rw-r--r--gcc/testsuite/jit.dg/test-error-global-init-too-small-array.c65
-rw-r--r--gcc/testsuite/jit.dg/test-error-global-lvalue-init.c60
-rw-r--r--gcc/testsuite/jit.dg/test-error-global-nonconst-init.c80
-rw-r--r--gcc/testsuite/jit.dg/test-global-init-rvalue.c1643
-rw-r--r--gcc/testsuite/jit.dg/test-local-init-rvalue.c707
14 files changed, 3115 insertions, 0 deletions
diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h
index 3e8ccbc..29afe06 100644
--- a/gcc/testsuite/jit.dg/all-non-failing-tests.h
+++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h
@@ -181,6 +181,13 @@
#undef create_code
#undef verify_code
+/* test-global-init-rvalue.c */
+#define create_code create_code_global_init_rvalue
+#define verify_code verify_code_global_init_rvalue
+#include "test-global-init-rvalue.c"
+#undef create_code
+#undef verify_code
+
/* test-global-set-initializer.c */
#define create_code create_code_global_set_initializer
#define verify_code verify_code_global_set_initializer
@@ -219,6 +226,13 @@
#undef create_code
#undef verify_code
+/* test-local-init-rvalue.c */
+#define create_code create_code_local_init_rvalue
+#define verify_code verify_code_local_init_rvalue
+#include "test-local-init-rvalue.c"
+#undef create_code
+#undef verify_code
+
/* test-long-names.c */
#define create_code create_code_long_names
#define verify_code verify_code_long_names
@@ -431,12 +445,18 @@ const struct testcase testcases[] = {
{"builtin-types",
create_code_builtin_types,
verify_code_builtin_types},
+ {"global_rvalue_init",
+ create_code_global_init_rvalue,
+ verify_code_global_init_rvalue},
{"hello_world",
create_code_hello_world,
verify_code_hello_world},
{"linked_list",
create_code_linked_list,
verify_code_linked_list},
+ {"local_rvalue_init",
+ create_code_local_init_rvalue,
+ verify_code_local_init_rvalue},
{"long_names",
create_code_long_names,
verify_code_long_names},
diff --git a/gcc/testsuite/jit.dg/test-error-ctor-array-wrong-obj.c b/gcc/testsuite/jit.dg/test-error-ctor-array-wrong-obj.c
new file mode 100644
index 0000000..6b54b85
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-error-ctor-array-wrong-obj.c
@@ -0,0 +1,54 @@
+/*
+
+ Test that the proper error is triggered when we build a ctor
+ for an array type, but has the type wrong on an element.
+
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt,
+ GCC_JIT_TYPE_INT);
+ gcc_jit_type *float_type = gcc_jit_context_get_type (ctxt,
+ GCC_JIT_TYPE_FLOAT);
+
+ gcc_jit_type *arr_type =
+ gcc_jit_context_new_array_type (ctxt, 0, int_type, 10);
+
+ gcc_jit_rvalue *frv = gcc_jit_context_new_rvalue_from_double (ctxt,
+ float_type,
+ 12);
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_array_constructor
+ (ctxt, 0,
+ arr_type,
+ 1,
+ &frv);
+
+ CHECK_VALUE (ctor, NULL);
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ /* Ensure that the bad API usage prevents the API giving a bogus
+ result back. */
+ 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_array_constructor: array element "
+ "value types differ from types in 'values' (element "
+ "type: int)('values' type: float)");
+ CHECK_STRING_VALUE (gcc_jit_context_get_last_error (ctxt),
+ "gcc_jit_context_new_array_constructor: array element "
+ "value types differ from types in 'values' (element "
+ "type: int)('values' type: float)");
+}
diff --git a/gcc/testsuite/jit.dg/test-error-ctor-struct-too-big.c b/gcc/testsuite/jit.dg/test-error-ctor-struct-too-big.c
new file mode 100644
index 0000000..6bc2045
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-error-ctor-struct-too-big.c
@@ -0,0 +1,71 @@
+/*
+
+ Test that the proper error is triggered when we build a ctor
+ for an struct type, but have too many fields and values.
+
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt,
+ GCC_JIT_TYPE_INT);
+
+ gcc_jit_field *b1 = gcc_jit_context_new_field (ctxt,
+ 0,
+ int_type,
+ "a");
+ gcc_jit_field *b2 = gcc_jit_context_new_field (ctxt,
+ 0,
+ int_type,
+ "b");
+ gcc_jit_field *b3 = gcc_jit_context_new_field (ctxt,
+ 0,
+ int_type,
+ "c");
+ gcc_jit_field *fields_b[] = {b1, b2, b3};
+
+ gcc_jit_type *struct_bar_type =
+ gcc_jit_struct_as_type (
+ gcc_jit_context_new_struct_type (ctxt,
+ 0,
+ "bar",
+ 3,
+ fields_b));
+
+ gcc_jit_field *fields_ctor[] = {b1, b2, b3, b3};
+ gcc_jit_rvalue *values[] = {0,0,0,0};
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_struct_constructor
+ (ctxt, 0,
+ struct_bar_type,
+ 4,
+ fields_ctor,
+ values);
+
+ CHECK_VALUE (ctor, NULL);
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ /* Ensure that the bad API usage prevents the API giving a bogus
+ result back. */
+ 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_struct_constructor: more values in "
+ "constructor (n=4) than fields in target struct "
+ "bar (n=3)");
+ CHECK_STRING_VALUE (gcc_jit_context_get_last_error (ctxt),
+ "gcc_jit_context_new_struct_constructor: more values in "
+ "constructor (n=4) than fields in target struct "
+ "bar (n=3)");
+}
diff --git a/gcc/testsuite/jit.dg/test-error-ctor-struct-wrong-field-obj.c b/gcc/testsuite/jit.dg/test-error-ctor-struct-wrong-field-obj.c
new file mode 100644
index 0000000..bc191e1
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-error-ctor-struct-wrong-field-obj.c
@@ -0,0 +1,86 @@
+/*
+
+ Test that the proper error is triggered when we build a ctor
+ for an struct type, but try to use a field object that was not
+ used to create the struct type.
+
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt,
+ GCC_JIT_TYPE_INT);
+
+ gcc_jit_field *b1 = gcc_jit_context_new_field (ctxt,
+ 0,
+ int_type,
+ "a");
+ gcc_jit_field *b2 = gcc_jit_context_new_field (ctxt,
+ 0,
+ int_type,
+ "b");
+ gcc_jit_field *b3 = gcc_jit_context_new_field (ctxt,
+ 0,
+ int_type,
+ "c");
+ gcc_jit_field *b4 = gcc_jit_context_new_field (ctxt,
+ 0,
+ int_type,
+ "d");
+ gcc_jit_field *b5 = gcc_jit_context_new_field (ctxt,
+ 0,
+ int_type,
+ "d");
+ gcc_jit_field *fields_b[] = {b1, b2, b3, b4, b5};
+
+ gcc_jit_type *struct_bar_type =
+ gcc_jit_struct_as_type (
+ gcc_jit_context_new_struct_type (ctxt,
+ 0,
+ "bar",
+ 5,
+ fields_b));
+
+
+ gcc_jit_field *b44 = gcc_jit_context_new_field (ctxt,
+ 0,
+ int_type,
+ "c");
+
+ gcc_jit_field *fields_ctor[] = {b1, b2, b44, b5};
+ gcc_jit_rvalue *values[] = {0,0,0,0};
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_struct_constructor
+ (ctxt, 0,
+ struct_bar_type,
+ 4,
+ fields_ctor,
+ values);
+
+ CHECK_VALUE (ctor, NULL);
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ /* Ensure that the bad API usage prevents the API giving a bogus
+ result back. */
+ 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_struct_constructor: field object "
+ "at index 2 (c), was not used when creating the "
+ "struct bar");
+ CHECK_STRING_VALUE (gcc_jit_context_get_last_error (ctxt),
+ "gcc_jit_context_new_struct_constructor: field object "
+ "at index 2 (c), was not used when creating the "
+ "struct bar");
+}
diff --git a/gcc/testsuite/jit.dg/test-error-ctor-struct-wrong-type.c b/gcc/testsuite/jit.dg/test-error-ctor-struct-wrong-type.c
new file mode 100644
index 0000000..364610b
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-error-ctor-struct-wrong-type.c
@@ -0,0 +1,76 @@
+/*
+
+ Test that the proper error is triggered when we build a ctor
+ for an struct type, but has the type wrong on a field.
+
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt,
+ GCC_JIT_TYPE_INT);
+ gcc_jit_type *float_type = gcc_jit_context_get_type (ctxt,
+ GCC_JIT_TYPE_FLOAT);
+
+ gcc_jit_field *b1 = gcc_jit_context_new_field (ctxt,
+ 0,
+ int_type,
+ "a");
+ gcc_jit_field *b2 = gcc_jit_context_new_field (ctxt,
+ 0,
+ int_type,
+ "b");
+ gcc_jit_field *b3 = gcc_jit_context_new_field (ctxt,
+ 0,
+ int_type,
+ "c");
+ gcc_jit_field *fields_b[] = {b1, b2, b3};
+
+ gcc_jit_type *struct_bar_type =
+ gcc_jit_struct_as_type (
+ gcc_jit_context_new_struct_type (ctxt,
+ 0,
+ "bar",
+ 3,
+ fields_b));
+ gcc_jit_rvalue *frv = gcc_jit_context_new_rvalue_from_double (ctxt,
+ float_type,
+ 12);
+
+ gcc_jit_field *fields_ctor[] = {b2};
+ gcc_jit_rvalue *values[] = {frv};
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_struct_constructor
+ (ctxt, 0,
+ struct_bar_type,
+ 1,
+ fields_ctor,
+ values);
+
+ CHECK_VALUE (ctor, NULL);
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ /* Ensure that the bad API usage prevents the API giving a bogus
+ result back. */
+ 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_struct_constructor: value and "
+ "field not the same unqualified type, at index 0 "
+ "(struct bar.b: int)(value type: float)");
+ CHECK_STRING_VALUE (gcc_jit_context_get_last_error (ctxt),
+ "gcc_jit_context_new_struct_constructor: value and "
+ "field not the same unqualified type, at index 0 "
+ "(struct bar.b: int)(value type: float)");
+}
diff --git a/gcc/testsuite/jit.dg/test-error-ctor-struct-wrong-type2.c b/gcc/testsuite/jit.dg/test-error-ctor-struct-wrong-type2.c
new file mode 100644
index 0000000..c2309de
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-error-ctor-struct-wrong-type2.c
@@ -0,0 +1,77 @@
+/*
+
+ Test that the proper error is triggered when we build a ctor
+ for an struct type, but has the type wrong on a field.
+
+ Like test-error-ctor-struct-wrong-type.c, but with implicit fields.
+
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt,
+ GCC_JIT_TYPE_INT);
+ gcc_jit_type *float_type = gcc_jit_context_get_type (ctxt,
+ GCC_JIT_TYPE_FLOAT);
+
+ gcc_jit_field *b1 = gcc_jit_context_new_field (ctxt,
+ 0,
+ int_type,
+ "a");
+ gcc_jit_field *b2 = gcc_jit_context_new_field (ctxt,
+ 0,
+ int_type,
+ "b");
+ gcc_jit_field *b3 = gcc_jit_context_new_field (ctxt,
+ 0,
+ int_type,
+ "c");
+ gcc_jit_field *fields_b[] = {b1, b2, b3};
+
+ gcc_jit_type *struct_bar_type =
+ gcc_jit_struct_as_type (
+ gcc_jit_context_new_struct_type (ctxt,
+ 0,
+ "bar",
+ 3,
+ fields_b));
+ gcc_jit_rvalue *frv = gcc_jit_context_new_rvalue_from_double (ctxt,
+ float_type,
+ 12);
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_struct_constructor
+ (ctxt, 0,
+ struct_bar_type,
+ 1,
+ 0,
+ &frv);
+
+ CHECK_VALUE (ctor, NULL);
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ /* Ensure that the bad API usage prevents the API giving a bogus
+ result back. */
+ 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_struct_constructor: value and "
+ "field not "
+ "the same unqualified type, "
+ "at index 0 (struct bar.a: int)(value type: float)");
+ CHECK_STRING_VALUE (gcc_jit_context_get_last_error (ctxt),
+ "gcc_jit_context_new_struct_constructor: value and "
+ "field not "
+ "the same unqualified type, "
+ "at index 0 (struct bar.a: int)(value type: float)");
+}
diff --git a/gcc/testsuite/jit.dg/test-error-ctor-union-wrong-field-name.c b/gcc/testsuite/jit.dg/test-error-ctor-union-wrong-field-name.c
new file mode 100644
index 0000000..2bf8ee4
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-error-ctor-union-wrong-field-name.c
@@ -0,0 +1,76 @@
+/*
+
+ Test that the proper error is triggered when we build a ctor
+ for an union type, but don't provide a correct field.
+
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt,
+ GCC_JIT_TYPE_INT);
+ gcc_jit_type *float_type = gcc_jit_context_get_type (ctxt,
+ GCC_JIT_TYPE_FLOAT);
+ gcc_jit_type *double_type = gcc_jit_context_get_type (ctxt,
+ GCC_JIT_TYPE_DOUBLE);
+
+ gcc_jit_field *b1 = gcc_jit_context_new_field (ctxt,
+ 0,
+ int_type,
+ "a");
+ gcc_jit_field *b2 = gcc_jit_context_new_field (ctxt,
+ 0,
+ float_type,
+ "b");
+ gcc_jit_field *b3 = gcc_jit_context_new_field (ctxt,
+ 0,
+ double_type,
+ "c");
+ gcc_jit_field *fields_b[] = {b1, b2, b3};
+
+ gcc_jit_type *union_bar_type =
+ gcc_jit_context_new_union_type (ctxt,
+ 0,
+ "bar",
+ 3,
+ fields_b);
+
+ gcc_jit_field *b33 = gcc_jit_context_new_field (ctxt,
+ 0,
+ double_type,
+ "c");
+
+ gcc_jit_rvalue *val =
+ gcc_jit_context_new_rvalue_from_double (ctxt, double_type, 1);
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_union_constructor
+ (ctxt, 0,
+ union_bar_type,
+ b33,
+ val);
+
+ CHECK_VALUE (ctor, NULL);
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ /* Ensure that the bad API usage prevents the API giving a bogus
+ result back. */
+ 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_union_constructor: field object (c)"
+ " was not used when creating the type union bar");
+ CHECK_STRING_VALUE (gcc_jit_context_get_last_error (ctxt),
+ "gcc_jit_context_new_union_constructor: field object (c)"
+ " was not used when creating the type union bar");
+}
diff --git a/gcc/testsuite/jit.dg/test-error-global-already-init.c b/gcc/testsuite/jit.dg/test-error-global-already-init.c
new file mode 100644
index 0000000..ecead87
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-error-global-already-init.c
@@ -0,0 +1,46 @@
+/*
+
+ Test that we can't set the initializer on a global twice.
+
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+
+ gcc_jit_lvalue *bar = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ int_type,
+ "global_lvalueinit_int_0");
+
+ gcc_jit_global_set_initializer_rvalue (
+ bar,
+ gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 1));
+ gcc_jit_global_set_initializer_rvalue (
+ bar,
+ gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 1));
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ /* Ensure that the bad API usage prevents the API giving a bogus
+ result back. */
+ CHECK_VALUE (result, NULL);
+
+ /* Verify that the correct error message was emitted. */
+ CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt),
+ "gcc_jit_global_set_initializer_rvalue: global variable "
+ "already initialized: global_lvalueinit_int_0");
+ CHECK_STRING_VALUE (gcc_jit_context_get_last_error (ctxt),
+ "gcc_jit_global_set_initializer_rvalue: global variable "
+ "already initialized: global_lvalueinit_int_0");
+}
diff --git a/gcc/testsuite/jit.dg/test-error-global-common-section.c b/gcc/testsuite/jit.dg/test-error-global-common-section.c
new file mode 100644
index 0000000..2f99454
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-error-global-common-section.c
@@ -0,0 +1,54 @@
+/*
+
+ Test that the proper error is triggered when we initialize
+ a global with a global that has no DECL_INITIAL (and is marked
+ DECL_COMMON(NODE) = 1).
+
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt,
+ GCC_JIT_TYPE_INT);
+
+ /* const int foo;
+ int bar = foo;
+ */
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ gcc_jit_type_get_const (int_type),
+ "global_const_int_0");
+ gcc_jit_lvalue *bar = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ int_type,
+ "global_lvalueinit_int_0");
+ gcc_jit_global_set_initializer_rvalue (bar,
+ gcc_jit_lvalue_as_rvalue (foo));
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ /* Ensure that the bad API usage prevents the API giving a bogus
+ result back. */
+ CHECK_VALUE (result, NULL);
+
+ /* Verify that the correct error message was emitted. */
+ CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt),
+ "unable to convert initial value for the global "
+ "variable global_lvalueinit_int_0 to a compile-time"
+ " constant");
+ CHECK_STRING_VALUE (gcc_jit_context_get_last_error (ctxt),
+ "unable to convert initial value for the global "
+ "variable global_lvalueinit_int_0 to a compile-time"
+ " constant");
+}
diff --git a/gcc/testsuite/jit.dg/test-error-global-init-too-small-array.c b/gcc/testsuite/jit.dg/test-error-global-init-too-small-array.c
new file mode 100644
index 0000000..2a3db7a
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-error-global-init-too-small-array.c
@@ -0,0 +1,65 @@
+/*
+
+ Test that the proper error is triggered when we initialize
+ a global array with a ctor with too many values.
+
+ Using gcc_jit_global_set_initializer_rvalue()
+
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{ /* float foo[1] = {1,2}; */
+
+ gcc_jit_type *float_type = gcc_jit_context_get_type (ctxt,
+ GCC_JIT_TYPE_FLOAT);
+ gcc_jit_type *arr_type = gcc_jit_context_new_array_type (ctxt,
+ 0,
+ float_type,
+ 1);
+ gcc_jit_rvalue *rval_1 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, float_type, 1);
+ gcc_jit_rvalue *rval_2 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, float_type, 2);
+
+ gcc_jit_rvalue *values[] = {rval_1, rval_2};
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_array_constructor (ctxt,
+ 0,
+ arr_type,
+ 2,
+ values);
+ if (!ctor)
+ return;
+
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ arr_type,
+ "global_floatarr_12");
+ gcc_jit_global_set_initializer_rvalue (foo, ctor);
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ /* Ensure that the bad API usage prevents the API giving a bogus
+ result back. */
+ 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_array_constructor: array "
+ "constructor has more values than the array type's "
+ "length (array type length: 1, constructor length: 2)");
+ CHECK_STRING_VALUE (gcc_jit_context_get_last_error (ctxt),
+ "gcc_jit_context_new_array_constructor: array "
+ "constructor has more values than the array type's "
+ "length (array type length: 1, constructor length: 2)");
+}
diff --git a/gcc/testsuite/jit.dg/test-error-global-lvalue-init.c b/gcc/testsuite/jit.dg/test-error-global-lvalue-init.c
new file mode 100644
index 0000000..65aa8a8
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-error-global-lvalue-init.c
@@ -0,0 +1,60 @@
+/*
+
+ Test that the proper error is triggered when we initialize
+ a global with another non-const global's rvalue.
+
+ Using gcc_jit_global_set_initializer_rvalue()
+
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt,
+ GCC_JIT_TYPE_INT);
+
+ gcc_jit_lvalue *foo;
+ { /* int bar; */
+ foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ int_type,
+ "global_lvalueinit_int1");
+ gcc_jit_rvalue *rval = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 3);
+ gcc_jit_global_set_initializer_rvalue (foo,
+ rval);
+ }
+ { /* int foo = bar; */
+
+ gcc_jit_lvalue *bar = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ int_type,
+ "global_lvalueinit_int2");
+ gcc_jit_global_set_initializer_rvalue (bar,
+ gcc_jit_lvalue_as_rvalue (foo));
+ }
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ /* Ensure that the bad API usage prevents the API giving a bogus
+ result back. */
+ CHECK_VALUE (result, NULL);
+
+ /* Verify that the correct error message was emitted. */
+ CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt),
+ "unable to convert initial value for the global variable"
+ " global_lvalueinit_int2 to a compile-time constant");
+ CHECK_STRING_VALUE (gcc_jit_context_get_last_error (ctxt),
+ "unable to convert initial value for the global variable"
+ " global_lvalueinit_int2 to a compile-time constant");
+}
diff --git a/gcc/testsuite/jit.dg/test-error-global-nonconst-init.c b/gcc/testsuite/jit.dg/test-error-global-nonconst-init.c
new file mode 100644
index 0000000..9dffe06
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-error-global-nonconst-init.c
@@ -0,0 +1,80 @@
+/*
+
+ Test that the proper error is triggered when we initialize
+ a global with a function call.
+
+ Using gcc_jit_global_set_initializer_rvalue()
+
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt,
+ GCC_JIT_TYPE_INT);
+
+ gcc_jit_function *fn_int_3;
+ { /* int foo () { int local = 3; return local;} */
+ fn_int_3 =
+ gcc_jit_context_new_function (ctxt,
+ 0,
+ GCC_JIT_FUNCTION_EXPORTED,
+ int_type,
+ "fn_int_3",
+ 0,
+ 0,
+ 0);
+ gcc_jit_block *block = gcc_jit_function_new_block (fn_int_3, "start");
+ gcc_jit_lvalue *local = gcc_jit_function_new_local (fn_int_3,
+ 0,
+ int_type,
+ "local");
+ gcc_jit_rvalue *rval = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 3);
+
+ gcc_jit_block_add_assignment (block, 0, local, rval);
+
+ gcc_jit_block_end_with_return (block,
+ 0,
+ gcc_jit_lvalue_as_rvalue(local));
+
+ }
+
+ { /* int bar = foo(); */
+ gcc_jit_rvalue *rval =
+ gcc_jit_context_new_call (ctxt,
+ 0,
+ fn_int_3,
+ 0,0);
+
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ int_type,
+ "global_nonconst_int");
+ gcc_jit_global_set_initializer_rvalue (foo,
+ rval);
+ }
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ /* Ensure that the bad API usage prevents the API giving a bogus
+ result back. */
+ CHECK_VALUE (result, NULL);
+
+ /* Verify that the correct error message was emitted. */
+ CHECK_STRING_VALUE (gcc_jit_context_get_first_error (ctxt),
+ "unable to convert initial value for the global variable"
+ " global_nonconst_int to a compile-time constant");
+ CHECK_STRING_VALUE (gcc_jit_context_get_last_error (ctxt),
+ "unable to convert initial value for the global variable"
+ " global_nonconst_int to a compile-time constant");
+}
diff --git a/gcc/testsuite/jit.dg/test-global-init-rvalue.c b/gcc/testsuite/jit.dg/test-global-init-rvalue.c
new file mode 100644
index 0000000..4866462
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-global-init-rvalue.c
@@ -0,0 +1,1643 @@
+/* This testcase checks that gcc_jit_global_set_initializer_rvalue() works
+ with rvalues, especially with gcc_jit_context_new_*_constructor() for
+ struct, unions and arrays. */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "libgccjit.h"
+#include "harness.h"
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt,
+ GCC_JIT_TYPE_INT);
+ gcc_jit_type *short_type = gcc_jit_context_get_type (ctxt,
+ GCC_JIT_TYPE_SHORT);
+ gcc_jit_type *pint_type = gcc_jit_type_get_pointer (int_type);
+ gcc_jit_type *double_type = gcc_jit_context_get_type (ctxt,
+ GCC_JIT_TYPE_DOUBLE);
+ gcc_jit_type *float_type = gcc_jit_context_get_type (ctxt,
+ GCC_JIT_TYPE_FLOAT);
+ gcc_jit_type *bool_type = gcc_jit_context_get_type (ctxt,
+ GCC_JIT_TYPE_BOOL);
+ gcc_jit_type *char_type = gcc_jit_context_get_type (ctxt,
+ GCC_JIT_TYPE_CHAR);
+ gcc_jit_type *cpchar_type = gcc_jit_context_get_type (ctxt,
+ GCC_JIT_TYPE_CONST_CHAR_PTR);
+ gcc_jit_type *size_type = gcc_jit_context_get_type (ctxt,
+ GCC_JIT_TYPE_SIZE_T);
+
+ /* Make a struct: struct fi { float f; int i;} */
+ gcc_jit_field *fi_f = gcc_jit_context_new_field (ctxt,
+ 0,
+ float_type,
+ "f");
+ gcc_jit_field *fi_i = gcc_jit_context_new_field (ctxt,
+ 0,
+ int_type,
+ "i");
+ gcc_jit_field *fields[] = {fi_f, fi_i};
+
+ gcc_jit_type *struct_fi_type =
+ gcc_jit_struct_as_type (
+ gcc_jit_context_new_struct_type (ctxt,
+ 0,
+ "fi",
+ 2,
+ fields));
+
+ /* Make a struct:
+
+ struct bar {
+ int ii;
+ struct fi fi;
+ float ff;
+ }
+ */
+ gcc_jit_field *bar_ff = gcc_jit_context_new_field (ctxt,
+ 0,
+ float_type,
+ "ff");
+ gcc_jit_field *bar_ii = gcc_jit_context_new_field (ctxt,
+ 0,
+ int_type,
+ "ii");
+ gcc_jit_field *bar_fi = gcc_jit_context_new_field (ctxt,
+ 0,
+ struct_fi_type,
+ "fi");
+ gcc_jit_field *fields2[] = {bar_ff, bar_fi, bar_ii};
+
+ gcc_jit_type *struct_bar_type =
+ gcc_jit_struct_as_type (
+ gcc_jit_context_new_struct_type (ctxt,
+ 0,
+ "bar",
+ 3,
+ fields2));
+
+ /* Make an union:
+
+ union ubar {
+ float ff;
+ int ii;
+ };
+ */
+ gcc_jit_field *ubar_ff = gcc_jit_context_new_field (ctxt,
+ 0,
+ float_type,
+ "ff");
+ gcc_jit_field *ubar_ii = gcc_jit_context_new_field (ctxt,
+ 0,
+ int_type,
+ "ii");
+ gcc_jit_field *fields3[] = {ubar_ff, ubar_ii};
+
+ gcc_jit_type *ubar = gcc_jit_context_new_union_type (ctxt,
+ 0,
+ "ubar",
+ 2,
+ fields3);
+
+ { /* struct bar bar = {.ff=1, .fi={.f=2, .i=3}, .ii=4};
+ I.e. nested ctors and with fields specified
+ */
+ gcc_jit_lvalue *bar = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ struct_bar_type,
+ "global_struct_bar_1234_1");
+
+ gcc_jit_rvalue *fval = gcc_jit_context_new_rvalue_from_int (
+ ctxt, float_type, 2);
+ gcc_jit_rvalue *ival = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 3);
+
+ gcc_jit_rvalue *vals[] = { fval, ival};
+ gcc_jit_field *fields[] = {fi_f, fi_i};
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_struct_constructor
+ (ctxt, 0,
+ struct_fi_type,
+ 2,
+ fields,
+ vals);
+
+ ival = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 4);
+ fval = gcc_jit_context_new_rvalue_from_int (
+ ctxt, float_type, 1);
+
+ gcc_jit_rvalue *vals2[] = {fval, ctor, ival};
+ gcc_jit_field *fields2[] = {bar_ff, bar_fi, bar_ii};
+
+ gcc_jit_rvalue *ctor_bar = gcc_jit_context_new_struct_constructor
+ (ctxt, 0,
+ struct_bar_type,
+ 3,
+ fields2,
+ vals2);
+
+ gcc_jit_global_set_initializer_rvalue (bar, ctor_bar);
+ }
+ { /* struct bar bar = {1, {2, 3}, 4};
+ I.e. nested ctors and fields implicit in definition order (fields=NULL)
+ */
+ gcc_jit_lvalue *bar = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ struct_bar_type,
+ "global_struct_bar_1234_2");
+
+ gcc_jit_rvalue *fval = gcc_jit_context_new_rvalue_from_int (
+ ctxt, float_type, 2);
+ gcc_jit_rvalue *ival = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 3);
+
+ gcc_jit_rvalue *vals[] = { fval, ival};
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_struct_constructor
+ (ctxt, 0,
+ struct_fi_type,
+ 2,
+ 0,
+ vals);
+
+ ival = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 4);
+ fval = gcc_jit_context_new_rvalue_from_int (
+ ctxt, float_type, 1);
+
+ gcc_jit_rvalue *vals2[] = {fval, ctor, ival};
+
+ gcc_jit_rvalue *ctor_bar = gcc_jit_context_new_struct_constructor
+ (ctxt, 0,
+ struct_bar_type,
+ 3,
+ 0,
+ vals2);
+
+ gcc_jit_global_set_initializer_rvalue (bar, ctor_bar);
+ }
+ { /* struct fi foo = {.f=2, .i=3}; */
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ struct_fi_type,
+ "global_struct_fi_23_1");
+
+ gcc_jit_rvalue *fval = gcc_jit_context_new_rvalue_from_int (
+ ctxt, float_type, 2);
+ gcc_jit_rvalue *ival = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 3);
+
+ gcc_jit_rvalue *vals[] = { fval, ival};
+ gcc_jit_field *fields[] = {fi_f, fi_i};
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_struct_constructor
+ (ctxt, 0,
+ struct_fi_type,
+ 2,
+ fields,
+ vals);
+
+ gcc_jit_global_set_initializer_rvalue (foo, ctor);
+ }
+ { /* struct fi foo = {2, 3}; */
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ struct_fi_type,
+ "global_struct_fi_23_2");
+
+ gcc_jit_rvalue *fval = gcc_jit_context_new_rvalue_from_int (
+ ctxt, float_type, 2);
+ gcc_jit_rvalue *ival = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 3);
+
+ gcc_jit_rvalue *vals[] = { fval, ival};
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_struct_constructor
+ (ctxt, 0,
+ struct_fi_type,
+ 2,
+ 0,
+ vals);
+
+ gcc_jit_global_set_initializer_rvalue (foo, ctor);
+ }
+ { /* struct fi foo = {.i=0, .f=0}; (null init) */
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ struct_fi_type,
+ "global_struct_fi_00_1");
+
+ gcc_jit_rvalue *vals[] = { 0, 0};
+ gcc_jit_field *fields[] = {fi_f, fi_i};
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_struct_constructor
+ (ctxt, 0,
+ struct_fi_type,
+ 2,
+ fields,
+ vals);
+
+ gcc_jit_global_set_initializer_rvalue (foo, ctor);
+ }
+ { /* struct fi foo = {0, 0}; (null fields, null elements in values) */
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ struct_fi_type,
+ "global_struct_fi_00_2");
+
+ gcc_jit_rvalue *vals[] = { 0, 0};
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_struct_constructor
+ (ctxt, 0,
+ struct_fi_type,
+ 2,
+ 0,
+ vals);
+
+ gcc_jit_global_set_initializer_rvalue (foo, ctor);
+ }
+ { /* struct fi foo = {.i = 0} (null init);
+
+ Null init values. */
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ struct_fi_type,
+ "global_struct_fi_0_1");
+
+ gcc_jit_rvalue *vals[] = {0};
+ gcc_jit_field *fields[] = {fi_i};
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_struct_constructor
+ (ctxt, 0,
+ struct_fi_type,
+ 1,
+ fields,
+ vals);
+ gcc_jit_global_set_initializer_rvalue (foo, ctor);
+ }
+ { /* struct fi foo = {0};
+
+ Null init values. */
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ struct_fi_type,
+ "global_struct_fi_0_2");
+
+ gcc_jit_rvalue *vals[] = {0};
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_struct_constructor
+ (ctxt, 0,
+ struct_fi_type,
+ 1,
+ 0,
+ vals);
+ gcc_jit_global_set_initializer_rvalue (foo, ctor);
+ }
+ { /* struct fi foo = {}; (null init)
+
+ Null fields and values. */
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ struct_fi_type,
+ "global_struct_fi_6");
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_struct_constructor
+ (ctxt, 0,
+ struct_fi_type,
+ 0,
+ 0,
+ 0);
+ gcc_jit_global_set_initializer_rvalue (foo, ctor);
+ }
+ { /* struct fi foo = {2 * 2, 3}; */
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ struct_fi_type,
+ "global_struct_fi_3");
+
+ gcc_jit_rvalue *fval = gcc_jit_context_new_rvalue_from_int (
+ ctxt, float_type, 2);
+ gcc_jit_rvalue *fval2 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, float_type, 2);
+ gcc_jit_rvalue *ival = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 3);
+ gcc_jit_rvalue *rval_mul = gcc_jit_context_new_binary_op (ctxt, 0,
+ GCC_JIT_BINARY_OP_MULT,
+ float_type,
+ fval,
+ fval2);
+
+ gcc_jit_rvalue *vals[] = { rval_mul, ival};
+ gcc_jit_field *fields[] = {fi_f, fi_i};
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_struct_constructor
+ (ctxt, 0,
+ struct_fi_type,
+ 2,
+ fields,
+ vals);
+
+ gcc_jit_global_set_initializer_rvalue (foo, ctor);
+ }
+ { /* union ubar foo = {.ff = 3}; */
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ ubar,
+ "global_union_ufoo_ff3");
+
+ gcc_jit_rvalue *fval = gcc_jit_context_new_rvalue_from_int (
+ ctxt, float_type, 3);
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_union_constructor (
+ ctxt,
+ 0,
+ ubar,
+ ubar_ff,
+ fval);
+
+ gcc_jit_global_set_initializer_rvalue (foo, ctor);
+ }
+ { /* union ubar foo = {.ii = 2}; */
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ ubar,
+ "global_union_ufoo_ii2");
+
+ gcc_jit_rvalue *ival = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 2);
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_union_constructor (
+ ctxt,
+ 0,
+ ubar,
+ ubar_ii,
+ ival);
+
+ gcc_jit_global_set_initializer_rvalue (foo, ctor);
+ }
+ { /* union ubar foo = {1.1f}; should init first field */
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ ubar,
+ "global_union_ufoo_ff1c1");
+
+ gcc_jit_rvalue *fval = gcc_jit_context_new_rvalue_from_double (
+ ctxt, float_type, 1.1);
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_union_constructor (
+ ctxt,
+ 0,
+ ubar,
+ 0,
+ fval);
+
+ gcc_jit_global_set_initializer_rvalue (foo, ctor);
+ }
+ { /* union ubar foo = (union ubar){}; */
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ ubar,
+ "global_union_ufoo_0");
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_union_constructor (
+ ctxt,
+ 0,
+ ubar,
+ 0,
+ 0);
+
+ gcc_jit_global_set_initializer_rvalue (foo, ctor);
+ }
+ { /* int foo = 3; */
+ gcc_jit_rvalue *rval = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 3);
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ int_type,
+ "global_int1_3");
+ gcc_jit_global_set_initializer_rvalue (foo,
+ rval);
+ }
+ { /* const volatile int foo = 3; */
+ gcc_jit_rvalue *rval = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 3);
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ gcc_jit_type_get_const (gcc_jit_type_get_volatile (int_type)),
+ "global_cvint1_3");
+ gcc_jit_global_set_initializer_rvalue (foo,
+ rval);
+ }
+ { /* Try the above, but with opposite order of global and literal calls */
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ int_type,
+ "global_int2_3");
+ gcc_jit_rvalue *rval = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 3);
+ gcc_jit_global_set_initializer_rvalue (foo,
+ rval);
+ }
+ { /* int foo = 3 * (3 + 3) */
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ int_type,
+ "global_int3_18");
+ gcc_jit_rvalue *rval3_0 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 3);
+ gcc_jit_rvalue *rval3_1 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 3);
+ gcc_jit_rvalue *rval3_2 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 3);
+ gcc_jit_rvalue *rval_plus = gcc_jit_context_new_binary_op (ctxt, 0,
+ GCC_JIT_BINARY_OP_PLUS,
+ int_type,
+ rval3_0,
+ rval3_1);
+ gcc_jit_rvalue *rval_mul = gcc_jit_context_new_binary_op (ctxt, 0,
+ GCC_JIT_BINARY_OP_MULT,
+ int_type,
+ rval_plus,
+ rval3_2);
+
+ gcc_jit_global_set_initializer_rvalue (foo,
+ rval_mul);
+ }
+ { /* int foo = ~(-(((((2 | 8) & 15) ^ 0) << 3 >> 2 - 1) / 2)); */
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ int_type,
+ "global_int_alotofoperators");
+ gcc_jit_rvalue *rval_0 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 2);
+ gcc_jit_rvalue *rval_1 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 8);
+ gcc_jit_rvalue *rval_2 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 15);
+ gcc_jit_rvalue *rval_3 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 0);
+ gcc_jit_rvalue *rval_4 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 3);
+ gcc_jit_rvalue *rval_5 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 2);
+ gcc_jit_rvalue *rval_6 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 1);
+ gcc_jit_rvalue *rval_7 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 2);
+
+ gcc_jit_rvalue *rval_or = gcc_jit_context_new_binary_op (ctxt, 0,
+ GCC_JIT_BINARY_OP_BITWISE_OR,
+ int_type,
+ rval_0,
+ rval_1);
+ gcc_jit_rvalue *rval_and = gcc_jit_context_new_binary_op (ctxt, 0,
+ GCC_JIT_BINARY_OP_BITWISE_AND,
+ int_type,
+ rval_or,
+ rval_2);
+ gcc_jit_rvalue *rval_xor = gcc_jit_context_new_binary_op (ctxt, 0,
+ GCC_JIT_BINARY_OP_BITWISE_XOR,
+ int_type,
+ rval_and,
+ rval_3);
+ gcc_jit_rvalue *rval_lsh = gcc_jit_context_new_binary_op (ctxt, 0,
+ GCC_JIT_BINARY_OP_LSHIFT,
+ int_type,
+ rval_xor,
+ rval_4);
+ gcc_jit_rvalue *rval_rsh = gcc_jit_context_new_binary_op (ctxt, 0,
+ GCC_JIT_BINARY_OP_RSHIFT,
+ int_type,
+ rval_lsh,
+ rval_5);
+ gcc_jit_rvalue *rval_min = gcc_jit_context_new_binary_op (ctxt, 0,
+ GCC_JIT_BINARY_OP_MINUS,
+ int_type,
+ rval_rsh,
+ rval_6);
+ gcc_jit_rvalue *rval_div = gcc_jit_context_new_binary_op (ctxt, 0,
+ GCC_JIT_BINARY_OP_DIVIDE,
+ int_type,
+ rval_min,
+ rval_7);
+ gcc_jit_rvalue *rval_umin = gcc_jit_context_new_unary_op (ctxt, 0,
+ GCC_JIT_UNARY_OP_MINUS,
+ int_type,
+ rval_div);
+ gcc_jit_rvalue *rval_neg = gcc_jit_context_new_unary_op (ctxt, 0,
+ GCC_JIT_UNARY_OP_BITWISE_NEGATE,
+ int_type,
+ rval_umin);
+
+ gcc_jit_global_set_initializer_rvalue (foo,
+ rval_neg);
+ }
+ { /* int foo = 3; int *pfoo = &foo; */
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ int_type,
+ "global_int4_3");
+ gcc_jit_rvalue *rval = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 3);
+ gcc_jit_global_set_initializer_rvalue (foo,
+ rval);
+
+ gcc_jit_lvalue *pfoo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ pint_type,
+ "global_pint5");
+ gcc_jit_global_set_initializer_rvalue (pfoo,
+ gcc_jit_lvalue_get_address (foo, 0));
+ }
+ { /* static int foo; int *pfoo = &foo; */
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_INTERNAL,
+ int_type,
+ "global_int5_3");
+
+ gcc_jit_lvalue *pfoo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ pint_type,
+ "global_pint6");
+ gcc_jit_global_set_initializer_rvalue (pfoo,
+ gcc_jit_lvalue_get_address (foo, 0));
+
+ gcc_jit_function *fn =
+ gcc_jit_context_new_function (ctxt,
+ 0,
+ GCC_JIT_FUNCTION_EXPORTED,
+ gcc_jit_type_get_pointer(int_type),
+ "fn_pint_0",
+ 0,
+ 0,
+ 0);
+
+ gcc_jit_block *block = gcc_jit_function_new_block (fn, "start");
+
+ gcc_jit_block_end_with_return (block,
+ 0,
+ gcc_jit_lvalue_get_address (foo, 0));
+ }
+ { /* int foo = 3; int *pfoo = &foo + 1; */
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ int_type,
+ "global_int6_3");
+ gcc_jit_rvalue *rval = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 3);
+ gcc_jit_global_set_initializer_rvalue (foo,
+ rval);
+
+ gcc_jit_lvalue *pfoo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ pint_type,
+ "global_pint7");
+ gcc_jit_global_set_initializer_rvalue (pfoo,
+ gcc_jit_lvalue_get_address (
+ gcc_jit_context_new_array_access(
+ ctxt,
+ 0,
+ gcc_jit_lvalue_get_address(foo, 0),
+ gcc_jit_context_one(ctxt, int_type)),
+ 0));
+ }
+ { /* double foo = 3; */
+ gcc_jit_lvalue *double1 = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ double_type,
+ "global_double1_3");
+ gcc_jit_rvalue *rval = gcc_jit_context_new_rvalue_from_int (
+ ctxt, double_type, 3);
+ gcc_jit_global_set_initializer_rvalue (double1,
+ rval);
+ }
+ { /* double foo = 3 * 3 + 3 */
+ gcc_jit_lvalue *double1 = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ double_type,
+ "global_double2_12");
+ gcc_jit_rvalue *rval = gcc_jit_context_new_rvalue_from_int (
+ ctxt, double_type, 3);
+ gcc_jit_rvalue *rval_mul = gcc_jit_context_new_binary_op (ctxt, 0,
+ GCC_JIT_BINARY_OP_MULT,
+ double_type,
+ rval,
+ rval);
+ gcc_jit_rvalue *rval_plus = gcc_jit_context_new_binary_op (ctxt, 0,
+ GCC_JIT_BINARY_OP_PLUS,
+ double_type,
+ rval_mul,
+ rval);
+ gcc_jit_global_set_initializer_rvalue (double1,
+ rval_plus);
+ }
+ { /* bool foo = 3 + 3 <= 6; */
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ bool_type,
+ "global_bool1_1");
+ gcc_jit_rvalue *rval3_0 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 3);
+ gcc_jit_rvalue *rval3_1 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 3);
+ gcc_jit_rvalue *rval6 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 6);
+ gcc_jit_rvalue *rval_plus = gcc_jit_context_new_binary_op (ctxt,
+ 0,
+ GCC_JIT_BINARY_OP_PLUS,
+ int_type,
+ rval3_0,
+ rval3_1);
+ gcc_jit_rvalue *rval_le = gcc_jit_context_new_comparison (ctxt,
+ 0,
+ GCC_JIT_COMPARISON_LE,
+ rval_plus,
+ rval6);
+
+ gcc_jit_global_set_initializer_rvalue (foo,
+ rval_le);
+ }
+ gcc_jit_lvalue *global_intarr_1234;
+ { /* int foo[] = {1,2,3,4}; */
+
+ gcc_jit_type *arr_type = gcc_jit_context_new_array_type (ctxt,
+ 0,
+ int_type,
+ 4);
+ gcc_jit_rvalue *rval_1 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 1);
+ gcc_jit_rvalue *rval_2 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 2);
+ gcc_jit_rvalue *rval_3 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 3);
+ gcc_jit_rvalue *rval_4 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 4);
+
+ gcc_jit_rvalue *values[] = {rval_1, rval_2, rval_3, rval_4};
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_array_constructor (ctxt,
+ 0,
+ arr_type,
+ 4,
+ values);
+ global_intarr_1234 = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ arr_type,
+ "global_intarr_1234");
+ gcc_jit_global_set_initializer_rvalue (global_intarr_1234, ctor);
+ }
+ { /* float foo[4] = {1,2}; */
+
+ gcc_jit_type *arr_type = gcc_jit_context_new_array_type (ctxt,
+ 0,
+ float_type,
+ 4);
+ gcc_jit_rvalue *rval_1 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, float_type, 1);
+ gcc_jit_rvalue *rval_2 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, float_type, 2);
+
+ gcc_jit_rvalue *values[] = {rval_1, rval_2};
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_array_constructor (ctxt,
+ 0,
+ arr_type,
+ 2,
+ values);
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ arr_type,
+ "global_floatarr_12");
+ gcc_jit_global_set_initializer_rvalue (foo, ctor);
+ }
+ { /* float foo[4] = {1,2};
+ With different array objects of same size and type. */
+
+ gcc_jit_type *arr_type = gcc_jit_context_new_array_type (ctxt,
+ 0,
+ float_type,
+ 4);
+ gcc_jit_type *arr_type1 = gcc_jit_context_new_array_type (ctxt,
+ 0,
+ float_type,
+ 4);
+ gcc_jit_rvalue *rval_1 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, float_type, 1);
+ gcc_jit_rvalue *rval_2 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, float_type, 2);
+
+ gcc_jit_rvalue *values[] = {rval_1, rval_2};
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_array_constructor (ctxt,
+ 0,
+ arr_type1,
+ 2,
+ values);
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ arr_type,
+ "global_floatarr_12_2");
+ gcc_jit_global_set_initializer_rvalue (foo, ctor);
+ }
+ { /* float foo[4] = {1,2,0}; (null init) */
+
+ gcc_jit_type *arr_type = gcc_jit_context_new_array_type (ctxt,
+ 0,
+ float_type,
+ 4);
+ gcc_jit_rvalue *rval_1 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, float_type, 1);
+ gcc_jit_rvalue *rval_2 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, float_type, 2);
+
+ gcc_jit_rvalue *values[] = {rval_1, rval_2, 0};
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_array_constructor (ctxt,
+ 0,
+ arr_type,
+ 2,
+ values);
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ arr_type,
+ "global_floatarr_120");
+ gcc_jit_global_set_initializer_rvalue (foo, ctor);
+ }
+ { /* float foo[4] = {}; (null init) */
+
+ gcc_jit_type *arr_type = gcc_jit_context_new_array_type (ctxt,
+ 0,
+ float_type,
+ 4);
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_array_constructor (ctxt,
+ 0,
+ arr_type,
+ 0,
+ 0);
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ arr_type,
+ "global_floatarr_0000");
+ gcc_jit_global_set_initializer_rvalue (foo, ctor);
+ }
+ { /* float foo[4] = {NULL , NULL, 3, NULL, 5, 6}; (null init) */
+
+ gcc_jit_type *arr_type = gcc_jit_context_new_array_type (ctxt,
+ 0,
+ float_type,
+ 8);
+ gcc_jit_rvalue *rval3 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, float_type, 3);
+ gcc_jit_rvalue *rval5 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, float_type, 5);
+ gcc_jit_rvalue *rval6 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, float_type, 6);
+
+ gcc_jit_rvalue *values[] = {0, 0, rval3, 0, rval5, rval6, 0 };
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_array_constructor (ctxt,
+ 0,
+ arr_type,
+ 7,
+ values);
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ arr_type,
+ "global_floatarr_00305600");
+ gcc_jit_global_set_initializer_rvalue (foo, ctor);
+ }
+ { /* int *foo[4] = {0, &global_intarr_1234[1], 0}; */
+
+ gcc_jit_type *arr_type = gcc_jit_context_new_array_type (ctxt,
+ 0,
+ pint_type,
+ 4);
+ gcc_jit_rvalue *rval_1 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 1);
+ gcc_jit_lvalue *arr_access = gcc_jit_context_new_array_access (
+ ctxt,
+ 0,
+ gcc_jit_lvalue_as_rvalue (global_intarr_1234),
+ rval_1);
+ gcc_jit_rvalue *rval_2 = gcc_jit_lvalue_get_address (arr_access, 0);
+ gcc_jit_rvalue *rval_3 = gcc_jit_context_null (ctxt, pint_type);
+
+ gcc_jit_rvalue *values[] = {0, rval_2, rval_3};
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_array_constructor (ctxt,
+ 0,
+ arr_type,
+ 2,
+ values);
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ arr_type,
+ "global_pintarr_x2xx");
+ gcc_jit_global_set_initializer_rvalue (foo, ctor);
+ }
+ { /* char foo[4] = {'q','w','e',0}; */
+
+ gcc_jit_type *arr_type = gcc_jit_context_new_array_type (ctxt,
+ 0,
+ char_type,
+ 4);
+
+
+ gcc_jit_rvalue *rvals[] = {
+ gcc_jit_context_new_rvalue_from_int ( ctxt, char_type, 'q'),
+ gcc_jit_context_new_rvalue_from_int ( ctxt, char_type, 'w'),
+ gcc_jit_context_new_rvalue_from_int ( ctxt, char_type, 'e'),
+ gcc_jit_context_new_rvalue_from_int ( ctxt, char_type, 0)
+ };
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_array_constructor (ctxt,
+ 0,
+ arr_type,
+ 4,
+ rvals);
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ arr_type,
+ "global_chararr_qwe");
+ gcc_jit_global_set_initializer_rvalue (foo, ctor);
+ }
+ { /* int foo[2][2] = {{1,2},{3,4}}; */
+
+ gcc_jit_type *row_type = gcc_jit_context_new_array_type (ctxt,
+ 0,
+ int_type,
+ 2);
+
+ gcc_jit_type *arr_type = gcc_jit_context_new_array_type (ctxt,
+ 0,
+ row_type,
+ 2);
+ gcc_jit_rvalue *rvals_row0[] = {
+ gcc_jit_context_new_rvalue_from_int ( ctxt, int_type, 1),
+ gcc_jit_context_new_rvalue_from_int ( ctxt, int_type, 2)
+ };
+ gcc_jit_rvalue *rvals_row1[] = {
+ gcc_jit_context_new_rvalue_from_int ( ctxt, int_type, 3),
+ gcc_jit_context_new_rvalue_from_int ( ctxt, int_type, 4)
+ };
+
+ gcc_jit_rvalue *ctor_row0 =
+ gcc_jit_context_new_array_constructor (ctxt,
+ 0,
+ row_type,
+ 2,
+ rvals_row0);
+ gcc_jit_rvalue *ctor_row1 =
+ gcc_jit_context_new_array_constructor (ctxt,
+ 0,
+ row_type,
+ 2,
+ rvals_row1);
+ gcc_jit_rvalue *ctors_row[] = {ctor_row0, ctor_row1};
+
+ gcc_jit_rvalue *ctor_arr =
+ gcc_jit_context_new_array_constructor (ctxt,
+ 0,
+ arr_type,
+ 2,
+ ctors_row);
+
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ arr_type,
+ "global_int2x2matrix_1234");
+
+ gcc_jit_global_set_initializer_rvalue (foo, ctor_arr);
+ }
+ { /* const char *foo[4] = {"qwe", "asd"}; */
+
+ gcc_jit_type *arr_type = gcc_jit_context_new_array_type (ctxt,
+ 0,
+ cpchar_type,
+ 4);
+
+
+ gcc_jit_rvalue *rvals[] = {
+ gcc_jit_context_new_string_literal (ctxt, "qwe"),
+ gcc_jit_context_new_string_literal (ctxt, "asd")
+ };
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_array_constructor (ctxt,
+ 0,
+ arr_type,
+ 2,
+ rvals);
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ arr_type,
+ "global_cpchararr_qwe_asd");
+ gcc_jit_global_set_initializer_rvalue (foo, ctor);
+ }
+ { /* const int foo = 3;
+ int bar = foo;
+ */
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ gcc_jit_type_get_const (int_type),
+ "global_const_int_3");
+ gcc_jit_rvalue *rval3 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 3);
+ gcc_jit_global_set_initializer_rvalue (foo,
+ rval3);
+ gcc_jit_lvalue *bar = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ int_type,
+ "global_lvalueinit_int_3");
+ gcc_jit_global_set_initializer_rvalue (bar,
+ gcc_jit_lvalue_as_rvalue (foo));
+ }
+ { /* int foo = 3 * 2;
+ int arr[] = {1,2,3,4};
+ int *bar = &arr[2] + 1
+
+ Example in the docs.
+ */
+
+ gcc_jit_type *arr_type = gcc_jit_context_new_array_type (ctxt,
+ 0,
+ int_type,
+ 4);
+ gcc_jit_rvalue *rval_1 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 1);
+ gcc_jit_rvalue *rval_2 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 2);
+ gcc_jit_rvalue *rval_3 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 3);
+ gcc_jit_rvalue *rval_4 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 4);
+
+ gcc_jit_rvalue *values[] = {rval_1, rval_2, rval_3, rval_4};
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_array_constructor (ctxt,
+ 0,
+ arr_type,
+ 4,
+ values);
+ gcc_jit_lvalue *global_intarr_1234 =
+ gcc_jit_context_new_global (ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ arr_type,
+ "global_intarr_1234_2");
+
+ gcc_jit_global_set_initializer_rvalue (global_intarr_1234, ctor);
+
+ gcc_jit_lvalue *bar =
+ gcc_jit_context_new_global (ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ int_type,
+ "global_int_6");
+ gcc_jit_global_set_initializer_rvalue
+ (bar,
+ gcc_jit_context_new_binary_op
+ (ctxt, 0, GCC_JIT_BINARY_OP_MULT,
+ int_type,
+ gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 3),
+ gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 2)));
+
+ gcc_jit_lvalue *pfoo =
+ gcc_jit_context_new_global (ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ gcc_jit_type_get_pointer (int_type),
+ "global_pint_4");
+ /* int *bar = &arr[2] + 1;
+
+ In practice we could just do &foo[3]
+ but just prove folding this works. */
+ gcc_jit_global_set_initializer_rvalue (
+ pfoo,
+ gcc_jit_lvalue_get_address (
+ gcc_jit_context_new_array_access (
+ ctxt, 0,
+ gcc_jit_lvalue_get_address (
+ gcc_jit_context_new_array_access (
+ ctxt, 0,
+ gcc_jit_lvalue_as_rvalue (global_intarr_1234),
+ gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 2)),
+ 0),
+ gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 1)),
+ 0));
+ }
+ { /* static int bar = 11;
+ int foo () { return bar; } */
+
+ gcc_jit_lvalue *bar = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_INTERNAL,
+ int_type,
+ "global_static_int_11");
+ gcc_jit_rvalue *rval1 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 11);
+ gcc_jit_global_set_initializer_rvalue (bar,
+ rval1);
+
+ gcc_jit_function *fn11 =
+ gcc_jit_context_new_function (ctxt,
+ 0,
+ GCC_JIT_FUNCTION_EXPORTED,
+ int_type,
+ "fn_int_11",
+ 0,
+ 0,
+ 0);
+ gcc_jit_block *block = gcc_jit_function_new_block (fn11, "start");
+
+ gcc_jit_block_end_with_return (block,
+ 0,
+ gcc_jit_lvalue_as_rvalue(bar));
+ }
+ { /* static const int cbar = 11;
+ int cfoo () { return cbar; } */
+
+ gcc_jit_lvalue *bar = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_INTERNAL,
+ gcc_jit_type_get_const (int_type),
+ "global_static_cint_11");
+ gcc_jit_rvalue *rval1 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 11);
+ gcc_jit_global_set_initializer_rvalue (bar,
+ rval1);
+
+ gcc_jit_function *fn11 =
+ gcc_jit_context_new_function (ctxt,
+ 0,
+ GCC_JIT_FUNCTION_EXPORTED,
+ int_type,
+ "fn_cint_11",
+ 0,
+ 0,
+ 0);
+ gcc_jit_block *block = gcc_jit_function_new_block (fn11, "start");
+
+ gcc_jit_block_end_with_return (block,
+ 0,
+ gcc_jit_lvalue_as_rvalue(bar));
+ }
+ { /* static const int cbar = 12;
+ const int* cfoo () { return &cbar; } */
+
+ gcc_jit_lvalue *bar = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_INTERNAL,
+ gcc_jit_type_get_const (int_type),
+ "global_static_cint_12");
+ gcc_jit_rvalue *rval1 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 12);
+ gcc_jit_global_set_initializer_rvalue (bar,
+ rval1);
+
+ gcc_jit_function *fn11 =
+ gcc_jit_context_new_function (ctxt,
+ 0,
+ GCC_JIT_FUNCTION_EXPORTED,
+ gcc_jit_type_get_pointer(int_type),
+ "fn_cint_12",
+ 0,
+ 0,
+ 0);
+
+ gcc_jit_block *block = gcc_jit_function_new_block (fn11, "start");
+
+ gcc_jit_block_end_with_return (block,
+ 0,
+ gcc_jit_lvalue_get_address (bar, 0));
+ }
+ { /* const int foo = 3;
+ short bar = (short)foo;
+
+ Assure casts fold
+ */
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ gcc_jit_type_get_const (int_type),
+ "global_const_int_4");
+ gcc_jit_rvalue *rval3 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 3);
+ gcc_jit_global_set_initializer_rvalue (foo,
+ rval3);
+ gcc_jit_lvalue *bar = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ short_type,
+ "global_lvalueinit_short_3");
+ gcc_jit_global_set_initializer_rvalue (
+ bar,
+ gcc_jit_context_new_cast( ctxt, 0,
+ gcc_jit_lvalue_as_rvalue (foo),
+ short_type));
+ }
+ { /* const int foo = 3;
+ const int const *bar = &foo; */
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ gcc_jit_type_get_const (int_type),
+ "global_const_int_6");
+ gcc_jit_rvalue *rval3 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 3);
+ gcc_jit_global_set_initializer_rvalue (foo,
+ rval3);
+ gcc_jit_lvalue *bar = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ gcc_jit_type_get_const (
+ gcc_jit_type_get_pointer (
+ gcc_jit_type_get_const (
+ int_type))),
+ "global_lvalueinit_cpcint_3");
+ gcc_jit_global_set_initializer_rvalue (
+ bar,
+ gcc_jit_lvalue_get_address (foo, 0));
+ }
+ { /* const int __attribute__ ((aligned (64))) foo = 3;
+ int bar = foo;
+
+ Assure alignement does not make the constant "miss"
+ or something strange.
+ */
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ gcc_jit_type_get_const (gcc_jit_type_get_aligned (int_type, 64)),
+ "global_const_int_7");
+ gcc_jit_rvalue *rval = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 4);
+ gcc_jit_global_set_initializer_rvalue (foo,
+ rval);
+ gcc_jit_lvalue *bar = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ int_type,
+ "global_lvalueinit_int_4");
+ gcc_jit_global_set_initializer_rvalue (bar,
+ gcc_jit_lvalue_as_rvalue (foo));
+ }
+ {
+ /* union upintsize { size_t s; int *p } u = {.s = 0xEEEFBEEF}; */
+ gcc_jit_field *f1 = gcc_jit_context_new_field (ctxt,
+ 0,
+ size_type,
+ "s");
+ gcc_jit_field *f2 = gcc_jit_context_new_field (ctxt,
+ 0,
+ pint_type,
+ "p");
+ gcc_jit_field *fields1[] = {f1, f2};
+
+ gcc_jit_type *ubar = gcc_jit_context_new_union_type (ctxt,
+ 0,
+ "upintsize",
+ 2,
+ fields1);
+ gcc_jit_lvalue *foo = gcc_jit_context_new_global (
+ ctxt, NULL,
+ GCC_JIT_GLOBAL_EXPORTED,
+ gcc_jit_type_get_const (ubar),
+ "global_const_upintsize_1");
+
+ gcc_jit_rvalue *val = gcc_jit_context_new_rvalue_from_long (
+ ctxt, size_type, 0xEEEFBEEF);
+
+ gcc_jit_rvalue *ctor =
+ gcc_jit_context_new_union_constructor (ctxt,
+ 0,
+ ubar,
+ f1,
+ val);
+
+ gcc_jit_global_set_initializer_rvalue (foo, ctor);
+ }
+ {/*
+ struct B;
+ struct A { B* b; };
+ struct B { A* a; };
+ extern struct B b;
+ struct A a = {.b = b};
+ struct B b = {.a = a};
+
+ See that opaque structs and circular pointers works.
+ */
+
+ gcc_jit_struct *struct_B =
+ gcc_jit_context_new_opaque_struct(ctxt,
+ 0, "B");
+
+ gcc_jit_field *fields_A[] =
+ {
+ gcc_jit_context_new_field (ctxt, 0,
+ gcc_jit_type_get_pointer (
+ gcc_jit_struct_as_type (struct_B)),
+ "b")
+ };
+
+ gcc_jit_struct *struct_A =
+ gcc_jit_context_new_struct_type(ctxt, 0, "A", 1, fields_A);
+
+ gcc_jit_field *fields_B[] =
+ {
+ gcc_jit_context_new_field (ctxt, 0,
+ gcc_jit_type_get_pointer (
+ gcc_jit_struct_as_type (struct_A)),
+ "a")
+ };
+
+ gcc_jit_struct_set_fields (struct_B, 0, 1, fields_B);
+
+ gcc_jit_lvalue *a =
+ gcc_jit_context_new_global (ctxt, 0, GCC_JIT_GLOBAL_EXPORTED,
+ gcc_jit_struct_as_type (struct_A),
+ "a_glb");
+ gcc_jit_lvalue *b =
+ gcc_jit_context_new_global (ctxt, 0, GCC_JIT_GLOBAL_EXPORTED,
+ gcc_jit_struct_as_type (struct_B),
+ "b_glb");
+ gcc_jit_rvalue *b_addr = gcc_jit_lvalue_get_address( b, 0);
+ gcc_jit_rvalue *a_ctor =
+ gcc_jit_context_new_struct_constructor (ctxt, 0,
+ gcc_jit_struct_as_type (struct_A),
+ 1, 0,
+ &b_addr);
+ gcc_jit_rvalue *a_addr = gcc_jit_lvalue_get_address( a, 0);
+ gcc_jit_rvalue *b_ctor =
+ gcc_jit_context_new_struct_constructor (ctxt, 0,
+ gcc_jit_struct_as_type (struct_B),
+ 1, 0,
+ &a_addr);
+
+ gcc_jit_global_set_initializer_rvalue(a, a_ctor);
+ gcc_jit_global_set_initializer_rvalue(b, b_ctor);
+ }
+}
+
+struct fi {
+ float f;
+ int i;
+};
+
+struct bar1 {
+ float ff;
+ struct fi fi;
+ int ii;
+};
+
+union ubar1 {
+ float ff;
+ int ii;
+};
+
+union upintsize {
+ size_t s;
+ int *p;
+};
+
+struct B_glb;
+struct A_glb {
+ struct B_glb *b;
+};
+struct B_glb {
+ struct A_glb *a;
+};
+
+int test_aligned64_works_in_linker_1 __attribute__ ((aligned (64))) = 0;
+int test_aligned64_works_in_linker_2 __attribute__ ((aligned (64))) = 0;
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ CHECK_NON_NULL (result);
+
+ {
+ struct bar1 *bar =
+ gcc_jit_result_get_global (result, "global_struct_bar_1234_1");
+
+ CHECK_VALUE (bar->ff, 1);
+ CHECK_VALUE (bar->fi.f, 2);
+ CHECK_VALUE (bar->fi.i, 3);
+ CHECK_VALUE (bar->ii, 4);
+ }
+ {
+ struct bar1 *bar =
+ gcc_jit_result_get_global (result, "global_struct_bar_1234_2");
+
+ CHECK_VALUE (bar->ff, 1);
+ CHECK_VALUE (bar->fi.f, 2);
+ CHECK_VALUE (bar->fi.i, 3);
+ CHECK_VALUE (bar->ii, 4);
+ }
+ {
+ struct fi *fi = gcc_jit_result_get_global (result, "global_struct_fi_23_1");
+
+ CHECK_VALUE (fi->f, 2);
+ CHECK_VALUE (fi->i, 3);
+ }
+ {
+ struct fi *fi = gcc_jit_result_get_global (result, "global_struct_fi_23_2");
+
+ CHECK_VALUE (fi->f, 2);
+ CHECK_VALUE (fi->i, 3);
+ }
+ {
+ struct fi *fi = gcc_jit_result_get_global (result, "global_struct_fi_00_1");
+
+ CHECK_VALUE (fi->f, 0);
+ CHECK_VALUE (fi->i, 0);
+ }
+ {
+ struct fi *fi = gcc_jit_result_get_global (result, "global_struct_fi_00_2");
+
+ CHECK_VALUE (fi->f, 0);
+ CHECK_VALUE (fi->i, 0);
+ }
+ {
+ struct fi *fi = gcc_jit_result_get_global (result, "global_struct_fi_0_1");
+
+ CHECK_VALUE (fi->f, 0);
+ CHECK_VALUE (fi->i, 0);
+ }
+ {
+ struct fi *fi = gcc_jit_result_get_global (result, "global_struct_fi_0_2");
+
+ CHECK_VALUE (fi->f, 0);
+ CHECK_VALUE (fi->i, 0);
+ }
+ {
+ struct fi *fi = gcc_jit_result_get_global (result, "global_struct_fi_6");
+
+ CHECK_VALUE (fi->f, 0);
+ CHECK_VALUE (fi->i, 0);
+ }
+ {
+ struct fi *fi = gcc_jit_result_get_global (result, "global_struct_fi_3");
+
+ CHECK_VALUE (fi->f, 2 * 2);
+ CHECK_VALUE (fi->i, 3);
+ }
+ {
+ union ubar1 *foo = gcc_jit_result_get_global (result,
+ "global_union_ufoo_ff3");
+ CHECK_VALUE (foo->ff, 3);
+ }
+ {
+ union ubar1 *foo = gcc_jit_result_get_global (result,
+ "global_union_ufoo_ii2");
+ CHECK_VALUE (foo->ii, 2);
+ }
+ {
+ union ubar1 *foo = gcc_jit_result_get_global (result,
+ "global_union_ufoo_ff1c1");
+ CHECK_VALUE (foo->ff, 1.1f);
+ }
+ {
+ union ubar1 *foo = gcc_jit_result_get_global (result,
+ "global_union_ufoo_0");
+ CHECK_VALUE (foo->ii, 0);
+ }
+ {
+ int *foo = gcc_jit_result_get_global (result, "global_int1_3");
+
+ CHECK_VALUE (*foo, 3);
+ }
+ {
+ int *foo = gcc_jit_result_get_global (result, "global_cvint1_3");
+
+ CHECK_VALUE (*foo, 3);
+ }
+ {
+ int *foo = gcc_jit_result_get_global (result, "global_int2_3");
+
+ CHECK_VALUE (*foo, 3);
+ }
+ {
+ int *foo = gcc_jit_result_get_global (result, "global_int3_18");
+
+ CHECK_VALUE (*foo, 18);
+ }
+ {
+ int *foo = gcc_jit_result_get_global (result, "global_int_alotofoperators");
+
+ CHECK_VALUE (*foo, ~(-((((((2 | 8) & 15) ^ 0) << 3 >> 2) - 1) / 2)));
+ }
+ {
+ int *foo = gcc_jit_result_get_global (result, "global_int4_3");
+ int **pfoo = gcc_jit_result_get_global (result, "global_pint5");
+
+ CHECK_VALUE (*foo, 3);
+ CHECK_VALUE (foo, *pfoo);
+ CHECK_VALUE (**pfoo, 3);
+ }
+ {
+ int * (*foo) (void) = gcc_jit_result_get_code (result, "fn_pint_0");
+ int **pfoo = gcc_jit_result_get_global (result, "global_pint6");
+
+ CHECK_VALUE (*foo (), 0);
+ CHECK_VALUE (foo (), *pfoo);
+ CHECK_VALUE (**pfoo, 0);
+ }
+ {
+ int *foo = gcc_jit_result_get_global (result, "global_int6_3");
+ int **pfoo = gcc_jit_result_get_global (result, "global_pint7");
+
+ CHECK_VALUE (*foo, 3);
+ CHECK_VALUE (foo + 1, *pfoo);
+ CHECK_VALUE (*(*pfoo - 1), 3);
+ }
+ {
+ double *foo = gcc_jit_result_get_global (result, "global_double1_3");
+
+ CHECK_VALUE (*foo, 3);
+ }
+ {
+ double *foo = gcc_jit_result_get_global (result, "global_double2_12");
+
+ CHECK_VALUE (*foo, 12);
+ }
+ {
+ _Bool *foo = gcc_jit_result_get_global (result, "global_bool1_1");
+
+ CHECK_VALUE (*foo, 1);
+ }
+ {
+ int *foo = gcc_jit_result_get_global (result, "global_intarr_1234");
+
+ CHECK_VALUE (foo[0], 1);
+ CHECK_VALUE (foo[1], 2);
+ CHECK_VALUE (foo[2], 3);
+ CHECK_VALUE (foo[3], 4);
+ }
+ {
+ float *foo = gcc_jit_result_get_global (result, "global_floatarr_12");
+
+ CHECK_VALUE (foo[0], 1);
+ CHECK_VALUE (foo[1], 2);
+ CHECK_VALUE (foo[2], 0);
+ CHECK_VALUE (foo[3], 0);
+ }
+ {
+ float *foo = gcc_jit_result_get_global (result, "global_floatarr_12_2");
+
+ CHECK_VALUE (foo[0], 1);
+ CHECK_VALUE (foo[1], 2);
+ CHECK_VALUE (foo[2], 0);
+ CHECK_VALUE (foo[3], 0);
+ }
+ {
+ float *foo = gcc_jit_result_get_global (result, "global_floatarr_120");
+
+ CHECK_VALUE (foo[0], 1);
+ CHECK_VALUE (foo[1], 2);
+ CHECK_VALUE (foo[2], 0);
+ CHECK_VALUE (foo[3], 0);
+ }
+ {
+ float *foo = gcc_jit_result_get_global (result, "global_floatarr_0000");
+
+ CHECK_VALUE (foo[0], 0);
+ CHECK_VALUE (foo[1], 0);
+ CHECK_VALUE (foo[2], 0);
+ CHECK_VALUE (foo[3], 0);
+ }
+ {
+ float *foo = gcc_jit_result_get_global (result, "global_floatarr_00305600");
+
+ float key[] = {0,0,3,0,5,6,0,0};
+
+ CHECK_VALUE (memcmp (foo, key, sizeof key), 0);
+ }
+ {
+ int **foo = gcc_jit_result_get_global (result, "global_pintarr_x2xx");
+
+ CHECK_VALUE (foo[0], 0);
+ CHECK_VALUE (*foo[1], 2);
+ }
+ {
+ char *foo = gcc_jit_result_get_global (result, "global_chararr_qwe");
+ const char *key = "qwe";
+ CHECK_VALUE (strcmp (foo, key), 0);
+ }
+ {
+ int *foo = gcc_jit_result_get_global (result, "global_int2x2matrix_1234");
+
+ for (int i = 0; i < 4; i++)
+ CHECK_VALUE (foo[i], i + 1);
+ }
+ {
+ const char **foo =
+ gcc_jit_result_get_global (result, "global_cpchararr_qwe_asd");
+
+ CHECK_VALUE (strcmp (foo[0], "qwe"), 0);
+ CHECK_VALUE (strcmp (foo[1], "asd"), 0);
+ }
+ {
+ int *foo = gcc_jit_result_get_global (result, "global_lvalueinit_int_3");
+
+ CHECK_VALUE (*foo, 3);
+ }
+ {
+ int **pint =
+ gcc_jit_result_get_global (result, "global_pint_4");
+ int *foo =
+ gcc_jit_result_get_global (result, "global_int_6");
+ CHECK_VALUE (**pint, 4);
+ CHECK_VALUE (*foo, 6);
+ }
+ {
+ int (*fn)(void) = gcc_jit_result_get_code (result, "fn_int_11");
+ CHECK_VALUE (fn (), 11);
+ }
+ {
+ int (*fn)(void) = gcc_jit_result_get_code (result, "fn_cint_11");
+ CHECK_VALUE (fn (), 11);
+ }
+ {
+ int *(*fn)(void) = gcc_jit_result_get_code (result, "fn_cint_12");
+ CHECK_VALUE (*fn (), 12);
+ }
+ {
+ short *foo =
+ gcc_jit_result_get_code (result, "global_lvalueinit_short_3");
+ CHECK_VALUE (*foo, 3);
+ }
+ {
+ int **foo =
+ gcc_jit_result_get_code (result, "global_lvalueinit_cpcint_3");
+ CHECK_VALUE (**foo, 3);
+ }
+ {
+ int *foo =
+ gcc_jit_result_get_code (result, "global_lvalueinit_int_4");
+ CHECK_VALUE (*foo, 4);
+
+ int *bar =
+ gcc_jit_result_get_code (result, "global_const_int_7");
+ CHECK_VALUE (*bar, 4);
+ /* The linker does not have to support up to 64 alignment, so test that
+ it does before testing that it works in libgccjit. */
+ if ((size_t) &test_aligned64_works_in_linker_1 % 64 == 0 &&
+ (size_t) &test_aligned64_works_in_linker_2 % 64 == 0)
+ CHECK_VALUE ((size_t) bar % 64, 0); /* __attribute__ ((aligned (64))) */
+ }
+ {
+ union upintsize *foo =
+ gcc_jit_result_get_code (result, "global_const_upintsize_1");
+ CHECK_VALUE (foo->p, (void*)0xEEEFBEEF);
+ }
+ {
+ struct A_glb *a =
+ gcc_jit_result_get_code (result, "a_glb");
+ struct B_glb *b =
+ gcc_jit_result_get_code (result, "b_glb");
+
+ CHECK_VALUE (a->b, b);
+ CHECK_VALUE (b->a, a);
+ }
+}
diff --git a/gcc/testsuite/jit.dg/test-local-init-rvalue.c b/gcc/testsuite/jit.dg/test-local-init-rvalue.c
new file mode 100644
index 0000000..1d74679
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-local-init-rvalue.c
@@ -0,0 +1,707 @@
+#include <stdio.h>
+#include "libgccjit.h"
+#include "harness.h"
+
+/* This testcase checks that gcc_jit_context_new_constructor() works
+ with locals. Tests that constructors can be used as return
+ values or function call values. Test that constructors can have side
+ effects and be assigned to locals.
+ */
+
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ gcc_jit_type *int_type = gcc_jit_context_get_type (ctxt,
+ GCC_JIT_TYPE_INT);
+ gcc_jit_type *pint_type = gcc_jit_type_get_pointer (int_type);
+ gcc_jit_type *double_type = gcc_jit_context_get_type (ctxt,
+ GCC_JIT_TYPE_DOUBLE);
+ gcc_jit_type *float_type = gcc_jit_context_get_type (ctxt,
+ GCC_JIT_TYPE_FLOAT);
+ gcc_jit_type *bool_type = gcc_jit_context_get_type (ctxt,
+ GCC_JIT_TYPE_BOOL);
+ gcc_jit_type *char_type = gcc_jit_context_get_type (ctxt,
+ GCC_JIT_TYPE_CHAR);
+ gcc_jit_type *size_type = gcc_jit_context_get_type (ctxt,
+ GCC_JIT_TYPE_SIZE_T);
+ gcc_jit_type *voidptr_type = gcc_jit_context_get_type (ctxt,
+ GCC_JIT_TYPE_VOID_PTR);
+ gcc_jit_type *void_type = gcc_jit_context_get_type (ctxt,
+ GCC_JIT_TYPE_VOID);
+
+ /* Make a struct: struct fi { float f; int i;} */
+ gcc_jit_field *fi_f = gcc_jit_context_new_field (ctxt,
+ 0,
+ float_type,
+ "f");
+ gcc_jit_field *fi_i = gcc_jit_context_new_field (ctxt,
+ 0,
+ int_type,
+ "i");
+ gcc_jit_field *fields[] = {fi_f, fi_i};
+
+ gcc_jit_type *struct_fi_type =
+ gcc_jit_struct_as_type (
+ gcc_jit_context_new_struct_type (ctxt,
+ 0,
+ "fi",
+ 2,
+ fields));
+
+ /* Make a struct:
+
+ struct bar {
+ int ii;
+ int arr[50];
+ float ff;
+ char cc;
+ }
+ */
+ gcc_jit_field *bar_ff = gcc_jit_context_new_field (ctxt,
+ 0,
+ float_type,
+ "ff");
+ gcc_jit_field *bar_ii = gcc_jit_context_new_field (ctxt,
+ 0,
+ int_type,
+ "ii");
+ gcc_jit_field *bar_cc = gcc_jit_context_new_field (ctxt,
+ 0,
+ char_type,
+ "cc");
+ gcc_jit_type *int50arr_type =
+ gcc_jit_context_new_array_type (ctxt,
+ 0,
+ int_type,
+ 50);
+ gcc_jit_field *bar_fi = gcc_jit_context_new_field (ctxt,
+ 0,
+ int50arr_type,
+ "arr");
+ gcc_jit_field *fields2[] = {bar_ff, bar_fi, bar_ii, bar_cc};
+
+ gcc_jit_type *struct_bar_type =
+ gcc_jit_struct_as_type (
+ gcc_jit_context_new_struct_type (ctxt,
+ 0,
+ "bar",
+ 4,
+ fields2));
+
+ /* Make an union:
+
+ union ubar {
+ float ff;
+ int ii;
+ };
+ */
+ gcc_jit_field *ubar_ff = gcc_jit_context_new_field (ctxt,
+ 0,
+ float_type,
+ "ff");
+ gcc_jit_field *ubar_ii = gcc_jit_context_new_field (ctxt,
+ 0,
+ int_type,
+ "ii");
+ gcc_jit_field *fields3[] = {ubar_ff, ubar_ii};
+ gcc_jit_type *ubar = gcc_jit_context_new_union_type (ctxt,
+ 0,
+ "ubar",
+ 2,
+ fields3);
+
+ (void) ubar;
+ (void) struct_bar_type;
+ (void) struct_fi_type;
+ (void) bool_type;
+ (void) double_type;
+ (void) pint_type;
+ (void) voidptr_type;
+ (void) size_type;
+
+ gcc_jit_function *fn_int_3;
+ { /* int foo () { int local = 3; return local;} */
+ fn_int_3 =
+ gcc_jit_context_new_function (ctxt,
+ 0,
+ GCC_JIT_FUNCTION_EXPORTED,
+ int_type,
+ "fn_int_3",
+ 0,
+ 0,
+ 0);
+ gcc_jit_block *block = gcc_jit_function_new_block (fn_int_3, "start");
+ gcc_jit_lvalue *local = gcc_jit_function_new_local (fn_int_3,
+ 0,
+ int_type,
+ "local");
+ gcc_jit_rvalue *rval = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 3);
+
+ gcc_jit_block_add_assignment (block, 0, local, rval);
+
+ gcc_jit_block_end_with_return (block,
+ 0,
+ gcc_jit_lvalue_as_rvalue(local));
+ }
+ { /* struct fi foo() { return (struct fi){1,2};} */
+ gcc_jit_function *fn =
+ gcc_jit_context_new_function (ctxt,
+ 0,
+ GCC_JIT_FUNCTION_EXPORTED,
+ struct_fi_type,
+ "fn_fi_1_2",
+ 0,
+ 0,
+ 0);
+ gcc_jit_block *block = gcc_jit_function_new_block (fn, "start");
+
+ gcc_jit_rvalue *rval_f1 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, float_type, 1);
+ gcc_jit_rvalue *rval_i2 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 2);
+
+ gcc_jit_rvalue *vals[] = { rval_f1, rval_i2};
+ gcc_jit_field *fields[] = {fi_f, fi_i};
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_struct_constructor
+ (ctxt, 0,
+ struct_fi_type,
+ 2,
+ fields,
+ vals);
+
+ gcc_jit_block_end_with_return (block,
+ 0,
+ ctor);
+ }
+ { /*
+ struct fi foo()
+ {
+ struct fi local = {1,2};
+ local = (struct fi){5,6};
+ return local;
+ }
+ */
+ gcc_jit_function *fn =
+ gcc_jit_context_new_function (ctxt,
+ 0,
+ GCC_JIT_FUNCTION_EXPORTED,
+ struct_fi_type,
+ "fn_fi_5_6",
+ 0,
+ 0,
+ 0);
+ gcc_jit_lvalue *local = gcc_jit_function_new_local (fn,
+ 0,
+ struct_fi_type,
+ "local");
+ gcc_jit_block *block = gcc_jit_function_new_block (fn, "start");
+
+ {
+ gcc_jit_rvalue *rval_f1 =
+ gcc_jit_context_new_rvalue_from_int (ctxt, float_type, 1);
+ gcc_jit_rvalue *rval_i2 =
+ gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 2);
+
+ gcc_jit_rvalue *vals[] = { rval_f1, rval_i2};
+ gcc_jit_field *fields[] = {fi_f, fi_i};
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_struct_constructor
+ (ctxt, 0,
+ struct_fi_type,
+ 2,
+ fields,
+ vals);
+ gcc_jit_block_add_assignment (block, 0, local, ctor);
+ }
+ {
+ gcc_jit_rvalue *rval_f1 =
+ gcc_jit_context_new_rvalue_from_int (ctxt, float_type, 5);
+ gcc_jit_rvalue *rval_i2 =
+ gcc_jit_context_new_rvalue_from_int (ctxt, int_type, 6);
+
+ gcc_jit_rvalue *vals[] = { rval_f1, rval_i2};
+ gcc_jit_field *fields[] = {fi_f, fi_i};
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_struct_constructor
+ (ctxt, 0,
+ struct_fi_type,
+ 2,
+ fields,
+ vals);
+ gcc_jit_block_add_assignment (block, 0, local, ctor);
+ }
+
+ gcc_jit_block_end_with_return (block,
+ 0,
+ gcc_jit_lvalue_as_rvalue(local));
+ }
+ { /* struct fi foo() { struct fi local = {1, fn_int_3()};
+ return local;}
+
+ The ctor has a side effect (funccall) */
+ gcc_jit_function *fn =
+ gcc_jit_context_new_function (ctxt,
+ 0,
+ GCC_JIT_FUNCTION_EXPORTED,
+ struct_fi_type,
+ "fn_fi_1_3",
+ 0,
+ 0,
+ 0);
+ gcc_jit_lvalue *local = gcc_jit_function_new_local (fn,
+ 0,
+ struct_fi_type,
+ "local");
+ gcc_jit_block *block = gcc_jit_function_new_block (fn, "start");
+
+ {
+ gcc_jit_rvalue *rval_f1 =
+ gcc_jit_context_new_rvalue_from_int (ctxt, float_type, 1);
+ gcc_jit_rvalue *rval_i2 =
+ gcc_jit_context_new_call (ctxt, 0, fn_int_3, 0, 0);
+
+ gcc_jit_rvalue *vals[] = { rval_f1, rval_i2};
+ gcc_jit_field *fields[] = {fi_f, fi_i};
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_struct_constructor
+ (ctxt, 0,
+ struct_fi_type,
+ 2,
+ fields,
+ vals);
+ gcc_jit_block_add_assignment (block, 0, local, ctor);
+ }
+
+ gcc_jit_block_end_with_return (block,
+ 0,
+ gcc_jit_lvalue_as_rvalue(local));
+ }
+ { /* struct fi foo(fi) { return fi;}
+ struct fi bar() { return foo((struct fi){3, 4}); }
+ */
+
+ gcc_jit_param *fi_param =
+ gcc_jit_context_new_param (ctxt, 0, struct_fi_type, "fi");
+
+ gcc_jit_function *fn0 =
+ gcc_jit_context_new_function (ctxt,
+ 0,
+ GCC_JIT_FUNCTION_EXPORTED,
+ struct_fi_type,
+ "fn_fi_x_x",
+ 1,
+ &fi_param,
+ 0);
+ gcc_jit_block *block0 = gcc_jit_function_new_block (fn0, "start");
+ gcc_jit_block_end_with_return (block0,
+ 0,
+ gcc_jit_param_as_rvalue (
+ gcc_jit_function_get_param (fn0, 0)));
+
+ gcc_jit_function *fn =
+ gcc_jit_context_new_function (ctxt,
+ 0,
+ GCC_JIT_FUNCTION_EXPORTED,
+ struct_fi_type,
+ "fn_fi_3_4",
+ 0,
+ 0,
+ 0);
+ gcc_jit_block *block = gcc_jit_function_new_block (fn, "start");
+
+ gcc_jit_rvalue *rval_f1 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, float_type, 3);
+ gcc_jit_rvalue *rval_i2 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 4);
+
+ gcc_jit_rvalue *vals[] = { rval_f1, rval_i2};
+ gcc_jit_field *fields[] = {fi_f, fi_i};
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_struct_constructor
+ (ctxt, 0,
+ struct_fi_type,
+ 2,
+ fields,
+ vals);
+
+ gcc_jit_rvalue *call = gcc_jit_context_new_call (ctxt, 0, fn0, 1, &ctor);
+
+ gcc_jit_block_end_with_return (block,
+ 0,
+ call);
+ }
+ { /*
+ void foo(struct bar *b) { *b = (struct bar) {.arr = {1,2}; }
+ */
+
+ gcc_jit_param *param =
+ gcc_jit_context_new_param (ctxt, 0,
+ gcc_jit_type_get_pointer (struct_bar_type),
+ "b");
+
+
+ gcc_jit_function *fn =
+ gcc_jit_context_new_function (ctxt,
+ 0,
+ GCC_JIT_FUNCTION_EXPORTED,
+ void_type,
+ "fn_pbar_12",
+ 1,
+ &param,
+ 0);
+ gcc_jit_block *block = gcc_jit_function_new_block (fn, "start");
+
+ gcc_jit_rvalue *rval_i1 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 1);
+ gcc_jit_rvalue *rval_i2 = gcc_jit_context_new_rvalue_from_int (
+ ctxt, int_type, 2);
+
+ gcc_jit_rvalue *arr_vals[] = { rval_i1, rval_i2};
+
+ gcc_jit_rvalue *arr_ctor = gcc_jit_context_new_array_constructor
+ (ctxt, 0,
+ int50arr_type,
+ 2,
+ arr_vals);
+
+ gcc_jit_rvalue *str_ctor = gcc_jit_context_new_struct_constructor
+ (ctxt,
+ 0,
+ struct_bar_type,
+ 1,
+ &bar_fi,
+ &arr_ctor);
+
+ gcc_jit_param *p0 = gcc_jit_function_get_param (fn, 0);
+ gcc_jit_lvalue *lv0 = gcc_jit_param_as_lvalue (p0);
+ gcc_jit_lvalue *deref =
+ gcc_jit_rvalue_dereference (gcc_jit_lvalue_as_rvalue (lv0), 0);
+
+ gcc_jit_block_add_assignment (block, 0,
+ deref,
+ str_ctor);
+
+ gcc_jit_block_end_with_void_return (block, 0);
+ }
+ { /* struct bar foo() { struct bar local = {};
+ return local;}
+ */
+ gcc_jit_function *fn =
+ gcc_jit_context_new_function (ctxt,
+ 0,
+ GCC_JIT_FUNCTION_EXPORTED,
+ struct_bar_type,
+ "fn_bar_0s",
+ 0,
+ 0,
+ 0);
+ gcc_jit_lvalue *local =
+ gcc_jit_function_new_local (fn,
+ 0,
+ struct_bar_type,
+ "local");
+ gcc_jit_block *block = gcc_jit_function_new_block (fn, "start");
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_struct_constructor
+ (ctxt, 0,
+ struct_bar_type,
+ 0,
+ 0,
+ 0);
+ gcc_jit_block_add_assignment (block, 0, local, ctor);
+
+ gcc_jit_block_end_with_return (block,
+ 0,
+ gcc_jit_lvalue_as_rvalue(local));
+ }
+ { /* struct bar foo() { struct bar local;
+ local.arr = (int [50]){1,2,3,4,5,6};
+ return local;}
+ */
+ gcc_jit_function *fn =
+ gcc_jit_context_new_function (ctxt,
+ 0,
+ GCC_JIT_FUNCTION_EXPORTED,
+ struct_bar_type,
+ "fn_bar_123s",
+ 0,
+ 0,
+ 0);
+ gcc_jit_lvalue *local =
+ gcc_jit_function_new_local (fn,
+ 0,
+ struct_bar_type,
+ "local");
+ gcc_jit_block *block = gcc_jit_function_new_block (fn, "start");
+
+ gcc_jit_rvalue *values[6];
+
+ for (int i = 0; i < 6; i++)
+ values[i] = gcc_jit_context_new_rvalue_from_int (ctxt, int_type, i + 1);
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_array_constructor
+ (ctxt, 0,
+ int50arr_type,
+ 6,
+ values);
+
+ gcc_jit_lvalue *arr_lv = gcc_jit_lvalue_access_field (local,
+ 0,
+ bar_fi);
+ gcc_jit_block_add_assignment (block, 0, arr_lv, ctor);
+
+ gcc_jit_block_end_with_return (block,
+ 0,
+ gcc_jit_lvalue_as_rvalue(local));
+ }
+ { /* int[50] foo() { int arr[50];
+ arr = (int [50]){1,2,3,4,5,6};
+ return arr;}
+
+ N.B: Not a typo, returning an array.
+ */
+ gcc_jit_function *fn =
+ gcc_jit_context_new_function (ctxt,
+ 0,
+ GCC_JIT_FUNCTION_EXPORTED,
+ int50arr_type,
+ "fn_int50arr_123s",
+ 0,
+ 0,
+ 0);
+ gcc_jit_lvalue *local =
+ gcc_jit_function_new_local (fn,
+ 0,
+ int50arr_type,
+ "local");
+ gcc_jit_block *block = gcc_jit_function_new_block (fn, "start");
+
+ gcc_jit_rvalue *values[6];
+
+ for (int i = 0; i < 6; i++)
+ values[i] = gcc_jit_context_new_rvalue_from_int (ctxt, int_type, i + 1);
+
+ gcc_jit_rvalue *ctor = gcc_jit_context_new_array_constructor (
+ ctxt,
+ 0,
+ int50arr_type,
+ 6,
+ values);
+
+ gcc_jit_block_add_assignment (block, 0, local, ctor);
+
+ gcc_jit_block_end_with_return (block,
+ 0,
+ gcc_jit_lvalue_as_rvalue(local));
+ }
+ { /*
+ Verify that circular linked lists compiles, .e.g.
+ that visit_children does not run in circles or something.
+
+ struct llist { struct llist *next; };
+
+ bool foo (void)
+ {
+ volatile struct llist a;
+ volatile struct llist b;
+
+ a = (struct llist) {.next = &b};
+ b = (struct llist) {.next = &a};
+
+ return a.next == &b;
+ }
+ */
+ gcc_jit_struct *llist =
+ gcc_jit_context_new_opaque_struct(ctxt,
+ 0, "llist_lcl");
+ gcc_jit_field *fields[] =
+ {
+ gcc_jit_context_new_field (ctxt, 0,
+ gcc_jit_type_get_pointer (
+ gcc_jit_struct_as_type (llist)),
+ "next")
+ };
+ gcc_jit_struct_set_fields (llist, 0, 1, fields);
+ gcc_jit_type *t_llist = gcc_jit_struct_as_type (llist);
+
+ gcc_jit_function *fn =
+ gcc_jit_context_new_function (ctxt,
+ 0,
+ GCC_JIT_FUNCTION_EXPORTED,
+ bool_type,
+ "fn_llist",
+ 0,
+ 0,
+ 0);
+ gcc_jit_block *block = gcc_jit_function_new_block (fn, "start");
+
+ gcc_jit_lvalue *a =
+ gcc_jit_function_new_local (fn,
+ 0,
+ gcc_jit_type_get_volatile (t_llist),
+ "a");
+ gcc_jit_lvalue *b =
+ gcc_jit_function_new_local (fn,
+ 0,
+ gcc_jit_type_get_volatile (t_llist),
+ "b");
+
+ gcc_jit_rvalue *a_addr = gcc_jit_lvalue_get_address( a, 0);
+ gcc_jit_rvalue *b_addr = gcc_jit_lvalue_get_address( b, 0);
+
+ gcc_jit_rvalue *a_ctor = gcc_jit_context_new_struct_constructor (
+ ctxt,
+ 0,
+ t_llist,
+ 1,
+ 0,
+ &b_addr);
+
+ gcc_jit_rvalue *b_ctor = gcc_jit_context_new_struct_constructor (
+ ctxt,
+ 0,
+ t_llist,
+ 1,
+ 0,
+ &a_addr);
+
+ gcc_jit_block_add_assignment (block, 0,
+ a, a_ctor);
+ gcc_jit_block_add_assignment (block, 0,
+ b, b_ctor);
+
+ gcc_jit_rvalue *cmp =
+ gcc_jit_context_new_comparison (
+ ctxt, 0,
+ GCC_JIT_COMPARISON_EQ,
+ gcc_jit_rvalue_access_field (gcc_jit_lvalue_as_rvalue (a),
+ 0, fields[0]),
+ gcc_jit_context_new_cast (ctxt, 0,
+ gcc_jit_lvalue_get_address (b, 0),
+ gcc_jit_type_get_pointer (t_llist)));
+
+ gcc_jit_block_end_with_return (block,
+ 0, cmp);
+ }
+}
+
+struct fi2 {
+ float f;
+ int i;
+};
+
+struct bar2 {
+ float ff;
+ int arr[50];
+ int ii;
+ char c;
+};
+
+union ubar2 {
+ float ff;
+ int ii;
+};
+
+struct int50arr {
+ int arr[50];
+};
+
+void __attribute__((optimize(0)))
+scramble_stack(void)
+ {
+ char *p = alloca(100);
+ for (int i = 0; i < 100; i++)
+ *p++ = 0xF0;
+ asm(""); /* Mark for side-effect */
+ }
+
+void __attribute__((optimize(0)))
+scramble_arr (char *arr, int len)
+{
+ for (int i = 0; i < len; i++)
+ *arr++ = i;
+ asm(""); /* Mark for side-effect */
+}
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ CHECK_NON_NULL (result);
+
+ {
+ struct fi2 (*fn) (void) = gcc_jit_result_get_code (result, "fn_fi_1_2");
+ scramble_stack ();
+ struct fi2 fi = fn ();
+ CHECK_VALUE (fi.f, 1);
+ CHECK_VALUE (fi.i, 2);
+ }
+ {
+ struct fi2 (*fn) (void) = gcc_jit_result_get_code (result, "fn_fi_5_6");
+ struct fi2 fi = fn ();
+ CHECK_VALUE (fi.f, 5);
+ CHECK_VALUE (fi.i, 6);
+ }
+ {
+ struct fi2 (*fn) (void) = gcc_jit_result_get_code (result, "fn_fi_1_3");
+ struct fi2 fi = fn ();
+ CHECK_VALUE (fi.f, 1);
+ CHECK_VALUE (fi.i, 3);
+ }
+ {
+ struct fi2 (*fn) (void) = gcc_jit_result_get_code (result, "fn_fi_3_4");
+ struct fi2 fi = fn ();
+ CHECK_VALUE (fi.f, 3);
+ CHECK_VALUE (fi.i, 4);
+ }
+ {
+ scramble_stack();
+ struct bar2 (*fn) (void) = gcc_jit_result_get_code (result, "fn_bar_0s");
+ struct bar2 bar = fn ();
+ struct bar2 key = {};
+
+ CHECK_VALUE (bar.ff, 0);
+ CHECK_VALUE (bar.ii, 0);
+ CHECK_VALUE (memcmp (&bar.arr, &key.arr, sizeof (key.arr)), 0);
+ }
+ {
+
+ void (*fn) (struct bar2 *) = gcc_jit_result_get_code (result, "fn_pbar_12");
+
+ struct bar2 bar = (struct bar2) {};
+
+ scramble_arr ((char*)&bar, sizeof bar);
+ scramble_stack();
+
+ fn (&bar);
+
+ struct bar2 key = {.arr = {1,2}};
+ __builtin_clear_padding (&key);
+
+ CHECK_VALUE (memcmp (&bar, &key, sizeof (key)), 0);
+ }
+ {
+ scramble_stack();
+ struct bar2 (*fn) (void) = gcc_jit_result_get_code (result, "fn_bar_123s");
+ struct bar2 bar = fn ();
+ struct bar2 key = {.arr = {1,2,3,4,5,6} };
+
+ CHECK_VALUE (memcmp (&bar.arr, &key.arr, sizeof (key.arr)), 0);
+ }
+ {
+ scramble_stack ();
+ /* This is abit shady. Lets just pretend that array returns à la Fortran
+ is the same thing as returning a struct with an array in it in C. */
+ struct int50arr (*fn) (void) =
+ gcc_jit_result_get_code (result, "fn_int50arr_123s");
+ struct int50arr ans = fn ();
+ int key[50] = {1,2,3,4,5,6};
+
+ CHECK_VALUE (memcmp (ans.arr, key, sizeof (key)), 0);
+ }
+ {
+ _Bool (*fn) (void) = gcc_jit_result_get_code (result, "fn_llist");
+ CHECK_VALUE (fn (), 1);
+ }
+}