aboutsummaryrefslogtreecommitdiff
path: root/src/cmd/compile/internal/typecheck/subr.go
diff options
context:
space:
mode:
authorKeith Randall <khr@golang.org>2020-11-28 16:01:58 -0800
committerKeith Randall <khr@golang.org>2020-12-29 18:04:10 +0000
commit0523d525ae0dea229cffc5634caddd0acbc066af (patch)
treead08e8b89b02662043d39e04ba410a601595f386 /src/cmd/compile/internal/typecheck/subr.go
parent9ea272e5ec5dd5eadd59d54c08377d5d9527a51b (diff)
downloadgo-0523d525ae0dea229cffc5634caddd0acbc066af.tar.gz
go-0523d525ae0dea229cffc5634caddd0acbc066af.zip
[dev.regabi] cmd/compile: separate out address taken computation from typechecker
This CL computes a second parallel addrtaken bit that we check against the old way of doing it. A subsequent CL will rip out the typechecker code and just use the new way. Change-Id: I62b7342c44f694144844695386f80088bbd40bf4 Reviewed-on: https://go-review.googlesource.com/c/go/+/275695 Trust: Keith Randall <khr@golang.org> Trust: Dan Scales <danscales@google.com> Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Dan Scales <danscales@google.com>
Diffstat (limited to 'src/cmd/compile/internal/typecheck/subr.go')
-rw-r--r--src/cmd/compile/internal/typecheck/subr.go48
1 files changed, 48 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/typecheck/subr.go b/src/cmd/compile/internal/typecheck/subr.go
index 178eba4484..8d31fea9ec 100644
--- a/src/cmd/compile/internal/typecheck/subr.go
+++ b/src/cmd/compile/internal/typecheck/subr.go
@@ -67,9 +67,57 @@ func NodAddr(n ir.Node) *ir.AddrExpr {
// nodAddrPos returns a node representing &n at position pos.
func NodAddrAt(pos src.XPos, n ir.Node) *ir.AddrExpr {
+ n = markAddrOf(n)
return ir.NewAddrExpr(pos, n)
}
+func markAddrOf(n ir.Node) ir.Node {
+ if incrementalAddrtaken {
+ // We can only do incremental addrtaken computation when it is ok
+ // to typecheck the argument of the OADDR. That's only safe after the
+ // main typecheck has completed.
+ // The argument to OADDR needs to be typechecked because &x[i] takes
+ // the address of x if x is an array, but not if x is a slice.
+ // Note: outervalue doesn't work correctly until n is typechecked.
+ n = typecheck(n, ctxExpr)
+ if x := ir.OuterValue(n); x.Op() == ir.ONAME {
+ x.Name().SetAddrtaken2(true)
+ }
+ } else {
+ // Remember that we built an OADDR without computing the Addrtaken bit for
+ // its argument. We'll do that later in bulk using computeAddrtaken.
+ dirtyAddrtaken = true
+ }
+ return n
+}
+
+// If incrementalAddrtaken is false, we do not compute Addrtaken for an OADDR Node
+// when it is built. The Addrtaken bits are set in bulk by computeAddrtaken.
+// If incrementalAddrtaken is true, then when an OADDR Node is built the Addrtaken
+// field of its argument is updated immediately.
+var incrementalAddrtaken = false
+
+// If dirtyAddrtaken is true, then there are OADDR whose corresponding arguments
+// have not yet been marked as Addrtaken.
+var dirtyAddrtaken = false
+
+func computeAddrtaken(top []ir.Node) {
+ for _, n := range top {
+ ir.Visit(n, func(n ir.Node) {
+ if n.Op() == ir.OADDR {
+ if x := ir.OuterValue(n.(*ir.AddrExpr).X); x.Op() == ir.ONAME {
+ x.Name().SetAddrtaken2(true)
+ if x.Name().IsClosureVar() {
+ // Mark the original variable as Addrtaken so that capturevars
+ // knows not to pass it by value.
+ x.Name().Defn.Name().SetAddrtaken2(true)
+ }
+ }
+ }
+ })
+ }
+}
+
func NodNil() ir.Node {
n := ir.NewNilExpr(base.Pos)
n.SetType(types.Types[types.TNIL])