1
0
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:
Russ Cox 2011-10-13 16:58:04 -04:00
parent d65aaf24a6
commit f58ed4e641
5 changed files with 26 additions and 3 deletions

View File

@ -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>

View File

@ -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;

View File

@ -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();

View File

@ -48,4 +48,8 @@ func main() {
case x := <-cs: // ERROR "receive"
_ = x
}
close(c)
close(cs)
close(cr) // ERROR "receive"
}

View File

@ -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)
})
}