diff options
Diffstat (limited to 'gcc/go')
-rw-r--r-- | gcc/go/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/go/go-lang.c | 1 | ||||
-rw-r--r-- | gcc/go/gofrontend/MERGE | 2 | ||||
-rw-r--r-- | gcc/go/gofrontend/expressions.h | 4 | ||||
-rw-r--r-- | gcc/go/gofrontend/types.cc | 77 | ||||
-rw-r--r-- | gcc/go/gofrontend/types.h | 13 |
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 |