diff options
author | Martin Liska <mliska@suse.cz> | 2021-10-18 14:43:12 +0200 |
---|---|---|
committer | Martin Liska <mliska@suse.cz> | 2021-10-18 14:43:12 +0200 |
commit | 39887dd2c2c81cf3e98466827d59cafda279a258 (patch) | |
tree | 4cacd91fc1a3199b6dec319bc63cf82ffb65d813 /gcc/go | |
parent | e07d0e579a4e532ac4bd2d223105d73d6418868f (diff) | |
parent | 247c407c83f0015f4b92d5f71e45b63192f6757e (diff) | |
download | gcc-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/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.cc | 2 | ||||
-rw-r--r-- | gcc/go/gofrontend/expressions.h | 4 | ||||
-rw-r--r-- | gcc/go/gofrontend/types.cc | 80 | ||||
-rw-r--r-- | gcc/go/gofrontend/types.h | 30 |
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. |