1 /* Test of PR jit/66700. */
2
3 #include <stdlib.h>
4 #include <stdio.h>
5
6 #include "libgccjit.h"
7
8 #include "harness.h"
9
10 #ifdef __cplusplus
11 extern "C" {
12 #endif
13
14 extern void
15 write_back_through_ptr (double *d);
16
17 #ifdef __cplusplus
18 }
19 #endif
20
21 void
create_code(gcc_jit_context * ctxt,void * user_data)22 create_code (gcc_jit_context *ctxt, void *user_data)
23 {
24 /* Let's try to inject the equivalent of:
25
26 double
27 test_caller_of_write_back_through_ptr (void)
28 {
29 double d;
30 d = 4.0;
31 write_back_through_ptr (&d);
32 return d;
33 }
34 */
35 gcc_jit_type *t_void =
36 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
37 gcc_jit_type *t_double =
38 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_DOUBLE);
39 gcc_jit_type *t_ptr_to_double =
40 gcc_jit_type_get_pointer (t_double);
41
42 /* Declare the imported function. */
43 gcc_jit_param *params[1];
44 params[0] =
45 gcc_jit_context_new_param (ctxt, NULL, t_ptr_to_double, "d");
46 gcc_jit_function *called_fn =
47 gcc_jit_context_new_function (ctxt, NULL,
48 GCC_JIT_FUNCTION_IMPORTED,
49 t_void,
50 "write_back_through_ptr",
51 1, params,
52 0);
53
54 /* Build the test_fn. */
55 gcc_jit_function *test_fn =
56 gcc_jit_context_new_function (ctxt, NULL,
57 GCC_JIT_FUNCTION_EXPORTED,
58 t_double,
59 "test_caller_of_write_back_through_ptr",
60 0, NULL,
61 0);
62 gcc_jit_lvalue *d =
63 gcc_jit_function_new_local (test_fn, NULL, t_double, "d");
64
65 gcc_jit_block *block = gcc_jit_function_new_block (test_fn, NULL);
66
67 /* "d = 0.0" */
68 gcc_jit_block_add_assignment (
69 block, NULL, d,
70 gcc_jit_context_new_rvalue_from_int (ctxt, t_double, 4));
71
72 /* "write_back_through_ptr (&d);" */
73 gcc_jit_rvalue *args[1];
74 args[0] = gcc_jit_lvalue_get_address (d, NULL);
75 gcc_jit_block_add_eval (
76 block, NULL,
77 gcc_jit_context_new_call (ctxt,
78 NULL,
79 called_fn,
80 1, args));
81 gcc_jit_block_end_with_return (block,
82 NULL,
83 gcc_jit_lvalue_as_rvalue (d));
84 }
85
86 extern void
write_back_through_ptr(double * d)87 write_back_through_ptr (double *d)
88 {
89 *d = 5.600000;
90 }
91
92 void
verify_code(gcc_jit_context * ctxt,gcc_jit_result * result)93 verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
94 {
95 typedef double (*fn_type) (void);
96 CHECK_NON_NULL (result);
97
98 fn_type test_caller_of_write_back_through_ptr =
99 (fn_type)gcc_jit_result_get_code (result,
100 "test_caller_of_write_back_through_ptr");
101 CHECK_NON_NULL (test_caller_of_write_back_through_ptr);
102
103 /* Call the JIT-generated function. */
104 double d = test_caller_of_write_back_through_ptr ();
105
106 /* Verify that it correctly called "write_back_through_ptr". */
107 CHECK_VALUE (d, 5.600000);
108 }
109
110