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)