Restrict cast types

This commit is contained in:
2025-03-21 10:24:57 +01:00
parent 5e8555b4f4
commit 07ed40cc24
7 changed files with 168 additions and 134 deletions

View File

@ -229,9 +229,20 @@ namespace elna::gcc
tree cast_target = this->current_expression;
expression->value().accept(this);
tree cast_source = TREE_TYPE(this->current_expression);
this->current_expression = build1_loc(get_location(&expression->position()), CONVERT_EXPR,
cast_target, this->current_expression);
if ((is_primitive_type(cast_target) || is_pointer_type(cast_target))
&& (is_primitive_type(cast_source) || is_pointer_type(cast_source)))
{
this->current_expression = build1_loc(get_location(&expression->position()), CONVERT_EXPR,
cast_target, this->current_expression);
}
else
{
error_at(get_location(&expression->position()), "Type '%s' cannot be converted to '%s'",
print_type(cast_source).c_str(), print_type(cast_target).c_str());
this->current_expression = error_mark_node;
}
}
void generic_visitor::visit(boot::program *program)
@ -1031,14 +1042,29 @@ namespace elna::gcc
{
expression->base().accept(this);
location_t expression_location = get_location(&expression->position());
tree field_declaration = find_field_by_name(expression_location,
TREE_TYPE(this->current_expression), expression->field());
tree aggregate_type = TREE_TYPE(this->current_expression);
if (field_declaration != error_mark_node)
if (is_array_type(aggregate_type) && expression->field() == "length")
{
this->current_expression = build3_loc(expression_location, COMPONENT_REF,
TREE_TYPE(field_declaration), this->current_expression,
field_declaration, NULL_TREE);
this->current_expression = fold_convert(elna_word_type_node,
TYPE_MAX_VALUE(TYPE_DOMAIN(aggregate_type)));
}
else if (is_array_type(aggregate_type) && expression->field() == "ptr")
{
tree ptr_type = build_pointer_type_for_mode(TREE_TYPE(aggregate_type), VOIDmode, true);
this->current_expression = build1(ADDR_EXPR, ptr_type, this->current_expression);
}
else
{
tree field_declaration = find_field_by_name(expression_location,
TREE_TYPE(this->current_expression), expression->field());
if (field_declaration != error_mark_node)
{
this->current_expression = build3_loc(expression_location, COMPONENT_REF,
TREE_TYPE(field_declaration), this->current_expression,
field_declaration, NULL_TREE);
}
}
}

View File

@ -35,7 +35,7 @@ namespace elna::gcc
bool is_integral_type(tree type)
{
gcc_assert(TYPE_P(type));
return TREE_CODE(type) == INTEGER_TYPE;
return TREE_CODE(type) == INTEGER_TYPE && type != elna_char_type_node;
}
bool is_numeric_type(tree type)
@ -43,6 +43,14 @@ namespace elna::gcc
return is_integral_type(type) || type == elna_float_type_node;
}
bool is_primitive_type(tree type)
{
gcc_assert(TYPE_P(type));
return TREE_CODE(type) == INTEGER_TYPE
|| type == elna_float_type_node
|| type == elna_bool_type_node;
}
bool is_array_type(tree type)
{
gcc_assert(TYPE_P(type));