This patch to the Go frontend fixes the case where a select clause sets
a map index.  For a map index we need to know whether it is an lvalue or
not, and the code forgot to set that.  This patch also fixes the parsing
of a select clause for a case like
        case v := <- r
when there are no statements.

Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu.
Committed to mainline.

Ian

diff -r e26f717e0ff5 go/parse.cc
--- a/go/parse.cc	Mon Mar 28 16:52:26 2011 -0700
+++ b/go/parse.cc	Tue Mar 29 11:51:29 2011 -0700
@@ -4274,41 +4274,43 @@
   bool got_case = this->comm_case(&is_send, &channel, &val, &closed,
 				  &varname, &closedname, &is_default);
 
+  if (!is_send
+      && varname.empty()
+      && closedname.empty()
+      && val != NULL
+      && val->index_expression() != NULL)
+    val->index_expression()->set_is_lvalue();
+
   if (this->peek_token()->is_op(OPERATOR_COLON))
     this->advance_token();
   else
     error_at(this->location(), "expected colon");
 
-  Block* statements = NULL;
+  this->gogo_->start_block(this->location());
+
   Named_object* var = NULL;
+  if (!varname.empty())
+    {
+      // FIXME: LOCATION is slightly wrong here.
+      Variable* v = new Variable(NULL, channel, false, false, false,
+				 location);
+      v->set_type_from_chan_element();
+      var = this->gogo_->add_variable(varname, v);
+    }
+
   Named_object* closedvar = NULL;
-  if (this->peek_token()->is_op(OPERATOR_SEMICOLON))
-    this->advance_token();
-  else if (this->statement_list_may_start_here())
+  if (!closedname.empty())
     {
-      this->gogo_->start_block(this->location());
-
-      if (!varname.empty())
-	{
-	  // FIXME: LOCATION is slightly wrong here.
-	  Variable* v = new Variable(NULL, channel, false, false, false,
-				     location);
-	  v->set_type_from_chan_element();
-	  var = this->gogo_->add_variable(varname, v);
-	}
-
-      if (!closedname.empty())
-	{
-	  // FIXME: LOCATION is slightly wrong here.
-	  Variable* v = new Variable(Type::lookup_bool_type(), NULL,
-				     false, false, false, location);
-	  closedvar = this->gogo_->add_variable(closedname, v);
-	}
-
-      this->statement_list();
-      statements = this->gogo_->finish_block(this->location());
+      // FIXME: LOCATION is slightly wrong here.
+      Variable* v = new Variable(Type::lookup_bool_type(), NULL,
+				 false, false, false, location);
+      closedvar = this->gogo_->add_variable(closedname, v);
     }
 
+  this->statement_list();
+
+  Block* statements = this->gogo_->finish_block(this->location());
+
   if (is_default)
     {
       if (*saw_default)

Reply via email to