GCC Code Coverage Report


Directory: src/
File: src/analysis/analysis-return-values.cpp
Date: 2025-10-24 11:14:59
Exec Total Coverage
Lines: 28 46 60.9%
Functions: 7 7 100.0%
Branches: 8 10 80.0%

Line Branch Exec Source
1 /* Copyright 2025 Jonathan S. Arney
2 *
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * https://github.com/jarney/gyoji/blob/master/LICENSE
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include <gyoji-analysis.hpp>
16 #include <stdio.h>
17
18 using namespace Gyoji::mir;
19 using namespace Gyoji::context;
20 using namespace Gyoji::analysis;
21
22 28 AnalysisPassReturnValues::AnalysisPassReturnValues(CompilerContext & _compiler_context)
23 56 : AnalysisPass(_compiler_context, "return-value consistency analysis")
24 28 {}
25 112 AnalysisPassReturnValues::~AnalysisPassReturnValues()
26 112 {}
27
28 void
29 28 AnalysisPassReturnValues::check(const Gyoji::mir::MIR & mir) const
30 {
31
2/2
✓ Branch 7 taken 270 times.
✓ Branch 8 taken 28 times.
298 for (const auto & function : mir.get_functions().get_functions()) {
32 270 check(*function);
33 }
34 28 }
35
36 namespace Gyoji::analysis {
37 class ReturnOperationVisitor : public OperationVisitor {
38 public:
39 ReturnOperationVisitor(
40 CompilerContext & _compiler_context,
41 const Function & _function
42 );
43 ~ReturnOperationVisitor();
44
45 void visit(
46 size_t block_id,
47 const BasicBlock & block,
48 size_t operation_index,
49 const Operation & operation
50 );
51 private:
52 CompilerContext & compiler_context;
53 const Function & function;
54 const Type *return_type;
55 };
56
57 };
58
59 270 ReturnOperationVisitor::ReturnOperationVisitor(
60 CompilerContext & _compiler_context,
61 const Function & _function
62 270 )
63 : OperationVisitor()
64 270 , compiler_context(_compiler_context)
65 270 , function(_function)
66 270 , return_type(_function.get_return_type())
67 {
68 270 }
69
70 270 ReturnOperationVisitor::~ReturnOperationVisitor()
71 270 {}
72
73 4378 void ReturnOperationVisitor::visit(
74 size_t block_id,
75 const BasicBlock & block,
76 size_t operation_index,
77 const Operation & operation
78 )
79 {
80
2/2
✓ Branch 1 taken 280 times.
✓ Branch 2 taken 4098 times.
4378 if (operation.get_type() == Operation::OP_RETURN) {
81 280 const Type *operation_type = function.tmpvar_get(operation.get_operands().at(0));
82
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 280 times.
280 if (return_type->get_name() != operation_type->get_name()) {
83 std::unique_ptr<Gyoji::context::Error> error = std::make_unique<Gyoji::context::Error>("Return statement returns incorrec type.");
84 error->add_message(
85 operation.get_source_ref(),
86 std::string("Return statement returns value of type ") + operation_type->get_name() + std::string(" but function is declared to return ") + return_type->get_name()
87 );
88 error->add_message(
89 function.get_source_ref(),
90 "Return-value of function declared here."
91 );
92 compiler_context
93 .get_errors()
94 .add_error(std::move(error));
95 }
96 }
97
2/2
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 4090 times.
4098 else if (operation.get_type() == Operation::OP_RETURN_VOID) {
98
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 8 times.
8 if (!return_type->is_void()) {
99 std::unique_ptr<Gyoji::context::Error> error = std::make_unique<Gyoji::context::Error>("Return statement returns incorrec type.");
100 error->add_message(
101 operation.get_source_ref(),
102 std::string("Return statement returns void (no value), but function is declared to return ") + return_type->get_name()
103 );
104 error->add_message(
105 function.get_source_ref(),
106 "Return-type of function declared here."
107 );
108 compiler_context
109 .get_errors()
110 .add_error(std::move(error));
111 }
112 }
113 4378 }
114
115 270 void AnalysisPassReturnValues::check(const Function & function) const
116 {
117 // This is what the function should return.
118 270 ReturnOperationVisitor ppVisitor(get_compiler_context(), function);
119
120 270 function.iterate_operations(ppVisitor);
121 270 }
122
123