* cfgloopmanip.c (duplicate_loop_to_header_edge): Cleanup profile
[official-gcc.git] / gcc / testsuite / jit.dg / test-returning-function-ptr.c
blobf96079c45f7a482827e413ab084d8c01acf5e331
1 #include <stdlib.h>
2 #include <stdio.h>
4 #include "libgccjit.h"
6 #include "harness.h"
8 #ifdef __cplusplus
9 extern "C" {
10 #endif
12 extern void
13 internally_called_function (int i, int j, int k);
15 #ifdef __cplusplus
17 #endif
19 void
20 create_code (gcc_jit_context *ctxt, void *user_data)
22 /* Let's try to inject the equivalent of:
23 extern void internally_called_function (int i, int j, int k);
25 static void
26 internal_test_caller (int a)
28 internally_called_function (a * 3, a * 4, a * 5);
31 typedef void (*fn_ptr_type) (int);
33 fn_ptr_type
34 get_test_caller (void)
36 // Verify that we can assign function pointers to variables
37 fn_ptr_type p;
38 p = internal_test_caller;
39 return p;
42 int i;
43 gcc_jit_type *void_type =
44 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID);
45 gcc_jit_type *int_type =
46 gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
48 /* Declare the imported function. */
49 gcc_jit_param *params[3];
50 params[0] =
51 gcc_jit_context_new_param (ctxt, NULL, int_type, "i");
52 params[1] =
53 gcc_jit_context_new_param (ctxt, NULL, int_type, "j");
54 params[2] =
55 gcc_jit_context_new_param (ctxt, NULL, int_type, "k");
56 gcc_jit_function *called_fn =
57 gcc_jit_context_new_function (ctxt, NULL,
58 GCC_JIT_FUNCTION_IMPORTED,
59 void_type,
60 "internally_called_function",
61 3, params,
62 0);
64 /* Build the test_caller fn. */
65 gcc_jit_param *param_a =
66 gcc_jit_context_new_param (ctxt, NULL, int_type, "a");
67 gcc_jit_function *test_caller =
68 gcc_jit_context_new_function (ctxt, NULL,
69 GCC_JIT_FUNCTION_EXPORTED,
70 void_type,
71 "internal_test_caller",
72 1, &param_a,
73 0);
74 /* "a * 3, a * 4, a * 5" */
75 gcc_jit_rvalue *args[3];
76 for (i = 0; i < 3; i++)
77 args[i]
78 = gcc_jit_context_new_binary_op
79 (ctxt, NULL,
80 GCC_JIT_BINARY_OP_MULT,
81 int_type,
82 gcc_jit_param_as_rvalue (param_a),
83 gcc_jit_context_new_rvalue_from_int (ctxt,
84 int_type,
85 (i + 3) ));
86 gcc_jit_block *block = gcc_jit_function_new_block (test_caller, NULL);
87 gcc_jit_block_add_eval (
88 block, NULL,
89 gcc_jit_context_new_call (ctxt,
90 NULL,
91 called_fn,
92 3, args));
93 gcc_jit_block_end_with_void_return (block, NULL);
95 gcc_jit_type *fn_ptr_type
96 = gcc_jit_context_new_function_ptr_type (ctxt, NULL,
97 void_type,
98 1, &int_type,
99 0);
101 /* Build the get_test_caller fn. */
102 gcc_jit_function *get_test_caller =
103 gcc_jit_context_new_function (ctxt, NULL,
104 GCC_JIT_FUNCTION_EXPORTED,
105 fn_ptr_type,
106 "get_test_caller",
107 0, NULL,
109 block = gcc_jit_function_new_block (get_test_caller, NULL);
111 /* fn_ptr_type p; */
112 gcc_jit_lvalue *local_p
113 = gcc_jit_function_new_local (get_test_caller, NULL,
114 fn_ptr_type, "p");
116 /* p = internal_test_caller; */
117 gcc_jit_block_add_assignment (block, NULL,
118 local_p,
119 gcc_jit_function_get_address (test_caller,
120 NULL));
122 /* return p; */
123 gcc_jit_block_end_with_return (block, NULL,
124 gcc_jit_lvalue_as_rvalue (local_p));
127 static int called_with[3];
129 extern void
130 internally_called_function (int i, int j, int k)
132 called_with[0] = i;
133 called_with[1] = j;
134 called_with[2] = k;
137 void
138 verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
140 typedef void (*test_caller_type) (int);
141 typedef test_caller_type (*get_test_caller_type) (void);
142 CHECK_NON_NULL (result);
144 get_test_caller_type get_test_caller =
145 (get_test_caller_type)gcc_jit_result_get_code (result, "get_test_caller");
146 CHECK_NON_NULL (get_test_caller);
148 test_caller_type test_caller = (test_caller_type)get_test_caller ();
149 CHECK_NON_NULL (test_caller);
151 called_with[0] = 0;
152 called_with[1] = 0;
153 called_with[2] = 0;
155 /* Call the JIT-generated function. */
156 test_caller (5);
158 /* Verify that it correctly called "internally_called_function". */
159 CHECK_VALUE (called_with[0], 15);
160 CHECK_VALUE (called_with[1], 20);
161 CHECK_VALUE (called_with[2], 25);