GCC Code Coverage Report


Directory: src/gate/
File: src/gate/tests/gatecore_cpp_test/test_functions.cpp
Date: 2026-05-04 21:11:01
Exec Total Coverage
Lines: 93 95 97.9%
Functions: 25 25 100.0%
Branches: 100 273 36.6%

Line Branch Exec Source
1 #include "gate/tests.hpp"
2 #include "gate/functions.hpp"
3 #include "gate/callstacks.hpp"
4
5 using namespace gate;
6
7
2/7
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
10 GATEXX_TEST_UNIT(CallstackTrace)
8 {
9 Callstack::Address addrbuffer[32];
10 4 Result<gate::size_t> traceResult = Callstack::trace(addrbuffer, sizeof(addrbuffer) / sizeof(addrbuffer[0]));
11
2/6
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
2 if (traceResult.hasError() && (traceResult.error() == results::NotSupported))
12 {
13 /* trace feature not support on platform, tests are meaningless */
14 }
15 else
16 {
17
4/12
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
2 GATEXX_TEST_REQUIRE(traceResult.hasValue());
18 2 gate::size_t addrbuffer_used = traceResult.value();
19
4/12
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
2 GATEXX_TEST_REQUIRE(addrbuffer_used > 0);
20
21
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
4 StringBuilder sb;
22 4 VoidResult printResult = Callstack::print(addrbuffer[0], sb);
23
4/12
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
2 GATEXX_TEST_CHECK(!printResult.hasError());
24 }
25 2 }
26
27
28 static int cs_state = 0;
29 static Callstack::Context main_context;
30 static Callstack::Context other_context;
31
32 class GATE_API_LOCAL OtherStackCode : public IRunnable
33 {
34 public:
35 1 void run() override
36 {
37 1 cs_state = 1;
38 1 Callstack::switchTo(other_context, main_context);
39 }
40 };
41
42
2/7
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
10 GATEXX_TEST_UNIT(CallstackRun)
43 {
44
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
4 Callstack cs(4096);
45 2 OtherStackCode otherCode;
46 2 cs_state = 0;
47 4 Result<result_t> result = cs.run(main_context, otherCode);
48
2/6
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
2 if (result.hasError() && (result.error() == results::NotSupported))
49 {
50 /* stack switching is not supported on this platform, further tests are meaningless*/
51 }
52 else
53 {
54
4/12
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
2 GATEXX_TEST_REQUIRE(!result.hasError());
55
4/12
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
2 GATEXX_TEST_CHECK(result.value() == results::Ok);
56
4/12
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
2 GATEXX_TEST_CHECK(cs_state == 1);
57 }
58 2 }
59
60
61 static int fork_state = 0;
62
63 class GATE_API_LOCAL MainForkCode : public IRunnable
64 {
65 public:
66 Callstack::Anchor anchor;
67
68 1 void run() override
69 {
70
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 GATEXX_TEST_CHECK(fork_state == 0);
71 1 fork_state = 1;
72 1 Callstack::jumpToBranch(this->anchor);
73 }
74 };
75
76 class GATE_API_LOCAL BranchCode : public IRunnable
77 {
78 public:
79 1 void run() override
80 {
81
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 GATEXX_TEST_CHECK(fork_state == 1);
82 1 fork_state = 2;
83 1 }
84 };
85
86
2/7
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
10 GATEXX_TEST_UNIT(CallstackFork)
87 {
88 4 MainForkCode maincode;
89 2 BranchCode branchcode;
90 2 fork_state = 0;
91 4 VoidResult result = Callstack::fork(maincode.anchor, maincode, branchcode);
92
4/12
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 16 not taken.
✗ Branch 17 not taken.
2 GATEXX_TEST_CHECK(!result.hasError());
93
4/12
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
2 GATEXX_TEST_CHECK(fork_state == 2);
94 2 }
95
96
97 1 static int test_func_sargs(signed char a, short b, int c, long d, long long e)
98 {
99 1 return a + b + c + d + static_cast<int>(e);
100 }
101
102 1 static unsigned int test_func_uargs(unsigned char a, unsigned short b, unsigned int c, unsigned long d, unsigned long long e)
103 {
104 1 return a + b + c + d + static_cast<unsigned>(e);
105 }
106
107 /*
108 static int test_func_float(float a, double b, void* c)
109 {
110 double* const ptr = static_cast<double*>(c);
111 GATEXX_TEST_CHECK(ptr != NULL);
112 if(ptr)
113 {
114 *ptr = a + b;
115 return static_cast<int>(*ptr);
116 }
117 return 0;
118 }
119 */
120
121 static int global_test_data1 = 123;
122 static int global_test_data2 = 234;
123 static int global_test_data3 = 345;
124
125 1 static int test_func_pointer(void* ptr1, void* ptr2, void* ptr3)
126 {
127
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 GATEXX_TEST_CHECK(ptr1 == &global_test_data1);
128
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 GATEXX_TEST_CHECK(ptr2 == &global_test_data2);
129
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 GATEXX_TEST_CHECK(ptr3 == &global_test_data3);
130
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
1 return (ptr1 == &global_test_data1) && (ptr2 == &global_test_data2) && (ptr3 == &global_test_data3)
131
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
2 ? 777 : 0;
132 }
133
134
2/7
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
10 GATEXX_TEST_UNIT(GenericFunction)
135 {
136 { // signed int
137 FunctionArgument args[5] = {
138 static_cast<signed char>(1),
139 static_cast<signed short>(2),
140 4 static_cast<signed int>(3),
141 static_cast<signed long>(4),
142 static_cast<signed long long>(5)
143
2/4
✓ Branch 5 taken 5 times.
✓ Branch 6 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
14 };
144
145
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
4 FunctionArgument retval = Function::invokeGeneric((gate_funcptr_t)&test_func_sargs, 0, args, 5);
146
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 retval.getType();
147
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 int iretval = *static_cast<int const*>(retval.getValuePtr());
148
4/12
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
2 GATEXX_TEST_CHECK_EQUAL(iretval, 15);
149 }
150
151 { // unsigned int
152 FunctionArgument args[5] = {
153 static_cast<unsigned char>(1),
154 static_cast<unsigned short>(2),
155 static_cast<unsigned int>(3),
156 static_cast<unsigned long>(4),
157 static_cast<unsigned long long>(5)
158
2/4
✓ Branch 5 taken 5 times.
✓ Branch 6 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
14 };
159
160
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
4 FunctionArgument retval = Function::invokeGeneric((gate_funcptr_t)&test_func_uargs, 0, args, 5);
161
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 retval.getType();
162
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 int iretval = *static_cast<int const*>(retval.getValuePtr());
163
4/12
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
2 GATEXX_TEST_CHECK_EQUAL(iretval, 15);
164
165 // test copy construction
166 4 FunctionArgument t0 = args[0];
167 4 FunctionArgument t1 = args[1];
168 4 FunctionArgument t2 = args[2];
169 4 FunctionArgument t3 = args[3];
170 2 FunctionArgument t4 = args[4];
171 }
172
173 /*
174 // NOTICE: floating point args are not working on register-based calling convention,
175 // tests will fail on X64
176 { // float + ptr
177 double dbl_result = 0.0;
178 FunctionArgument args[3] = {
179 static_cast<double>(1.0),
180 static_cast<float>(2.0),
181 static_cast<void*>(&dbl_result)
182 };
183
184 FunctionArgument retval = Function::invokeGeneric((gate_funcptr_t)&test_func_float, 0, args, 3);
185 int iretval = *static_cast<int const*>(retval.getValuePtr());
186 GATEXX_TEST_CHECK_EQUAL(iretval, 3);
187 }
188 */
189
190 // test generic pointer
191 {
192 FunctionArgument args[3] = {
193 static_cast<void*>(&global_test_data1),
194 static_cast<void*>(&global_test_data2),
195 static_cast<void*>(&global_test_data3)
196
2/4
✓ Branch 3 taken 3 times.
✓ Branch 4 taken 1 times.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
10 };
197
198
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
4 FunctionArgument retval = Function::invokeGeneric((gate_funcptr_t)&test_func_pointer, 0, args, 3);
199
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 int iretval = *static_cast<int const*>(retval.getValuePtr());
200
4/12
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
2 GATEXX_TEST_CHECK_EQUAL(iretval, 777);
201 }
202
203
204 2 }
205
206 class GATE_API_INTERNAL GuardedCodeTarget : public gate::IRunnable, public gate::IQuitable
207 {
208 public:
209 result_t exitResult;
210
211 3 explicit GuardedCodeTarget(result_t exit_result = results::Ok)
212 3 : exitResult(exit_result)
213 {
214 3 }
215
216 6 virtual ~GuardedCodeTarget() noexcept
217 6 {
218 6 }
219
220 3 virtual void run() override
221 {
222
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 if (this->exitResult == results::UnknownException)
223 {
224 1 throw 123;
225 }
226
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 GATEXX_CHECK_EXCEPTION(this->exitResult);
227 1 }
228
229 1 virtual void quit() override
230 {
231 1 }
232 };
233
234
2/7
✓ Branch 2 taken 3 times.
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
10 GATEXX_TEST_UNIT(InvokeGuarded)
235 {
236 {
237 4 GuardedCodeTarget noThrowCode(results::Ok);
238
4/14
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
2 GATEXX_TEST_CHECK_NOTHROW(Function::invokeGuarded(noThrowCode));
239 2 noThrowCode.quit();
240 }
241 {
242 4 GuardedCodeTarget throwCode(results::Failed);
243
5/14
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
4 GATEXX_TEST_CHECK_THROW(Function::invokeGuarded(throwCode));
244 }
245 {
246 4 GuardedCodeTarget foreignCxxThrowCode(results::UnknownException);
247
5/14
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 10 not taken.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✓ Branch 17 taken 1 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
4 GATEXX_TEST_CHECK_THROW(Function::invokeGuarded(foreignCxxThrowCode));
248 }
249 2 }
250