mirror of
https://github.com/golang/go.git
synced 2025-12-08 06:10:04 +00:00
[dev.regabi] cmd/compile: replace Node.HasCall with walk.mayCall
After CL 284220, we now only need to detect expressions that contain function calls in the arguments list of further function calls. So we can simplify Node.HasCall/fncall/etc a lot. Instead of incrementally tracking whether an expression contains function calls all throughout walk, simply check once at the point of using an expression as a function call argument. Since any expression checked here will itself become a function call argument, it won't be checked again because we'll short circuit at the enclosing function call. Also, restructure the recursive walk code to use mayCall, and trim down the list of acceptable expressions. It should be okay to be stricter, since we'll now only see function call arguments and after they've already been walked. It's possible I was overly aggressive removing Ops here. But if so, we'll get an ICE, and it'll be easy to re-add them. I think this is better than the alternative of accidentally allowing expressions through that risk silently clobbering the stack. Passes toolstash -cmp. Change-Id: I585ef35dcccd9f4018e4bf2c3f9ccb1514a826f3 Reviewed-on: https://go-review.googlesource.com/c/go/+/284223 Trust: Matthew Dempsky <mdempsky@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com>
This commit is contained in:
parent
6de9423445
commit
78e5aabcdb
7 changed files with 72 additions and 163 deletions
|
|
@ -248,18 +248,6 @@ func walkReturn(n *ir.ReturnStmt) ir.Node {
|
|||
return n
|
||||
}
|
||||
|
||||
// fncall reports whether assigning an rvalue of type rt to an lvalue l might involve a function call.
|
||||
func fncall(l ir.Node, rt *types.Type) bool {
|
||||
if l.HasCall() || l.Op() == ir.OINDEXMAP {
|
||||
return true
|
||||
}
|
||||
if types.Identical(l.Type(), rt) {
|
||||
return false
|
||||
}
|
||||
// There might be a conversion required, which might involve a runtime call.
|
||||
return true
|
||||
}
|
||||
|
||||
// check assign type list to
|
||||
// an expression list. called in
|
||||
// expr-list = func()
|
||||
|
|
@ -275,9 +263,9 @@ func ascompatet(nl ir.Nodes, nr *types.Type) []ir.Node {
|
|||
}
|
||||
r := nr.Field(i)
|
||||
|
||||
// Any assignment to an lvalue that might cause a function call must be
|
||||
// deferred until all the returned values have been read.
|
||||
if fncall(l, r.Type) {
|
||||
// Order should have created autotemps of the appropriate type for
|
||||
// us to store results into.
|
||||
if tmp, ok := l.(*ir.Name); !ok || !tmp.AutoTemp() || !types.Identical(tmp.Type(), r.Type) {
|
||||
base.FatalfAt(l.Pos(), "assigning %v to %+v", r.Type, l)
|
||||
}
|
||||
|
||||
|
|
@ -286,14 +274,7 @@ func ascompatet(nl ir.Nodes, nr *types.Type) []ir.Node {
|
|||
res.SetType(r.Type)
|
||||
res.SetTypecheck(1)
|
||||
|
||||
a := convas(ir.NewAssignStmt(base.Pos, l, res), &nn)
|
||||
updateHasCall(a)
|
||||
if a.HasCall() {
|
||||
ir.Dump("ascompatet ucount", a)
|
||||
base.Fatalf("ascompatet: too many function calls evaluating parameters")
|
||||
}
|
||||
|
||||
nn.Append(a)
|
||||
nn.Append(ir.NewAssignStmt(base.Pos, l, res))
|
||||
}
|
||||
return nn
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue