The Go language specification permits a general expression in select { case x := <-c: } which basically means that it can look like case x := (<-c): The gccgo parser was failing to handle that case. This patch fixes it. Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu. Committed to mainline.
Ian
diff -r 36a50b3d3a7d go/parse.cc --- a/go/parse.cc Tue Jan 31 16:00:53 2012 -0800 +++ b/go/parse.cc Wed Feb 01 06:26:31 2012 -0800 @@ -4640,9 +4640,14 @@ if (token->is_op(OPERATOR_COLONEQ)) { // case rv := <-c: - if (!this->advance_token()->is_op(OPERATOR_CHANOP)) + this->advance_token(); + Expression* e = this->expression(PRECEDENCE_NORMAL, false, false, + NULL); + Receive_expression* re = e->receive_expression(); + if (re == NULL) { - error_at(this->location(), "expected %<<-%>"); + if (!e->is_error_expression()) + error_at(this->location(), "expected receive expression"); return false; } if (recv_var == "_") @@ -4653,8 +4658,7 @@ } *is_send = false; *varname = gogo->pack_hidden_name(recv_var, is_rv_exported); - this->advance_token(); - *channel = this->expression(PRECEDENCE_NORMAL, false, true, NULL); + *channel = re->channel(); return true; } else if (token->is_op(OPERATOR_COMMA)) @@ -4671,9 +4675,15 @@ if (token->is_op(OPERATOR_COLONEQ)) { // case rv, rc := <-c: - if (!this->advance_token()->is_op(OPERATOR_CHANOP)) + this->advance_token(); + Expression* e = this->expression(PRECEDENCE_NORMAL, false, + false, NULL); + Receive_expression* re = e->receive_expression(); + if (re == NULL) { - error_at(this->location(), "expected %<<-%>"); + if (!e->is_error_expression()) + error_at(this->location(), + "expected receive expression"); return false; } if (recv_var == "_" && recv_closed == "_") @@ -4689,9 +4699,7 @@ if (recv_closed != "_") *closedname = gogo->pack_hidden_name(recv_closed, is_rc_exported); - this->advance_token(); - *channel = this->expression(PRECEDENCE_NORMAL, false, true, - NULL); + *channel = re->channel(); return true; }