mirror of git://gcc.gnu.org/git/gcc.git
compiler: More cases that need a temporary for interface conversion.
From-SVN: r218952
This commit is contained in:
parent
6b0e0695a5
commit
16f72d88dd
|
|
@ -5142,6 +5142,9 @@ Expression*
|
|||
Binary_expression::do_flatten(Gogo* gogo, Named_object*,
|
||||
Statement_inserter* inserter)
|
||||
{
|
||||
if (this->classification() == EXPRESSION_ERROR)
|
||||
return this;
|
||||
|
||||
Location loc = this->location();
|
||||
Temporary_statement* temp;
|
||||
if (this->left_->type()->is_string_type()
|
||||
|
|
@ -6877,30 +6880,53 @@ Expression*
|
|||
Builtin_call_expression::do_flatten(Gogo*, Named_object*,
|
||||
Statement_inserter* inserter)
|
||||
{
|
||||
if (this->code_ == BUILTIN_APPEND
|
||||
|| this->code_ == BUILTIN_COPY)
|
||||
Location loc = this->location();
|
||||
|
||||
switch (this->code_)
|
||||
{
|
||||
Location loc = this->location();
|
||||
Type* at = this->args()->front()->type();
|
||||
for (Expression_list::iterator pa = this->args()->begin();
|
||||
pa != this->args()->end();
|
||||
++pa)
|
||||
{
|
||||
if ((*pa)->is_nil_expression())
|
||||
{
|
||||
Expression* nil = Expression::make_nil(loc);
|
||||
Expression* zero = Expression::make_integer_ul(0, NULL, loc);
|
||||
*pa = Expression::make_slice_value(at, nil, zero, zero, loc);
|
||||
}
|
||||
if (!(*pa)->is_variable())
|
||||
{
|
||||
Temporary_statement* temp =
|
||||
default:
|
||||
break;
|
||||
|
||||
case BUILTIN_APPEND:
|
||||
case BUILTIN_COPY:
|
||||
{
|
||||
Type* at = this->args()->front()->type();
|
||||
for (Expression_list::iterator pa = this->args()->begin();
|
||||
pa != this->args()->end();
|
||||
++pa)
|
||||
{
|
||||
if ((*pa)->is_nil_expression())
|
||||
{
|
||||
Expression* nil = Expression::make_nil(loc);
|
||||
Expression* zero = Expression::make_integer_ul(0, NULL, loc);
|
||||
*pa = Expression::make_slice_value(at, nil, zero, zero, loc);
|
||||
}
|
||||
if (!(*pa)->is_variable())
|
||||
{
|
||||
Temporary_statement* temp =
|
||||
Statement::make_temporary(NULL, *pa, loc);
|
||||
inserter->insert(temp);
|
||||
*pa = Expression::make_temporary_reference(temp, loc);
|
||||
}
|
||||
}
|
||||
inserter->insert(temp);
|
||||
*pa = Expression::make_temporary_reference(temp, loc);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case BUILTIN_PANIC:
|
||||
for (Expression_list::iterator pa = this->args()->begin();
|
||||
pa != this->args()->end();
|
||||
++pa)
|
||||
{
|
||||
if (!(*pa)->is_variable() && (*pa)->type()->interface_type() != NULL)
|
||||
{
|
||||
Temporary_statement* temp =
|
||||
Statement::make_temporary(NULL, *pa, loc);
|
||||
inserter->insert(temp);
|
||||
*pa = Expression::make_temporary_reference(temp, loc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -421,6 +421,28 @@ Temporary_statement::do_check_types(Gogo*)
|
|||
}
|
||||
}
|
||||
|
||||
// Flatten a temporary statement: add another temporary when it might
|
||||
// be needed for interface conversion.
|
||||
|
||||
Statement*
|
||||
Temporary_statement::do_flatten(Gogo*, Named_object*, Block*,
|
||||
Statement_inserter* inserter)
|
||||
{
|
||||
if (this->type_ != NULL
|
||||
&& this->init_ != NULL
|
||||
&& !Type::are_identical(this->type_, this->init_->type(), false, NULL)
|
||||
&& this->init_->type()->interface_type() != NULL
|
||||
&& !this->init_->is_variable())
|
||||
{
|
||||
Temporary_statement *temp =
|
||||
Statement::make_temporary(NULL, this->init_, this->location());
|
||||
inserter->insert(temp);
|
||||
this->init_ = Expression::make_temporary_reference(temp,
|
||||
this->location());
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
// Convert to backend representation.
|
||||
|
||||
Bstatement*
|
||||
|
|
@ -440,9 +462,10 @@ Temporary_statement::do_get_backend(Translate_context* context)
|
|||
binit = this->init_->get_backend(context);
|
||||
else
|
||||
{
|
||||
Expression* init = Expression::make_cast(this->type_, this->init_,
|
||||
this->location());
|
||||
context->gogo()->lower_expression(context->function(), NULL, &init);
|
||||
Expression* init = Expression::convert_for_assignment(context->gogo(),
|
||||
this->type_,
|
||||
this->init_,
|
||||
this->location());
|
||||
binit = init->get_backend(context);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -550,6 +550,9 @@ class Temporary_statement : public Statement
|
|||
void
|
||||
do_check_types(Gogo*);
|
||||
|
||||
Statement*
|
||||
do_flatten(Gogo*, Named_object*, Block*, Statement_inserter*);
|
||||
|
||||
Bstatement*
|
||||
do_get_backend(Translate_context*);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue