]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: fix missing update source type in storeArgOrLoad
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Mon, 1 Nov 2021 07:32:39 +0000 (14:32 +0700)
committerCuong Manh Le <cuong.manhle.vn@gmail.com>
Thu, 4 Nov 2021 02:12:52 +0000 (02:12 +0000)
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>
src/cmd/compile/internal/ssa/expand_calls.go
test/fixedbugs/issue49249.go [new file with mode: 0644]

index 18c9ab696d5d0e011210d669f6c1b30f9fcbf3cc..91ff9f87f93107e81dac562a63898845505b4041 100644 (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)
                }
diff --git a/test/fixedbugs/issue49249.go b/test/fixedbugs/issue49249.go
new file mode 100644 (file)
index 0000000..f152a5a
--- /dev/null
@@ -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
+               }()
+       }()
+}