diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2018-02-05 01:40:51 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2018-02-05 01:40:51 +0000 |
commit | 6ac0aed81501d236ed456b54a85684ac03dde713 (patch) | |
tree | 66c3dca0610f5d50be8c2f5de46c6000fa5fd5a3 /gcc/go/gofrontend/parse.cc | |
parent | 59597e373547a60ee635083f06ef322f8537f7c0 (diff) | |
download | gcc-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.cc | 26 |
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: |