]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.regabi] cmd/compile: do not rely on CallExpr.Rargs for detect already walked...
authorCuong Manh Le <cuong.manhle.vn@gmail.com>
Wed, 6 Jan 2021 03:47:35 +0000 (10:47 +0700)
committerCuong Manh Le <cuong.manhle.vn@gmail.com>
Thu, 14 Jan 2021 05:48:28 +0000 (05:48 +0000)
Currently, there's an awkward issue with walk pass. When walking the AST
tree, the compiler generate code for runtime functions (using mkcall* variants),
add/modify the AST tree and walk new generated tree again. This causes the
double walking on some CallExpr, which is relying on checking Rargs to prevent
that. But checking Rargs has its own issue as well.

For functions that does not have arguments, this check is failed, and we
still double walk the CallExpr node.

This CL change the way that compiler detects double walking, by using
separated field instead of relying on Rargs. In perfect world, we should make
the compiler walks the AST tree just once, but it's not safe to do that at
this moment.

Passes toolstash -cmp.

Change-Id: Ifdd1e0f98940ddb1f574af2da2ac7f005b5fcadd
Reviewed-on: https://go-review.googlesource.com/c/go/+/283672
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>
src/cmd/compile/internal/ir/mini.go
src/cmd/compile/internal/walk/expr.go

index 4dd9a8807aadf4e17563f29c23c2c843d2f7408f..429f4ed360bb079bab78b351db88395d0a7907df 100644 (file)
@@ -58,6 +58,7 @@ const (
        miniTypecheckShift = 2
        miniDiag           = 1 << 4
        miniHasCall        = 1 << 5 // for miniStmt
+       miniWalked         = 1 << 6 // to prevent/catch re-walking
 )
 
 func (n *miniNode) Typecheck() uint8 { return n.bits.get2(miniTypecheckShift) }
@@ -71,6 +72,9 @@ func (n *miniNode) SetTypecheck(x uint8) {
 func (n *miniNode) Diag() bool     { return n.bits&miniDiag != 0 }
 func (n *miniNode) SetDiag(x bool) { n.bits.set(miniDiag, x) }
 
+func (n *miniNode) Walked() bool     { return n.bits&miniWalked != 0 }
+func (n *miniNode) SetWalked(x bool) { n.bits.set(miniWalked, x) }
+
 // Empty, immutable graph structure.
 
 func (n *miniNode) Init() Nodes { return Nodes{} }
index 893a95f403198c16ce3a0e966a1aa7c6e1b6289b..449f8ea3ec0fd5440073b6e967afecf830f7d2ce 100644 (file)
@@ -497,9 +497,10 @@ func walkCall(n *ir.CallExpr, init *ir.Nodes) ir.Node {
 }
 
 func walkCall1(n *ir.CallExpr, init *ir.Nodes) {
-       if len(n.Rargs) != 0 {
+       if n.Walked() {
                return // already walked
        }
+       n.SetWalked(true)
 
        // If this is a method call t.M(...),
        // rewrite into a function call T.M(t, ...).