1
0
mirror of https://github.com/golang/go synced 2024-11-11 19:21:37 -07:00

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 <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>
This commit is contained in:
Cuong Manh Le 2021-11-01 14:32:39 +07:00
parent d9bb5f6f10
commit bd49a998bf
2 changed files with 57 additions and 0 deletions

View File

@ -954,6 +954,7 @@ func (x *expandState) storeArgOrLoad(pos src.XPos, b *Block, source, mem *Value,
elt := t.Elem()
if source.Type != t && t.NumElem() == 1 && elt.Size() == t.Size() && t.Size() == x.regSize {
t = removeTrivialWrapperTypes(t)
source.Type = t
// it could be a leaf type, but the "leaf" could be complex64 (for example)
return x.storeArgOrLoad(pos, b, source, mem, t, storeOffset, loadRegOffset, storeRc)
}
@ -987,6 +988,7 @@ func (x *expandState) storeArgOrLoad(pos src.XPos, b *Block, source, mem *Value,
// v139 is later stored as an intVal == struct{val *big.Int} which naively requires the fields of
// of a *uint8, which does not succeed.
t = removeTrivialWrapperTypes(t)
source.Type = t
// it could be a leaf type, but the "leaf" could be complex64 (for example)
return x.storeArgOrLoad(pos, b, source, mem, t, storeOffset, loadRegOffset, storeRc)
}

View File

@ -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
}()
}()
}