Patchwork libgo patch committed: Fix reflect.Call passing function

login
register
mail settings
Submitter Ian Taylor
Date Oct. 1, 2013, 3:12 a.m.
Message ID <mcrbo39elb2.fsf@iant-glaptop.roam.corp.google.com>
Download mbox | patch
Permalink /patch/279319/
State New
Headers show

Comments

Ian Taylor - Oct. 1, 2013, 3:12 a.m.
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

Patch

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 {