go/test/fixedbugs/issue63657.go
Keith Randall 962ccbef91 cmd/compile: ensure pointer arithmetic happens after the nil check
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>
2023-10-31 20:45:54 +00:00

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