aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorDavid Chase <drchase@google.com>2021-04-23 21:49:08 -0400
committerDavid Chase <drchase@google.com>2021-05-03 17:46:12 +0000
commit90ec25773523ac2c5e075f1e5d7519ee08201b8c (patch)
tree769352c6a7649417f79259c29b2aef5bc1769ea0 /test
parentb5842308892e0c4f9e772a42d5826f6f62f57be3 (diff)
downloadgo-90ec25773523ac2c5e075f1e5d7519ee08201b8c.tar.gz
go-90ec25773523ac2c5e075f1e5d7519ee08201b8c.zip
cmd/compile: make the stack allocator more careful about register args.
Assignment between input parameters causes them to have more than one "Name", and running this backwards from names to values can end up confusing (conflating) parameter spill slots. Around 105a6e9518, this cases a stack overflow running go test -race encoding/pem because two slice parameters spill (incorrectly) into the same stack slots (in the AB?I-defined parameter spill area). This also tickles a failure in cue, which turned out to be easier to isolate. Fixes #45851. Updates #40724. Change-Id: I39c56815bd6abb652f1ccbe83c47f4f373a125c3 Reviewed-on: https://go-review.googlesource.com/c/go/+/313212 Trust: David Chase <drchase@google.com> Run-TryBot: David Chase <drchase@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
Diffstat (limited to 'test')
-rw-r--r--test/fixedbugs/issue45851.go68
1 files changed, 68 insertions, 0 deletions
diff --git a/test/fixedbugs/issue45851.go b/test/fixedbugs/issue45851.go
new file mode 100644
index 0000000000..b137071e4f
--- /dev/null
+++ b/test/fixedbugs/issue45851.go
@@ -0,0 +1,68 @@
+// 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 tickles a stack-allocation bug when the register ABI is enabled.
+// The original report was from cue, internal/core/adt/equality.go,
+// function equalVertex.
+
+// In the failing case, something bad gets passed to equalTerminal.
+
+package main
+
+import "fmt"
+
+type Kind uint16
+type Flag uint16
+
+const (
+ allKinds Kind = 1
+ TopKind Kind = (allKinds - 1)
+)
+type Value interface {
+ Kind() Kind
+}
+type Vertex struct {
+ BaseValue Value
+ name string
+}
+func (v *Vertex) Kind() Kind {
+ return TopKind
+}
+
+func main() {
+ vA := &Vertex{name:"vA",}
+ vB := &Vertex{name:"vB",}
+ vX := &Vertex{name:"vX",}
+ vA.BaseValue = vX
+ vB.BaseValue = vX
+ _ = equalVertex(vA, vB, Flag(1))
+}
+
+var foo string
+
+//go:noinline
+func (v *Vertex) IsClosedStruct() bool {
+ return true
+}
+
+func equalVertex(x *Vertex, v Value, flags Flag) bool {
+ y, ok := v.(*Vertex)
+ if !ok {
+ return false
+ }
+ v, ok1 := x.BaseValue.(Value)
+ w, ok2 := y.BaseValue.(Value)
+ if !ok1 && !ok2 {
+ return true // both are struct or list.
+ }
+ return equalTerminal(v, w, flags)
+}
+
+//go:noinline
+func equalTerminal(x Value, y Value, flags Flag) bool {
+ foo = fmt.Sprintf("EQclosed %s %s %d\n", x.(*Vertex).name, y.(*Vertex).name, flags)
+ return true
+}