]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: in expand calls, preserve pointer store type but decompose aggregate...
authorCherry Zhang <cherryyz@google.com>
Thu, 1 Apr 2021 18:21:12 +0000 (14:21 -0400)
committerCherry Zhang <cherryyz@google.com>
Fri, 2 Apr 2021 00:45:56 +0000 (00:45 +0000)
In CL 305672 we preserve the pointer type of a store by just not
decomposing it. But this can be problematic when the source of
the store is a direct interface aggregate type (e.g.
struct { x map[int]int }.

In this CL we take a different approach: we preserve the store
type when generating the new store, but also decompose the source.

Fixes #45344.

Change-Id: If5dd496458dee95aa649c6d106b96a6cdcf3e60d
Reviewed-on: https://go-review.googlesource.com/c/go/+/306669
Trust: Cherry Zhang <cherryyz@google.com>
Run-TryBot: Cherry Zhang <cherryyz@google.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/issue45344.go [new file with mode: 0644]

index 29352364730c8de5122f830f519101ff3e66da4d..a5fe6f4d29c5dd769e1b84d61728ce36d44fd40d 100644 (file)
@@ -589,6 +589,14 @@ func (x *expandState) decomposeArg(pos src.XPos, b *Block, source, mem *Value, t
                        if w == nil {
                                w = x.newArgToMemOrRegs(source, w, off, i, rt, pos)
                        }
+                       if t.IsPtrShaped() {
+                               // Preserve the original store type. This ensures pointer type
+                               // properties aren't discarded (e.g, notinheap).
+                               if rt.Width != t.Width || len(pa.Registers) != 1 || i != loadRegOffset {
+                                       b.Func.Fatalf("incompatible store type %v and %v, i=%d", t, rt, i)
+                               }
+                               rt = t
+                       }
                        mem = x.storeArgOrLoad(pos, b, w, mem, rt, storeOffset+off, i, storeRc.next(rt))
                }
                return mem
@@ -1114,9 +1122,6 @@ func expandCalls(f *Func) {
                for _, v := range b.Values {
                        if v.Op == OpStore {
                                t := v.Aux.(*types.Type)
-                               if t.IsPtrShaped() { // Everything already fits, and this ensures pointer type properties aren't discarded (e.g, notinheap)
-                                       continue
-                               }
                                source := v.Args[1]
                                tSrc := source.Type
                                iAEATt := x.isAlreadyExpandedAggregateType(t)
diff --git a/test/fixedbugs/issue45344.go b/test/fixedbugs/issue45344.go
new file mode 100644 (file)
index 0000000..70c3d89
--- /dev/null
@@ -0,0 +1,20 @@
+// 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.
+
+// Issue 45344: expand_calls does not handle direct interface
+// typed argument well.
+
+package p
+
+type T struct {
+       a map[int]int
+}
+
+func F(t T) {
+       G(t)
+}
+
+func G(...interface{})