diff options
| author | Eugen Wissner <belka@caraus.de> | 2026-10-18 09:25:36 +0200 |
|---|---|---|
| committer | Eugen Wissner <belka@caraus.de> | 2026-10-18 22:54:00 +0200 |
| commit | 7440060f179e35fe63155a149bb5003c97e12013 (patch) | |
| tree | abdcb8aa74513312b2cc92d4c2b2b986c29fbc03 /boot | |
| parent | 81043b67437445dcf83055098490e04cc88ff7ee (diff) | |
| download | elna-7440060f179e35fe63155a149bb5003c97e12013.tar.gz | |
Fix ICE on variable declarations in case branches
Diffstat (limited to 'boot')
| -rw-r--r-- | boot/ast.cc | 29 | ||||
| -rw-r--r-- | boot/name_analysis.cc | 3 | ||||
| -rw-r--r-- | boot/type_check.cc | 42 |
3 files changed, 31 insertions, 43 deletions
diff --git a/boot/ast.cc b/boot/ast.cc index 15e4928..e712f16 100644 --- a/boot/ast.cc +++ b/boot/ast.cc @@ -243,7 +243,7 @@ namespace elna::boot } if (declaration->body.has_value()) { - traverse_block(this, declaration->body.value()); + boot::traverse_block(this, declaration->body.value()); if (declaration->body.value().return_expression != nullptr) { declaration->body.value().return_expression->accept(this); @@ -257,54 +257,59 @@ namespace elna::boot statement->rvalue().accept(this); } + void walking_visitor::traverse_block(const block& body) + { + boot::traverse_block(this, body); + } + void walking_visitor::visit(if_statement *statement) { statement->branch().prerequisite().accept(this); - traverse_block(this, statement->branch().body); + traverse_block(statement->branch().body); for (conditional_statements& branch : statement->branches) { branch.prerequisite().accept(this); - traverse_block(this, branch.body); + traverse_block(branch.body); } if (statement->alternative != nullptr) { - traverse_block(this, *statement->alternative); + traverse_block(*statement->alternative); } } void walking_visitor::visit(while_statement *statement) { statement->branch().prerequisite().accept(this); - traverse_block(this, statement->branch().body); + traverse_block(statement->branch().body); for (conditional_statements& branch : statement->branches) { branch.prerequisite().accept(this); - traverse_block(this, branch.body); + traverse_block(branch.body); } } void walking_visitor::visit(repeat_statement *statement) { statement->condition().accept(this); - traverse_block(this, statement->body); + traverse_block(statement->body); } void walking_visitor::visit(for_statement *statement) { statement->range().accept(this); - traverse_block(this, statement->body); + traverse_block(statement->body); } void walking_visitor::visit(defer_statement *statement) { - traverse_block(this, statement->body); + traverse_block(statement->body); } void walking_visitor::visit(block_statement *statement) { - traverse_block(this, statement->body); + traverse_block(statement->body); } void walking_visitor::visit(break_statement *) @@ -321,11 +326,11 @@ namespace elna::boot for (const switch_case& case_block : statement->cases) { visit_all(this, case_block.labels); - traverse_block(this, case_block.body); + traverse_block(case_block.body); } if (statement->alternative != nullptr) { - traverse_block(this, *statement->alternative); + traverse_block(*statement->alternative); } } diff --git a/boot/name_analysis.cc b/boot/name_analysis.cc index 9305cd2..11380db 100644 --- a/boot/name_analysis.cc +++ b/boot/name_analysis.cc @@ -1628,7 +1628,8 @@ namespace elna::boot this->bag.leave(); info_object->parameters = type_parameters; info_object->exported = declaration->identifier.exported(); - info_object->position.emplace(declaration->position()); + info_object->position.emplace(declaration->position().start(), + declaration->heading().position().end()); info_object->file = this->module_file; info_object->noreturn = noreturn; diff --git a/boot/type_check.cc b/boot/type_check.cc index 5a8170a..5033ffd 100644 --- a/boot/type_check.cc +++ b/boot/type_check.cc @@ -494,9 +494,8 @@ namespace elna::boot return is_assignable_from(left, right) || is_assignable_from(right, left); } - void type_analysis_visitor::visit_and_validate_condition(expression& condition) + void type_analysis_visitor::validate_condition(const expression& condition) { - condition.accept(this); if (!is_primitive_type(condition.type_decoration, "Bool")) { add_error<type_requirement_error>(condition.position(), @@ -824,7 +823,7 @@ namespace elna::boot void type_analysis_visitor::visit(for_statement *statement) { - statement->range().accept(this); + walking_visitor::visit(statement); const type resolved_range = resolve_underlying_type(statement->range().type_decoration); if (!get_range_base_type(resolved_range)) @@ -832,47 +831,40 @@ namespace elna::boot add_error<type_requirement_error>(statement->range().position(), statement->range().type_decoration, type_requirement_error::kind::for_range); } - traverse_block(statement->body); } - void type_analysis_visitor::traverse_block(block& body) + void type_analysis_visitor::traverse_block(const block& body) { this->bag.enter(body.symbols); - boot::traverse_block(this, body); + walking_visitor::traverse_block(body); this->bag.leave(); } void type_analysis_visitor::visit(repeat_statement *statement) { - visit_and_validate_condition(statement->condition()); - traverse_block(statement->body); + walking_visitor::visit(statement); + validate_condition(statement->condition()); } void type_analysis_visitor::visit(while_statement *statement) { - visit_and_validate_condition(statement->branch().prerequisite()); - traverse_block(statement->branch().body); + walking_visitor::visit(statement); + validate_condition(statement->branch().prerequisite()); for (conditional_statements& branch : statement->branches) { - visit_and_validate_condition(branch.prerequisite()); - traverse_block(branch.body); + validate_condition(branch.prerequisite()); } } void type_analysis_visitor::visit(if_statement *statement) { - visit_and_validate_condition(statement->branch().prerequisite()); - traverse_block(statement->branch().body); + walking_visitor::visit(statement); + validate_condition(statement->branch().prerequisite()); for (conditional_statements& branch : statement->branches) { - visit_and_validate_condition(branch.prerequisite()); - traverse_block(branch.body); - } - if (statement->alternative != nullptr) - { - traverse_block(*statement->alternative); + validate_condition(branch.prerequisite()); } } @@ -1462,16 +1454,6 @@ namespace elna::boot } // else callable is not declared, or inference failed and reported. } - - void type_analysis_visitor::visit(defer_statement *statement) - { - traverse_block(statement->body); - } - - void type_analysis_visitor::visit(block_statement *statement) - { - traverse_block(statement->body); - } void type_analysis_visitor::visit(record_constructor_expression *expression) { |
