Commit 68c5d97b by Ian Lance Taylor Committed by Ian Lance Taylor

compiler: Be more careful to follow GENERIC type rules.

	* go-gcc.cc (Gcc_backend::assignment_statement): Convert the rhs
	to the lhs type if necessary.

From-SVN: r185128
parent 762c2799
2012-03-09 Ian Lance Taylor <iant@google.com>
* go-gcc.cc (Gcc_backend::assignment_statement): Convert the rhs
to the lhs type if necessary.
2012-03-08 Ian Lance Taylor <iant@google.com>
* go-gcc.cc (Gcc_backend::init_statement): Don't initialize a
......
......@@ -918,6 +918,30 @@ Gcc_backend::assignment_statement(Bexpression* lhs, Bexpression* rhs,
return this->compound_statement(this->expression_statement(lhs),
this->expression_statement(rhs));
// Sometimes the same unnamed Go type can be created multiple times
// and thus have multiple tree representations. Make sure this does
// not confuse the middle-end.
if (TREE_TYPE(lhs_tree) != TREE_TYPE(rhs_tree))
{
tree lhs_type_tree = TREE_TYPE(lhs_tree);
gcc_assert(TREE_CODE(lhs_type_tree) == TREE_CODE(TREE_TYPE(rhs_tree)));
if (POINTER_TYPE_P(lhs_type_tree)
|| INTEGRAL_TYPE_P(lhs_type_tree)
|| SCALAR_FLOAT_TYPE_P(lhs_type_tree)
|| COMPLEX_FLOAT_TYPE_P(lhs_type_tree))
rhs_tree = fold_convert_loc(location.gcc_location(), lhs_type_tree,
rhs_tree);
else if (TREE_CODE(lhs_type_tree) == RECORD_TYPE
|| TREE_CODE(lhs_type_tree) == ARRAY_TYPE)
{
gcc_assert(int_size_in_bytes(lhs_type_tree)
== int_size_in_bytes(TREE_TYPE(rhs_tree)));
rhs_tree = fold_build1_loc(location.gcc_location(),
VIEW_CONVERT_EXPR,
lhs_type_tree, rhs_tree);
}
}
return this->make_statement(fold_build2_loc(location.gcc_location(),
MODIFY_EXPR,
void_type_node,
......
......@@ -205,9 +205,6 @@ Expression::convert_for_assignment(Translate_context* context, Type* lhs_type,
Type* rhs_type, tree rhs_tree,
Location location)
{
if (lhs_type == rhs_type)
return rhs_tree;
if (lhs_type->is_error() || rhs_type->is_error())
return error_mark_node;
......@@ -220,7 +217,7 @@ Expression::convert_for_assignment(Translate_context* context, Type* lhs_type,
if (lhs_type_tree == error_mark_node)
return error_mark_node;
if (lhs_type->interface_type() != NULL)
if (lhs_type != rhs_type && lhs_type->interface_type() != NULL)
{
if (rhs_type->interface_type() == NULL)
return Expression::convert_type_to_interface(context, lhs_type,
......@@ -231,7 +228,7 @@ Expression::convert_for_assignment(Translate_context* context, Type* lhs_type,
rhs_type, rhs_tree,
false, location);
}
else if (rhs_type->interface_type() != NULL)
else if (lhs_type != rhs_type && rhs_type->interface_type() != NULL)
return Expression::convert_interface_to_type(context, lhs_type, rhs_type,
rhs_tree, location);
else if (lhs_type->is_slice_type() && rhs_type->is_nil_type())
......@@ -289,10 +286,16 @@ Expression::convert_for_assignment(Translate_context* context, Type* lhs_type,
|| (TREE_CODE(lhs_type_tree) == ARRAY_TYPE
&& TREE_CODE(TREE_TYPE(rhs_tree)) == ARRAY_TYPE))
{
// Avoid confusion from zero sized variables which may be
// represented as non-zero-sized.
if (int_size_in_bytes(lhs_type_tree) == 0
|| int_size_in_bytes(TREE_TYPE(rhs_tree)) == 0)
return rhs_tree;
// This conversion must be permitted by Go, or we wouldn't have
// gotten here.
go_assert(int_size_in_bytes(lhs_type_tree)
== int_size_in_bytes(TREE_TYPE(rhs_tree)));
== int_size_in_bytes(TREE_TYPE(rhs_tree)));
return fold_build1_loc(location.gcc_location(), VIEW_CONVERT_EXPR,
lhs_type_tree, rhs_tree);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment