aboutsummaryrefslogtreecommitdiff
path: root/gcc/go/go-gcc.cc
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2018-01-31 06:17:25 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2018-01-31 06:17:25 +0000
commitebc2f4010dc789bf50fe46460594fd947df8084d (patch)
tree7fc9b95e68b06c4ab1928cb2dfb46b6cce4b7803 /gcc/go/go-gcc.cc
parent5837571173e41e9c30eccb92f75b17e52bed2116 (diff)
downloadgcc-ebc2f4010dc789bf50fe46460594fd947df8084d.zip
gcc-ebc2f4010dc789bf50fe46460594fd947df8084d.tar.gz
gcc-ebc2f4010dc789bf50fe46460594fd947df8084d.tar.bz2
go-gcc.cc (Gcc_backend::convert_tree): New private method.
* 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 From-SVN: r257218
Diffstat (limited to 'gcc/go/go-gcc.cc')
-rw-r--r--gcc/go/go-gcc.cc70
1 files changed, 43 insertions, 27 deletions
diff --git a/gcc/go/go-gcc.cc b/gcc/go/go-gcc.cc
index 9bc049e..de1cadf 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;