This patch to the Go frontend corrects parsing of parenthesized select cases. The frontend used to mishandle `select { case (<-c): }` and friends. The test case for this is https://golang.org/cl/91657. This fixes https://golang.org/issue/20923. Bootstrapped and ran Go testsuite on x86_64-pc-linux-gnu. Committed to mainline.
Ian
Index: gcc/go/gofrontend/MERGE =================================================================== --- gcc/go/gofrontend/MERGE (revision 257373) +++ gcc/go/gofrontend/MERGE (working copy) @@ -1,4 +1,4 @@ -9057b8f71e6078f140938fe60be9aaa7d59a3a2b +2f7ac42a3f83b78d97912ce1e86296b2af4f52b7 The first line of this file holds the git revision number of the last merge done from the gofrontend repository. Index: gcc/go/gofrontend/parse.cc =================================================================== --- gcc/go/gofrontend/parse.cc (revision 257357) +++ gcc/go/gofrontend/parse.cc (working copy) @@ -5160,7 +5160,18 @@ Parse::send_or_recv_stmt(bool* is_send, Expression* e; if (saw_comma || !this->peek_token()->is_op(OPERATOR_CHANOP)) - e = this->expression(PRECEDENCE_NORMAL, true, true, NULL, NULL); + { + e = this->expression(PRECEDENCE_NORMAL, true, true, NULL, NULL); + if (e->receive_expression() != NULL) + { + *is_send = false; + *channel = e->receive_expression()->channel(); + // This is 'case (<-c):'. We now expect ':'. If we see + // '<-', then we have case (<-c)<-v: + if (!this->peek_token()->is_op(OPERATOR_CHANOP)) + return true; + } + } else { // case <-c: @@ -5189,14 +5200,17 @@ Parse::send_or_recv_stmt(bool* is_send, if (this->peek_token()->is_op(OPERATOR_EQ)) { - if (!this->advance_token()->is_op(OPERATOR_CHANOP)) + *is_send = false; + this->advance_token(); + Location recvloc = this->location(); + Expression* recvexpr = this->expression(PRECEDENCE_NORMAL, false, + true, NULL, NULL); + if (recvexpr->receive_expression() == NULL) { - go_error_at(this->location(), "missing %<<-%>"); + go_error_at(recvloc, "missing %<<-%>"); return false; } - *is_send = false; - this->advance_token(); - *channel = this->expression(PRECEDENCE_NORMAL, false, true, NULL, NULL); + *channel = recvexpr->receive_expression()->channel(); if (saw_comma) { // case v, e = <-c: