mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
Revert "cmd/compile: fix mishandling of unsafe-uintptr arguments with call method in go/defer"
This reverts commit CL 294849. Reason for revert: this doesn't actually fix the issue, as revealed by the noopt builder's failures. Change-Id: Ib4ea9ceb4d75e46b3b91ec348b365fd8c83316ad Reviewed-on: https://go-review.googlesource.com/c/go/+/296629 Trust: Matthew Dempsky <mdempsky@google.com> Reviewed-by: Bryan C. Mills <bcmills@google.com>
This commit is contained in:
parent
b83d073e9e
commit
9a7fe196e4
4 changed files with 14 additions and 72 deletions
|
|
@ -503,8 +503,21 @@ func walkCall1(n *ir.CallExpr, init *ir.Nodes) {
|
||||||
}
|
}
|
||||||
n.SetWalked(true)
|
n.SetWalked(true)
|
||||||
|
|
||||||
|
// If this is a method call t.M(...),
|
||||||
|
// rewrite into a function call T.M(t, ...).
|
||||||
// TODO(mdempsky): Do this right after type checking.
|
// TODO(mdempsky): Do this right after type checking.
|
||||||
rewriteMethodCall(n)
|
if n.Op() == ir.OCALLMETH {
|
||||||
|
withRecv := make([]ir.Node, len(n.Args)+1)
|
||||||
|
dot := n.X.(*ir.SelectorExpr)
|
||||||
|
withRecv[0] = dot.X
|
||||||
|
copy(withRecv[1:], n.Args)
|
||||||
|
n.Args = withRecv
|
||||||
|
|
||||||
|
dot = ir.NewSelectorExpr(dot.Pos(), ir.OXDOT, ir.TypeNode(dot.X.Type()), dot.Selection.Sym)
|
||||||
|
|
||||||
|
n.SetOp(ir.OCALLFUNC)
|
||||||
|
n.X = typecheck.Expr(dot)
|
||||||
|
}
|
||||||
|
|
||||||
args := n.Args
|
args := n.Args
|
||||||
params := n.X.Type().Params()
|
params := n.X.Type().Params()
|
||||||
|
|
@ -534,23 +547,6 @@ func walkCall1(n *ir.CallExpr, init *ir.Nodes) {
|
||||||
n.Args = args
|
n.Args = args
|
||||||
}
|
}
|
||||||
|
|
||||||
// rewriteMethodCall rewrites a method call t.M(...) into a function call T.M(t, ...).
|
|
||||||
func rewriteMethodCall(n *ir.CallExpr) {
|
|
||||||
if n.Op() != ir.OCALLMETH {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
withRecv := make([]ir.Node, len(n.Args)+1)
|
|
||||||
dot := n.X.(*ir.SelectorExpr)
|
|
||||||
withRecv[0] = dot.X
|
|
||||||
copy(withRecv[1:], n.Args)
|
|
||||||
n.Args = withRecv
|
|
||||||
|
|
||||||
dot = ir.NewSelectorExpr(dot.Pos(), ir.OXDOT, ir.TypeNode(dot.X.Type()), dot.Selection.Sym)
|
|
||||||
|
|
||||||
n.SetOp(ir.OCALLFUNC)
|
|
||||||
n.X = typecheck.Expr(dot)
|
|
||||||
}
|
|
||||||
|
|
||||||
// walkDivMod walks an ODIV or OMOD node.
|
// walkDivMod walks an ODIV or OMOD node.
|
||||||
func walkDivMod(n *ir.BinaryExpr, init *ir.Nodes) ir.Node {
|
func walkDivMod(n *ir.BinaryExpr, init *ir.Nodes) ir.Node {
|
||||||
n.X = walkExpr(n.X, init)
|
n.X = walkExpr(n.X, init)
|
||||||
|
|
|
||||||
|
|
@ -241,9 +241,6 @@ func wrapCall(n *ir.CallExpr, init *ir.Nodes) ir.Node {
|
||||||
init.Append(ir.TakeInit(n)...)
|
init.Append(ir.TakeInit(n)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(mdempsky): Do this right after type checking.
|
|
||||||
rewriteMethodCall(n)
|
|
||||||
|
|
||||||
isBuiltinCall := n.Op() != ir.OCALLFUNC && n.Op() != ir.OCALLMETH && n.Op() != ir.OCALLINTER
|
isBuiltinCall := n.Op() != ir.OCALLFUNC && n.Op() != ir.OCALLMETH && n.Op() != ir.OCALLINTER
|
||||||
|
|
||||||
// Turn f(a, b, []T{c, d, e}...) back into f(a, b, c, d, e).
|
// Turn f(a, b, []T{c, d, e}...) back into f(a, b, c, d, e).
|
||||||
|
|
|
||||||
|
|
@ -48,30 +48,6 @@ func f() int {
|
||||||
return test("return", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup()))
|
return test("return", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup()))
|
||||||
}
|
}
|
||||||
|
|
||||||
type S struct{}
|
|
||||||
|
|
||||||
//go:noinline
|
|
||||||
//go:uintptrescapes
|
|
||||||
func (S) test(s string, p, q uintptr, rest ...uintptr) int {
|
|
||||||
runtime.GC()
|
|
||||||
runtime.GC()
|
|
||||||
|
|
||||||
if *(*string)(unsafe.Pointer(p)) != "ok" {
|
|
||||||
panic(s + ": p failed")
|
|
||||||
}
|
|
||||||
if *(*string)(unsafe.Pointer(q)) != "ok" {
|
|
||||||
panic(s + ": q failed")
|
|
||||||
}
|
|
||||||
for _, r := range rest {
|
|
||||||
if *(*string)(unsafe.Pointer(r)) != "ok" {
|
|
||||||
panic(s + ": r[i] failed")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
done <- true
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
test("normal", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup()))
|
test("normal", uintptr(setup()), uintptr(setup()), uintptr(setup()), uintptr(setup()))
|
||||||
<-done
|
<-done
|
||||||
|
|
@ -84,12 +60,6 @@ func main() {
|
||||||
}()
|
}()
|
||||||
<-done
|
<-done
|
||||||
|
|
||||||
func() {
|
|
||||||
s := &S{}
|
|
||||||
defer s.test("method call", uintptr(setup()), uintptr(setup()))
|
|
||||||
}()
|
|
||||||
<-done
|
|
||||||
|
|
||||||
f()
|
f()
|
||||||
<-done
|
<-done
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
// 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.
|
|
||||||
|
|
||||||
// +build windows
|
|
||||||
|
|
||||||
package p
|
|
||||||
|
|
||||||
import (
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
)
|
|
||||||
|
|
||||||
var dllKernel = syscall.NewLazyDLL("Kernel32.dll")
|
|
||||||
|
|
||||||
func Call() {
|
|
||||||
procLocalFree := dllKernel.NewProc("LocalFree")
|
|
||||||
defer procLocalFree.Call(uintptr(unsafe.Pointer(nil)))
|
|
||||||
}
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue