From bc5fc4877c9e7bb6c0dd4d742a0a497f454e213c Mon Sep 17 00:00:00 2001 From: ian Date: Wed, 31 Jan 2018 06:17:25 +0000 Subject: [PATCH] * go-gcc.cc (Gcc_backend::convert_tree): New private method. (Gcc_backend::constructor_expression): Call it. (Gcc_backend::assignment_statement): Likewise. (Gcc_backend::temporary_variable): Likewise. Fixes https://golang.org/issue/#23606 git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@257218 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/go/ChangeLog | 7 ++++++ gcc/go/go-gcc.cc | 70 ++++++++++++++++++++++++++++++++++---------------------- 2 files changed, 50 insertions(+), 27 deletions(-) diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog index ae6d0006573..b1876c57d5a 100644 --- a/gcc/go/ChangeLog +++ b/gcc/go/ChangeLog @@ -1,3 +1,10 @@ +2018-01-30 Ian Lance Taylor + + * go-gcc.cc (Gcc_backend::convert_tree): New private method. + (Gcc_backend::constructor_expression): Call it. + (Gcc_backend::assignment_statement): Likewise. + (Gcc_backend::temporary_variable): Likewise. + 2018-01-09 Cherry Zhang * go-gcc.cc (local_variable): Add decl_var parameter. diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc index 9bc049ebd9a..de1cadfda31 100644 --- a/gcc/go/go-gcc.cc +++ b/gcc/go/go-gcc.cc @@ -541,6 +541,9 @@ class Gcc_backend : public Backend tree non_zero_size_type(tree); + tree + convert_tree(tree, tree, Location); + private: void define_builtin(built_in_function bcode, const char* name, const char* libname, @@ -1785,8 +1788,7 @@ Gcc_backend::constructor_expression(Btype* btype, constructor_elt empty = {NULL, NULL}; constructor_elt* elt = init->quick_push(empty); elt->index = field; - elt->value = fold_convert_loc(location.gcc_location(), TREE_TYPE(field), - val); + elt->value = this->convert_tree(TREE_TYPE(field), val, location); if (!TREE_CONSTANT(elt->value)) is_constant = false; } @@ -2055,29 +2057,7 @@ Gcc_backend::assignment_statement(Bfunction* bfn, Bexpression* lhs, return this->compound_statement(this->expression_statement(bfn, lhs), this->expression_statement(bfn, 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); - } - } + rhs_tree = this->convert_tree(TREE_TYPE(lhs_tree), rhs_tree, location); return this->make_statement(fold_build2_loc(location.gcc_location(), MODIFY_EXPR, @@ -2507,6 +2487,43 @@ Gcc_backend::non_zero_size_type(tree type) gcc_unreachable(); } +// Convert EXPR_TREE to TYPE_TREE. 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. + +tree +Gcc_backend::convert_tree(tree type_tree, tree expr_tree, Location location) +{ + if (type_tree == TREE_TYPE(expr_tree)) + return expr_tree; + + if (type_tree == error_mark_node + || expr_tree == error_mark_node + || TREE_TYPE(expr_tree) == error_mark_node) + return error_mark_node; + + gcc_assert(TREE_CODE(type_tree) == TREE_CODE(TREE_TYPE(expr_tree))); + if (POINTER_TYPE_P(type_tree) + || INTEGRAL_TYPE_P(type_tree) + || SCALAR_FLOAT_TYPE_P(type_tree) + || COMPLEX_FLOAT_TYPE_P(type_tree)) + return fold_convert_loc(location.gcc_location(), type_tree, expr_tree); + else if (TREE_CODE(type_tree) == RECORD_TYPE + || TREE_CODE(type_tree) == ARRAY_TYPE) + { + gcc_assert(int_size_in_bytes(type_tree) + == int_size_in_bytes(TREE_TYPE(expr_tree))); + if (TYPE_MAIN_VARIANT(type_tree) + == TYPE_MAIN_VARIANT(TREE_TYPE(expr_tree))) + return fold_build1_loc(location.gcc_location(), NOP_EXPR, + type_tree, expr_tree); + return fold_build1_loc(location.gcc_location(), VIEW_CONVERT_EXPR, + type_tree, expr_tree); + } + + gcc_unreachable(); +} + // Make a global variable. Bvariable* @@ -2717,8 +2734,7 @@ Gcc_backend::temporary_variable(Bfunction* function, Bblock* bblock, } if (this->type_size(btype) != 0 && init_tree != NULL_TREE) - DECL_INITIAL(var) = fold_convert_loc(location.gcc_location(), type_tree, - init_tree); + DECL_INITIAL(var) = this->convert_tree(type_tree, init_tree, location); if (is_address_taken) TREE_ADDRESSABLE(var) = 1; -- 2.11.4.GIT