mirror of
https://github.com/golang/go
synced 2024-11-17 17:04:47 -07:00
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 <gobot@golang.org> Run-TryBot: Austin Clements <austin@google.com> Reviewed-by: Michael Pratt <mpratt@google.com>
This commit is contained in:
parent
f758d648b0
commit
da384766a0
@ -52,21 +52,21 @@ func panicunsafestringnilptr() {
|
||||
// Keep this code in sync with cmd/compile/internal/walk/builtin.go:walkUnsafeSlice
|
||||
func unsafeslice(et *_type, ptr unsafe.Pointer, len int) {
|
||||
if len < 0 {
|
||||
panicunsafeslicelen()
|
||||
panicunsafeslicelen1(getcallerpc())
|
||||
}
|
||||
|
||||
if et.size == 0 {
|
||||
if ptr == nil && len > 0 {
|
||||
panicunsafeslicenilptr()
|
||||
panicunsafeslicenilptr1(getcallerpc())
|
||||
}
|
||||
}
|
||||
|
||||
mem, overflow := math.MulUintptr(et.size, uintptr(len))
|
||||
if overflow || mem > -uintptr(ptr) {
|
||||
if ptr == nil {
|
||||
panicunsafeslicenilptr()
|
||||
panicunsafeslicenilptr1(getcallerpc())
|
||||
}
|
||||
panicunsafeslicelen()
|
||||
panicunsafeslicelen1(getcallerpc())
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,7 +74,7 @@ func unsafeslice(et *_type, ptr unsafe.Pointer, len int) {
|
||||
func unsafeslice64(et *_type, ptr unsafe.Pointer, len64 int64) {
|
||||
len := int(len64)
|
||||
if int64(len) != len64 {
|
||||
panicunsafeslicelen()
|
||||
panicunsafeslicelen1(getcallerpc())
|
||||
}
|
||||
unsafeslice(et, ptr, len)
|
||||
}
|
||||
@ -90,9 +90,25 @@ func unsafeslicecheckptr(et *_type, ptr unsafe.Pointer, len64 int64) {
|
||||
}
|
||||
|
||||
func panicunsafeslicelen() {
|
||||
// This is called only from compiler-generated code, so we can get the
|
||||
// source of the panic.
|
||||
panicunsafeslicelen1(getcallerpc())
|
||||
}
|
||||
|
||||
//go:yeswritebarrierrec
|
||||
func panicunsafeslicelen1(pc uintptr) {
|
||||
panicCheck1(pc, "unsafe.Slice: len out of range")
|
||||
panic(errorString("unsafe.Slice: len out of range"))
|
||||
}
|
||||
|
||||
func panicunsafeslicenilptr() {
|
||||
// This is called only from compiler-generated code, so we can get the
|
||||
// source of the panic.
|
||||
panicunsafeslicenilptr1(getcallerpc())
|
||||
}
|
||||
|
||||
//go:yeswritebarrierrec
|
||||
func panicunsafeslicenilptr1(pc uintptr) {
|
||||
panicCheck1(pc, "unsafe.Slice: ptr is nil and len is not zero")
|
||||
panic(errorString("unsafe.Slice: ptr is nil and len is not zero"))
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user