mirror of
https://github.com/golang/go
synced 2024-11-11 18:41:36 -07:00
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 #49282 Change-Id: Ibda6c4a45d960dd412a641f5e02276f663c80785 Reviewed-on: https://go-review.googlesource.com/c/go/+/361410 Run-TryBot: Alberto Donizetti <alb.donizetti@gmail.com> TryBot-Result: Go Bot <gobot@golang.org> Trust: Alberto Donizetti <alb.donizetti@gmail.com> Trust: Than McIntosh <thanm@google.com> Reviewed-by: David Chase <drchase@google.com>
This commit is contained in:
parent
f19e400180
commit
4f083c7dcf
@ -5075,6 +5075,18 @@ func (s *state) call(n *ir.CallExpr, k callKind, returnResultAddr bool) *ssa.Val
|
||||
for _, p := range params.InParams() { // includes receiver for interface calls
|
||||
ACArgs = append(ACArgs, p.Type)
|
||||
}
|
||||
|
||||
// Split the entry block if there are open defers, because later calls to
|
||||
// openDeferSave may cause a mismatch between the mem for an OpDereference
|
||||
// and the call site which uses it. See #49282.
|
||||
if s.curBlock.ID == s.f.Entry.ID && s.hasOpenDefers {
|
||||
b := s.endBlock()
|
||||
b.Kind = ssa.BlockPlain
|
||||
curb := s.f.NewBlock(ssa.BlockPlain)
|
||||
b.AddEdgeTo(curb)
|
||||
s.startBlock(curb)
|
||||
}
|
||||
|
||||
for i, n := range args {
|
||||
callArgs = append(callArgs, s.putArg(n, t.Params().Field(i).Type))
|
||||
}
|
||||
|
44
test/fixedbugs/issue49282.go
Normal file
44
test/fixedbugs/issue49282.go
Normal file
@ -0,0 +1,44 @@
|
||||
// compile
|
||||
|
||||
// Copyright 2021 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.
|
||||
|
||||
package p
|
||||
|
||||
//go:noinline
|
||||
func g(d uintptr, a, m []int, s struct {
|
||||
a, b, c, d, e int
|
||||
}, u uint) {
|
||||
_ = a
|
||||
_ = m
|
||||
_ = s
|
||||
func() {
|
||||
for i := 0; i < 5; i++ {
|
||||
_ = a
|
||||
_ = m
|
||||
_, _ = s, s
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
var One float64 = 1.0
|
||||
|
||||
func f(d uintptr) {
|
||||
var a, m []int
|
||||
var s struct {
|
||||
a, b, c, d, e int
|
||||
}
|
||||
|
||||
g(d, a, m, s, uint(One)) // Uint of not-a-constant inserts a conditional, necessary to bug
|
||||
|
||||
defer func() uint {
|
||||
return 0
|
||||
}()
|
||||
}
|
||||
|
||||
var d uintptr
|
||||
|
||||
func h() {
|
||||
f(d)
|
||||
}
|
Loading…
Reference in New Issue
Block a user