1 #include <stdlib.h>
2 #include <stdio.h>
3
4 #include "libgccjit.h"
5
6 #include "harness.h"
7
8 struct assignable_struct
9 {
10 int a;
11 char b;
12 float c;
13 };
14
15 union assignable_union
16 {
17 int a;
18 char b;
19 float c;
20 };
21
22 /* Verify that compound assignment works; let's try to inject the
23 equivalent of:
24
25 struct assignable_struct
26 test_struct_assignment (struct assignable_struct x)
27 {
28 struct assignable_struct y, z;
29 y = x;
30 z = y;
31 return z;
32 }
33
34 and the same, for "union assignable_union". */
35
36 /* Make the type "struct assignable_struct" or "union assignable_union". */
37
38 static gcc_jit_type *
make_type(gcc_jit_context * ctxt,int make_union)39 make_type (gcc_jit_context *ctxt, int make_union)
40 {
41 gcc_jit_type *t_int =
42 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
43 gcc_jit_type *t_char =
44 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CHAR);
45 gcc_jit_type *t_float =
46 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_FLOAT);
47
48 gcc_jit_field *a =
49 gcc_jit_context_new_field (ctxt,
50 NULL,
51 t_int,
52 "a");
53 gcc_jit_field *b =
54 gcc_jit_context_new_field (ctxt,
55 NULL,
56 t_char,
57 "b");
58 gcc_jit_field *c =
59 gcc_jit_context_new_field (ctxt,
60 NULL,
61 t_float,
62 "c");
63 gcc_jit_field *fields[] = {a, b, c};
64 if (make_union)
65 return gcc_jit_context_new_union_type (ctxt, NULL,
66 "assignable_union",
67 3, fields);
68 else
69 return gcc_jit_struct_as_type (
70 gcc_jit_context_new_struct_type (ctxt, NULL,
71 "assignable_struct",
72 3, fields));
73 }
74
75 static void
make_function(gcc_jit_context * ctxt,int make_union,const char * funcname)76 make_function (gcc_jit_context *ctxt, int make_union, const char *funcname)
77 {
78 gcc_jit_type *test_type = make_type (ctxt, make_union);
79 gcc_jit_param *x =
80 gcc_jit_context_new_param (ctxt, NULL,
81 test_type, "x");
82 gcc_jit_function *fn =
83 gcc_jit_context_new_function (ctxt, NULL,
84 GCC_JIT_FUNCTION_EXPORTED,
85 test_type,
86 funcname,
87 1, &x,
88 0);
89 gcc_jit_lvalue *y =
90 gcc_jit_function_new_local (fn, NULL, test_type, "y");
91 gcc_jit_lvalue *z =
92 gcc_jit_function_new_local (fn, NULL, test_type, "z");
93 gcc_jit_block *block =
94 gcc_jit_function_new_block (fn, NULL);
95 gcc_jit_block_add_assignment (block, NULL,
96 y, gcc_jit_param_as_rvalue (x));
97 gcc_jit_block_add_assignment (block, NULL,
98 z, gcc_jit_lvalue_as_rvalue (y));
99 gcc_jit_block_end_with_return (block, NULL,
100 gcc_jit_lvalue_as_rvalue (z));
101 }
102
103 void
create_code(gcc_jit_context * ctxt,void * user_data)104 create_code (gcc_jit_context *ctxt, void *user_data)
105 {
106 make_function (ctxt, 0, "test_struct_assignment");
107 make_function (ctxt, 1, "test_union_assignment");
108 }
109
110 static void
verify_test_struct_assignment(gcc_jit_result * result)111 verify_test_struct_assignment (gcc_jit_result *result)
112 {
113 typedef struct assignable_struct (*fn_type) (struct assignable_struct);
114 fn_type test_struct_assignment =
115 (fn_type)gcc_jit_result_get_code (result, "test_struct_assignment");
116 CHECK_NON_NULL (test_struct_assignment);
117
118 struct assignable_struct s, t;
119 s.a = 500;
120 s.b = 'A';
121 s.c = 1.0;
122 t = test_struct_assignment (s);
123 CHECK_VALUE (t.a, 500);
124 CHECK_VALUE (t.b, 'A');
125 CHECK_VALUE (t.c, 1.0);
126 }
127
128 static void
verify_test_union_assignment(gcc_jit_result * result)129 verify_test_union_assignment (gcc_jit_result *result)
130 {
131 typedef union assignable_union (*fn_type) (union assignable_union);
132 fn_type test_union_assignment =
133 (fn_type)gcc_jit_result_get_code (result, "test_union_assignment");
134 CHECK_NON_NULL (test_union_assignment);
135
136 union assignable_union p, q;
137
138 p.a = 500;
139 q = test_union_assignment (p);
140 CHECK_VALUE (q.a, 500);
141
142 p.b = 'A';
143 q = test_union_assignment (p);
144 CHECK_VALUE (q.b, 'A');
145
146 p.c = 1.0;
147 q = test_union_assignment (p);
148 CHECK_VALUE (q.c, 1.0);
149 }
150
151 void
verify_code(gcc_jit_context * ctxt,gcc_jit_result * result)152 verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
153 {
154 CHECK_NON_NULL (result);
155 verify_test_struct_assignment (result);
156 verify_test_union_assignment (result);
157 }
158