Type check the return statement

This commit is contained in:
2025-03-25 11:29:29 +01:00
parent c022805c53
commit d57934973d
5 changed files with 152 additions and 285 deletions

View File

@@ -1225,18 +1225,42 @@ namespace elna::gcc
void generic_visitor::visit(boot::return_statement *statement)
{
boot::expression *return_expression = statement->return_expression();
location_t statement_position = get_location(&statement->position());
tree set_result{ NULL_TREE };
tree return_type = TREE_TYPE(TREE_TYPE(current_function_decl));
if (return_expression == nullptr)
if (TREE_THIS_VOLATILE(current_function_decl) == 1)
{
error_at(statement_position, "This procedure is not allowed to return");
return;
}
return_expression->accept(this);
tree set_result = build2(INIT_EXPR, void_type_node, DECL_RESULT(current_function_decl),
this->current_expression);
tree return_stmt = build1(RETURN_EXPR, void_type_node, set_result);
append_statement(return_stmt);
if (return_expression != nullptr)
{
return_expression->accept(this);
set_result = build2(INIT_EXPR, void_type_node, DECL_RESULT(current_function_decl),
this->current_expression);
}
if (return_type == void_type_node && set_result != NULL_TREE)
{
error_at(statement_position, "Proper procedure is not allowed to return a value");
}
else if (return_type != void_type_node && set_result == NULL_TREE)
{
error_at(statement_position, "Procedure is expected to return a value of type '%s'",
print_type(return_type).c_str());
}
else if (return_type != void_type_node && !is_assignable_from(return_type, this->current_expression))
{
error_at(statement_position, "Cannot return '%s' from a procedure returning '%s'",
print_type(return_type).c_str(),
print_type(TREE_TYPE(this->current_expression)).c_str());
}
else
{
tree return_stmt = build1_loc(statement_position, RETURN_EXPR, void_type_node, set_result);
append_statement(return_stmt);
}
this->current_expression = NULL_TREE;
}