From: Ian Lance Taylor Date: Mon, 5 Feb 2018 01:40:51 +0000 (+0000) Subject: compiler: correct parse of parenthesized select case X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=6ac0aed81501d236ed456b54a85684ac03dde713;p=gcc.git 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 --- diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index 9cf3b14e31a..257ca95199e 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 8162abf342b..86d3510475e 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: