aboutsummaryrefslogtreecommitdiff
path: root/gcc/go
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2021-10-07 15:28:36 -0700
committerIan Lance Taylor <iant@golang.org>2021-10-07 15:28:36 -0700
commit0b6b70a0733672600644c8df96942cda5bf86d3d (patch)
tree9a1fbd7f782c54df55ab225ed1be057e3f3b0b8a /gcc/go
parenta5b5cabc91c38710adbe5c8a2b53882abe994441 (diff)
parentfba228e259dd5112851527f2dbb62c5601100985 (diff)
downloadgcc-0b6b70a0733672600644c8df96942cda5bf86d3d.zip
gcc-0b6b70a0733672600644c8df96942cda5bf86d3d.tar.gz
gcc-0b6b70a0733672600644c8df96942cda5bf86d3d.tar.bz2
Merge from trunk revision fba228e259dd5112851527f2dbb62c5601100985.
Diffstat (limited to 'gcc/go')
-rw-r--r--gcc/go/ChangeLog5
-rw-r--r--gcc/go/go-lang.c1
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/expressions.h4
-rw-r--r--gcc/go/gofrontend/types.cc77
-rw-r--r--gcc/go/gofrontend/types.h13
6 files changed, 77 insertions, 25 deletions
diff --git a/gcc/go/ChangeLog b/gcc/go/ChangeLog
index 60ebb89..c17e3a4 100644
--- a/gcc/go/ChangeLog
+++ b/gcc/go/ChangeLog
@@ -1,3 +1,8 @@
+2021-09-27 Martin Liska <mliska@suse.cz>
+
+ * go-lang.c (go_langhook_init_options_struct): Set also
+ x_flag_default_complex_method.
+
2021-06-29 Ian Lance Taylor <iant@golang.org>
* go-gcc.cc (Gcc_backend::static_chain_variable): Set
diff --git a/gcc/go/go-lang.c b/gcc/go/go-lang.c
index a01db8d..c3ae6f0 100644
--- a/gcc/go/go-lang.c
+++ b/gcc/go/go-lang.c
@@ -174,6 +174,7 @@ go_langhook_init_options_struct (struct gcc_options *opts)
/* Default to avoiding range issues for complex multiply and
divide. */
opts->x_flag_complex_method = 2;
+ opts->x_flag_default_complex_method = opts->x_flag_complex_method;
/* The builtin math functions should not set errno. */
opts->x_flag_errno_math = 0;
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index edfbe46..affba73 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-e3bfc0889237a5bb8aa7ae30e1cff14f90a5f941
+925ace70ac7426c3f8b5c0bfb75aa9601f071de4
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h
index 9f8f4e9..9348354 100644
--- a/gcc/go/gofrontend/expressions.h
+++ b/gcc/go/gofrontend/expressions.h
@@ -999,7 +999,9 @@ class Expression
determine_type_no_context();
// Return the current type of the expression. This may be changed
- // by determine_type.
+ // by determine_type. This should not be called before the lowering
+ // pass, unless the is_type_expression method returns true (i.e.,
+ // this is an EXPRESSION_TYPE).
Type*
type()
{ return this->do_type(); }
diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc
index cd69250..0f66661 100644
--- a/gcc/go/gofrontend/types.cc
+++ b/gcc/go/gofrontend/types.cc
@@ -2259,7 +2259,7 @@ Named_object*
Type::build_equal_function(Gogo* gogo, Named_type* name, int64_t size,
Function_type* equal_fntype)
{
- std::pair<Type*, Named_object*> val(name != NULL ? name : this, NULL);
+ std::pair<Type*, Named_object*> val(name != NULL ? name : this, nullptr);
std::pair<Type_function::iterator, bool> ins =
Type::type_equal_functions_table.insert(val);
if (!ins.second)
@@ -6413,7 +6413,7 @@ Struct_type::interface_method_table(Interface_type* interface,
bool is_pointer)
{
std::pair<Struct_type*, Struct_type::Struct_method_table_pair*>
- val(this, NULL);
+ val(this, nullptr);
std::pair<Struct_type::Struct_method_tables::iterator, bool> ins =
Struct_type::struct_method_tables.insert(val);
@@ -11789,8 +11789,9 @@ Type::build_stub_methods(Gogo* gogo, const Type* type, const Methods* methods,
{
stub = gogo->start_function(stub_name, stub_type, false,
fntype->location());
- Type::build_one_stub_method(gogo, m, buf, stub_params,
- fntype->is_varargs(), location);
+ Type::build_one_stub_method(gogo, m, buf, receiver_type, stub_params,
+ fntype->is_varargs(), stub_results,
+ location);
gogo->finish_function(fntype->location());
if (type->named_type() == NULL && stub->is_function())
@@ -11810,16 +11811,20 @@ Type::build_stub_methods(Gogo* gogo, const Type* type, const Methods* methods,
void
Type::build_one_stub_method(Gogo* gogo, Method* method,
const char* receiver_name,
+ const Type* receiver_type,
const Typed_identifier_list* params,
bool is_varargs,
+ const Typed_identifier_list* results,
Location location)
{
Named_object* receiver_object = gogo->lookup(receiver_name, NULL);
go_assert(receiver_object != NULL);
Expression* expr = Expression::make_var_reference(receiver_object, location);
- expr = Type::apply_field_indexes(expr, method->field_indexes(), location);
- if (expr->type()->points_to() == NULL)
+ const Type* expr_type = receiver_type;
+ expr = Type::apply_field_indexes(expr, method->field_indexes(), location,
+ &expr_type);
+ if (expr_type->points_to() == NULL)
expr = Expression::make_unary(OPERATOR_AND, expr, location);
Expression_list* arguments;
@@ -11844,8 +11849,7 @@ Type::build_one_stub_method(Gogo* gogo, Method* method,
go_assert(func != NULL);
Call_expression* call = Expression::make_call(func, arguments, is_varargs,
location);
-
- gogo->add_statement(Statement::make_return_from_call(call, location));
+ Type::add_return_from_results(gogo, call, results, location);
}
// Build direct interface stub methods for TYPE as needed. METHODS
@@ -11954,8 +11958,9 @@ Type::build_direct_iface_stub_methods(Gogo* gogo, const Type* type,
{
stub = gogo->start_function(stub_name, stub_type, false,
fntype->location());
- Type::build_one_iface_stub_method(gogo, m, buf, stub_params,
- fntype->is_varargs(), loc);
+ Type::build_one_iface_stub_method(gogo, m, buf, stub_params,
+ fntype->is_varargs(), stub_results,
+ loc);
gogo->finish_function(fntype->location());
if (type->named_type() == NULL && stub->is_function())
@@ -11982,7 +11987,9 @@ void
Type::build_one_iface_stub_method(Gogo* gogo, Method* method,
const char* receiver_name,
const Typed_identifier_list* params,
- bool is_varargs, Location loc)
+ bool is_varargs,
+ const Typed_identifier_list* results,
+ Location loc)
{
Named_object* receiver_object = gogo->lookup(receiver_name, NULL);
go_assert(receiver_object != NULL);
@@ -12014,31 +12021,63 @@ Type::build_one_iface_stub_method(Gogo* gogo, Method* method,
go_assert(func != NULL);
Call_expression* call = Expression::make_call(func, arguments, is_varargs,
loc);
+ Type::add_return_from_results(gogo, call, results, loc);
+}
- gogo->add_statement(Statement::make_return_from_call(call, loc));
+// Build and add a return statement from a call expression and a list
+// of result parameters. All we need to know is the number of
+// results.
+
+void
+Type::add_return_from_results(Gogo* gogo, Call_expression* call,
+ const Typed_identifier_list* results,
+ Location loc)
+{
+ Statement* s;
+ if (results == NULL || results->empty())
+ s = Statement::make_statement(call, true);
+ else
+ {
+ Expression_list* vals = new Expression_list();
+ size_t rc = results->size();
+ if (rc == 1)
+ vals->push_back(call);
+ else
+ {
+ for (size_t i = 0; i < rc; ++i)
+ vals->push_back(Expression::make_call_result(call, i));
+ }
+ s = Statement::make_return_statement(vals, loc);
+ }
+
+ gogo->add_statement(s);
}
// Apply FIELD_INDEXES to EXPR. The field indexes have to be applied
-// in reverse order.
+// in reverse order. *PEXPR_TYPE maintains the type of EXPR; we use
+// this to avoid calling EXPR->type() before the lowering pass.
Expression*
Type::apply_field_indexes(Expression* expr,
const Method::Field_indexes* field_indexes,
- Location location)
+ Location location,
+ const Type** pexpr_type)
{
if (field_indexes == NULL)
return expr;
- expr = Type::apply_field_indexes(expr, field_indexes->next, location);
- Struct_type* stype = expr->type()->deref()->struct_type();
+ expr = Type::apply_field_indexes(expr, field_indexes->next, location,
+ pexpr_type);
+ const Type* expr_type = *pexpr_type;
+ const Struct_type* stype = expr_type->deref()->struct_type();
go_assert(stype != NULL
&& field_indexes->field_index < stype->field_count());
- if (expr->type()->struct_type() == NULL)
+ if (expr_type->struct_type() == NULL)
{
- go_assert(expr->type()->points_to() != NULL);
+ go_assert(expr_type->points_to()->struct_type() == stype);
expr = Expression::make_dereference(expr, Expression::NIL_CHECK_DEFAULT,
location);
- go_assert(expr->type()->struct_type() == stype);
}
+ *pexpr_type = stype->field(field_indexes->field_index)->type();
return Expression::make_field_reference(expr, field_indexes->field_index,
location);
}
diff --git a/gcc/go/gofrontend/types.h b/gcc/go/gofrontend/types.h
index 0c51806..a33453a 100644
--- a/gcc/go/gofrontend/types.h
+++ b/gcc/go/gofrontend/types.h
@@ -1355,8 +1355,9 @@ class Type
static void
build_one_stub_method(Gogo*, Method*, const char* receiver_name,
+ const Type* receiver_type,
const Typed_identifier_list*, bool is_varargs,
- Location);
+ const Typed_identifier_list*, Location);
// Build direct interface stub methods for a type.
static void
@@ -1364,12 +1365,16 @@ class Type
static void
build_one_iface_stub_method(Gogo*, Method*, const char*,
- const Typed_identifier_list*,
- bool, Location);
+ const Typed_identifier_list*, bool,
+ const Typed_identifier_list*, Location);
+
+ static void
+ add_return_from_results(Gogo*, Call_expression*,
+ const Typed_identifier_list*, Location);
static Expression*
apply_field_indexes(Expression*, const Method::Field_indexes*,
- Location);
+ Location, const Type**);
// Look for a field or method named NAME in TYPE.
static bool