From: Ian Lance Taylor Date: Wed, 10 Dec 2014 20:38:13 +0000 (+0000) Subject: re PR go/61316 (gccgo: spurious "incompatible types in assignment" error [GoSmith]) X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c44f74e4cb760a204865655d2abc80276d7b6c4e;p=gcc.git 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 --- diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc index 0916adc3f3e..4d07c223b34 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -8525,6 +8525,7 @@ Call_expression::do_lower(Gogo* gogo, Named_object* function, || fntype->is_builtin())) { Call_expression* call = this->args_->front()->call_expression(); + call->set_is_multi_value_arg(); Expression_list* args = new Expression_list; for (size_t i = 0; i < rc; ++i) args->push_back(Expression::make_call_result(call, i)); diff --git a/gcc/go/gofrontend/expressions.h b/gcc/go/gofrontend/expressions.h index d96df28bbc1..398709ee386 100644 --- a/gcc/go/gofrontend/expressions.h +++ b/gcc/go/gofrontend/expressions.h @@ -1632,7 +1632,7 @@ class Call_expression : public Expression fn_(fn), args_(args), type_(NULL), results_(NULL), call_(NULL), call_temp_(NULL), expected_result_count_(0), is_varargs_(is_varargs), 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. @@ -1703,6 +1703,17 @@ class Call_expression : public Expression bool 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: int do_traverse(Traverse*); @@ -1806,6 +1817,8 @@ class Call_expression : public Expression // results and uses. This is to avoid producing multiple errors // when there are multiple Call_result_expressions. 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. diff --git a/gcc/go/gofrontend/statements.cc b/gcc/go/gofrontend/statements.cc index 57d7f9da91c..5b8c2e73fc7 100644 --- a/gcc/go/gofrontend/statements.cc +++ b/gcc/go/gofrontend/statements.cc @@ -726,6 +726,17 @@ Move_ordered_evals::expression(Expression** pexpr) 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(); Temporary_statement* temp = Statement::make_temporary(NULL, *pexpr, loc); this->block_->add_statement(temp);