Skip to content

Commit

Permalink
[release-branch.go1.17] cmd/compile: only update source type when pro…
Browse files Browse the repository at this point in the history
…cessing 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]>
  • Loading branch information
cuonglm authored and mknyszek committed Dec 2, 2021
1 parent 0177913 commit 759a921
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/cmd/compile/internal/ssa/expand_calls.go
Original file line number Diff line number Diff line change
Expand Up @@ -952,6 +952,7 @@ func (x *expandState) storeArgOrLoad(pos src.XPos, b *Block, source, mem *Value,
return x.storeArgOrLoad(pos, b, source, mem, t, storeOffset, loadRegOffset, storeRc)
}
eltRO := x.regWidth(elt)
source.Type = t
for i := int64(0); i < t.NumElem(); i++ {
sel := source.Block.NewValue1I(pos, OpArraySelect, elt, i, source)
mem = x.storeArgOrLoad(pos, b, sel, mem, elt, storeOffset+i*elt.Width, loadRegOffset, storeRc.at(t, 0))
Expand Down Expand Up @@ -985,6 +986,7 @@ func (x *expandState) storeArgOrLoad(pos src.XPos, b *Block, source, mem *Value,
return x.storeArgOrLoad(pos, b, source, mem, t, storeOffset, loadRegOffset, storeRc)
}

source.Type = t
for i := 0; i < t.NumFields(); i++ {
fld := t.Field(i)
sel := source.Block.NewValue1I(pos, OpStructSelect, fld.Type, int64(i), source)
Expand Down
55 changes: 55 additions & 0 deletions test/fixedbugs/issue49249.go
Original file line number Diff line number Diff line change
@@ -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
}()
}()
}
25 changes: 25 additions & 0 deletions test/fixedbugs/issue49378.go
Original file line number Diff line number Diff line change
@@ -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))
}()
}

0 comments on commit 759a921

Please sign in to comment.