]> Cypherpunks repositories - gostls13.git/commitdiff
reflect: add tests for variadic method calls
authorIan Lance Taylor <iant@golang.org>
Wed, 8 Oct 2014 22:48:46 +0000 (15:48 -0700)
committerIan Lance Taylor <iant@golang.org>
Wed, 8 Oct 2014 22:48:46 +0000 (15:48 -0700)
These tests fail when using gccgo.  In gccgo using Interface
on the value of a method function is implemented using a
variant of MakeFunc.  That approach did not correctly handle
variadic functions.

LGTM=r
R=golang-codereviews, r
CC=golang-codereviews
https://golang.org/cl/151280043

src/reflect/all_test.go

index d17ef5c5e9a8a314d89c3f4f5b7f6350cbad0dd4..f13b91b742b93121430bad6f8a71cda5e81e3dc3 100644 (file)
@@ -1569,6 +1569,24 @@ func (p Point) Dist(scale int) int {
        return p.x*p.x*scale + p.y*p.y*scale
 }
 
+// This will be index 2.
+func (p Point) GCMethod(k int) int {
+       runtime.GC()
+       return k + p.x
+}
+
+// This will be index 3.
+func (p Point) TotalDist(points ...Point) int {
+       tot := 0
+       for _, q := range points {
+               dx := q.x - p.x
+               dy := q.y - p.y
+               tot += dx*dx + dy*dy // Should call Sqrt, but it's just a test.
+
+       }
+       return tot
+}
+
 func TestMethod(t *testing.T) {
        // Non-curried method of type.
        p := Point{3, 4}
@@ -1751,6 +1769,37 @@ func TestMethodValue(t *testing.T) {
        }
 }
 
+func TestVariadicMethodValue(t *testing.T) {
+       p := Point{3, 4}
+       points := []Point{{20, 21}, {22, 23}, {24, 25}}
+       want := int64(p.TotalDist(points[0], points[1], points[2]))
+
+       // Curried method of value.
+       tfunc := TypeOf((func(...Point) int)(nil))
+       v := ValueOf(p).Method(3)
+       if tt := v.Type(); tt != tfunc {
+               t.Errorf("Variadic Method Type is %s; want %s", tt, tfunc)
+       }
+       i := ValueOf(v.Interface()).Call([]Value{ValueOf(points[0]), ValueOf(points[1]), ValueOf(points[2])})[0].Int()
+       if i != want {
+               t.Errorf("Variadic Method returned %d; want %d", i, want)
+       }
+       i = ValueOf(v.Interface()).CallSlice([]Value{ValueOf(points)})[0].Int()
+       if i != want {
+               t.Errorf("Variadic Method CallSlice returned %d; want %d", i, want)
+       }
+
+       f := v.Interface().(func(...Point) int)
+       i = int64(f(points[0], points[1], points[2]))
+       if i != want {
+               t.Errorf("Variadic Method Interface returned %d; want %d", i, want)
+       }
+       i = int64(f(points...))
+       if i != want {
+               t.Errorf("Variadic Method Interface Slice returned %d; want %d", i, want)
+       }
+}
+
 // Reflect version of $GOROOT/test/method5.go
 
 // Concrete types implementing M method.
@@ -3770,11 +3819,6 @@ func TestReflectFuncTraceback(t *testing.T) {
        f.Call([]Value{})
 }
 
-func (p Point) GCMethod(k int) int {
-       runtime.GC()
-       return k + p.x
-}
-
 func TestReflectMethodTraceback(t *testing.T) {
        p := Point{3, 4}
        m := ValueOf(p).MethodByName("GCMethod")