Restrict cast types
This commit is contained in:
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user