mirror of
https://github.com/golang/go.git
synced 2025-05-28 19:02:22 +00: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:
parent
adba6c4fdf
commit
def7c65b70
@ -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
|
||||
|
@ -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") }
|
||||
|
39
src/cmd/compile/internal/gc/testdata/closure_ssa.go
vendored
Normal file
39
src/cmd/compile/internal/gc/testdata/closure_ssa.go
vendored
Normal 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")
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user