]> Cypherpunks repositories - gostls13.git/commitdiff
[release-branch.go1.18] cmd/compile: do not use special literal assignment if LHS...
authorCherry Mui <cherryyz@google.com>
Wed, 18 May 2022 15:58:53 +0000 (11:58 -0400)
committerCherry Mui <cherryyz@google.com>
Tue, 26 Jul 2022 14:15:46 +0000 (14:15 +0000)
A composite literal assignment

x = T{field: v}

may be compiled to

x = T{}
x.field = v

We already do not use this form is RHS uses LHS. If LHS is
address-taken, RHS may uses LHS implicitly, e.g.

v = &x.field
x = T{field: *v}

The lowering above would change the value of RHS (*v).

Updates #52953.
Fixes #52961.

Change-Id: I3f798e00598aaa550b8c17182c7472fef440d483
Reviewed-on: https://go-review.googlesource.com/c/go/+/407014
Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
Run-TryBot: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
(cherry picked from commit 1c77137d4fdfbb3e7e8d9efaab3bab5ee736a19d)
Reviewed-on: https://go-review.googlesource.com/c/go/+/419450
Reviewed-by: Matthew Dempsky <mdempsky@google.com>
src/cmd/compile/internal/walk/complit.go
test/fixedbugs/issue52953.go [new file with mode: 0644]

index b985b4caeb8597ec7387cb7ca24eb4cde01e5c0d..e9575800710234b158f8bc1b0c101fa98232237a 100644 (file)
@@ -621,6 +621,12 @@ func oaslit(n *ir.AssignStmt, init *ir.Nodes) bool {
                // not a special composite literal assignment
                return false
        }
+       if x.Addrtaken() {
+               // If x is address-taken, the RHS may (implicitly) uses LHS.
+               // Not safe to do a special composite literal assignment
+               // (which may expand to multiple assignments).
+               return false
+       }
 
        switch n.Y.Op() {
        default:
@@ -629,7 +635,7 @@ func oaslit(n *ir.AssignStmt, init *ir.Nodes) bool {
 
        case ir.OSTRUCTLIT, ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT:
                if ir.Any(n.Y, func(y ir.Node) bool { return ir.Uses(y, x) }) {
-                       // not a special composite literal assignment
+                       // not safe to do a special composite literal assignment if RHS uses LHS.
                        return false
                }
                anylit(n.Y, n.X, init)
diff --git a/test/fixedbugs/issue52953.go b/test/fixedbugs/issue52953.go
new file mode 100644 (file)
index 0000000..2085e4e
--- /dev/null
@@ -0,0 +1,29 @@
+// run
+
+// Copyright 2022 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 52953: miscompilation for composite literal assignment
+// when LHS is address-taken.
+
+package main
+
+type T struct {
+       Field1 bool
+}
+
+func main() {
+       var ret T
+       ret.Field1 = true
+       var v *bool = &ret.Field1
+       ret = T{Field1: *v}
+       check(ret.Field1)
+}
+
+//go:noinline
+func check(b bool) {
+       if !b {
+               panic("FAIL")
+       }
+}