]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: only update source type when processing struct/array
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Fri, 5 Nov 2021 13:30:38 +0000 (20:30 +0700)
committerCuong Manh Le <cuong.manhle.vn@gmail.com>
Fri, 5 Nov 2021 16:35:00 +0000 (16:35 +0000)
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>
src/cmd/compile/internal/ssa/expand_calls.go
test/fixedbugs/issue49378.go [new file with mode: 0644]

index 91ff9f87f93107e81dac562a63898845505b4041..a3cea855f2fa456a31e18ae0560d9d773ca5f689 100644 (file)
@@ -954,11 +954,11 @@ 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)
                }
                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.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
                        // 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)
                }
 
+               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)
diff --git a/test/fixedbugs/issue49378.go b/test/fixedbugs/issue49378.go
new file mode 100644 (file)
index 0000000..70f466c
--- /dev/null
@@ -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))
+       }()
+}