Skip to content

Commit deaf29a

Browse files
committed
cmd/compile: fix order-of-assignment issue w/ defers
CL 261677 fixed a logic issue in walk's alias detection, where it was checking the RHS expression instead of the LHS expression when trying to determine the kind of assignment. However, correcting this exposed a latent issue with assigning to result parameters in functions with defers, where an assignment could become visible earlier than intended if a later expression could panic. Fixes #43835. Change-Id: I061ced125e3896e26d65f45b28c99db2c8a74a8c Reviewed-on: https://go-review.googlesource.com/c/go/+/285633 Run-TryBot: Matthew Dempsky <[email protected]> Reviewed-by: Cuong Manh Le <[email protected]> Reviewed-by: Keith Randall <[email protected]> Trust: Matthew Dempsky <[email protected]>
1 parent ad2ca26 commit deaf29a

File tree

2 files changed

+43
-2
lines changed

2 files changed

+43
-2
lines changed

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

+10-2
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ func walkstmt(n *Node) *Node {
267267
if n.List.Len() == 0 {
268268
break
269269
}
270-
if (Curfn.Type.FuncType().Outnamed && n.List.Len() > 1) || paramoutheap(Curfn) {
270+
if (Curfn.Type.FuncType().Outnamed && n.List.Len() > 1) || paramoutheap(Curfn) || Curfn.Func.HasDefer() {
271271
// assign to the function out parameters,
272272
// so that reorder3 can fix up conflicts
273273
var rl []*Node
@@ -2233,7 +2233,15 @@ func aliased(r *Node, all []*Node) bool {
22332233
memwrite = true
22342234
continue
22352235

2236-
case PAUTO, PPARAM, PPARAMOUT:
2236+
case PPARAMOUT:
2237+
// Assignments to a result parameter in a function with defers
2238+
// becomes visible early if evaluation of any later expression
2239+
// panics (#43835).
2240+
if Curfn.Func.HasDefer() {
2241+
return true
2242+
}
2243+
fallthrough
2244+
case PAUTO, PPARAM:
22372245
if l.Name.Addrtaken() {
22382246
memwrite = true
22392247
continue

test/fixedbugs/issue43835.go

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// run
2+
3+
// Copyright 2021 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+
package main
8+
9+
func main() {
10+
if f() {
11+
panic("FAIL")
12+
}
13+
if bad, _ := g(); bad {
14+
panic("FAIL")
15+
}
16+
}
17+
18+
func f() (bad bool) {
19+
defer func() {
20+
recover()
21+
}()
22+
var p *int
23+
bad, _ = true, *p
24+
return
25+
}
26+
27+
func g() (bool, int) {
28+
defer func() {
29+
recover()
30+
}()
31+
var p *int
32+
return true, *p
33+
}

0 commit comments

Comments
 (0)