1
0
mirror of https://github.com/golang/go synced 2024-10-05 16:41:21 -06:00

[dev.ssa] cmd/compile/internal/ssa: implement OCFUNC

Change-Id: Ieb9cddf8876bf8cd5ee1705d9210d22c3959e8cc
Reviewed-on: https://go-review.googlesource.com/14329
Reviewed-by: Keith Randall <khr@golang.org>
Run-TryBot: Todd Neal <todd@tneal.org>
This commit is contained in:
Todd Neal 2015-09-07 19:07:02 -05:00
parent adba6c4fdf
commit def7c65b70
3 changed files with 50 additions and 4 deletions

View File

@ -1203,6 +1203,9 @@ func (s *state) expr(n *Node) *ssa.Value {
s.stmtList(n.Ninit)
switch n.Op {
case OCFUNC:
aux := &ssa.ExternSymbol{n.Type, n.Left.Sym}
return s.entryNewValue1A(ssa.OpAddr, n.Type, aux, s.sb)
case ONAME:
if n.Class == PFUNC {
// "value" of a function is the address of the function's closure
@ -1296,16 +1299,17 @@ func (s *state) expr(n *Node) *ssa.Value {
case OCONVNOP:
to := n.Type
from := n.Left.Type
if to.Etype == TFUNC {
s.Unimplementedf("CONVNOP closure")
return nil
}
// Assume everything will work out, so set up our return value.
// Anything interesting that happens from here is a fatal.
x := s.expr(n.Left)
v := s.newValue1(ssa.OpCopy, to, x) // ensure that v has the right type
// CONVNOP closure
if to.Etype == TFUNC && from.IsPtr() {
return v
}
// named <--> unnamed type or typed <--> untyped const
if from.Etype == to.Etype {
return v

View File

@ -78,3 +78,6 @@ func TestRegalloc(t *testing.T) { runTest(t, "regalloc_ssa.go") }
func TestString(t *testing.T) { runTest(t, "string_ssa.go") }
func TestDeferNoReturn(t *testing.T) { buildTest(t, "deferNoReturn_ssa.go") }
// TestClosure tests closure related behavior.
func TestClosure(t *testing.T) { runTest(t, "closure_ssa.go") }

View File

@ -0,0 +1,39 @@
// Copyright 2015 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.
// map_ssa.go tests map operations.
package main
import "fmt"
var failed = false
func testCFunc_ssa() int {
switch { // prevent inlining
}
a := 0
b := func() {
switch {
}
a++
}
b()
b()
return a
}
func testCFunc() {
if want, got := 2, testCFunc_ssa(); got != want {
fmt.Printf("expected %d, got %d", want, got)
failed = true
}
}
func main() {
testCFunc()
if failed {
panic("failed")
}
}