From 6ac0aed81501d236ed456b54a85684ac03dde713 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Mon, 5 Feb 2018 01:40:51 +0000 Subject: [PATCH] compiler: correct parse of parenthesized select case We used to mishandle `select { case (<-c): }` and friends. The test case for this is https://golang.org/cl/91657. Fixes golang/go#20923 Reviewed-on: https://go-review.googlesource.com/91695 From-SVN: r257374 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/parse.cc | 26 ++++++++++++++++++++------ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 9cf3b14..257ca95 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -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. diff --git a/gcc/go/gofrontend/parse.cc b/gcc/go/gofrontend/parse.cc index 8162abf..86d3510 100644 --- a/gcc/go/gofrontend/parse.cc +++ b/gcc/go/gofrontend/parse.cc @@ -5160,7 +5160,18 @@ Parse::send_or_recv_stmt(bool* is_send, Expression** channel, Expression** val, 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, Expression** channel, Expression** val, 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: -- 2.7.4