GCC Code Coverage Report


Directory: ./
File: unit_tests/tests/test_cpp_memory_layout.cpp
Date: 2025-10-03 00:57:22
Coverage Exec Excl Total
Lines: 89.5% 34 0 38
Functions: 81.8% 9 0 11
Branches: 37.5% 42 0 112
Decisions: -% 0 - 0

Line Branch Decision Exec Source
1 /*
2 * test_cpp_memory_layout.cpp
3 *
4 * Jun 15, 2019
5 * @author Andrey Belomutskiy, (c) 2012-2020
6 */
7
8 #include "pch.h"
9
10 // in C++ struct is pretty much a class just fields are public by default
11 struct TestParent {
12 int field0 = 540;
13 float field1 = 333.33;
14 };
15
16 class TestPlainChild: public TestParent {
17 public:
18 float getSum();
19 };
20
21 class TestPlainChildExtraFields: public TestParent {
22 public:
23 float field3 = 35555;
24 float field4 = 45555;
25 };
26
27
28 float TestPlainChild::getSum() {
29 return field0 + field1;
30 }
31
32 class TestChildWithVirtual: public TestParent {
33 public:
34 virtual float getSumVirtual() {
35 return field0 + field1;
36 }
37 };
38
39
40 4 TEST(CppMemoryLayout, PlainStruct) {
41 1 TestPlainChild c;
42 // validate field initializers just for fun
43
3/8
✓ Branch 3 taken 1 time.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 time.
✗ Branch 11 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✓ Branch 26 taken 1 time.
✗ Branch 27 not taken.
1 ASSERT_EQ(540, c.field0);
44
3/8
✓ Branch 2 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
✓ Branch 24 taken 1 time.
✗ Branch 25 not taken.
1 ASSERT_NEAR(333.33, c.field1, EPS4D);
45
46
3/8
✓ Branch 4 taken 1 time.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 time.
✗ Branch 13 not taken.
✗ Branch 18 not taken.
✗ Branch 21 not taken.
✓ Branch 28 taken 1 time.
✗ Branch 29 not taken.
1 ASSERT_EQ(sizeof(c), sizeof(TestParent));
47
48 1 int destimationInt = 1;
49 // no virtual table since nothing virtual on TestPlainChild
50 1 memcpy(&destimationInt, &c, 4);
51
3/8
✓ Branch 3 taken 1 time.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 time.
✗ Branch 11 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✓ Branch 26 taken 1 time.
✗ Branch 27 not taken.
1 ASSERT_EQ(540, destimationInt);
52
53
3/8
✓ Branch 4 taken 1 time.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 time.
✗ Branch 13 not taken.
✗ Branch 18 not taken.
✗ Branch 21 not taken.
✓ Branch 28 taken 1 time.
✗ Branch 29 not taken.
1 ASSERT_EQ((uintptr_t)&c.field0, (uintptr_t)&c);
54 }
55
56 static int valueWePointAt;
57
58 4 TEST(CppMemoryLayout, VirtualStruct) {
59 1 TestChildWithVirtual c;
60
61 // '4' in case of 32 bit target
62 // '8' in case of 64 bit target
63 1 size_t MAGIC_VTABLE_SIZE = sizeof(void*);
64
65 // validate field initializers just for fun
66
3/8
✓ Branch 3 taken 1 time.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 time.
✗ Branch 11 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✓ Branch 26 taken 1 time.
✗ Branch 27 not taken.
1 ASSERT_EQ(540, c.field0);
67
3/8
✓ Branch 2 taken 1 time.
✗ Branch 5 not taken.
✓ Branch 6 taken 1 time.
✗ Branch 9 not taken.
✗ Branch 14 not taken.
✗ Branch 17 not taken.
✓ Branch 24 taken 1 time.
✗ Branch 25 not taken.
1 ASSERT_NEAR(333.33, c.field1, EPS4D);
68
69
3/8
✓ Branch 4 taken 1 time.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 time.
✗ Branch 13 not taken.
✗ Branch 18 not taken.
✗ Branch 21 not taken.
✓ Branch 28 taken 1 time.
✗ Branch 29 not taken.
1 ASSERT_EQ(sizeof(c), sizeof(TestParent) + MAGIC_VTABLE_SIZE);
70
71
72 1 int destimationInt = 1;
73 1 memcpy(&destimationInt, &c, 4);
74
3/8
✓ Branch 3 taken 1 time.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 time.
✗ Branch 11 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✓ Branch 26 taken 1 time.
✗ Branch 27 not taken.
1 ASSERT_NE(540, destimationInt);
75
76 // static_cast is smart to skip the vtable, we like static_cast
77 1 TestParent *parent = static_cast<TestParent*>(&c);
78
3/8
✓ Branch 4 taken 1 time.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 time.
✗ Branch 13 not taken.
✗ Branch 18 not taken.
✗ Branch 21 not taken.
✓ Branch 28 taken 1 time.
✗ Branch 29 not taken.
1 ASSERT_EQ((uintptr_t)&c.field0, (uintptr_t)parent);
79
80
3/8
✓ Branch 3 taken 1 time.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 time.
✗ Branch 11 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✓ Branch 26 taken 1 time.
✗ Branch 27 not taken.
1 ASSERT_EQ(MAGIC_VTABLE_SIZE, (uintptr_t)&c.field0 - (uintptr_t)&c);
81
82
83 }
84
85 4 TEST(CppMemoryLayout, PlainExtraFieldsStruct) {
86 1 TestPlainChildExtraFields c;
87
88
3/8
✓ Branch 4 taken 1 time.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 time.
✗ Branch 13 not taken.
✗ Branch 18 not taken.
✗ Branch 21 not taken.
✓ Branch 28 taken 1 time.
✗ Branch 29 not taken.
1 ASSERT_EQ(sizeof(c), sizeof(TestParent) + 8);
89
90 1 int destimationInt = 1;
91 // parent fields go first
92 1 memcpy(&destimationInt, &c, 4);
93
3/8
✓ Branch 3 taken 1 time.
✗ Branch 7 not taken.
✓ Branch 8 taken 1 time.
✗ Branch 11 not taken.
✗ Branch 16 not taken.
✗ Branch 19 not taken.
✓ Branch 26 taken 1 time.
✗ Branch 27 not taken.
1 ASSERT_EQ(540, destimationInt);
94
3/8
✓ Branch 4 taken 1 time.
✗ Branch 9 not taken.
✓ Branch 10 taken 1 time.
✗ Branch 13 not taken.
✗ Branch 18 not taken.
✗ Branch 21 not taken.
✓ Branch 28 taken 1 time.
✗ Branch 29 not taken.
1 ASSERT_EQ(0u, (uintptr_t)&c.field0 - (uintptr_t)&c);
95 }
96
97 TEST(CppMemoryLayout, structSize) {
98 ASSERT_EQ(1u, sizeof(adc_channel_e)) << "adc_channel_e enum size";
99 ASSERT_EQ(1u, sizeof(pin_input_mode_e)) << "pin_input_mode_e enum size";
100 ASSERT_EQ(1u, sizeof(pin_output_mode_e)) << "pin_output_mode_e enum size";
101 ASSERT_EQ(2u, sizeof(brain_pin_e)) << "brain_pin_e enum size";
102 ASSERT_EQ(12u, sizeof(air_pressure_sensor_config_s));
103 ASSERT_EQ(size_t(TOTAL_CONFIG_SIZE), sizeof(persistent_config_s));
104 }
105