diff options
author | Ian Lance Taylor <iant@google.com> | 2012-03-09 08:25:05 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2012-03-09 08:25:05 +0000 |
commit | 68c5d97bad2d405e2b27826bcb95f224baec6465 (patch) | |
tree | bd0a2765d69acdf83a414c1a6f425dc3adc2543d | |
parent | 762c279900efedc1407c3c38d98601ddbff575ae (diff) | |
download | gcc-68c5d97bad2d405e2b27826bcb95f224baec6465.zip gcc-68c5d97bad2d405e2b27826bcb95f224baec6465.tar.gz gcc-68c5d97bad2d405e2b27826bcb95f224baec6465.tar.bz2 |
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
-rw-r--r-- | gcc/go/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/go/go-gcc.cc | 24 | ||||
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 15 |
3 files changed, 38 insertions, 6 deletions
diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index 2c0b3c2..f779e9b 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -1,3 +1,8 @@ +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 diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc index 0cc167d..96c1718 100644 --- a/gcc/go/go-gcc.cc +++ b/gcc/go/go-gcc.cc @@ -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, diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 134b5ae..90cf6f3 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -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); } |