aboutsummaryrefslogtreecommitdiff
path: root/gcc/go/gofrontend/expressions.cc
diff options
context:
space:
mode:
authorClément Chigot <chigot.c@gmail.com>2020-05-29 11:39:42 +0200
committerIan Lance Taylor <iant@golang.org>2020-08-10 16:45:16 -0700
commitf4b9b136808c31118c52c0addafb3fd323484d1b (patch)
treecc518ef3fc753c719afdcd1c2eb5476188f3c027 /gcc/go/gofrontend/expressions.cc
parent636686662326496f68451e7eb91882fe462f850a (diff)
downloadgcc-f4b9b136808c31118c52c0addafb3fd323484d1b.zip
gcc-f4b9b136808c31118c52c0addafb3fd323484d1b.tar.gz
gcc-f4b9b136808c31118c52c0addafb3fd323484d1b.tar.bz2
runtime: revert eqtype for AIX
AIX linker is not able to merge identical type descriptors in a single symbol if there are coming from different object or shared object files. This results into several pointers referencing the same type descriptors. Thus, eqtype is needed to ensure that these different symbols will be considered as the same type descriptor. Fixes golang/go#39276 gcc/go/ChangeLog: * go-c.h (struct go_create_gogo_args): Add need_eqtype field. * go-lang.c (go_langhook_init): Set need_eqtype. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/235697
Diffstat (limited to 'gcc/go/gofrontend/expressions.cc')
-rw-r--r--gcc/go/gofrontend/expressions.cc27
1 files changed, 19 insertions, 8 deletions
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index 7e7fb8c..d295fd1 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -208,7 +208,7 @@ Expression::is_same_variable(Expression* a, Expression* b)
// assignment.
Expression*
-Expression::convert_for_assignment(Gogo*, Type* lhs_type,
+Expression::convert_for_assignment(Gogo* gogo, Type* lhs_type,
Expression* rhs, Location location)
{
Type* rhs_type = rhs->type();
@@ -229,7 +229,7 @@ Expression::convert_for_assignment(Gogo*, Type* lhs_type,
location);
}
else if (!are_identical && rhs_type->interface_type() != NULL)
- return Expression::convert_interface_to_type(lhs_type, rhs, location);
+ return Expression::convert_interface_to_type(gogo, lhs_type, rhs, location);
else if (lhs_type->is_slice_type() && rhs_type->is_nil_type())
{
// Assigning nil to a slice.
@@ -498,7 +498,7 @@ Expression::convert_interface_to_interface(Type *lhs_type, Expression* rhs,
// non-interface type.
Expression*
-Expression::convert_interface_to_type(Type *lhs_type, Expression* rhs,
+Expression::convert_interface_to_type(Gogo* gogo, Type *lhs_type, Expression* rhs,
Location location)
{
// We are going to evaluate RHS multiple times.
@@ -507,8 +507,11 @@ Expression::convert_interface_to_type(Type *lhs_type, Expression* rhs,
// Build an expression to check that the type is valid. It will
// panic with an appropriate runtime type error if the type is not
// valid.
- // (lhs_type != rhs_type ? panicdottype(lhs_type, rhs_type, inter_type) :
- // nil /*dummy*/)
+ // (lhs_type == rhs_type ? nil /*dummy*/ :
+ // panicdottype(lhs_type, rhs_type, inter_type))
+ // For some Oses, we need to call runtime.eqtype instead of
+ // lhs_type == rhs_type, as we may have unmerged type descriptors
+ // from shared libraries.
Expression* lhs_type_expr = Expression::make_type_descriptor(lhs_type,
location);
Expression* rhs_descriptor =
@@ -518,15 +521,23 @@ Expression::convert_interface_to_type(Type *lhs_type, Expression* rhs,
Expression* rhs_inter_expr = Expression::make_type_descriptor(rhs_type,
location);
- Expression* cond = Expression::make_binary(OPERATOR_NOTEQ, lhs_type_expr,
- rhs_descriptor, location);
+ Expression* cond;
+ if (gogo->need_eqtype()) {
+ cond = Runtime::make_call(Runtime::EQTYPE, location,
+ 2, lhs_type_expr,
+ rhs_descriptor);
+ } else {
+ cond = Expression::make_binary(OPERATOR_EQEQ, lhs_type_expr,
+ rhs_descriptor, location);
+ }
+
rhs_descriptor = Expression::get_interface_type_descriptor(rhs);
Expression* panic = Runtime::make_call(Runtime::PANICDOTTYPE, location,
3, lhs_type_expr->copy(),
rhs_descriptor,
rhs_inter_expr);
Expression* nil = Expression::make_nil(location);
- Expression* check = Expression::make_conditional(cond, panic, nil,
+ Expression* check = Expression::make_conditional(cond, nil, panic,
location);
// If the conversion succeeds, pull out the value.