aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLE Manh Cuong <cuong.manhle.vn@gmail.com>2019-03-23 01:43:06 +0700
committerAndrew Bonventre <andybons@golang.org>2019-04-02 19:43:35 +0000
commit991583017c856a14431382794a2a2f98ca52e537 (patch)
treeb89b1b22b65348b3dc2a38818d1bfdf1dd88d38d
parent578e281583f098c67ad5803ed2db1dad436b54d9 (diff)
downloadgo-991583017c856a14431382794a2a2f98ca52e537.tar.gz
go-991583017c856a14431382794a2a2f98ca52e537.zip
[release-branch.go1.12] cmd/compile: fix literal struct interface {} lost passing by value
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 #31209 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> (cherry picked from commit d47db6dc0ce72d1371c81a677b45d7bdba39ff46) Reviewed-on: https://go-review.googlesource.com/c/go/+/170437 Run-TryBot: Andrew Bonventre <andybons@golang.org> Reviewed-by: Cherry Zhang <cherryyz@google.com>
-rw-r--r--src/cmd/compile/internal/gc/order.go6
-rw-r--r--test/fixedbugs/issue30956.go32
-rw-r--r--test/fixedbugs/issue30956.out1
3 files changed, 36 insertions, 3 deletions
diff --git a/src/cmd/compile/internal/gc/order.go b/src/cmd/compile/internal/gc/order.go
index 0098242c79..c252e7ae20 100644
--- a/src/cmd/compile/internal/gc/order.go
+++ b/src/cmd/compile/internal/gc/order.go
@@ -1108,10 +1108,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
index 0000000000..021e6c5d47
--- /dev/null
+++ b/test/fixedbugs/issue30956.go
@@ -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
index 0000000000..04f25e8ae7
--- /dev/null
+++ b/test/fixedbugs/issue30956.out
@@ -0,0 +1 @@
+{42}