Skip to content

Commit ebd1b4d

Browse files
hanchaoqundmitshur
authored andcommitted
[release-branch.go1.17] cmd/compile: avoid adding LECall to the entry block when has opendefers
The openDeferRecord always insert vardef/varlive pairs into the entry block, it may destroy the mem chain when LECall's args are writing into the same block. So create a new block before that happens. Fixes #49413 Change-Id: Ibda6c4a45d960dd412a641f5e02276f663c80785 Reviewed-on: https://go-review.googlesource.com/c/go/+/361410 Run-TryBot: Alberto Donizetti <[email protected]> TryBot-Result: Go Bot <[email protected]> Trust: Alberto Donizetti <[email protected]> Trust: Than McIntosh <[email protected]> Reviewed-by: David Chase <[email protected]> (cherry picked from commit 4f083c7) Reviewed-on: https://go-review.googlesource.com/c/go/+/362054 Reviewed-by: Keith Randall <[email protected]> Trust: Matthew Dempsky <[email protected]> Run-TryBot: Dmitri Shuralyov <[email protected]> TryBot-Result: Gopher Robot <[email protected]>
1 parent 0aa7f8f commit ebd1b4d

File tree

2 files changed

+56
-0
lines changed

2 files changed

+56
-0
lines changed

src/cmd/compile/internal/ssagen/ssa.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5118,6 +5118,18 @@ func (s *state) call(n *ir.CallExpr, k callKind, returnResultAddr bool) *ssa.Val
51185118
for _, p := range params.InParams() { // includes receiver for interface calls
51195119
ACArgs = append(ACArgs, p.Type)
51205120
}
5121+
5122+
// Split the entry block if there are open defers, because later calls to
5123+
// openDeferSave may cause a mismatch between the mem for an OpDereference
5124+
// and the call site which uses it. See #49282.
5125+
if s.curBlock.ID == s.f.Entry.ID && s.hasOpenDefers {
5126+
b := s.endBlock()
5127+
b.Kind = ssa.BlockPlain
5128+
curb := s.f.NewBlock(ssa.BlockPlain)
5129+
b.AddEdgeTo(curb)
5130+
s.startBlock(curb)
5131+
}
5132+
51215133
for i, n := range args {
51225134
callArgs = append(callArgs, s.putArg(n, t.Params().Field(i).Type))
51235135
}

test/fixedbugs/issue49282.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// compile
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 p
8+
9+
//go:noinline
10+
func g(d uintptr, a, m []int, s struct {
11+
a, b, c, d, e int
12+
}, u uint) {
13+
_ = a
14+
_ = m
15+
_ = s
16+
func() {
17+
for i := 0; i < 5; i++ {
18+
_ = a
19+
_ = m
20+
_, _ = s, s
21+
}
22+
}()
23+
}
24+
25+
var One float64 = 1.0
26+
27+
func f(d uintptr) {
28+
var a, m []int
29+
var s struct {
30+
a, b, c, d, e int
31+
}
32+
33+
g(d, a, m, s, uint(One)) // Uint of not-a-constant inserts a conditional, necessary to bug
34+
35+
defer func() uint {
36+
return 0
37+
}()
38+
}
39+
40+
var d uintptr
41+
42+
func h() {
43+
f(d)
44+
}

0 commit comments

Comments
 (0)