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
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
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") }
--- /dev/null
+// 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")
+ }
+}