mirror of
https://github.com/golang/go
synced 2024-11-21 14:34:41 -07:00
gc: disallow close on receive-only channels
Fixes #2353. Fixes #2246. R=golang-dev, r, gri CC=golang-dev https://golang.org/cl/5282042
This commit is contained in:
parent
d65aaf24a6
commit
f58ed4e641
@ -4531,12 +4531,13 @@ BuiltinArgs = Type [ "," ExpressionList ] | ExpressionList .
|
||||
|
||||
<p>
|
||||
For a channel <code>c</code>, the built-in function <code>close(c)</code>
|
||||
marks the channel as unable to accept more values through a send operation;
|
||||
sending to or closing a closed channel causes a <a href="#Run_time_panics">run-time panic</a>.
|
||||
records that no more values will be sent on the channel.
|
||||
It is an error if <code>c</code> is a receive-only channel.
|
||||
Sending to or closing a closed channel causes a <a href="#Run_time_panics">run-time panic</a>.
|
||||
Closing the nil channel also causes a <a href="#Run_time_panics">run-time panic</a>.
|
||||
After calling <code>close</code>, and after any previously
|
||||
sent values have been received, receive operations will return
|
||||
the zero value for the channel's type without blocking.
|
||||
|
||||
The multi-valued <a href="#Receive_operator">receive operation</a>
|
||||
returns a received value along with an indication of whether the channel is closed.
|
||||
</p>
|
||||
|
@ -984,6 +984,10 @@ reswitch:
|
||||
yyerror("invalid operation: %#N (non-chan type %T)", n, t);
|
||||
goto error;
|
||||
}
|
||||
if(!(t->chan & Csend)) {
|
||||
yyerror("invalid operation: %#N (cannot close receive-only channel)", n);
|
||||
goto error;
|
||||
}
|
||||
ok |= Etop;
|
||||
goto ret;
|
||||
|
||||
|
@ -1052,6 +1052,9 @@ runtime·closechan(Hchan *c)
|
||||
SudoG *sg;
|
||||
G* gp;
|
||||
|
||||
if(c == nil)
|
||||
runtime·panicstring("close of nil channel");
|
||||
|
||||
if(runtime·gcwaiting)
|
||||
runtime·gosched();
|
||||
|
||||
|
@ -48,4 +48,8 @@ func main() {
|
||||
case x := <-cs: // ERROR "receive"
|
||||
_ = x
|
||||
}
|
||||
|
||||
close(c)
|
||||
close(cs)
|
||||
close(cr) // ERROR "receive"
|
||||
}
|
||||
|
@ -327,4 +327,15 @@ func main() {
|
||||
testclosed(mk(closedasync()))
|
||||
}
|
||||
}
|
||||
|
||||
var ch chan int
|
||||
shouldPanic(func() {
|
||||
close(ch)
|
||||
})
|
||||
|
||||
ch = make(chan int)
|
||||
close(ch)
|
||||
shouldPanic(func() {
|
||||
close(ch)
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user