aboutsummaryrefslogtreecommitdiff
path: root/gcc/go
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2021-03-11 16:12:22 -0800
committerIan Lance Taylor <iant@golang.org>2021-03-11 16:12:22 -0800
commitbc636c218f2b28da06cd1404d5b35d1f8cc43fd1 (patch)
tree764937d8460563db6132d7c75e19b95ef3ea6ea8 /gcc/go
parent89d7be42db00cd0953e7d4584877cf50a56ed046 (diff)
parent7ad5a72c8bc6aa71a0d195ddfa207db01265fe0b (diff)
downloadgcc-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/MERGE2
-rw-r--r--gcc/go/gofrontend/embed.cc15
-rw-r--r--gcc/go/gofrontend/expressions.cc136
-rw-r--r--gcc/go/gofrontend/expressions.h5
-rw-r--r--gcc/go/gofrontend/gogo.cc9
-rw-r--r--gcc/go/gofrontend/gogo.h11
-rw-r--r--gcc/go/gofrontend/parse.cc2
-rw-r--r--gcc/go/gofrontend/statements.cc6
-rw-r--r--gcc/go/gofrontend/wb.cc4
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);