Fix select { case v, ok := <-c: }.
From-SVN: r180992
This commit is contained in:
parent
cf9e9959d1
commit
95ac3b7ad0
2 changed files with 49 additions and 4 deletions
|
@ -4559,10 +4559,26 @@ Select_clauses::Select_clause::lower(Gogo* gogo, Named_object* function,
|
|||
loc);
|
||||
Statement* s = Statement::make_tuple_receive_assignment(val, closed, ref,
|
||||
true, loc);
|
||||
|
||||
// We have to put S in STATEMENTS_, because that is where the
|
||||
// variables are declared.
|
||||
|
||||
go_assert(this->statements_ != NULL);
|
||||
this->statements_->add_statement_at_front(s);
|
||||
|
||||
// Skip the variable declaration statements themselves.
|
||||
size_t skip = 1;
|
||||
if (this->var_ != NULL)
|
||||
skip = 2;
|
||||
|
||||
// Verify that we are only skipping variable declarations.
|
||||
size_t i = 0;
|
||||
for (Block::iterator p = this->statements_->begin();
|
||||
i < skip && p != this->statements_->end();
|
||||
++p, ++i)
|
||||
go_assert((*p)->variable_declaration_statement() != NULL);
|
||||
|
||||
this->statements_->insert_statement_before(skip, s);
|
||||
|
||||
// We have to lower STATEMENTS_ again, to lower the tuple
|
||||
// receive assignment we just added.
|
||||
gogo->lower_block(function, this->statements_);
|
||||
|
@ -4655,7 +4671,8 @@ Select_clauses::Select_clause::dump_clause(
|
|||
{
|
||||
ast_dump_context->dump_expression(this->channel_);
|
||||
ast_dump_context->ostream() << " <- " ;
|
||||
ast_dump_context->dump_expression(this->val_);
|
||||
if (this->val_ != NULL)
|
||||
ast_dump_context->dump_expression(this->val_);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -4667,8 +4684,7 @@ Select_clauses::Select_clause::dump_clause(
|
|||
ast_dump_context->ostream() << " , " ;
|
||||
ast_dump_context->dump_expression(this->closed_);
|
||||
}
|
||||
if (this->closedvar_ != NULL ||
|
||||
this->var_ != NULL)
|
||||
if (this->closedvar_ != NULL || this->var_ != NULL)
|
||||
ast_dump_context->ostream() << " := " ;
|
||||
|
||||
ast_dump_context->ostream() << " <- " ;
|
||||
|
|
|
@ -11,6 +11,10 @@
|
|||
|
||||
package main
|
||||
|
||||
import "os"
|
||||
|
||||
var failed bool
|
||||
|
||||
type Chan interface {
|
||||
Send(int)
|
||||
Nbsend(int) bool
|
||||
|
@ -225,19 +229,23 @@ func test1(c Chan) {
|
|||
// recv a close signal (a zero value)
|
||||
if x := c.Recv(); x != 0 {
|
||||
println("test1: recv on closed:", x, c.Impl())
|
||||
failed = true
|
||||
}
|
||||
if x, ok := c.Recv2(); x != 0 || ok {
|
||||
println("test1: recv2 on closed:", x, ok, c.Impl())
|
||||
failed = true
|
||||
}
|
||||
|
||||
// should work with select: received a value without blocking, so selected == true.
|
||||
x, selected := c.Nbrecv()
|
||||
if x != 0 || !selected {
|
||||
println("test1: recv on closed nb:", x, selected, c.Impl())
|
||||
failed = true
|
||||
}
|
||||
x, ok, selected := c.Nbrecv2()
|
||||
if x != 0 || ok || !selected {
|
||||
println("test1: recv2 on closed nb:", x, ok, selected, c.Impl())
|
||||
failed = true
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -247,12 +255,14 @@ func test1(c Chan) {
|
|||
// the value should have been discarded.
|
||||
if x := c.Recv(); x != 0 {
|
||||
println("test1: recv on closed got non-zero after send on closed:", x, c.Impl())
|
||||
failed = true
|
||||
}
|
||||
|
||||
// similarly Send.
|
||||
shouldPanic(func() { c.Send(2) })
|
||||
if x := c.Recv(); x != 0 {
|
||||
println("test1: recv on closed got non-zero after send on closed:", x, c.Impl())
|
||||
failed = true
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -260,6 +270,7 @@ func testasync1(c Chan) {
|
|||
// should be able to get the last value via Recv
|
||||
if x := c.Recv(); x != 1 {
|
||||
println("testasync1: Recv did not get 1:", x, c.Impl())
|
||||
failed = true
|
||||
}
|
||||
|
||||
test1(c)
|
||||
|
@ -269,6 +280,7 @@ func testasync2(c Chan) {
|
|||
// should be able to get the last value via Recv2
|
||||
if x, ok := c.Recv2(); x != 1 || !ok {
|
||||
println("testasync1: Recv did not get 1, true:", x, ok, c.Impl())
|
||||
failed = true
|
||||
}
|
||||
|
||||
test1(c)
|
||||
|
@ -278,6 +290,7 @@ func testasync3(c Chan) {
|
|||
// should be able to get the last value via Nbrecv
|
||||
if x, selected := c.Nbrecv(); x != 1 || !selected {
|
||||
println("testasync2: Nbrecv did not get 1, true:", x, selected, c.Impl())
|
||||
failed = true
|
||||
}
|
||||
|
||||
test1(c)
|
||||
|
@ -287,6 +300,7 @@ func testasync4(c Chan) {
|
|||
// should be able to get the last value via Nbrecv2
|
||||
if x, ok, selected := c.Nbrecv2(); x != 1 || !ok || !selected {
|
||||
println("testasync2: Nbrecv did not get 1, true, true:", x, ok, selected, c.Impl())
|
||||
failed = true
|
||||
}
|
||||
test1(c)
|
||||
}
|
||||
|
@ -327,4 +341,19 @@ func main() {
|
|||
testclosed(mk(closedasync()))
|
||||
}
|
||||
}
|
||||
|
||||
var ch chan int
|
||||
shouldPanic(func() {
|
||||
close(ch)
|
||||
})
|
||||
|
||||
ch = make(chan int)
|
||||
close(ch)
|
||||
shouldPanic(func() {
|
||||
close(ch)
|
||||
})
|
||||
|
||||
if failed {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue