Skip to content

Commit ed50277

Browse files
committed
[release-branch.go1.18] cmd/compile: do not use special literal assignment if LHS is address-taken
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 <[email protected]> Run-TryBot: Cherry Mui <[email protected]> TryBot-Result: Gopher Robot <[email protected]> Reviewed-by: Michael Knyszek <[email protected]> (cherry picked from commit 1c77137) Reviewed-on: https://go-review.googlesource.com/c/go/+/419450 Reviewed-by: Matthew Dempsky <[email protected]>
1 parent d06c911 commit ed50277

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

src/cmd/compile/internal/walk/complit.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,12 @@ func oaslit(n *ir.AssignStmt, init *ir.Nodes) bool {
621621
// not a special composite literal assignment
622622
return false
623623
}
624+
if x.Addrtaken() {
625+
// If x is address-taken, the RHS may (implicitly) uses LHS.
626+
// Not safe to do a special composite literal assignment
627+
// (which may expand to multiple assignments).
628+
return false
629+
}
624630

625631
switch n.Y.Op() {
626632
default:
@@ -629,7 +635,7 @@ func oaslit(n *ir.AssignStmt, init *ir.Nodes) bool {
629635

630636
case ir.OSTRUCTLIT, ir.OARRAYLIT, ir.OSLICELIT, ir.OMAPLIT:
631637
if ir.Any(n.Y, func(y ir.Node) bool { return ir.Uses(y, x) }) {
632-
// not a special composite literal assignment
638+
// not safe to do a special composite literal assignment if RHS uses LHS.
633639
return false
634640
}
635641
anylit(n.Y, n.X, init)

test/fixedbugs/issue52953.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// run
2+
3+
// Copyright 2022 The Go Authors. All rights reserved.
4+
// Use of this source code is governed by a BSD-style
5+
// license that can be found in the LICENSE file.
6+
7+
// Issue 52953: miscompilation for composite literal assignment
8+
// when LHS is address-taken.
9+
10+
package main
11+
12+
type T struct {
13+
Field1 bool
14+
}
15+
16+
func main() {
17+
var ret T
18+
ret.Field1 = true
19+
var v *bool = &ret.Field1
20+
ret = T{Field1: *v}
21+
check(ret.Field1)
22+
}
23+
24+
//go:noinline
25+
func check(b bool) {
26+
if !b {
27+
panic("FAIL")
28+
}
29+
}

0 commit comments

Comments
 (0)