GCC Code Coverage Report


Directory: src/
File: src/analysis/analysis-borrow-checker.cpp
Date: 2025-10-15 09:43:47
Exec Total Coverage
Lines: 41 48 85.4%
Functions: 9 10 90.0%
Branches: 7 8 87.5%

Line Branch Exec Source
1 #include <gyoji-analysis.hpp>
2 #include <stdio.h>
3
4 using namespace Gyoji::mir;
5 using namespace Gyoji::context;
6 using namespace Gyoji::analysis;
7
8 /**
9 * This class indicates an operation
10 * inside a basic block. The block
11 * is the ID of the basic block
12 * and operation is the index into
13 * that basic block indicating
14 * a specific operation.
15 */
16 class BasicBlockOperation {
17 public:
18 BasicBlockOperation(size_t _blockid, size_t _operationid);
19 BasicBlockOperation(const BasicBlockOperation & _other);
20 ~BasicBlockOperation();
21 size_t blockid;
22 size_t operationid;
23 };
24
25 /**
26 * This class represents an edge in the control-flow
27 * graph with edges between operations and the 'next'
28 * operation in the graph.
29 */
30 class CFGEdge {
31 public:
32 CFGEdge(const BasicBlockOperation & start, const BasicBlockOperation & end);
33 CFGEdge(const CFGEdge & _other);
34 ~CFGEdge();
35 BasicBlockOperation start;
36 BasicBlockOperation end;
37 };
38 ///////////////////////////////
39 // BasicBlockOperation
40 ///////////////////////////////
41 724 BasicBlockOperation::BasicBlockOperation(size_t _blockid, size_t _operationid)
42 724 : blockid(_blockid)
43 724 , operationid(_operationid)
44 724 {}
45 1728 BasicBlockOperation::BasicBlockOperation(const BasicBlockOperation & _other)
46 1728 : blockid(_other.blockid)
47 1728 , operationid(_other.operationid)
48 1728 {}
49 2452 BasicBlockOperation::~BasicBlockOperation()
50 2452 {}
51 ///////////////////////////////
52 // CFGEdge
53 ///////////////////////////////
54 362 CFGEdge::CFGEdge(const BasicBlockOperation & _start, const BasicBlockOperation & _end)
55 362 : start(_start)
56 362 , end(_end)
57 362 {}
58 502 CFGEdge::CFGEdge(const CFGEdge & _other)
59 502 : start(_other.start)
60 502 , end(_other.end)
61 502 {}
62 864 CFGEdge::~CFGEdge()
63 864 {}
64
65 ///////////////////////////////
66 // AnalysisPassBorrowChecker
67 ///////////////////////////////
68 30 AnalysisPassBorrowChecker::AnalysisPassBorrowChecker(CompilerContext & _compiler_context)
69 60 : AnalysisPass(_compiler_context, "borrow checker")
70 30 {}
71 AnalysisPassBorrowChecker::~AnalysisPassBorrowChecker()
72 {}
73
74 void
75 30 AnalysisPassBorrowChecker::check(const MIR & mir) const
76 {
77 // Here, we follow the basic plan of the 'Polonius' algorithm
78 // for borrow checking.
79
80
2/2
✓ Branch 7 taken 266 times.
✓ Branch 8 taken 30 times.
296 for (const auto & function : mir.get_functions().get_functions()) {
81 266 check(*function);
82 }
83
84 30 }
85
86 266 void AnalysisPassBorrowChecker::check(const Function & function) const
87 {
88 // We start with mapping the "edges" of the graph
89 // from the basic-blocks of the function.
90 266 const auto & blocks = function.get_blocks();
91
92 266 std::vector<CFGEdge> cfg_edges;
93
94
2/2
✓ Branch 5 taken 362 times.
✓ Branch 6 taken 266 times.
628 for (const auto & block_it : blocks) {
95 362 const BasicBlock & block = *block_it.second;
96 362 const std::vector<Gyoji::owned<Operation>> & operations = block.get_operations();
97
98 // Each basic block must have at least one operation.
99
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 362 times.
362 if (operations.size() == 0) {
100 get_compiler_context()
101 .get_errors()
102 .add_simple_error(function.get_source_ref(),
103 "Compiler bug! Please report this message(borrow)",
104 std::string("Function ") + function.get_name() + std::string(" found with empty Basic Block")
105 );
106 break;
107 }
108
109 // TODO: Finish the logic of
110 // tying blocks together in a graph
111 // by traversing it.
112 362 BasicBlockOperation startblock(block_it.first, 0);
113 362 BasicBlockOperation endblock(block_it.first, 1);
114 362 cfg_edges.push_back(CFGEdge(startblock, endblock));
115
2/2
✓ Branch 6 taken 3994 times.
✓ Branch 7 taken 362 times.
4356 for (const auto & operation_ptr : block.get_operations()) {
116 3994 const Operation & operation = *operation_ptr;
117 }
118 362 }
119
120 // TODO:
121 // We need to finish the CFG above
122 // and also extract the 'loans', the 'regions',
123 // and the 'live/killed' status of each variable from the MIR.
124
125 // Finally, we perform the graph-traversal
126 // to solve this. It should mainly take the form of
127 // a Hornsat solver, I think.
128 266 }
129