GCC Code Coverage Report


Directory: src/gate/
File: src/gate/tests/gatecore_cpp_test/test_functions.cpp
Date: 2025-12-12 23:40:09
Exec Total Coverage
Lines: 83 92 90.2%
Functions: 24 25 96.0%
Branches: 86 245 35.1%

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 static int test_func_float(float a, double b, void* c)
108 {
109 double* const ptr = static_cast<double*>(c);
110 GATEXX_TEST_CHECK(ptr != NULL);
111 if(ptr)
112 {
113 /* prohibit segfault on param error */
114 *ptr = a + b;
115 return static_cast<int>(*ptr);
116 }
117 return 0;
118 }
119
120
121
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)
122 {
123 { // signed int
124 FunctionArgument args[5] = {
125 static_cast<signed char>(1),
126 static_cast<signed short>(2),
127 4 static_cast<signed int>(3),
128 static_cast<signed long>(4),
129 static_cast<signed long long>(5)
130
2/4
✓ Branch 5 taken 5 times.
✓ Branch 6 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
14 };
131
132
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);
133
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 retval.getType();
134
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 int iretval = *static_cast<int const*>(retval.getValuePtr());
135
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);
136 }
137
138 { // unsigned int
139 FunctionArgument args[5] = {
140 static_cast<unsigned char>(1),
141 static_cast<unsigned short>(2),
142 static_cast<unsigned int>(3),
143 static_cast<unsigned long>(4),
144 static_cast<unsigned long long>(5)
145
2/4
✓ Branch 5 taken 5 times.
✓ Branch 6 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
14 };
146
147
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);
148
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 retval.getType();
149
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 int iretval = *static_cast<int const*>(retval.getValuePtr());
150
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);
151
152 // test copy construction
153 4 FunctionArgument t0 = args[0];
154 4 FunctionArgument t1 = args[1];
155 4 FunctionArgument t2 = args[2];
156 4 FunctionArgument t3 = args[3];
157 2 FunctionArgument t4 = args[4];
158 }
159
160 /*
161 // NOTICE: floating point args are not working on register-based calling convention,
162 // tests will fail on X64
163 { // float + ptr
164 double dbl_result = 0.0;
165 FunctionArgument args[3] = {
166 static_cast<double>(1.0),
167 static_cast<float>(2.0),
168 static_cast<void*>(&dbl_result)
169 };
170
171 FunctionArgument retval = Function::invokeGeneric((gate_funcptr_t)&test_func_float, 0, args, 3);
172 int iretval = *static_cast<int const*>(retval.getValuePtr());
173 GATEXX_TEST_CHECK_EQUAL(iretval, 3);
174 }
175 */
176 2 }
177
178 class GATE_CORE_CPP_API GuardedCodeTarget : public gate::IRunnable, public gate::IQuitable
179 {
180 public:
181 result_t exitResult;
182
183 3 explicit GuardedCodeTarget(result_t exit_result = results::Ok)
184 3 : exitResult(exit_result)
185 {
186 3 }
187
188 6 virtual ~GuardedCodeTarget() noexcept
189 6 {
190 6 }
191
192 3 virtual void run() override
193 {
194
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 if (this->exitResult == results::UnknownException)
195 {
196 1 throw 123;
197 }
198
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 GATEXX_CHECK_EXCEPTION(this->exitResult);
199 1 }
200
201 1 virtual void quit() override
202 {
203 1 }
204 };
205
206
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)
207 {
208 {
209 4 GuardedCodeTarget noThrowCode(results::Ok);
210
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));
211 2 noThrowCode.quit();
212 }
213 {
214 4 GuardedCodeTarget throwCode(results::Failed);
215
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));
216 }
217 {
218 4 GuardedCodeTarget foreignCxxThrowCode(results::UnknownException);
219
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));
220 }
221 2 }
222