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