Skip to content

Commit

Permalink
reflect: panic on recv channel close
Browse files Browse the repository at this point in the history
It is possible to call reflect.ValueOf(ch).Close() on a recv-only channel,
 while close(ch) is a compile-time error. Following the same reflect
semantics as send and recv this should result in a panic.

Fixes #61445

Change-Id: I2a9ee8f45963593a37bd6df4643dd64fb322f9f9
GitHub-Last-Rev: fe2d5e0
GitHub-Pull-Request: #61453
Reviewed-on: https://go-review.googlesource.com/c/go/+/511295
Auto-Submit: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Ian Lance Taylor <iant@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
  • Loading branch information
mauri870 authored and gopherbot committed Jul 21, 2023
1 parent b104a0e commit f2d709b
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 1 deletion.
6 changes: 6 additions & 0 deletions src/reflect/all_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1706,6 +1706,12 @@ func TestChan(t *testing.T) {
if i, ok := cv.Recv(); i.Int() != 0 || ok {
t.Errorf("after close Recv %d, %t", i.Int(), ok)
}
// Closing a read-only channel
shouldPanic("", func() {
c := make(<-chan int, 1)
cv := ValueOf(c)
cv.Close()
})
}

// check creation of unbuffered channel
Expand Down
8 changes: 7 additions & 1 deletion src/reflect/value.go
Original file line number Diff line number Diff line change
Expand Up @@ -1187,10 +1187,16 @@ func (v Value) capNonSlice() int {
}

// Close closes the channel v.
// It panics if v's Kind is not Chan.
// It panics if v's Kind is not Chan or
// v is a receive-only channel.
func (v Value) Close() {
v.mustBe(Chan)
v.mustBeExported()
tt := (*chanType)(unsafe.Pointer(v.typ()))
if ChanDir(tt.Dir)&SendDir == 0 {
panic("reflect: close of receive-only channel")
}

chanclose(v.pointer())
}

Expand Down

0 comments on commit f2d709b

Please sign in to comment.