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