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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
|
Reference in New Issue
Block a user