]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: fix literal struct interface {} lost passing by value
authorLE Manh Cuong <cuong.manhle.vn@gmail.com>
Fri, 22 Mar 2019 18:43:06 +0000 (01:43 +0700)
committerKeith Randall <khr@golang.org>
Wed, 27 Mar 2019 17:28:06 +0000 (17:28 +0000)
CL 135377 introduces pass strings and slices to convT2{E,I} by value.
Before that CL, all types, except interface will be allocated temporary
address. The CL changes the logic that only constant and type which
needs address (determine by convFuncName) will be allocated.

It fails to cover the case where type is static composite literal.
Adding condition to check that case fixes the issue.

Also, static composite literal node implies constant type, so consttype
checking can be removed.

Fixes #30956

Change-Id: Ifc750a029fb4889c2d06e73e44bf85e6ef4ce881
Reviewed-on: https://go-review.googlesource.com/c/go/+/168858
Run-TryBot: Ian Lance Taylor <iant@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Keith Randall <khr@golang.org>
src/cmd/compile/internal/gc/order.go
test/fixedbugs/issue30956.go [new file with mode: 0644]
test/fixedbugs/issue30956.out [new file with mode: 0644]

index aae18ff22727cfa9aa80a1fe9e678974475381c2..3aca63abafb042abbcf3b45bb8da5e11ed07d5b7 100644 (file)
@@ -1060,10 +1060,10 @@ func (o *Order) expr(n, lhs *Node) *Node {
                if n.Left.Type.IsInterface() {
                        break
                }
-               if _, needsaddr := convFuncName(n.Left.Type, n.Type); needsaddr || consttype(n.Left) > 0 {
+               if _, needsaddr := convFuncName(n.Left.Type, n.Type); needsaddr || isStaticCompositeLiteral(n.Left) {
                        // Need a temp if we need to pass the address to the conversion function.
-                       // We also process constants here, making a named static global whose
-                       // address we can put directly in an interface (see OCONVIFACE case in walk).
+                       // We also process static composite literal node here, making a named static global
+                       // whose address we can put directly in an interface (see OCONVIFACE case in walk).
                        n.Left = o.addrTemp(n.Left)
                }
 
diff --git a/test/fixedbugs/issue30956.go b/test/fixedbugs/issue30956.go
new file mode 100644 (file)
index 0000000..021e6c5
--- /dev/null
@@ -0,0 +1,32 @@
+// run
+
+// Copyright 2019 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.
+
+// Check for compile generated static data for literal
+// composite struct
+
+package main
+
+import "fmt"
+
+type X struct {
+       V interface{}
+
+       a int
+       b int
+       c int
+}
+
+func pr(x X) {
+       fmt.Println(x.V)
+}
+
+func main() {
+       pr(X{
+               V: struct {
+                       A int
+               }{42},
+       })
+}
diff --git a/test/fixedbugs/issue30956.out b/test/fixedbugs/issue30956.out
new file mode 100644 (file)
index 0000000..04f25e8
--- /dev/null
@@ -0,0 +1 @@
+{42}