mirror of
https://github.com/golang/go
synced 2024-11-25 21:18:02 -07:00
cmd/compile: only update source type when processing struct/array
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 #49378 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>
This commit is contained in:
parent
a0d661ab0f
commit
f249fa27a9
@ -954,11 +954,11 @@ func (x *expandState) storeArgOrLoad(pos src.XPos, b *Block, source, mem *Value,
|
|||||||
elt := t.Elem()
|
elt := t.Elem()
|
||||||
if source.Type != t && t.NumElem() == 1 && elt.Size() == t.Size() && t.Size() == x.regSize {
|
if source.Type != t && t.NumElem() == 1 && elt.Size() == t.Size() && t.Size() == x.regSize {
|
||||||
t = removeTrivialWrapperTypes(t)
|
t = removeTrivialWrapperTypes(t)
|
||||||
source.Type = t
|
|
||||||
// it could be a leaf type, but the "leaf" could be complex64 (for example)
|
// 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)
|
return x.storeArgOrLoad(pos, b, source, mem, t, storeOffset, loadRegOffset, storeRc)
|
||||||
}
|
}
|
||||||
eltRO := x.regWidth(elt)
|
eltRO := x.regWidth(elt)
|
||||||
|
source.Type = t
|
||||||
for i := int64(0); i < t.NumElem(); i++ {
|
for i := int64(0); i < t.NumElem(); i++ {
|
||||||
sel := source.Block.NewValue1I(pos, OpArraySelect, elt, i, source)
|
sel := source.Block.NewValue1I(pos, OpArraySelect, elt, i, source)
|
||||||
mem = x.storeArgOrLoad(pos, b, sel, mem, elt, storeOffset+i*elt.Size(), loadRegOffset, storeRc.at(t, 0))
|
mem = x.storeArgOrLoad(pos, b, sel, mem, elt, storeOffset+i*elt.Size(), loadRegOffset, storeRc.at(t, 0))
|
||||||
@ -988,11 +988,11 @@ 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
|
// v139 is later stored as an intVal == struct{val *big.Int} which naively requires the fields of
|
||||||
// of a *uint8, which does not succeed.
|
// of a *uint8, which does not succeed.
|
||||||
t = removeTrivialWrapperTypes(t)
|
t = removeTrivialWrapperTypes(t)
|
||||||
source.Type = t
|
|
||||||
// it could be a leaf type, but the "leaf" could be complex64 (for example)
|
// 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)
|
return x.storeArgOrLoad(pos, b, source, mem, t, storeOffset, loadRegOffset, storeRc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
source.Type = t
|
||||||
for i := 0; i < t.NumFields(); i++ {
|
for i := 0; i < t.NumFields(); i++ {
|
||||||
fld := t.Field(i)
|
fld := t.Field(i)
|
||||||
sel := source.Block.NewValue1I(pos, OpStructSelect, fld.Type, int64(i), source)
|
sel := source.Block.NewValue1I(pos, OpStructSelect, fld.Type, int64(i), source)
|
||||||
|
25
test/fixedbugs/issue49378.go
Normal file
25
test/fixedbugs/issue49378.go
Normal file
@ -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))
|
||||||
|
}()
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user