mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-22 23:39:57 +08:00
re PR go/61316 (gccgo: spurious "incompatible types in assignment" error [GoSmith])
PR go/61316 compiler: Don't lower multi-valued arguments into temporaries. From-SVN: r218606
This commit is contained in:
parent
1b457aa45d
commit
c44f74e4cb
@ -8525,6 +8525,7 @@ Call_expression::do_lower(Gogo* gogo, Named_object* function,
|
|||||||
|| fntype->is_builtin()))
|
|| fntype->is_builtin()))
|
||||||
{
|
{
|
||||||
Call_expression* call = this->args_->front()->call_expression();
|
Call_expression* call = this->args_->front()->call_expression();
|
||||||
|
call->set_is_multi_value_arg();
|
||||||
Expression_list* args = new Expression_list;
|
Expression_list* args = new Expression_list;
|
||||||
for (size_t i = 0; i < rc; ++i)
|
for (size_t i = 0; i < rc; ++i)
|
||||||
args->push_back(Expression::make_call_result(call, i));
|
args->push_back(Expression::make_call_result(call, i));
|
||||||
|
@ -1632,7 +1632,7 @@ class Call_expression : public Expression
|
|||||||
fn_(fn), args_(args), type_(NULL), results_(NULL), call_(NULL),
|
fn_(fn), args_(args), type_(NULL), results_(NULL), call_(NULL),
|
||||||
call_temp_(NULL), expected_result_count_(0), is_varargs_(is_varargs),
|
call_temp_(NULL), expected_result_count_(0), is_varargs_(is_varargs),
|
||||||
varargs_are_lowered_(false), types_are_determined_(false),
|
varargs_are_lowered_(false), types_are_determined_(false),
|
||||||
is_deferred_(false), issued_error_(false)
|
is_deferred_(false), issued_error_(false), is_multi_value_arg_(false)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
// The function to call.
|
// The function to call.
|
||||||
@ -1703,6 +1703,17 @@ class Call_expression : public Expression
|
|||||||
bool
|
bool
|
||||||
issue_error();
|
issue_error();
|
||||||
|
|
||||||
|
// Whether this call returns multiple results that are used as an
|
||||||
|
// multi-valued argument.
|
||||||
|
bool
|
||||||
|
is_multi_value_arg() const
|
||||||
|
{ return this->is_multi_value_arg_; }
|
||||||
|
|
||||||
|
// Note this call is used as a multi-valued argument.
|
||||||
|
void
|
||||||
|
set_is_multi_value_arg()
|
||||||
|
{ this->is_multi_value_arg_ = true; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int
|
int
|
||||||
do_traverse(Traverse*);
|
do_traverse(Traverse*);
|
||||||
@ -1806,6 +1817,8 @@ class Call_expression : public Expression
|
|||||||
// results and uses. This is to avoid producing multiple errors
|
// results and uses. This is to avoid producing multiple errors
|
||||||
// when there are multiple Call_result_expressions.
|
// when there are multiple Call_result_expressions.
|
||||||
bool issued_error_;
|
bool issued_error_;
|
||||||
|
// True if this call is used as an argument that returns multiple results.
|
||||||
|
bool is_multi_value_arg_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// An expression which represents a pointer to a function.
|
// An expression which represents a pointer to a function.
|
||||||
|
@ -726,6 +726,17 @@ Move_ordered_evals::expression(Expression** pexpr)
|
|||||||
|
|
||||||
if ((*pexpr)->must_eval_in_order())
|
if ((*pexpr)->must_eval_in_order())
|
||||||
{
|
{
|
||||||
|
Call_expression* call = (*pexpr)->call_expression();
|
||||||
|
if (call != NULL && call->is_multi_value_arg())
|
||||||
|
{
|
||||||
|
// A call expression which returns multiple results as an argument
|
||||||
|
// to another call must be handled specially. We can't create a
|
||||||
|
// temporary because there is no type to give it. Instead, group
|
||||||
|
// the caller and this multi-valued call argument and use a temporary
|
||||||
|
// variable to hold them.
|
||||||
|
return TRAVERSE_SKIP_COMPONENTS;
|
||||||
|
}
|
||||||
|
|
||||||
Location loc = (*pexpr)->location();
|
Location loc = (*pexpr)->location();
|
||||||
Temporary_statement* temp = Statement::make_temporary(NULL, *pexpr, loc);
|
Temporary_statement* temp = Statement::make_temporary(NULL, *pexpr, loc);
|
||||||
this->block_->add_statement(temp);
|
this->block_->add_statement(temp);
|
||||||
|
Loading…
Reference in New Issue
Block a user