| 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 | AnalysisPassUnreachable::AnalysisPassUnreachable(CompilerContext & _compiler_context) | |
| 23 | 56 | : AnalysisPass(_compiler_context, "unreachable analysis") | |
| 24 | 28 | {} | |
| 25 | 112 | AnalysisPassUnreachable::~AnalysisPassUnreachable() | |
| 26 | 112 | {} | |
| 27 | |||
| 28 | void | ||
| 29 | 28 | AnalysisPassUnreachable::check(const 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 | 270 | void AnalysisPassUnreachable::check(const Function & function) const | |
| 37 | { | ||
| 38 | // Note that we do assume that all empty unreachable | ||
| 39 | // blocks have already been culled. | ||
| 40 | |||
| 41 | // Check for operations after the terminator. | ||
| 42 | // These are by definition unreachable because | ||
| 43 | // the terminator stops execution, so nothing after | ||
| 44 | // that will be reachable. | ||
| 45 | 270 | const auto & blocks = function.get_blocks(); | |
| 46 |
2/2✓ Branch 5 taken 364 times.
✓ Branch 6 taken 270 times.
|
634 | for (const auto & block_it : blocks) { |
| 47 | 364 | const BasicBlock & block = *block_it.second; | |
| 48 | 364 | const std::vector<Gyoji::owned<Operation>> & operations = block.get_operations(); | |
| 49 |
4/6✓ Branch 2 taken 270 times.
✓ Branch 3 taken 94 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 270 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 364 times.
|
364 | if (block.get_reachable_from().size() == 0 && block_it.first != 0) { |
| 50 | // Unreachable if the block is unreachable and has anything at all inside it. | ||
| 51 | ✗ | if (operations.size() != 0) { | |
| 52 | ✗ | const auto & op = operations.at(operations.size()-1); | |
| 53 | ✗ | get_compiler_context() | |
| 54 | ✗ | .get_errors() | |
| 55 | ✗ | .add_simple_error(op->get_source_ref(), | |
| 56 | "Unreachable statement", | ||
| 57 | ✗ | std::string("Statement is unreachable.") | |
| 58 | ); | ||
| 59 | } | ||
| 60 | } | ||
| 61 | else { | ||
| 62 | // Unreachable if the block is reachable and | ||
| 63 | // there are statements after the return. | ||
| 64 | 364 | bool terminated = false; | |
| 65 |
2/2✓ Branch 5 taken 4378 times.
✓ Branch 6 taken 364 times.
|
4742 | for (const auto & op : operations) { |
| 66 | 4378 | const auto & operation = *op; | |
| 67 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4378 times.
|
4378 | if (terminated) { |
| 68 | ✗ | get_compiler_context() | |
| 69 | ✗ | .get_errors() | |
| 70 | ✗ | .add_simple_error(operation.get_source_ref(), | |
| 71 | "Unreachable Statement", | ||
| 72 | ✗ | std::string("Function ") | |
| 73 | ✗ | + function.get_name() | |
| 74 | ✗ | + std::string(" contains unreachable statement.") | |
| 75 | ); | ||
| 76 | ✗ | break; | |
| 77 | } | ||
| 78 | // We found a terminating operation. | ||
| 79 |
2/2✓ Branch 1 taken 364 times.
✓ Branch 2 taken 4014 times.
|
4378 | if (operation.is_terminating()) { |
| 80 | 364 | terminated = true; | |
| 81 | 364 | continue; | |
| 82 | } | ||
| 83 | } | ||
| 84 | } | ||
| 85 | } | ||
| 86 | 270 | } | |
| 87 |