diff mbox series

Go patch committed: Correct parse of parenthesized select case

Message ID CAOyqgcWhGCTt8QnZ1DZhK3LC2-5=was0BcM9nr_uD5AJBeUzZQ@mail.gmail.com
State New
Headers show
Series Go patch committed: Correct parse of parenthesized select case | expand

Commit Message

Ian Lance Taylor Feb. 5, 2018, 1:41 a.m. UTC
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
diff mbox series

Patch

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: