diff options
author | Than McIntosh <thanm@google.com> | 2021-05-21 10:53:10 -0400 |
---|---|---|
committer | Than McIntosh <thanm@google.com> | 2021-05-22 00:51:17 +0000 |
commit | cca23a73733ff166722c69359f0bb45e12ccaa2b (patch) | |
tree | 58538e226710c181249112dbbed060f3c7f91ac2 /test | |
parent | f87194cbd7e79eef07c897a6240fbf2dc115f9ff (diff) | |
download | go-cca23a73733ff166722c69359f0bb45e12ccaa2b.tar.gz go-cca23a73733ff166722c69359f0bb45e12ccaa2b.zip |
cmd/compile: revert CL/316890
This is a revert of https://go-review.googlesource.com/c/go/+/316890,
which has positive effects on debugging + DWARF variable locations
for register parameters when the reg abi is in effect, but also
turns out to interact badly with the register allocator.
Fixes #46304.
Change-Id: I624bd980493411a9cde45d44fcd3c46cad796909
Reviewed-on: https://go-review.googlesource.com/c/go/+/321830
Trust: Than McIntosh <thanm@google.com>
Run-TryBot: Than McIntosh <thanm@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Diffstat (limited to 'test')
-rw-r--r-- | test/fixedbugs/issue46304.go | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/test/fixedbugs/issue46304.go b/test/fixedbugs/issue46304.go new file mode 100644 index 0000000000..b8ecfc93a5 --- /dev/null +++ b/test/fixedbugs/issue46304.go @@ -0,0 +1,76 @@ +// run + +// Copyright 2021 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. + +// This testcase caused a crash when the register ABI was in effect, +// on amd64 (problem with register allocation). + +package main + +type Op struct { + tag string + _x []string + _q [20]uint64 + plist []P +} + +type P struct { + tag string + _x [10]uint64 + b bool +} + +type M int + +//go:noinline +func (w *M) walkP(p *P) *P { + np := &P{} + *np = *p + np.tag += "new" + return np +} + +func (w *M) walkOp(op *Op) *Op { + if op == nil { + return nil + } + + orig := op + cloned := false + clone := func() { + if !cloned { + cloned = true + op = &Op{} + *op = *orig + } + } + + pCloned := false + for i := range op.plist { + if s := w.walkP(&op.plist[i]); s != &op.plist[i] { + if !pCloned { + pCloned = true + clone() + op.plist = make([]P, len(orig.plist)) + copy(op.plist, orig.plist) + } + op.plist[i] = *s + } + } + + return op +} + +func main() { + var ww M + w := &ww + p1 := P{tag: "a"} + p1._x[1] = 9 + o := Op{tag: "old", plist: []P{p1}} + no := w.walkOp(&o) + if no.plist[0].tag != "anew" { + panic("bad") + } +} |