mirror of
https://github.com/golang/go
synced 2024-11-25 14:27:57 -07:00
962ccbef91
Have nil checks return a pointer that is known non-nil. Users of that pointer can use the result, ensuring that they are ordered after the nil check itself. The order dependence goes away after scheduling, when we've fixed an order. At that point we move uses back to the original pointer so it doesn't change regalloc any. This prevents pointer arithmetic on nil from being spilled to the stack and then observed by a stack scan. Fixes #63657 Change-Id: I1a5fa4f2e6d9000d672792b4f90dfc1b7b67f6ea Reviewed-on: https://go-review.googlesource.com/c/go/+/537775 Reviewed-by: David Chase <drchase@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Keith Randall <khr@google.com>
49 lines
677 B
Go
49 lines
677 B
Go
// run
|
|
|
|
// Copyright 2023 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// Make sure address calculations don't float up before
|
|
// the corresponding nil check.
|
|
|
|
package main
|
|
|
|
type T struct {
|
|
a, b int
|
|
}
|
|
|
|
//go:noinline
|
|
func f(x *T, p *bool, n int) {
|
|
*p = n != 0
|
|
useStack(1000)
|
|
g(&x.b)
|
|
}
|
|
|
|
//go:noinline
|
|
func g(p *int) {
|
|
}
|
|
|
|
func useStack(n int) {
|
|
if n == 0 {
|
|
return
|
|
}
|
|
useStack(n - 1)
|
|
}
|
|
|
|
func main() {
|
|
mustPanic(func() {
|
|
var b bool
|
|
f(nil, &b, 3)
|
|
})
|
|
}
|
|
|
|
func mustPanic(f func()) {
|
|
defer func() {
|
|
if recover() == nil {
|
|
panic("expected panic, got nil")
|
|
}
|
|
}()
|
|
f()
|
|
}
|