aboutsummaryrefslogtreecommitdiff
path: root/gcc/go
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2021-10-18 14:43:12 +0200
committerMartin Liska <mliska@suse.cz>2021-10-18 14:43:12 +0200
commit39887dd2c2c81cf3e98466827d59cafda279a258 (patch)
tree4cacd91fc1a3199b6dec319bc63cf82ffb65d813 /gcc/go
parente07d0e579a4e532ac4bd2d223105d73d6418868f (diff)
parent247c407c83f0015f4b92d5f71e45b63192f6757e (diff)
downloadgcc-39887dd2c2c81cf3e98466827d59cafda279a258.zip
gcc-39887dd2c2c81cf3e98466827d59cafda279a258.tar.gz
gcc-39887dd2c2c81cf3e98466827d59cafda279a258.tar.bz2
Merge branch 'master' into devel/sphinx
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.cc2
-rw-r--r--gcc/go/gofrontend/expressions.h4
-rw-r--r--gcc/go/gofrontend/types.cc80
-rw-r--r--gcc/go/gofrontend/types.h30
7 files changed, 96 insertions, 28 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 950f179..affba73 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-77bc32767b61feb6499ca7921e96b356603517dc
+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.cc b/gcc/go/gofrontend/expressions.cc
index 8d4d168..ddb1d91 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -9350,7 +9350,7 @@ Builtin_call_expression::flatten_append(Gogo* gogo, Named_object* function,
ref2 = Expression::make_cast(uint_type, ref2, loc);
cond = Expression::make_binary(OPERATOR_GT, ref, ref2, loc);
zero = Expression::make_integer_ul(0, int_type, loc);
- call = Expression::make_conditional(cond, call, zero, loc);
+ call = Expression::make_conditional(cond, zero, call, loc);
}
}
else
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 e76600d..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)
@@ -5050,6 +5050,7 @@ Function_type::get_backend_fntype(Gogo* gogo)
Struct_type* st = Type::make_struct_type(sfl,
this->location());
st->set_is_struct_incomparable();
+ st->set_is_results_struct();
ins.first->second = st->get_backend(gogo);
}
bresult_struct = ins.first->second;
@@ -6412,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);
@@ -6458,7 +6459,7 @@ get_backend_struct_fields(Gogo* gogo, Struct_type* type, bool use_placeholder,
saw_nonzero = true;
}
go_assert(i == fields->size());
- if (saw_nonzero && lastsize == 0)
+ if (saw_nonzero && lastsize == 0 && !type->is_results_struct())
{
// For nonzero-sized structs which end in a zero-sized thing, we add
// an extra byte of padding to the type. This padding ensures that
@@ -11788,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())
@@ -11809,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;
@@ -11843,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
@@ -11953,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())
@@ -11981,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);
@@ -12013,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 ca1ab49..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
@@ -2501,7 +2506,8 @@ class Struct_type : public Type
Struct_type(Struct_field_list* fields, Location location)
: Type(TYPE_STRUCT),
fields_(fields), location_(location), all_methods_(NULL),
- is_struct_incomparable_(false), has_padding_(false)
+ is_struct_incomparable_(false), has_padding_(false),
+ is_results_struct_(false)
{ }
// Return the field NAME. This only looks at local fields, not at
@@ -2632,6 +2638,17 @@ class Struct_type : public Type
set_has_padding()
{ this->has_padding_ = true; }
+ // Return whether this is a results struct created to hold the
+ // results of a function that returns multiple results.
+ bool
+ is_results_struct() const
+ { return this->is_results_struct_; }
+
+ // Record that this is a results struct.
+ void
+ set_is_results_struct()
+ { this->is_results_struct_ = true; }
+
// Write the hash function for this type.
void
write_hash_function(Gogo*, Function_type*);
@@ -2742,6 +2759,9 @@ class Struct_type : public Type
// True if this struct's backend type has padding, due to trailing
// zero-sized field.
bool has_padding_;
+ // True if this is a results struct created to hold the results of a
+ // function that returns multiple results.
+ bool is_results_struct_;
};
// The type of an array.