Skip to content

Commit bd49a99

Browse files
committed
cmd/compile: fix missing update source type in storeArgOrLoad
After removing trivial wrapper types, the source needs to be updated with new type, otherwise, it leads to mismatch between field offset and the source type for selecting struct/array. Fixes #49249 Change-Id: I26f9440bcb2e78bcf0617afc21d9d40cdbe4aca6 Reviewed-on: https://go-review.googlesource.com/c/go/+/360057 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]>
1 parent d9bb5f6 commit bd49a99

File tree

2 files changed

+57
-0
lines changed

2 files changed

+57
-0
lines changed

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

+2
Original file line numberDiff line numberDiff line change
@@ -954,6 +954,7 @@ func (x *expandState) storeArgOrLoad(pos src.XPos, b *Block, source, mem *Value,
954954
elt := t.Elem()
955955
if source.Type != t && t.NumElem() == 1 && elt.Size() == t.Size() && t.Size() == x.regSize {
956956
t = removeTrivialWrapperTypes(t)
957+
source.Type = t
957958
// it could be a leaf type, but the "leaf" could be complex64 (for example)
958959
return x.storeArgOrLoad(pos, b, source, mem, t, storeOffset, loadRegOffset, storeRc)
959960
}
@@ -987,6 +988,7 @@ func (x *expandState) storeArgOrLoad(pos src.XPos, b *Block, source, mem *Value,
987988
// v139 is later stored as an intVal == struct{val *big.Int} which naively requires the fields of
988989
// of a *uint8, which does not succeed.
989990
t = removeTrivialWrapperTypes(t)
991+
source.Type = t
990992
// it could be a leaf type, but the "leaf" could be complex64 (for example)
991993
return x.storeArgOrLoad(pos, b, source, mem, t, storeOffset, loadRegOffset, storeRc)
992994
}

test/fixedbugs/issue49249.go

+55
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+
}

0 commit comments

Comments
 (0)