diff options
author | Ian Lance Taylor <iant@golang.org> | 2021-03-11 16:12:22 -0800 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2021-03-11 16:12:22 -0800 |
commit | bc636c218f2b28da06cd1404d5b35d1f8cc43fd1 (patch) | |
tree | 764937d8460563db6132d7c75e19b95ef3ea6ea8 /gcc/go | |
parent | 89d7be42db00cd0953e7d4584877cf50a56ed046 (diff) | |
parent | 7ad5a72c8bc6aa71a0d195ddfa207db01265fe0b (diff) | |
download | gcc-bc636c218f2b28da06cd1404d5b35d1f8cc43fd1.zip gcc-bc636c218f2b28da06cd1404d5b35d1f8cc43fd1.tar.gz gcc-bc636c218f2b28da06cd1404d5b35d1f8cc43fd1.tar.bz2 |
Merge from trunk revision 7ad5a72c8bc6aa71a0d195ddfa207db01265fe0b.
Diffstat (limited to 'gcc/go')
-rw-r--r-- | gcc/go/gofrontend/MERGE | 2 | ||||
-rw-r--r-- | gcc/go/gofrontend/embed.cc | 15 | ||||
-rw-r--r-- | gcc/go/gofrontend/expressions.cc | 136 | ||||
-rw-r--r-- | gcc/go/gofrontend/expressions.h | 5 | ||||
-rw-r--r-- | gcc/go/gofrontend/gogo.cc | 9 | ||||
-rw-r--r-- | gcc/go/gofrontend/gogo.h | 11 | ||||
-rw-r--r-- | gcc/go/gofrontend/parse.cc | 2 | ||||
-rw-r--r-- | gcc/go/gofrontend/statements.cc | 6 | ||||
-rw-r--r-- | gcc/go/gofrontend/wb.cc | 4 |
9 files changed, 113 insertions, 77 deletions
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 3175ba0..58c881a 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -a5d7c4225fbbd06b97db6fa424cc0cb5191082d4 +bf35249a7c752836741b1cab43a312f87916fcb0 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/embed.cc b/gcc/go/gofrontend/embed.cc index 0a7df05..0584f70 100644 --- a/gcc/go/gofrontend/embed.cc +++ b/gcc/go/gofrontend/embed.cc @@ -663,21 +663,6 @@ Embedcfg_reader::error(const char* msg) this->filename_, msg); } -// Return whether the current file imports "embed". - -bool -Gogo::is_embed_imported() const -{ - Packages::const_iterator p = this->packages_.find("embed"); - if (p == this->packages_.end()) - return false; - - // We track current file imports in the package aliases, where a - // typical import will just list the package name in aliases. So - // the package has been imported if there is at least one alias. - return !p->second->aliases().empty(); -} - // Implement the sort order for a list of embedded files, as discussed // at the docs for embed.FS. diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 17b4cfd..101cbe7 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -526,7 +526,7 @@ Expression::convert_interface_to_interface(Type *lhs_type, Expression* rhs, // method table. // We are going to evaluate RHS multiple times. - go_assert(rhs->is_variable()); + go_assert(rhs->is_multi_eval_safe()); // Get the type descriptor for the right hand side. This will be // NULL for a nil interface. @@ -569,7 +569,7 @@ Expression::convert_interface_to_type(Gogo* gogo, Type *lhs_type, Expression* rh Location location) { // We are going to evaluate RHS multiple times. - go_assert(rhs->is_variable()); + go_assert(rhs->is_multi_eval_safe()); // Build an expression to check that the type is valid. It will // panic with an appropriate runtime type error if the type is not @@ -707,8 +707,8 @@ Expression::check_bounds(Expression* val, Operator op, Expression* bound, Statement_inserter* inserter, Location loc) { - go_assert(val->is_variable() || val->is_constant()); - go_assert(bound->is_variable() || bound->is_constant()); + go_assert(val->is_multi_eval_safe()); + go_assert(bound->is_multi_eval_safe()); Type* int_type = Type::lookup_integer_type("int"); int int_type_size = int_type->integer_type()->bits(); @@ -3976,7 +3976,7 @@ Type_conversion_expression::do_flatten(Gogo*, Named_object*, if (((this->type()->is_string_type() && this->expr_->type()->is_slice_type()) || this->expr_->type()->interface_type() != NULL) - && !this->expr_->is_variable()) + && !this->expr_->is_multi_eval_safe()) { Temporary_statement* temp = Statement::make_temporary(NULL, this->expr_, this->location()); @@ -4264,7 +4264,7 @@ Type_conversion_expression::do_get_backend(Translate_context* context) Array_type* a = expr_type->array_type(); Type* e = a->element_type()->forwarded(); go_assert(e->integer_type() != NULL); - go_assert(this->expr_->is_variable()); + go_assert(this->expr_->is_multi_eval_safe()); Expression* buf; if (this->no_escape_ && !this->no_copy_) @@ -4711,7 +4711,7 @@ Unary_expression::do_flatten(Gogo* gogo, Named_object*, Location location = this->location(); if (this->op_ == OPERATOR_MULT - && !this->expr_->is_variable()) + && !this->expr_->is_multi_eval_safe()) { go_assert(this->expr_->type()->points_to() != NULL); switch (this->requires_nil_check(gogo)) @@ -4731,7 +4731,7 @@ Unary_expression::do_flatten(Gogo* gogo, Named_object*, } } - if (this->create_temp_ && !this->expr_->is_variable()) + if (this->create_temp_ && !this->expr_->is_multi_eval_safe()) { Temporary_statement* temp = Statement::make_temporary(NULL, this->expr_, location); @@ -5326,7 +5326,7 @@ Unary_expression::do_get_backend(Translate_context* context) bexpr = gogo->backend()->var_expression(decl, loc); } - go_assert(!this->create_temp_ || this->expr_->is_variable()); + go_assert(!this->create_temp_ || this->expr_->is_multi_eval_safe()); ret = gogo->backend()->address_expression(bexpr, loc); break; @@ -5347,7 +5347,7 @@ Unary_expression::do_get_backend(Translate_context* context) } case NIL_CHECK_NEEDED: { - go_assert(this->expr_->is_variable()); + go_assert(this->expr_->is_multi_eval_safe()); // If we're nil-checking the result of a set-and-use-temporary // expression, then pick out the target temp and use that @@ -6496,13 +6496,13 @@ Binary_expression::do_flatten(Gogo* gogo, Named_object*, && (gogo->check_divide_by_zero() || gogo->check_divide_overflow())) || is_string_op) { - if (!this->left_->is_variable() && !this->left_->is_constant()) + if (!this->left_->is_multi_eval_safe()) { temp = Statement::make_temporary(NULL, this->left_, loc); inserter->insert(temp); this->left_ = Expression::make_temporary_reference(temp, loc); } - if (!this->right_->is_variable() && !this->right_->is_constant()) + if (!this->right_->is_multi_eval_safe()) { temp = Statement::make_temporary(NULL, this->right_, loc); @@ -7478,8 +7478,8 @@ Expression::comparison(Translate_context* context, Type* result_type, if (left_type->is_string_type() && right_type->is_string_type()) { - go_assert(left->is_variable() || left->is_constant()); - go_assert(right->is_variable() || right->is_constant()); + go_assert(left->is_multi_eval_safe()); + go_assert(right->is_multi_eval_safe()); if (op == OPERATOR_EQEQ || op == OPERATOR_NOTEQ) { @@ -8078,7 +8078,7 @@ Bound_method_expression::do_flatten(Gogo* gogo, Named_object*, // we are going to do nil checks below, but it's easy enough to // always do it. Expression* expr = this->expr_; - if (!expr->is_variable()) + if (!expr->is_multi_eval_safe()) { Temporary_statement* etemp = Statement::make_temporary(NULL, expr, loc); inserter->insert(etemp); @@ -8419,7 +8419,7 @@ Builtin_call_expression::do_lower(Gogo*, Named_object* function, pa != this->args()->end(); ++pa) { - if (!(*pa)->is_variable() && !(*pa)->is_constant()) + if (!(*pa)->is_multi_eval_safe()) { Temporary_statement* temp = Statement::make_temporary(NULL, *pa, loc); @@ -8470,7 +8470,7 @@ Builtin_call_expression::do_flatten(Gogo* gogo, Named_object* function, Expression* zero = Expression::make_integer_ul(0, NULL, loc); *pa = Expression::make_slice_value(at, nil, zero, zero, loc); } - if (!(*pa)->is_variable()) + if (!(*pa)->is_multi_eval_safe()) { Temporary_statement* temp = Statement::make_temporary(NULL, *pa, loc); @@ -8484,8 +8484,8 @@ Builtin_call_expression::do_flatten(Gogo* gogo, Named_object* function, go_assert(args != NULL && args->size() == 2); Expression* arg1 = args->front(); Expression* arg2 = args->back(); - go_assert(arg1->is_variable()); - go_assert(arg2->is_variable()); + go_assert(arg1->is_multi_eval_safe()); + go_assert(arg2->is_multi_eval_safe()); bool arg2_is_string = arg2->type()->is_string_type(); Expression* ret; @@ -8573,7 +8573,8 @@ Builtin_call_expression::do_flatten(Gogo* gogo, Named_object* function, pa != this->args()->end(); ++pa) { - if (!(*pa)->is_variable() && (*pa)->type()->interface_type() != NULL) + if (!(*pa)->is_multi_eval_safe() + && (*pa)->type()->interface_type() != NULL) { Temporary_statement* temp = Statement::make_temporary(NULL, *pa, loc); @@ -8587,7 +8588,7 @@ Builtin_call_expression::do_flatten(Gogo* gogo, Named_object* function, case BUILTIN_CAP: { Expression_list::iterator pa = this->args()->begin(); - if (!(*pa)->is_variable() + if (!(*pa)->is_multi_eval_safe() && ((*pa)->type()->map_type() != NULL || (*pa)->type()->channel_type() != NULL)) { @@ -9024,7 +9025,7 @@ Builtin_call_expression::flatten_append(Gogo* gogo, Named_object* function, Expression_list::const_iterator pa = args->begin(); for (++pa; pa != args->end(); ++pa) { - if ((*pa)->is_variable()) + if ((*pa)->is_multi_eval_safe()) add->push_back(*pa); else { @@ -11235,7 +11236,7 @@ Call_expression::do_flatten(Gogo* gogo, Named_object*, { Location loc = (*pa)->location(); Expression* arg = *pa; - if (!arg->is_variable()) + if (!arg->is_multi_eval_safe()) { Temporary_statement *temp = Statement::make_temporary(NULL, arg, loc); @@ -11457,7 +11458,7 @@ Call_expression::intrinsify(Gogo* gogo, && this->args_ != NULL && this->args_->size() == 1) { Expression* arg = this->args_->front(); - if (!arg->is_variable()) + if (!arg->is_multi_eval_safe()) { Temporary_statement* ts = Statement::make_temporary(uint32_type, arg, loc); inserter->insert(ts); @@ -11476,7 +11477,7 @@ Call_expression::intrinsify(Gogo* gogo, && this->args_ != NULL && this->args_->size() == 1) { Expression* arg = this->args_->front(); - if (!arg->is_variable()) + if (!arg->is_multi_eval_safe()) { Temporary_statement* ts = Statement::make_temporary(uint64_type, arg, loc); inserter->insert(ts); @@ -11526,7 +11527,7 @@ Call_expression::intrinsify(Gogo* gogo, && this->args_ != NULL && this->args_->size() == 1) { Expression* arg = this->args_->front(); - if (!arg->is_variable()) + if (!arg->is_multi_eval_safe()) { Temporary_statement* ts = Statement::make_temporary(uint32_type, arg, loc); inserter->insert(ts); @@ -11549,7 +11550,7 @@ Call_expression::intrinsify(Gogo* gogo, && this->args_ != NULL && this->args_->size() == 1) { Expression* arg = this->args_->front(); - if (!arg->is_variable()) + if (!arg->is_multi_eval_safe()) { Temporary_statement* ts = Statement::make_temporary(uint64_type, arg, loc); inserter->insert(ts); @@ -13087,14 +13088,14 @@ Array_index_expression::do_flatten(Gogo* gogo, Named_object*, } Temporary_statement* temp; - if (array_type->is_slice_type() && !array->is_variable()) + if (array_type->is_slice_type() && !array->is_multi_eval_safe()) { temp = Statement::make_temporary(NULL, array, loc); inserter->insert(temp); this->array_ = Expression::make_temporary_reference(temp, loc); array = this->array_; } - if (!start->is_variable() && !start->is_constant()) + if (!start->is_multi_eval_safe()) { temp = Statement::make_temporary(NULL, start, loc); inserter->insert(temp); @@ -13103,15 +13104,14 @@ Array_index_expression::do_flatten(Gogo* gogo, Named_object*, } if (end != NULL && !end->is_nil_expression() - && !end->is_variable() - && !end->is_constant()) + && !end->is_multi_eval_safe()) { temp = Statement::make_temporary(NULL, end, loc); inserter->insert(temp); this->end_ = Expression::make_temporary_reference(temp, loc); end = this->end_; } - if (cap != NULL && !cap->is_variable() && !cap->is_constant()) + if (cap != NULL && !cap->is_multi_eval_safe()) { temp = Statement::make_temporary(NULL, cap, loc); inserter->insert(temp); @@ -13270,7 +13270,8 @@ Array_index_expression::do_get_backend(Translate_context* context) go_assert(this->array_->type()->is_error()); return context->backend()->error_expression(); } - go_assert(!array_type->is_slice_type() || this->array_->is_variable()); + go_assert(!array_type->is_slice_type() + || this->array_->is_multi_eval_safe()); Location loc = this->location(); Gogo* gogo = context->gogo(); @@ -13484,14 +13485,14 @@ String_index_expression::do_flatten(Gogo*, Named_object*, } Temporary_statement* temp; - if (!string->is_variable()) + if (!string->is_multi_eval_safe()) { temp = Statement::make_temporary(NULL, string, loc); inserter->insert(temp); this->string_ = Expression::make_temporary_reference(temp, loc); string = this->string_; } - if (!start->is_variable()) + if (!start->is_multi_eval_safe()) { temp = Statement::make_temporary(NULL, start, loc); inserter->insert(temp); @@ -13500,7 +13501,7 @@ String_index_expression::do_flatten(Gogo*, Named_object*, } if (end != NULL && !end->is_nil_expression() - && !end->is_variable()) + && !end->is_multi_eval_safe()) { temp = Statement::make_temporary(NULL, end, loc); inserter->insert(temp); @@ -13659,8 +13660,8 @@ String_index_expression::do_get_backend(Translate_context* context) return context->backend()->error_expression(); } - go_assert(this->string_->is_variable()); - go_assert(this->start_->is_variable()); + go_assert(this->string_->is_multi_eval_safe()); + go_assert(this->start_->is_multi_eval_safe()); Expression* start = Expression::make_cast(int_type, this->start_, loc); Bfunction* bfn = context->function()->func_value()->get_decl(); @@ -13685,7 +13686,7 @@ String_index_expression::do_get_backend(Translate_context* context) end = length; else { - go_assert(this->end_->is_variable()); + go_assert(this->end_->is_multi_eval_safe()); end = Expression::make_cast(int_type, this->end_, loc); } @@ -13815,7 +13816,7 @@ Map_index_expression::do_flatten(Gogo* gogo, Named_object*, NULL)) { if (this->index_->type()->interface_type() != NULL - && !this->index_->is_variable()) + && !this->index_->is_multi_eval_safe()) { Temporary_statement* temp = Statement::make_temporary(NULL, this->index_, loc); @@ -13826,7 +13827,7 @@ Map_index_expression::do_flatten(Gogo* gogo, Named_object*, this->index_, loc); } - if (!this->index_->is_variable()) + if (!this->index_->is_multi_eval_safe()) { Temporary_statement* temp = Statement::make_temporary(NULL, this->index_, loc); @@ -13839,7 +13840,7 @@ Map_index_expression::do_flatten(Gogo* gogo, Named_object*, if (this->value_pointer_->is_error_expression() || this->value_pointer_->type()->is_error_type()) return Expression::make_error(loc); - if (!this->value_pointer_->is_variable()) + if (!this->value_pointer_->is_multi_eval_safe()) { Temporary_statement* temp = Statement::make_temporary(NULL, this->value_pointer_, loc); @@ -13923,7 +13924,7 @@ Map_index_expression::do_get_backend(Translate_context* context) } go_assert(this->value_pointer_ != NULL - && this->value_pointer_->is_variable()); + && this->value_pointer_->is_multi_eval_safe()); Expression* val = Expression::make_dereference(this->value_pointer_, NIL_CHECK_NOT_NEEDED, @@ -14268,7 +14269,7 @@ Interface_field_reference_expression::do_flatten(Gogo*, Named_object*, return Expression::make_error(this->location()); } - if (!this->expr_->is_variable()) + if (!this->expr_->is_multi_eval_safe()) { Temporary_statement* temp = Statement::make_temporary(NULL, this->expr_, this->location()); @@ -15165,7 +15166,7 @@ Struct_construction_expression::do_flatten(Gogo*, Named_object*, go_assert(saw_errors()); return Expression::make_error(loc); } - if (!(*pv)->is_variable()) + if (!(*pv)->is_multi_eval_safe()) { Temporary_statement* temp = Statement::make_temporary(NULL, *pv, loc); @@ -15471,7 +15472,7 @@ Array_construction_expression::do_flatten(Gogo*, Named_object*, go_assert(saw_errors()); return Expression::make_error(loc); } - if (!(*pv)->is_variable()) + if (!(*pv)->is_multi_eval_safe()) { Temporary_statement* temp = Statement::make_temporary(NULL, *pv, loc); @@ -15914,7 +15915,8 @@ Map_construction_expression::do_flatten(Gogo* gogo, Named_object*, go_assert(saw_errors()); return Expression::make_error(loc); } - if (key->type()->interface_type() != NULL && !key->is_variable()) + if (key->type()->interface_type() != NULL + && !key->is_multi_eval_safe()) { Temporary_statement* temp = Statement::make_temporary(NULL, key, loc); @@ -15930,7 +15932,8 @@ Map_construction_expression::do_flatten(Gogo* gogo, Named_object*, go_assert(saw_errors()); return Expression::make_error(loc); } - if (val->type()->interface_type() != NULL && !val->is_variable()) + if (val->type()->interface_type() != NULL + && !val->is_multi_eval_safe()) { Temporary_statement* temp = Statement::make_temporary(NULL, val, loc); @@ -17037,6 +17040,41 @@ Expression::is_local_variable() const || (no->is_variable() && !no->var_value()->is_global())); } +// Return true if multiple evaluations are OK. + +bool +Expression::is_multi_eval_safe() +{ + switch (this->classification_) + { + case EXPRESSION_VAR_REFERENCE: + { + // A variable is a simple reference if not stored in the heap. + const Named_object* no = this->var_expression()->named_object(); + if (no->is_variable()) + return !no->var_value()->is_in_heap(); + else if (no->is_result_variable()) + return !no->result_var_value()->is_in_heap(); + else + go_unreachable(); + } + + case EXPRESSION_TEMPORARY_REFERENCE: + return true; + + default: + break; + } + + if (!this->is_constant()) + return false; + + // Only numeric and boolean constants are really multi-evaluation + // safe. We don't want multiple copies of string constants. + Type* type = this->type(); + return type->is_numeric_type() || type->is_boolean_type(); +} + const Named_object* Expression::named_constant() const { @@ -17070,7 +17108,7 @@ Type_guard_expression::do_flatten(Gogo*, Named_object*, return Expression::make_error(this->location()); } - if (!this->expr_->is_variable()) + if (!this->expr_->is_multi_eval_safe()) { Temporary_statement* temp = Statement::make_temporary(NULL, this->expr_, this->location()); diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h index 712f687..e3747cc 100644 --- a/gcc/go/gofrontend/expressions.h +++ b/gcc/go/gofrontend/expressions.h @@ -916,6 +916,11 @@ class Expression bool is_local_variable() const; + // Return true if multiple evaluations of this expression are OK. + // This is true for simple variable references and constants. + bool + is_multi_eval_safe(); + // Return true if two expressions refer to the same variable or // struct field. static bool diff --git a/gcc/go/gofrontend/gogo.cc b/gcc/go/gofrontend/gogo.cc index 62b06be..93b54fd 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -37,6 +37,7 @@ Gogo::Gogo(Backend* backend, Linemap* linemap, int, int pointer_size) imports_(), imported_unsafe_(false), current_file_imported_unsafe_(false), + current_file_imported_embed_(false), packages_(), init_functions_(), var_deps_(), @@ -469,6 +470,9 @@ Gogo::import_package(const std::string& filename, return; } + if (filename == "embed") + this->current_file_imported_embed_ = true; + Imports::const_iterator p = this->imports_.find(filename); if (p != this->imports_.end()) { @@ -2717,6 +2721,7 @@ Gogo::clear_file_scope() } this->current_file_imported_unsafe_ = false; + this->current_file_imported_embed_ = false; } // Queue up a type-specific hash function for later writing. These @@ -5898,7 +5903,7 @@ Function::export_func_with_type(Export* exp, const Named_object* no, exp->write_name(receiver->name()); exp->write_escape(receiver->note()); exp->write_c_string(" "); - exp->write_type(receiver->type()); + exp->write_type(receiver->type()->unalias()); exp->write_c_string(") "); } @@ -7574,7 +7579,7 @@ Variable::flatten_init_expression(Gogo* gogo, Named_object* function, Type::COMPARE_ERRORS | Type::COMPARE_TAGS, NULL) && this->init_->type()->interface_type() != NULL - && !this->init_->is_variable()) + && !this->init_->is_multi_eval_safe()) { Temporary_statement* temp = Statement::make_temporary(NULL, this->init_, this->location_); diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h index 51b6575..f4155a2 100644 --- a/gcc/go/gofrontend/gogo.h +++ b/gcc/go/gofrontend/gogo.h @@ -397,10 +397,6 @@ class Gogo void read_embedcfg(const char* filename); - // Return whether the current file imports "embed". - bool - is_embed_imported() const; - // Build an initializer for a variable with a go:embed directive. Expression* initializer_for_embeds(Type*, const std::vector<std::string>*, Location); @@ -709,6 +705,11 @@ class Gogo current_file_imported_unsafe() const { return this->current_file_imported_unsafe_; } + // Return whether the current file imported the embed package. + bool + current_file_imported_embed() const + { return this->current_file_imported_embed_; } + // Clear out all names in file scope. This is called when we start // parsing a new file. void @@ -1251,6 +1252,8 @@ class Gogo bool imported_unsafe_; // Whether the magic unsafe package was imported by the current file. bool current_file_imported_unsafe_; + // Whether the embed package was imported by the current file. + bool current_file_imported_embed_; // Mapping from package names we have seen to packages. This does // not include the package we are compiling. Packages packages_; diff --git a/gcc/go/gofrontend/parse.cc b/gcc/go/gofrontend/parse.cc index fd81a85..e43b5f2 100644 --- a/gcc/go/gofrontend/parse.cc +++ b/gcc/go/gofrontend/parse.cc @@ -1321,7 +1321,7 @@ Parse::declaration() embeds = new(std::vector<std::string>); this->lex_->get_and_clear_embeds(embeds); - if (!this->gogo_->is_embed_imported()) + if (!this->gogo_->current_file_imported_embed()) { go_error_at(token->location(), "invalid go:embed: missing import %<embed%>"); diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc index da0e084..7ad7339 100644 --- a/gcc/go/gofrontend/statements.cc +++ b/gcc/go/gofrontend/statements.cc @@ -588,7 +588,7 @@ Temporary_statement::do_flatten(Gogo*, Named_object*, Block*, Type::COMPARE_ERRORS | Type::COMPARE_TAGS, NULL) && this->init_->type()->interface_type() != NULL - && !this->init_->is_variable()) + && !this->init_->is_multi_eval_safe()) { Temporary_statement *temp = Statement::make_temporary(NULL, this->init_, this->location()); @@ -1125,7 +1125,7 @@ Assignment_statement::do_flatten(Gogo*, Named_object*, Block*, Type::COMPARE_ERRORS | Type::COMPARE_TAGS, NULL) && this->rhs_->type()->interface_type() != NULL - && !this->rhs_->is_variable()) + && !this->rhs_->is_multi_eval_safe()) { Temporary_statement* temp = Statement::make_temporary(NULL, this->rhs_, this->location()); @@ -5116,7 +5116,7 @@ Send_statement::do_flatten(Gogo*, Named_object*, Block*, Type::COMPARE_ERRORS | Type::COMPARE_TAGS, NULL) && this->val_->type()->interface_type() != NULL - && !this->val_->is_variable()) + && !this->val_->is_multi_eval_safe()) { Temporary_statement* temp = Statement::make_temporary(NULL, this->val_, this->location()); diff --git a/gcc/go/gofrontend/wb.cc b/gcc/go/gofrontend/wb.cc index ac1f0a1..104c5db 100644 --- a/gcc/go/gofrontend/wb.cc +++ b/gcc/go/gofrontend/wb.cc @@ -883,7 +883,7 @@ Gogo::assign_with_write_barrier(Function* function, Block* enclosing, Type::COMPARE_ERRORS | Type::COMPARE_TAGS, NULL) && rhs->type()->interface_type() != NULL - && !rhs->is_variable()) + && !rhs->is_multi_eval_safe()) { // May need a temporary for interface conversion. Temporary_statement* temp = Statement::make_temporary(NULL, rhs, loc); @@ -892,7 +892,7 @@ Gogo::assign_with_write_barrier(Function* function, Block* enclosing, } rhs = Expression::convert_for_assignment(this, type, rhs, loc); Temporary_statement* rhs_temp = NULL; - if (!rhs->is_variable() && !rhs->is_constant()) + if (!rhs->is_multi_eval_safe()) { rhs_temp = Statement::make_temporary(NULL, rhs, loc); inserter->insert(rhs_temp); |