aboutsummaryrefslogtreecommitdiff
path: root/gcc/go/gofrontend/parse.cc
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2018-02-05 01:40:51 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2018-02-05 01:40:51 +0000
commit6ac0aed81501d236ed456b54a85684ac03dde713 (patch)
tree66c3dca0610f5d50be8c2f5de46c6000fa5fd5a3 /gcc/go/gofrontend/parse.cc
parent59597e373547a60ee635083f06ef322f8537f7c0 (diff)
downloadgcc-6ac0aed81501d236ed456b54a85684ac03dde713.zip
gcc-6ac0aed81501d236ed456b54a85684ac03dde713.tar.gz
gcc-6ac0aed81501d236ed456b54a85684ac03dde713.tar.bz2
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
Diffstat (limited to 'gcc/go/gofrontend/parse.cc')
-rw-r--r--gcc/go/gofrontend/parse.cc26
1 files changed, 20 insertions, 6 deletions
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: