aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/walk
diff options
context:
space:
mode:
authorCuong Manh Le <cuong.manhle.vn@gmail.com>2021-06-25 22:24:29 +0700
committerCuong Manh Le <cuong.manhle.vn@gmail.com>2021-06-26 08:39:47 +0000
commit0cf71f7f92c2623a132ab3257690826643d548af (patch)
tree4b830dda9c969984b9a6518d55f756378a19a961 /src/cmd/compile/internal/walk
parent180c338c6893c2e8b7f4692ed62f92a1ed0cd1e8 (diff)
downloadgo-0cf71f7f92c2623a132ab3257690826643d548af.tar.gz
go-0cf71f7f92c2623a132ab3257690826643d548af.zip
[dev.typeparams] cmd/compile: rewrite method calls during typecheck
CL 330671 move rewriting method call to method expression to escape analysis. This CL move the rewriting up further, into typecheck. It helps simplify the code for dowstream passes, as they now only have to deal with OCALLFUNC. There're two notes: - For -G=3, we can't rewrite d.M() where d is an instantiated receiver in transformCall, but let irgen.stencil to rewrite it. - Escape analysis still have to check for rewriting method calls, as the devirtualization pass can still generate OCALLMETH. Does not pass toolstash, since when the export data now contains method expression calls instead of method calls. Change-Id: I77465ef04d50dc4efedddca7eb55b3fc9483db0e Reviewed-on: https://go-review.googlesource.com/c/go/+/330831 Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com> Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
Diffstat (limited to 'src/cmd/compile/internal/walk')
-rw-r--r--src/cmd/compile/internal/walk/convert.go4
-rw-r--r--src/cmd/compile/internal/walk/expr.go11
-rw-r--r--src/cmd/compile/internal/walk/order.go19
-rw-r--r--src/cmd/compile/internal/walk/stmt.go1
-rw-r--r--src/cmd/compile/internal/walk/walk.go2
5 files changed, 25 insertions, 12 deletions
diff --git a/src/cmd/compile/internal/walk/convert.go b/src/cmd/compile/internal/walk/convert.go
index 5297332f6b..e659ee59f1 100644
--- a/src/cmd/compile/internal/walk/convert.go
+++ b/src/cmd/compile/internal/walk/convert.go
@@ -462,7 +462,9 @@ func walkCheckPtrArithmetic(n *ir.ConvExpr, init *ir.Nodes) ir.Node {
// TODO(mdempsky): Make stricter. We only need to exempt
// reflect.Value.Pointer and reflect.Value.UnsafeAddr.
switch n.X.Op() {
- case ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER:
+ case ir.OCALLMETH:
+ base.FatalfAt(n.X.Pos(), "OCALLMETH missed by typecheck")
+ case ir.OCALLFUNC, ir.OCALLINTER:
return n
}
diff --git a/src/cmd/compile/internal/walk/expr.go b/src/cmd/compile/internal/walk/expr.go
index 86c6d44501..f7675c3b7d 100644
--- a/src/cmd/compile/internal/walk/expr.go
+++ b/src/cmd/compile/internal/walk/expr.go
@@ -167,7 +167,7 @@ func walkExpr1(n ir.Node, init *ir.Nodes) ir.Node {
case ir.OCFUNC:
return n
- case ir.OCALLINTER, ir.OCALLFUNC, ir.OCALLMETH:
+ case ir.OCALLINTER, ir.OCALLFUNC:
n := n.(*ir.CallExpr)
return walkCall(n, init)
@@ -487,9 +487,12 @@ func walkAddString(n *ir.AddStringExpr, init *ir.Nodes) ir.Node {
return r1
}
-// walkCall walks an OCALLFUNC, OCALLINTER, or OCALLMETH node.
+// walkCall walks an OCALLFUNC or OCALLINTER node.
func walkCall(n *ir.CallExpr, init *ir.Nodes) ir.Node {
- if n.Op() == ir.OCALLINTER || n.Op() == ir.OCALLMETH || n.X.Op() == ir.OMETHEXPR {
+ if n.Op() == ir.OCALLMETH {
+ base.FatalfAt(n.Pos(), "OCALLMETH missed by typecheck")
+ }
+ if n.Op() == ir.OCALLINTER || n.X.Op() == ir.OMETHEXPR {
// We expect both interface call reflect.Type.Method and concrete
// call reflect.(*rtype).Method.
usemethod(n)
@@ -550,7 +553,7 @@ func walkCall1(n *ir.CallExpr, init *ir.Nodes) {
n.SetWalked(true)
if n.Op() == ir.OCALLMETH {
- typecheck.FixMethodCall(n)
+ base.FatalfAt(n.Pos(), "OCALLMETH missed by typecheck")
}
args := n.Args
diff --git a/src/cmd/compile/internal/walk/order.go b/src/cmd/compile/internal/walk/order.go
index 9912feba63..16a124d2ff 100644
--- a/src/cmd/compile/internal/walk/order.go
+++ b/src/cmd/compile/internal/walk/order.go
@@ -506,15 +506,18 @@ func (o *orderState) init(n ir.Node) {
}
// call orders the call expression n.
-// n.Op is OCALLMETH/OCALLFUNC/OCALLINTER or a builtin like OCOPY.
+// n.Op is OCALLFUNC/OCALLINTER or a builtin like OCOPY.
func (o *orderState) call(nn ir.Node) {
if len(nn.Init()) > 0 {
// Caller should have already called o.init(nn).
base.Fatalf("%v with unexpected ninit", nn.Op())
}
+ if nn.Op() == ir.OCALLMETH {
+ base.FatalfAt(nn.Pos(), "OCALLMETH missed by typecheck")
+ }
// Builtin functions.
- if nn.Op() != ir.OCALLFUNC && nn.Op() != ir.OCALLMETH && nn.Op() != ir.OCALLINTER {
+ if nn.Op() != ir.OCALLFUNC && nn.Op() != ir.OCALLINTER {
switch n := nn.(type) {
default:
base.Fatalf("unexpected call: %+v", n)
@@ -707,7 +710,7 @@ func (o *orderState) stmt(n ir.Node) {
o.out = append(o.out, n)
// Special: handle call arguments.
- case ir.OCALLFUNC, ir.OCALLINTER, ir.OCALLMETH:
+ case ir.OCALLFUNC, ir.OCALLINTER:
n := n.(*ir.CallExpr)
t := o.markTemp()
o.call(n)
@@ -1147,7 +1150,10 @@ func (o *orderState) expr1(n, lhs ir.Node) ir.Node {
case ir.OCONVNOP:
n := n.(*ir.ConvExpr)
- if n.Type().IsKind(types.TUNSAFEPTR) && n.X.Type().IsKind(types.TUINTPTR) && (n.X.Op() == ir.OCALLFUNC || n.X.Op() == ir.OCALLINTER || n.X.Op() == ir.OCALLMETH) {
+ if n.X.Op() == ir.OCALLMETH {
+ base.FatalfAt(n.X.Pos(), "OCALLMETH missed by typecheck")
+ }
+ if n.Type().IsKind(types.TUNSAFEPTR) && n.X.Type().IsKind(types.TUINTPTR) && (n.X.Op() == ir.OCALLFUNC || n.X.Op() == ir.OCALLINTER) {
call := n.X.(*ir.CallExpr)
// When reordering unsafe.Pointer(f()) into a separate
// statement, the conversion and function call must stay
@@ -1200,9 +1206,12 @@ func (o *orderState) expr1(n, lhs ir.Node) ir.Node {
o.out = append(o.out, nif)
return r
+ case ir.OCALLMETH:
+ base.FatalfAt(n.Pos(), "OCALLMETH missed by typecheck")
+ panic("unreachable")
+
case ir.OCALLFUNC,
ir.OCALLINTER,
- ir.OCALLMETH,
ir.OCAP,
ir.OCOMPLEX,
ir.OCOPY,
diff --git a/src/cmd/compile/internal/walk/stmt.go b/src/cmd/compile/internal/walk/stmt.go
index 0c216d2e8a..4581bca3df 100644
--- a/src/cmd/compile/internal/walk/stmt.go
+++ b/src/cmd/compile/internal/walk/stmt.go
@@ -40,7 +40,6 @@ func walkStmt(n ir.Node) ir.Node {
ir.OAS2MAPR,
ir.OCLOSE,
ir.OCOPY,
- ir.OCALLMETH,
ir.OCALLINTER,
ir.OCALL,
ir.OCALLFUNC,
diff --git a/src/cmd/compile/internal/walk/walk.go b/src/cmd/compile/internal/walk/walk.go
index 6e992a91b8..f687127fee 100644
--- a/src/cmd/compile/internal/walk/walk.go
+++ b/src/cmd/compile/internal/walk/walk.go
@@ -308,7 +308,7 @@ func mayCall(n ir.Node) bool {
default:
base.FatalfAt(n.Pos(), "mayCall %+v", n)
- case ir.OCALLFUNC, ir.OCALLMETH, ir.OCALLINTER,
+ case ir.OCALLFUNC, ir.OCALLINTER,
ir.OUNSAFEADD, ir.OUNSAFESLICE:
return true