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:

Reply via email to