Skip to content

Commit 759a921

Browse files
cuonglmmknyszek
authored andcommitted
[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 golang#49392 Change-Id: Ib7e10f72f818880f550aae5c9f653db463ce29b0 Reviewed-on: https://go-review.googlesource.com/c/go/+/361594 Trust: Cuong Manh Le <[email protected]> Run-TryBot: Cuong Manh Le <[email protected]> TryBot-Result: Go Bot <[email protected]> Reviewed-by: David Chase <[email protected]> Reviewed-on: https://go-review.googlesource.com/c/go/+/361596 TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Keith Randall <[email protected]>
1 parent 0177913 commit 759a921

3 files changed

Lines changed: 82 additions & 0 deletions

File tree

src/cmd/compile/internal/ssa/expand_calls.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -952,6 +952,7 @@ func (x *expandState) storeArgOrLoad(pos src.XPos, b *Block, source, mem *Value,
952952
return x.storeArgOrLoad(pos, b, source, mem, t, storeOffset, loadRegOffset, storeRc)
953953
}
954954
eltRO := x.regWidth(elt)
955+
source.Type = t
955956
for i := int64(0); i < t.NumElem(); i++ {
956957
sel := source.Block.NewValue1I(pos, OpArraySelect, elt, i, source)
957958
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,
985986
return x.storeArgOrLoad(pos, b, source, mem, t, storeOffset, loadRegOffset, storeRc)
986987
}
987988

989+
source.Type = t
988990
for i := 0; i < t.NumFields(); i++ {
989991
fld := t.Field(i)
990992
sel := source.Block.NewValue1I(pos, OpStructSelect, fld.Type, int64(i), source)

test/fixedbugs/issue49249.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// compile -l
2+
3+
// Copyright 2021 The Go Authors. All rights reserved.
4+
// Use of this source code is governed by a BSD-style
5+
// license that can be found in the LICENSE file.
6+
7+
package p
8+
9+
func f() int {
10+
var a, b struct {
11+
s struct {
12+
s struct {
13+
byte
14+
float32
15+
}
16+
}
17+
}
18+
_ = a
19+
20+
return func() int {
21+
return func() int {
22+
a = struct {
23+
s struct {
24+
s struct {
25+
byte
26+
float32
27+
}
28+
}
29+
}{b.s}
30+
return 0
31+
}()
32+
}()
33+
}
34+
35+
func g() int {
36+
var a, b struct {
37+
s [1][1]struct {
38+
byte
39+
float32
40+
}
41+
}
42+
_ = a
43+
44+
return func() int {
45+
return func() int {
46+
a = struct {
47+
s [1][1]struct {
48+
byte
49+
float32
50+
}
51+
}{b.s}
52+
return 0
53+
}()
54+
}()
55+
}

test/fixedbugs/issue49378.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// compile
2+
3+
// Copyright 2021 The Go Authors. All rights reserved.
4+
// Use of this source code is governed by a BSD-style
5+
// license that can be found in the LICENSE file.
6+
7+
package p
8+
9+
func f(i int) {
10+
var s1 struct {
11+
s struct{ s struct{ i int } }
12+
}
13+
var s2, s3 struct {
14+
a struct{ i int }
15+
b int
16+
}
17+
func() {
18+
i = 1 + 2*i + s3.a.i + func() int {
19+
s2.a, s2.b = s3.a, s3.b
20+
return 0
21+
}() + func(*int) int {
22+
return s1.s.s.i
23+
}(new(int))
24+
}()
25+
}

0 commit comments

Comments
 (0)