Type check the return statement
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user