There was a bug in the libgo implementation of reflect.Call when passing a function following a non-pointer type. This patch fixes the bug and adds a test. Bootstrapped and ran Go testsuite on x86_64-unknown-linux-gnu. Committed to mainline and 4.8 branch.
Ian
diff -r 7c369498bb81 libgo/go/reflect/all_test.go --- a/libgo/go/reflect/all_test.go Mon Sep 30 11:06:06 2013 -0700 +++ b/libgo/go/reflect/all_test.go Mon Sep 30 20:03:54 2013 -0700 @@ -2406,6 +2406,15 @@ } } +func TestFuncArg(t *testing.T) { + f1 := func(i int, f func(int) int) int { return f(i) } + f2 := func(i int) int { return i + 1 } + r := ValueOf(f1).Call([]Value{ValueOf(100), ValueOf(f2)}) + if r[0].Int() != 101 { + t.Errorf("function returned %d, want 101", r[0].Int()) + } +} + var tagGetTests = []struct { Tag StructTag Key string diff -r 7c369498bb81 libgo/go/reflect/value.go --- a/libgo/go/reflect/value.go Mon Sep 30 11:06:06 2013 -0700 +++ b/libgo/go/reflect/value.go Mon Sep 30 20:03:54 2013 -0700 @@ -433,7 +433,7 @@ if v.flag&flagMethod != 0 { nin++ } - firstPointer := len(in) > 0 && Kind(t.In(0).(*rtype).kind) != Ptr && v.flag&flagMethod == 0 && isMethod(v.typ) + firstPointer := len(in) > 0 && t.In(0).Kind() != Ptr && v.flag&flagMethod == 0 && isMethod(v.typ) params := make([]unsafe.Pointer, nin) off := 0 if v.flag&flagMethod != 0 { @@ -497,8 +497,10 @@ sawRet := false for i, c := range s { if c == '(' { + if parens == 0 { + params++ + } parens++ - params++ } else if c == ')' { parens-- } else if parens == 0 && c == ' ' && s[i+1] != '(' && !sawRet {