aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCuong Manh Le <cuong.manhle.vn@gmail.com>2021-11-05 20:30:38 +0700
committerMichael Knyszek <mknyszek@google.com>2021-12-02 17:52:07 +0000
commit759a9211d4e3d3eace3125e8a55d7fca1c94dcc6 (patch)
tree819018bd250f0a40d640e33e6f5b704945fdfeee
parent01779135c09ac4c2ba0d0bc7b3ae0889ad9ad989 (diff)
downloadgo-759a9211d4e3d3eace3125e8a55d7fca1c94dcc6.tar.gz
go-759a9211d4e3d3eace3125e8a55d7fca1c94dcc6.zip
[release-branch.go1.17] cmd/compile: only update source type when processing struct/array
This is backport of CL 3651594, with the test from CL 360057. CL 360057 fixed missing update source type in storeArgOrLoad. However, we should only update the type when processing struct/array. If we update the type right before calling storeArgOrLoad, we may generate a value with invalid type, e.g, OpStructSelect with non-struct type. Fixes #49392 Change-Id: Ib7e10f72f818880f550aae5c9f653db463ce29b0 Reviewed-on: https://go-review.googlesource.com/c/go/+/361594 Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com> Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com> Reviewed-on: https://go-review.googlesource.com/c/go/+/361596 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
-rw-r--r--src/cmd/compile/internal/ssa/expand_calls.go2
-rw-r--r--test/fixedbugs/issue49249.go55
-rw-r--r--test/fixedbugs/issue49378.go25
3 files changed, 82 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/ssa/expand_calls.go b/src/cmd/compile/internal/ssa/expand_calls.go
index 7e973ab205..0c4a7fba4d 100644
--- a/src/cmd/compile/internal/ssa/expand_calls.go
+++ b/src/cmd/compile/internal/ssa/expand_calls.go
@@ -952,6 +952,7 @@ func (x *expandState) storeArgOrLoad(pos src.XPos, b *Block, source, mem *Value,
return x.storeArgOrLoad(pos, b, source, mem, t, storeOffset, loadRegOffset, storeRc)
}
eltRO := x.regWidth(elt)
+ source.Type = t
for i := int64(0); i < t.NumElem(); i++ {
sel := source.Block.NewValue1I(pos, OpArraySelect, elt, i, source)
mem = x.storeArgOrLoad(pos, b, sel, mem, elt, storeOffset+i*elt.Width, loadRegOffset, storeRc.at(t, 0))
@@ -985,6 +986,7 @@ func (x *expandState) storeArgOrLoad(pos src.XPos, b *Block, source, mem *Value,
return x.storeArgOrLoad(pos, b, source, mem, t, storeOffset, loadRegOffset, storeRc)
}
+ source.Type = t
for i := 0; i < t.NumFields(); i++ {
fld := t.Field(i)
sel := source.Block.NewValue1I(pos, OpStructSelect, fld.Type, int64(i), source)
diff --git a/test/fixedbugs/issue49249.go b/test/fixedbugs/issue49249.go
new file mode 100644
index 0000000000..f152a5a701
--- /dev/null
+++ b/test/fixedbugs/issue49249.go
@@ -0,0 +1,55 @@
+// compile -l
+
+// 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.
+
+package p
+
+func f() int {
+ var a, b struct {
+ s struct {
+ s struct {
+ byte
+ float32
+ }
+ }
+ }
+ _ = a
+
+ return func() int {
+ return func() int {
+ a = struct {
+ s struct {
+ s struct {
+ byte
+ float32
+ }
+ }
+ }{b.s}
+ return 0
+ }()
+ }()
+}
+
+func g() int {
+ var a, b struct {
+ s [1][1]struct {
+ byte
+ float32
+ }
+ }
+ _ = a
+
+ return func() int {
+ return func() int {
+ a = struct {
+ s [1][1]struct {
+ byte
+ float32
+ }
+ }{b.s}
+ return 0
+ }()
+ }()
+}
diff --git a/test/fixedbugs/issue49378.go b/test/fixedbugs/issue49378.go
new file mode 100644
index 0000000000..70f466c929
--- /dev/null
+++ b/test/fixedbugs/issue49378.go
@@ -0,0 +1,25 @@
+// compile
+
+// 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.
+
+package p
+
+func f(i int) {
+ var s1 struct {
+ s struct{ s struct{ i int } }
+ }
+ var s2, s3 struct {
+ a struct{ i int }
+ b int
+ }
+ func() {
+ i = 1 + 2*i + s3.a.i + func() int {
+ s2.a, s2.b = s3.a, s3.b
+ return 0
+ }() + func(*int) int {
+ return s1.s.s.i
+ }(new(int))
+ }()
+}