Skip to content

Commit 8a12f5d

Browse files
cuonglmmknyszek
authored andcommitted
[release-branch.go1.16] 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 #49391 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/+/361597 TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
1 parent b29e772 commit 8a12f5d

File tree

3 files changed

+82
-0
lines changed

3 files changed

+82
-0
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,7 @@ func expandCalls(f *Func) {
527527
// it could be a leaf type, but the "leaf" could be complex64 (for example)
528528
return storeArgOrLoad(pos, b, base, source, mem, t, offset)
529529
}
530+
source.Type = t
530531
for i := int64(0); i < t.NumElem(); i++ {
531532
sel := source.Block.NewValue1I(pos, OpArraySelect, elt, i, source)
532533
mem = storeArgOrLoad(pos, b, base, sel, mem, elt, offset+i*elt.Width)
@@ -559,6 +560,7 @@ func expandCalls(f *Func) {
559560
return storeArgOrLoad(pos, b, base, source, mem, t, offset)
560561
}
561562

563+
source.Type = t
562564
for i := 0; i < t.NumFields(); i++ {
563565
fld := t.Field(i)
564566
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)