Skip to content

Commit da38476

Browse files
committed
runtime: make unsafe.Slice usable from nowritebarrierrec
Many compiler-generated panics are dynamically changed to a "throw" when they happen in the runtime. One effect of this is that they are allowed in nowritebarrierrec contexts. Currently, the unsafe.Slice panics don't have this treatment. We're about to expose more code that uses unsafe.Slice to the write barrier checker (it's actually already there and it just can't see through an indirect call), so give these panics the dynamic check. Very indirectly updates #54466. Change-Id: I65cb96fa17eb751041e4fa25a1c1bd03246c82ba Reviewed-on: https://go-review.googlesource.com/c/go/+/468296 TryBot-Result: Gopher Robot <[email protected]> Run-TryBot: Austin Clements <[email protected]> Reviewed-by: Michael Pratt <[email protected]>
1 parent f758d64 commit da38476

File tree

1 file changed

+21
-5
lines changed

1 file changed

+21
-5
lines changed

src/runtime/unsafe.go

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,29 +52,29 @@ func panicunsafestringnilptr() {
5252
// Keep this code in sync with cmd/compile/internal/walk/builtin.go:walkUnsafeSlice
5353
func unsafeslice(et *_type, ptr unsafe.Pointer, len int) {
5454
if len < 0 {
55-
panicunsafeslicelen()
55+
panicunsafeslicelen1(getcallerpc())
5656
}
5757

5858
if et.size == 0 {
5959
if ptr == nil && len > 0 {
60-
panicunsafeslicenilptr()
60+
panicunsafeslicenilptr1(getcallerpc())
6161
}
6262
}
6363

6464
mem, overflow := math.MulUintptr(et.size, uintptr(len))
6565
if overflow || mem > -uintptr(ptr) {
6666
if ptr == nil {
67-
panicunsafeslicenilptr()
67+
panicunsafeslicenilptr1(getcallerpc())
6868
}
69-
panicunsafeslicelen()
69+
panicunsafeslicelen1(getcallerpc())
7070
}
7171
}
7272

7373
// Keep this code in sync with cmd/compile/internal/walk/builtin.go:walkUnsafeSlice
7474
func unsafeslice64(et *_type, ptr unsafe.Pointer, len64 int64) {
7575
len := int(len64)
7676
if int64(len) != len64 {
77-
panicunsafeslicelen()
77+
panicunsafeslicelen1(getcallerpc())
7878
}
7979
unsafeslice(et, ptr, len)
8080
}
@@ -90,9 +90,25 @@ func unsafeslicecheckptr(et *_type, ptr unsafe.Pointer, len64 int64) {
9090
}
9191

9292
func panicunsafeslicelen() {
93+
// This is called only from compiler-generated code, so we can get the
94+
// source of the panic.
95+
panicunsafeslicelen1(getcallerpc())
96+
}
97+
98+
//go:yeswritebarrierrec
99+
func panicunsafeslicelen1(pc uintptr) {
100+
panicCheck1(pc, "unsafe.Slice: len out of range")
93101
panic(errorString("unsafe.Slice: len out of range"))
94102
}
95103

96104
func panicunsafeslicenilptr() {
105+
// This is called only from compiler-generated code, so we can get the
106+
// source of the panic.
107+
panicunsafeslicenilptr1(getcallerpc())
108+
}
109+
110+
//go:yeswritebarrierrec
111+
func panicunsafeslicenilptr1(pc uintptr) {
112+
panicCheck1(pc, "unsafe.Slice: ptr is nil and len is not zero")
97113
panic(errorString("unsafe.Slice: ptr is nil and len is not zero"))
98114
}

0 commit comments

Comments
 (0)