016-08-04 Bernd Edlinger <bernd.edlinger@hotmail.de>
[official-gcc.git] / libgo / go / reflect / all_test.go
blob7045e448ea386212b5f912c6d649ada9d859d6c4
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 package reflect_test
7 import (
8 "bytes"
9 "encoding/base64"
10 "flag"
11 "fmt"
12 "io"
13 "math"
14 "math/rand"
15 "os"
16 . "reflect"
17 "runtime"
18 "sort"
19 "strconv"
20 "strings"
21 "sync"
22 "testing"
23 "time"
24 "unicode"
25 "unicode/utf8"
26 "unsafe"
29 func TestBool(t *testing.T) {
30 v := ValueOf(true)
31 if v.Bool() != true {
32 t.Fatal("ValueOf(true).Bool() = false")
36 type integer int
37 type T struct {
38 a int
39 b float64
40 c string
41 d *int
44 type pair struct {
45 i interface{}
46 s string
49 func assert(t *testing.T, s, want string) {
50 if s != want {
51 t.Errorf("have %#q want %#q", s, want)
55 var typeTests = []pair{
56 {struct{ x int }{}, "int"},
57 {struct{ x int8 }{}, "int8"},
58 {struct{ x int16 }{}, "int16"},
59 {struct{ x int32 }{}, "int32"},
60 {struct{ x int64 }{}, "int64"},
61 {struct{ x uint }{}, "uint"},
62 {struct{ x uint8 }{}, "uint8"},
63 {struct{ x uint16 }{}, "uint16"},
64 {struct{ x uint32 }{}, "uint32"},
65 {struct{ x uint64 }{}, "uint64"},
66 {struct{ x float32 }{}, "float32"},
67 {struct{ x float64 }{}, "float64"},
68 {struct{ x int8 }{}, "int8"},
69 {struct{ x (**int8) }{}, "**int8"},
70 {struct{ x (**integer) }{}, "**reflect_test.integer"},
71 {struct{ x ([32]int32) }{}, "[32]int32"},
72 {struct{ x ([]int8) }{}, "[]int8"},
73 {struct{ x (map[string]int32) }{}, "map[string]int32"},
74 {struct{ x (chan<- string) }{}, "chan<- string"},
75 {struct {
76 x struct {
77 c chan *int32
78 d float32
80 }{},
81 "struct { c chan *int32; d float32 }",
83 {struct{ x (func(a int8, b int32)) }{}, "func(int8, int32)"},
84 {struct {
85 x struct {
86 c func(chan *integer, *int8)
88 }{},
89 "struct { c func(chan *reflect_test.integer, *int8) }",
91 {struct {
92 x struct {
93 a int8
94 b int32
96 }{},
97 "struct { a int8; b int32 }",
99 {struct {
100 x struct {
101 a int8
102 b int8
103 c int32
105 }{},
106 "struct { a int8; b int8; c int32 }",
108 {struct {
109 x struct {
110 a int8
111 b int8
112 c int8
113 d int32
115 }{},
116 "struct { a int8; b int8; c int8; d int32 }",
118 {struct {
119 x struct {
120 a int8
121 b int8
122 c int8
123 d int8
124 e int32
126 }{},
127 "struct { a int8; b int8; c int8; d int8; e int32 }",
129 {struct {
130 x struct {
131 a int8
132 b int8
133 c int8
134 d int8
135 e int8
136 f int32
138 }{},
139 "struct { a int8; b int8; c int8; d int8; e int8; f int32 }",
141 {struct {
142 x struct {
143 a int8 `reflect:"hi there"`
145 }{},
146 `struct { a int8 "reflect:\"hi there\"" }`,
148 {struct {
149 x struct {
150 a int8 `reflect:"hi \x00there\t\n\"\\"`
152 }{},
153 `struct { a int8 "reflect:\"hi \\x00there\\t\\n\\\"\\\\\"" }`,
155 {struct {
156 x struct {
157 f func(args ...int)
159 }{},
160 "struct { f func(...int) }",
162 {struct {
163 x (interface {
164 a(func(func(int) int) func(func(int)) int)
167 }{},
168 "interface { reflect_test.a(func(func(int) int) func(func(int)) int); reflect_test.b() }",
172 var valueTests = []pair{
173 {new(int), "132"},
174 {new(int8), "8"},
175 {new(int16), "16"},
176 {new(int32), "32"},
177 {new(int64), "64"},
178 {new(uint), "132"},
179 {new(uint8), "8"},
180 {new(uint16), "16"},
181 {new(uint32), "32"},
182 {new(uint64), "64"},
183 {new(float32), "256.25"},
184 {new(float64), "512.125"},
185 {new(complex64), "532.125+10i"},
186 {new(complex128), "564.25+1i"},
187 {new(string), "stringy cheese"},
188 {new(bool), "true"},
189 {new(*int8), "*int8(0)"},
190 {new(**int8), "**int8(0)"},
191 {new([5]int32), "[5]int32{0, 0, 0, 0, 0}"},
192 {new(**integer), "**reflect_test.integer(0)"},
193 {new(map[string]int32), "map[string]int32{<can't iterate on maps>}"},
194 {new(chan<- string), "chan<- string"},
195 {new(func(a int8, b int32)), "func(int8, int32)(0)"},
196 {new(struct {
197 c chan *int32
198 d float32
200 "struct { c chan *int32; d float32 }{chan *int32, 0}",
202 {new(struct{ c func(chan *integer, *int8) }),
203 "struct { c func(chan *reflect_test.integer, *int8) }{func(chan *reflect_test.integer, *int8)(0)}",
205 {new(struct {
206 a int8
207 b int32
209 "struct { a int8; b int32 }{0, 0}",
211 {new(struct {
212 a int8
213 b int8
214 c int32
216 "struct { a int8; b int8; c int32 }{0, 0, 0}",
220 func testType(t *testing.T, i int, typ Type, want string) {
221 s := typ.String()
222 if s != want {
223 t.Errorf("#%d: have %#q, want %#q", i, s, want)
227 func TestTypes(t *testing.T) {
228 for i, tt := range typeTests {
229 testType(t, i, ValueOf(tt.i).Field(0).Type(), tt.s)
233 func TestSet(t *testing.T) {
234 for i, tt := range valueTests {
235 v := ValueOf(tt.i)
236 v = v.Elem()
237 switch v.Kind() {
238 case Int:
239 v.SetInt(132)
240 case Int8:
241 v.SetInt(8)
242 case Int16:
243 v.SetInt(16)
244 case Int32:
245 v.SetInt(32)
246 case Int64:
247 v.SetInt(64)
248 case Uint:
249 v.SetUint(132)
250 case Uint8:
251 v.SetUint(8)
252 case Uint16:
253 v.SetUint(16)
254 case Uint32:
255 v.SetUint(32)
256 case Uint64:
257 v.SetUint(64)
258 case Float32:
259 v.SetFloat(256.25)
260 case Float64:
261 v.SetFloat(512.125)
262 case Complex64:
263 v.SetComplex(532.125 + 10i)
264 case Complex128:
265 v.SetComplex(564.25 + 1i)
266 case String:
267 v.SetString("stringy cheese")
268 case Bool:
269 v.SetBool(true)
271 s := valueToString(v)
272 if s != tt.s {
273 t.Errorf("#%d: have %#q, want %#q", i, s, tt.s)
278 func TestSetValue(t *testing.T) {
279 for i, tt := range valueTests {
280 v := ValueOf(tt.i).Elem()
281 switch v.Kind() {
282 case Int:
283 v.Set(ValueOf(int(132)))
284 case Int8:
285 v.Set(ValueOf(int8(8)))
286 case Int16:
287 v.Set(ValueOf(int16(16)))
288 case Int32:
289 v.Set(ValueOf(int32(32)))
290 case Int64:
291 v.Set(ValueOf(int64(64)))
292 case Uint:
293 v.Set(ValueOf(uint(132)))
294 case Uint8:
295 v.Set(ValueOf(uint8(8)))
296 case Uint16:
297 v.Set(ValueOf(uint16(16)))
298 case Uint32:
299 v.Set(ValueOf(uint32(32)))
300 case Uint64:
301 v.Set(ValueOf(uint64(64)))
302 case Float32:
303 v.Set(ValueOf(float32(256.25)))
304 case Float64:
305 v.Set(ValueOf(512.125))
306 case Complex64:
307 v.Set(ValueOf(complex64(532.125 + 10i)))
308 case Complex128:
309 v.Set(ValueOf(complex128(564.25 + 1i)))
310 case String:
311 v.Set(ValueOf("stringy cheese"))
312 case Bool:
313 v.Set(ValueOf(true))
315 s := valueToString(v)
316 if s != tt.s {
317 t.Errorf("#%d: have %#q, want %#q", i, s, tt.s)
322 var _i = 7
324 var valueToStringTests = []pair{
325 {123, "123"},
326 {123.5, "123.5"},
327 {byte(123), "123"},
328 {"abc", "abc"},
329 {T{123, 456.75, "hello", &_i}, "reflect_test.T{123, 456.75, hello, *int(&7)}"},
330 {new(chan *T), "*chan *reflect_test.T(&chan *reflect_test.T)"},
331 {[10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "[10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}"},
332 {&[10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "*[10]int(&[10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})"},
333 {[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}"},
334 {&[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, "*[]int(&[]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})"},
337 func TestValueToString(t *testing.T) {
338 for i, test := range valueToStringTests {
339 s := valueToString(ValueOf(test.i))
340 if s != test.s {
341 t.Errorf("#%d: have %#q, want %#q", i, s, test.s)
346 func TestArrayElemSet(t *testing.T) {
347 v := ValueOf(&[10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}).Elem()
348 v.Index(4).SetInt(123)
349 s := valueToString(v)
350 const want = "[10]int{1, 2, 3, 4, 123, 6, 7, 8, 9, 10}"
351 if s != want {
352 t.Errorf("[10]int: have %#q want %#q", s, want)
355 v = ValueOf([]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
356 v.Index(4).SetInt(123)
357 s = valueToString(v)
358 const want1 = "[]int{1, 2, 3, 4, 123, 6, 7, 8, 9, 10}"
359 if s != want1 {
360 t.Errorf("[]int: have %#q want %#q", s, want1)
364 func TestPtrPointTo(t *testing.T) {
365 var ip *int32
366 var i int32 = 1234
367 vip := ValueOf(&ip)
368 vi := ValueOf(&i).Elem()
369 vip.Elem().Set(vi.Addr())
370 if *ip != 1234 {
371 t.Errorf("got %d, want 1234", *ip)
374 ip = nil
375 vp := ValueOf(&ip).Elem()
376 vp.Set(Zero(vp.Type()))
377 if ip != nil {
378 t.Errorf("got non-nil (%p), want nil", ip)
382 func TestPtrSetNil(t *testing.T) {
383 var i int32 = 1234
384 ip := &i
385 vip := ValueOf(&ip)
386 vip.Elem().Set(Zero(vip.Elem().Type()))
387 if ip != nil {
388 t.Errorf("got non-nil (%d), want nil", *ip)
392 func TestMapSetNil(t *testing.T) {
393 m := make(map[string]int)
394 vm := ValueOf(&m)
395 vm.Elem().Set(Zero(vm.Elem().Type()))
396 if m != nil {
397 t.Errorf("got non-nil (%p), want nil", m)
401 func TestAll(t *testing.T) {
402 testType(t, 1, TypeOf((int8)(0)), "int8")
403 testType(t, 2, TypeOf((*int8)(nil)).Elem(), "int8")
405 typ := TypeOf((*struct {
406 c chan *int32
407 d float32
408 })(nil))
409 testType(t, 3, typ, "*struct { c chan *int32; d float32 }")
410 etyp := typ.Elem()
411 testType(t, 4, etyp, "struct { c chan *int32; d float32 }")
412 styp := etyp
413 f := styp.Field(0)
414 testType(t, 5, f.Type, "chan *int32")
416 f, present := styp.FieldByName("d")
417 if !present {
418 t.Errorf("FieldByName says present field is absent")
420 testType(t, 6, f.Type, "float32")
422 f, present = styp.FieldByName("absent")
423 if present {
424 t.Errorf("FieldByName says absent field is present")
427 typ = TypeOf([32]int32{})
428 testType(t, 7, typ, "[32]int32")
429 testType(t, 8, typ.Elem(), "int32")
431 typ = TypeOf((map[string]*int32)(nil))
432 testType(t, 9, typ, "map[string]*int32")
433 mtyp := typ
434 testType(t, 10, mtyp.Key(), "string")
435 testType(t, 11, mtyp.Elem(), "*int32")
437 typ = TypeOf((chan<- string)(nil))
438 testType(t, 12, typ, "chan<- string")
439 testType(t, 13, typ.Elem(), "string")
441 // make sure tag strings are not part of element type
442 typ = TypeOf(struct {
443 d []uint32 `reflect:"TAG"`
444 }{}).Field(0).Type
445 testType(t, 14, typ, "[]uint32")
448 func TestInterfaceGet(t *testing.T) {
449 var inter struct {
450 E interface{}
452 inter.E = 123.456
453 v1 := ValueOf(&inter)
454 v2 := v1.Elem().Field(0)
455 assert(t, v2.Type().String(), "interface {}")
456 i2 := v2.Interface()
457 v3 := ValueOf(i2)
458 assert(t, v3.Type().String(), "float64")
461 func TestInterfaceValue(t *testing.T) {
462 var inter struct {
463 E interface{}
465 inter.E = 123.456
466 v1 := ValueOf(&inter)
467 v2 := v1.Elem().Field(0)
468 assert(t, v2.Type().String(), "interface {}")
469 v3 := v2.Elem()
470 assert(t, v3.Type().String(), "float64")
472 i3 := v2.Interface()
473 if _, ok := i3.(float64); !ok {
474 t.Error("v2.Interface() did not return float64, got ", TypeOf(i3))
478 func TestFunctionValue(t *testing.T) {
479 var x interface{} = func() {}
480 v := ValueOf(x)
481 if fmt.Sprint(v.Interface()) != fmt.Sprint(x) {
482 t.Fatalf("TestFunction returned wrong pointer")
484 assert(t, v.Type().String(), "func()")
487 var appendTests = []struct {
488 orig, extra []int
490 {make([]int, 2, 4), []int{22}},
491 {make([]int, 2, 4), []int{22, 33, 44}},
494 func sameInts(x, y []int) bool {
495 if len(x) != len(y) {
496 return false
498 for i, xx := range x {
499 if xx != y[i] {
500 return false
503 return true
506 func TestAppend(t *testing.T) {
507 for i, test := range appendTests {
508 origLen, extraLen := len(test.orig), len(test.extra)
509 want := append(test.orig, test.extra...)
510 // Convert extra from []int to []Value.
511 e0 := make([]Value, len(test.extra))
512 for j, e := range test.extra {
513 e0[j] = ValueOf(e)
515 // Convert extra from []int to *SliceValue.
516 e1 := ValueOf(test.extra)
517 // Test Append.
518 a0 := ValueOf(test.orig)
519 have0 := Append(a0, e0...).Interface().([]int)
520 if !sameInts(have0, want) {
521 t.Errorf("Append #%d: have %v, want %v (%p %p)", i, have0, want, test.orig, have0)
523 // Check that the orig and extra slices were not modified.
524 if len(test.orig) != origLen {
525 t.Errorf("Append #%d origLen: have %v, want %v", i, len(test.orig), origLen)
527 if len(test.extra) != extraLen {
528 t.Errorf("Append #%d extraLen: have %v, want %v", i, len(test.extra), extraLen)
530 // Test AppendSlice.
531 a1 := ValueOf(test.orig)
532 have1 := AppendSlice(a1, e1).Interface().([]int)
533 if !sameInts(have1, want) {
534 t.Errorf("AppendSlice #%d: have %v, want %v", i, have1, want)
536 // Check that the orig and extra slices were not modified.
537 if len(test.orig) != origLen {
538 t.Errorf("AppendSlice #%d origLen: have %v, want %v", i, len(test.orig), origLen)
540 if len(test.extra) != extraLen {
541 t.Errorf("AppendSlice #%d extraLen: have %v, want %v", i, len(test.extra), extraLen)
546 func TestCopy(t *testing.T) {
547 a := []int{1, 2, 3, 4, 10, 9, 8, 7}
548 b := []int{11, 22, 33, 44, 1010, 99, 88, 77, 66, 55, 44}
549 c := []int{11, 22, 33, 44, 1010, 99, 88, 77, 66, 55, 44}
550 for i := 0; i < len(b); i++ {
551 if b[i] != c[i] {
552 t.Fatalf("b != c before test")
555 a1 := a
556 b1 := b
557 aa := ValueOf(&a1).Elem()
558 ab := ValueOf(&b1).Elem()
559 for tocopy := 1; tocopy <= 7; tocopy++ {
560 aa.SetLen(tocopy)
561 Copy(ab, aa)
562 aa.SetLen(8)
563 for i := 0; i < tocopy; i++ {
564 if a[i] != b[i] {
565 t.Errorf("(i) tocopy=%d a[%d]=%d, b[%d]=%d",
566 tocopy, i, a[i], i, b[i])
569 for i := tocopy; i < len(b); i++ {
570 if b[i] != c[i] {
571 if i < len(a) {
572 t.Errorf("(ii) tocopy=%d a[%d]=%d, b[%d]=%d, c[%d]=%d",
573 tocopy, i, a[i], i, b[i], i, c[i])
574 } else {
575 t.Errorf("(iii) tocopy=%d b[%d]=%d, c[%d]=%d",
576 tocopy, i, b[i], i, c[i])
578 } else {
579 t.Logf("tocopy=%d elem %d is okay\n", tocopy, i)
585 func TestCopyArray(t *testing.T) {
586 a := [8]int{1, 2, 3, 4, 10, 9, 8, 7}
587 b := [11]int{11, 22, 33, 44, 1010, 99, 88, 77, 66, 55, 44}
588 c := b
589 aa := ValueOf(&a).Elem()
590 ab := ValueOf(&b).Elem()
591 Copy(ab, aa)
592 for i := 0; i < len(a); i++ {
593 if a[i] != b[i] {
594 t.Errorf("(i) a[%d]=%d, b[%d]=%d", i, a[i], i, b[i])
597 for i := len(a); i < len(b); i++ {
598 if b[i] != c[i] {
599 t.Errorf("(ii) b[%d]=%d, c[%d]=%d", i, b[i], i, c[i])
600 } else {
601 t.Logf("elem %d is okay\n", i)
606 func TestBigUnnamedStruct(t *testing.T) {
607 b := struct{ a, b, c, d int64 }{1, 2, 3, 4}
608 v := ValueOf(b)
609 b1 := v.Interface().(struct {
610 a, b, c, d int64
612 if b1.a != b.a || b1.b != b.b || b1.c != b.c || b1.d != b.d {
613 t.Errorf("ValueOf(%v).Interface().(*Big) = %v", b, b1)
617 type big struct {
618 a, b, c, d, e int64
621 func TestBigStruct(t *testing.T) {
622 b := big{1, 2, 3, 4, 5}
623 v := ValueOf(b)
624 b1 := v.Interface().(big)
625 if b1.a != b.a || b1.b != b.b || b1.c != b.c || b1.d != b.d || b1.e != b.e {
626 t.Errorf("ValueOf(%v).Interface().(big) = %v", b, b1)
630 type Basic struct {
631 x int
632 y float32
635 type NotBasic Basic
637 type DeepEqualTest struct {
638 a, b interface{}
639 eq bool
642 // Simple functions for DeepEqual tests.
643 var (
644 fn1 func() // nil.
645 fn2 func() // nil.
646 fn3 = func() { fn1() } // Not nil.
649 type self struct{}
651 var deepEqualTests = []DeepEqualTest{
652 // Equalities
653 {nil, nil, true},
654 {1, 1, true},
655 {int32(1), int32(1), true},
656 {0.5, 0.5, true},
657 {float32(0.5), float32(0.5), true},
658 {"hello", "hello", true},
659 {make([]int, 10), make([]int, 10), true},
660 {&[3]int{1, 2, 3}, &[3]int{1, 2, 3}, true},
661 {Basic{1, 0.5}, Basic{1, 0.5}, true},
662 {error(nil), error(nil), true},
663 {map[int]string{1: "one", 2: "two"}, map[int]string{2: "two", 1: "one"}, true},
664 {fn1, fn2, true},
666 // Inequalities
667 {1, 2, false},
668 {int32(1), int32(2), false},
669 {0.5, 0.6, false},
670 {float32(0.5), float32(0.6), false},
671 {"hello", "hey", false},
672 {make([]int, 10), make([]int, 11), false},
673 {&[3]int{1, 2, 3}, &[3]int{1, 2, 4}, false},
674 {Basic{1, 0.5}, Basic{1, 0.6}, false},
675 {Basic{1, 0}, Basic{2, 0}, false},
676 {map[int]string{1: "one", 3: "two"}, map[int]string{2: "two", 1: "one"}, false},
677 {map[int]string{1: "one", 2: "txo"}, map[int]string{2: "two", 1: "one"}, false},
678 {map[int]string{1: "one"}, map[int]string{2: "two", 1: "one"}, false},
679 {map[int]string{2: "two", 1: "one"}, map[int]string{1: "one"}, false},
680 {nil, 1, false},
681 {1, nil, false},
682 {fn1, fn3, false},
683 {fn3, fn3, false},
684 {[][]int{{1}}, [][]int{{2}}, false},
685 {math.NaN(), math.NaN(), false},
686 {&[1]float64{math.NaN()}, &[1]float64{math.NaN()}, false},
687 {&[1]float64{math.NaN()}, self{}, true},
688 {[]float64{math.NaN()}, []float64{math.NaN()}, false},
689 {[]float64{math.NaN()}, self{}, true},
690 {map[float64]float64{math.NaN(): 1}, map[float64]float64{1: 2}, false},
691 {map[float64]float64{math.NaN(): 1}, self{}, true},
693 // Nil vs empty: not the same.
694 {[]int{}, []int(nil), false},
695 {[]int{}, []int{}, true},
696 {[]int(nil), []int(nil), true},
697 {map[int]int{}, map[int]int(nil), false},
698 {map[int]int{}, map[int]int{}, true},
699 {map[int]int(nil), map[int]int(nil), true},
701 // Mismatched types
702 {1, 1.0, false},
703 {int32(1), int64(1), false},
704 {0.5, "hello", false},
705 {[]int{1, 2, 3}, [3]int{1, 2, 3}, false},
706 {&[3]interface{}{1, 2, 4}, &[3]interface{}{1, 2, "s"}, false},
707 {Basic{1, 0.5}, NotBasic{1, 0.5}, false},
708 {map[uint]string{1: "one", 2: "two"}, map[int]string{2: "two", 1: "one"}, false},
711 func TestDeepEqual(t *testing.T) {
712 for _, test := range deepEqualTests {
713 if test.b == (self{}) {
714 test.b = test.a
716 if r := DeepEqual(test.a, test.b); r != test.eq {
717 t.Errorf("DeepEqual(%v, %v) = %v, want %v", test.a, test.b, r, test.eq)
722 func TestTypeOf(t *testing.T) {
723 // Special case for nil
724 if typ := TypeOf(nil); typ != nil {
725 t.Errorf("expected nil type for nil value; got %v", typ)
727 for _, test := range deepEqualTests {
728 v := ValueOf(test.a)
729 if !v.IsValid() {
730 continue
732 typ := TypeOf(test.a)
733 if typ != v.Type() {
734 t.Errorf("TypeOf(%v) = %v, but ValueOf(%v).Type() = %v", test.a, typ, test.a, v.Type())
739 type Recursive struct {
740 x int
741 r *Recursive
744 func TestDeepEqualRecursiveStruct(t *testing.T) {
745 a, b := new(Recursive), new(Recursive)
746 *a = Recursive{12, a}
747 *b = Recursive{12, b}
748 if !DeepEqual(a, b) {
749 t.Error("DeepEqual(recursive same) = false, want true")
753 type _Complex struct {
754 a int
755 b [3]*_Complex
756 c *string
757 d map[float64]float64
760 func TestDeepEqualComplexStruct(t *testing.T) {
761 m := make(map[float64]float64)
762 stra, strb := "hello", "hello"
763 a, b := new(_Complex), new(_Complex)
764 *a = _Complex{5, [3]*_Complex{a, b, a}, &stra, m}
765 *b = _Complex{5, [3]*_Complex{b, a, a}, &strb, m}
766 if !DeepEqual(a, b) {
767 t.Error("DeepEqual(complex same) = false, want true")
771 func TestDeepEqualComplexStructInequality(t *testing.T) {
772 m := make(map[float64]float64)
773 stra, strb := "hello", "helloo" // Difference is here
774 a, b := new(_Complex), new(_Complex)
775 *a = _Complex{5, [3]*_Complex{a, b, a}, &stra, m}
776 *b = _Complex{5, [3]*_Complex{b, a, a}, &strb, m}
777 if DeepEqual(a, b) {
778 t.Error("DeepEqual(complex different) = true, want false")
782 type UnexpT struct {
783 m map[int]int
786 func TestDeepEqualUnexportedMap(t *testing.T) {
787 // Check that DeepEqual can look at unexported fields.
788 x1 := UnexpT{map[int]int{1: 2}}
789 x2 := UnexpT{map[int]int{1: 2}}
790 if !DeepEqual(&x1, &x2) {
791 t.Error("DeepEqual(x1, x2) = false, want true")
794 y1 := UnexpT{map[int]int{2: 3}}
795 if DeepEqual(&x1, &y1) {
796 t.Error("DeepEqual(x1, y1) = true, want false")
800 func check2ndField(x interface{}, offs uintptr, t *testing.T) {
801 s := ValueOf(x)
802 f := s.Type().Field(1)
803 if f.Offset != offs {
804 t.Error("mismatched offsets in structure alignment:", f.Offset, offs)
808 // Check that structure alignment & offsets viewed through reflect agree with those
809 // from the compiler itself.
810 func TestAlignment(t *testing.T) {
811 type T1inner struct {
812 a int
814 type T1 struct {
815 T1inner
816 f int
818 type T2inner struct {
819 a, b int
821 type T2 struct {
822 T2inner
823 f int
826 x := T1{T1inner{2}, 17}
827 check2ndField(x, uintptr(unsafe.Pointer(&x.f))-uintptr(unsafe.Pointer(&x)), t)
829 x1 := T2{T2inner{2, 3}, 17}
830 check2ndField(x1, uintptr(unsafe.Pointer(&x1.f))-uintptr(unsafe.Pointer(&x1)), t)
833 func Nil(a interface{}, t *testing.T) {
834 n := ValueOf(a).Field(0)
835 if !n.IsNil() {
836 t.Errorf("%v should be nil", a)
840 func NotNil(a interface{}, t *testing.T) {
841 n := ValueOf(a).Field(0)
842 if n.IsNil() {
843 t.Errorf("value of type %v should not be nil", ValueOf(a).Type().String())
847 func TestIsNil(t *testing.T) {
848 // These implement IsNil.
849 // Wrap in extra struct to hide interface type.
850 doNil := []interface{}{
851 struct{ x *int }{},
852 struct{ x interface{} }{},
853 struct{ x map[string]int }{},
854 struct{ x func() bool }{},
855 struct{ x chan int }{},
856 struct{ x []string }{},
858 for _, ts := range doNil {
859 ty := TypeOf(ts).Field(0).Type
860 v := Zero(ty)
861 v.IsNil() // panics if not okay to call
864 // Check the implementations
865 var pi struct {
866 x *int
868 Nil(pi, t)
869 pi.x = new(int)
870 NotNil(pi, t)
872 var si struct {
873 x []int
875 Nil(si, t)
876 si.x = make([]int, 10)
877 NotNil(si, t)
879 var ci struct {
880 x chan int
882 Nil(ci, t)
883 ci.x = make(chan int)
884 NotNil(ci, t)
886 var mi struct {
887 x map[int]int
889 Nil(mi, t)
890 mi.x = make(map[int]int)
891 NotNil(mi, t)
893 var ii struct {
894 x interface{}
896 Nil(ii, t)
897 ii.x = 2
898 NotNil(ii, t)
900 var fi struct {
901 x func(t *testing.T)
903 Nil(fi, t)
904 fi.x = TestIsNil
905 NotNil(fi, t)
908 func TestInterfaceExtraction(t *testing.T) {
909 var s struct {
910 W io.Writer
913 s.W = os.Stdout
914 v := Indirect(ValueOf(&s)).Field(0).Interface()
915 if v != s.W.(interface{}) {
916 t.Error("Interface() on interface: ", v, s.W)
920 func TestNilPtrValueSub(t *testing.T) {
921 var pi *int
922 if pv := ValueOf(pi); pv.Elem().IsValid() {
923 t.Error("ValueOf((*int)(nil)).Elem().IsValid()")
927 func TestMap(t *testing.T) {
928 m := map[string]int{"a": 1, "b": 2}
929 mv := ValueOf(m)
930 if n := mv.Len(); n != len(m) {
931 t.Errorf("Len = %d, want %d", n, len(m))
933 keys := mv.MapKeys()
934 newmap := MakeMap(mv.Type())
935 for k, v := range m {
936 // Check that returned Keys match keys in range.
937 // These aren't required to be in the same order.
938 seen := false
939 for _, kv := range keys {
940 if kv.String() == k {
941 seen = true
942 break
945 if !seen {
946 t.Errorf("Missing key %q", k)
949 // Check that value lookup is correct.
950 vv := mv.MapIndex(ValueOf(k))
951 if vi := vv.Int(); vi != int64(v) {
952 t.Errorf("Key %q: have value %d, want %d", k, vi, v)
955 // Copy into new map.
956 newmap.SetMapIndex(ValueOf(k), ValueOf(v))
958 vv := mv.MapIndex(ValueOf("not-present"))
959 if vv.IsValid() {
960 t.Errorf("Invalid key: got non-nil value %s", valueToString(vv))
963 newm := newmap.Interface().(map[string]int)
964 if len(newm) != len(m) {
965 t.Errorf("length after copy: newm=%d, m=%d", len(newm), len(m))
968 for k, v := range newm {
969 mv, ok := m[k]
970 if mv != v {
971 t.Errorf("newm[%q] = %d, but m[%q] = %d, %v", k, v, k, mv, ok)
975 newmap.SetMapIndex(ValueOf("a"), Value{})
976 v, ok := newm["a"]
977 if ok {
978 t.Errorf("newm[\"a\"] = %d after delete", v)
981 mv = ValueOf(&m).Elem()
982 mv.Set(Zero(mv.Type()))
983 if m != nil {
984 t.Errorf("mv.Set(nil) failed")
988 func TestNilMap(t *testing.T) {
989 var m map[string]int
990 mv := ValueOf(m)
991 keys := mv.MapKeys()
992 if len(keys) != 0 {
993 t.Errorf(">0 keys for nil map: %v", keys)
996 // Check that value for missing key is zero.
997 x := mv.MapIndex(ValueOf("hello"))
998 if x.Kind() != Invalid {
999 t.Errorf("m.MapIndex(\"hello\") for nil map = %v, want Invalid Value", x)
1002 // Check big value too.
1003 var mbig map[string][10 << 20]byte
1004 x = ValueOf(mbig).MapIndex(ValueOf("hello"))
1005 if x.Kind() != Invalid {
1006 t.Errorf("mbig.MapIndex(\"hello\") for nil map = %v, want Invalid Value", x)
1009 // Test that deletes from a nil map succeed.
1010 mv.SetMapIndex(ValueOf("hi"), Value{})
1013 func TestChan(t *testing.T) {
1014 for loop := 0; loop < 2; loop++ {
1015 var c chan int
1016 var cv Value
1018 // check both ways to allocate channels
1019 switch loop {
1020 case 1:
1021 c = make(chan int, 1)
1022 cv = ValueOf(c)
1023 case 0:
1024 cv = MakeChan(TypeOf(c), 1)
1025 c = cv.Interface().(chan int)
1028 // Send
1029 cv.Send(ValueOf(2))
1030 if i := <-c; i != 2 {
1031 t.Errorf("reflect Send 2, native recv %d", i)
1034 // Recv
1035 c <- 3
1036 if i, ok := cv.Recv(); i.Int() != 3 || !ok {
1037 t.Errorf("native send 3, reflect Recv %d, %t", i.Int(), ok)
1040 // TryRecv fail
1041 val, ok := cv.TryRecv()
1042 if val.IsValid() || ok {
1043 t.Errorf("TryRecv on empty chan: %s, %t", valueToString(val), ok)
1046 // TryRecv success
1047 c <- 4
1048 val, ok = cv.TryRecv()
1049 if !val.IsValid() {
1050 t.Errorf("TryRecv on ready chan got nil")
1051 } else if i := val.Int(); i != 4 || !ok {
1052 t.Errorf("native send 4, TryRecv %d, %t", i, ok)
1055 // TrySend fail
1056 c <- 100
1057 ok = cv.TrySend(ValueOf(5))
1058 i := <-c
1059 if ok {
1060 t.Errorf("TrySend on full chan succeeded: value %d", i)
1063 // TrySend success
1064 ok = cv.TrySend(ValueOf(6))
1065 if !ok {
1066 t.Errorf("TrySend on empty chan failed")
1067 select {
1068 case x := <-c:
1069 t.Errorf("TrySend failed but it did send %d", x)
1070 default:
1072 } else {
1073 if i = <-c; i != 6 {
1074 t.Errorf("TrySend 6, recv %d", i)
1078 // Close
1079 c <- 123
1080 cv.Close()
1081 if i, ok := cv.Recv(); i.Int() != 123 || !ok {
1082 t.Errorf("send 123 then close; Recv %d, %t", i.Int(), ok)
1084 if i, ok := cv.Recv(); i.Int() != 0 || ok {
1085 t.Errorf("after close Recv %d, %t", i.Int(), ok)
1089 // check creation of unbuffered channel
1090 var c chan int
1091 cv := MakeChan(TypeOf(c), 0)
1092 c = cv.Interface().(chan int)
1093 if cv.TrySend(ValueOf(7)) {
1094 t.Errorf("TrySend on sync chan succeeded")
1096 if v, ok := cv.TryRecv(); v.IsValid() || ok {
1097 t.Errorf("TryRecv on sync chan succeeded: isvalid=%v ok=%v", v.IsValid(), ok)
1100 // len/cap
1101 cv = MakeChan(TypeOf(c), 10)
1102 c = cv.Interface().(chan int)
1103 for i := 0; i < 3; i++ {
1104 c <- i
1106 if l, m := cv.Len(), cv.Cap(); l != len(c) || m != cap(c) {
1107 t.Errorf("Len/Cap = %d/%d want %d/%d", l, m, len(c), cap(c))
1111 // caseInfo describes a single case in a select test.
1112 type caseInfo struct {
1113 desc string
1114 canSelect bool
1115 recv Value
1116 closed bool
1117 helper func()
1118 panic bool
1121 var allselect = flag.Bool("allselect", false, "exhaustive select test")
1123 func TestSelect(t *testing.T) {
1124 selectWatch.once.Do(func() { go selectWatcher() })
1126 var x exhaustive
1127 nch := 0
1128 newop := func(n int, cap int) (ch, val Value) {
1129 nch++
1130 if nch%101%2 == 1 {
1131 c := make(chan int, cap)
1132 ch = ValueOf(c)
1133 val = ValueOf(n)
1134 } else {
1135 c := make(chan string, cap)
1136 ch = ValueOf(c)
1137 val = ValueOf(fmt.Sprint(n))
1139 return
1142 for n := 0; x.Next(); n++ {
1143 if testing.Short() && n >= 1000 {
1144 break
1146 if n >= 100000 && !*allselect {
1147 break
1149 if n%100000 == 0 && testing.Verbose() {
1150 println("TestSelect", n)
1152 var cases []SelectCase
1153 var info []caseInfo
1155 // Ready send.
1156 if x.Maybe() {
1157 ch, val := newop(len(cases), 1)
1158 cases = append(cases, SelectCase{
1159 Dir: SelectSend,
1160 Chan: ch,
1161 Send: val,
1163 info = append(info, caseInfo{desc: "ready send", canSelect: true})
1166 // Ready recv.
1167 if x.Maybe() {
1168 ch, val := newop(len(cases), 1)
1169 ch.Send(val)
1170 cases = append(cases, SelectCase{
1171 Dir: SelectRecv,
1172 Chan: ch,
1174 info = append(info, caseInfo{desc: "ready recv", canSelect: true, recv: val})
1177 // Blocking send.
1178 if x.Maybe() {
1179 ch, val := newop(len(cases), 0)
1180 cases = append(cases, SelectCase{
1181 Dir: SelectSend,
1182 Chan: ch,
1183 Send: val,
1185 // Let it execute?
1186 if x.Maybe() {
1187 f := func() { ch.Recv() }
1188 info = append(info, caseInfo{desc: "blocking send", helper: f})
1189 } else {
1190 info = append(info, caseInfo{desc: "blocking send"})
1194 // Blocking recv.
1195 if x.Maybe() {
1196 ch, val := newop(len(cases), 0)
1197 cases = append(cases, SelectCase{
1198 Dir: SelectRecv,
1199 Chan: ch,
1201 // Let it execute?
1202 if x.Maybe() {
1203 f := func() { ch.Send(val) }
1204 info = append(info, caseInfo{desc: "blocking recv", recv: val, helper: f})
1205 } else {
1206 info = append(info, caseInfo{desc: "blocking recv"})
1210 // Zero Chan send.
1211 if x.Maybe() {
1212 // Maybe include value to send.
1213 var val Value
1214 if x.Maybe() {
1215 val = ValueOf(100)
1217 cases = append(cases, SelectCase{
1218 Dir: SelectSend,
1219 Send: val,
1221 info = append(info, caseInfo{desc: "zero Chan send"})
1224 // Zero Chan receive.
1225 if x.Maybe() {
1226 cases = append(cases, SelectCase{
1227 Dir: SelectRecv,
1229 info = append(info, caseInfo{desc: "zero Chan recv"})
1232 // nil Chan send.
1233 if x.Maybe() {
1234 cases = append(cases, SelectCase{
1235 Dir: SelectSend,
1236 Chan: ValueOf((chan int)(nil)),
1237 Send: ValueOf(101),
1239 info = append(info, caseInfo{desc: "nil Chan send"})
1242 // nil Chan recv.
1243 if x.Maybe() {
1244 cases = append(cases, SelectCase{
1245 Dir: SelectRecv,
1246 Chan: ValueOf((chan int)(nil)),
1248 info = append(info, caseInfo{desc: "nil Chan recv"})
1251 // closed Chan send.
1252 if x.Maybe() {
1253 ch := make(chan int)
1254 close(ch)
1255 cases = append(cases, SelectCase{
1256 Dir: SelectSend,
1257 Chan: ValueOf(ch),
1258 Send: ValueOf(101),
1260 info = append(info, caseInfo{desc: "closed Chan send", canSelect: true, panic: true})
1263 // closed Chan recv.
1264 if x.Maybe() {
1265 ch, val := newop(len(cases), 0)
1266 ch.Close()
1267 val = Zero(val.Type())
1268 cases = append(cases, SelectCase{
1269 Dir: SelectRecv,
1270 Chan: ch,
1272 info = append(info, caseInfo{desc: "closed Chan recv", canSelect: true, closed: true, recv: val})
1275 var helper func() // goroutine to help the select complete
1277 // Add default? Must be last case here, but will permute.
1278 // Add the default if the select would otherwise
1279 // block forever, and maybe add it anyway.
1280 numCanSelect := 0
1281 canProceed := false
1282 canBlock := true
1283 canPanic := false
1284 helpers := []int{}
1285 for i, c := range info {
1286 if c.canSelect {
1287 canProceed = true
1288 canBlock = false
1289 numCanSelect++
1290 if c.panic {
1291 canPanic = true
1293 } else if c.helper != nil {
1294 canProceed = true
1295 helpers = append(helpers, i)
1298 if !canProceed || x.Maybe() {
1299 cases = append(cases, SelectCase{
1300 Dir: SelectDefault,
1302 info = append(info, caseInfo{desc: "default", canSelect: canBlock})
1303 numCanSelect++
1304 } else if canBlock {
1305 // Select needs to communicate with another goroutine.
1306 cas := &info[helpers[x.Choose(len(helpers))]]
1307 helper = cas.helper
1308 cas.canSelect = true
1309 numCanSelect++
1312 // Permute cases and case info.
1313 // Doing too much here makes the exhaustive loop
1314 // too exhausting, so just do two swaps.
1315 for loop := 0; loop < 2; loop++ {
1316 i := x.Choose(len(cases))
1317 j := x.Choose(len(cases))
1318 cases[i], cases[j] = cases[j], cases[i]
1319 info[i], info[j] = info[j], info[i]
1322 if helper != nil {
1323 // We wait before kicking off a goroutine to satisfy a blocked select.
1324 // The pause needs to be big enough to let the select block before
1325 // we run the helper, but if we lose that race once in a while it's okay: the
1326 // select will just proceed immediately. Not a big deal.
1327 // For short tests we can grow [sic] the timeout a bit without fear of taking too long
1328 pause := 10 * time.Microsecond
1329 if testing.Short() {
1330 pause = 100 * time.Microsecond
1332 time.AfterFunc(pause, helper)
1335 // Run select.
1336 i, recv, recvOK, panicErr := runSelect(cases, info)
1337 if panicErr != nil && !canPanic {
1338 t.Fatalf("%s\npanicked unexpectedly: %v", fmtSelect(info), panicErr)
1340 if panicErr == nil && canPanic && numCanSelect == 1 {
1341 t.Fatalf("%s\nselected #%d incorrectly (should panic)", fmtSelect(info), i)
1343 if panicErr != nil {
1344 continue
1347 cas := info[i]
1348 if !cas.canSelect {
1349 recvStr := ""
1350 if recv.IsValid() {
1351 recvStr = fmt.Sprintf(", received %v, %v", recv.Interface(), recvOK)
1353 t.Fatalf("%s\nselected #%d incorrectly%s", fmtSelect(info), i, recvStr)
1354 continue
1356 if cas.panic {
1357 t.Fatalf("%s\nselected #%d incorrectly (case should panic)", fmtSelect(info), i)
1358 continue
1361 if cases[i].Dir == SelectRecv {
1362 if !recv.IsValid() {
1363 t.Fatalf("%s\nselected #%d but got %v, %v, want %v, %v", fmtSelect(info), i, recv, recvOK, cas.recv.Interface(), !cas.closed)
1365 if !cas.recv.IsValid() {
1366 t.Fatalf("%s\nselected #%d but internal error: missing recv value", fmtSelect(info), i)
1368 if recv.Interface() != cas.recv.Interface() || recvOK != !cas.closed {
1369 if recv.Interface() == cas.recv.Interface() && recvOK == !cas.closed {
1370 t.Fatalf("%s\nselected #%d, got %#v, %v, and DeepEqual is broken on %T", fmtSelect(info), i, recv.Interface(), recvOK, recv.Interface())
1372 t.Fatalf("%s\nselected #%d but got %#v, %v, want %#v, %v", fmtSelect(info), i, recv.Interface(), recvOK, cas.recv.Interface(), !cas.closed)
1374 } else {
1375 if recv.IsValid() || recvOK {
1376 t.Fatalf("%s\nselected #%d but got %v, %v, want %v, %v", fmtSelect(info), i, recv, recvOK, Value{}, false)
1382 // selectWatch and the selectWatcher are a watchdog mechanism for running Select.
1383 // If the selectWatcher notices that the select has been blocked for >1 second, it prints
1384 // an error describing the select and panics the entire test binary.
1385 var selectWatch struct {
1386 sync.Mutex
1387 once sync.Once
1388 now time.Time
1389 info []caseInfo
1392 func selectWatcher() {
1393 for {
1394 time.Sleep(1 * time.Second)
1395 selectWatch.Lock()
1396 if selectWatch.info != nil && time.Since(selectWatch.now) > 10*time.Second {
1397 fmt.Fprintf(os.Stderr, "TestSelect:\n%s blocked indefinitely\n", fmtSelect(selectWatch.info))
1398 panic("select stuck")
1400 selectWatch.Unlock()
1404 // runSelect runs a single select test.
1405 // It returns the values returned by Select but also returns
1406 // a panic value if the Select panics.
1407 func runSelect(cases []SelectCase, info []caseInfo) (chosen int, recv Value, recvOK bool, panicErr interface{}) {
1408 defer func() {
1409 panicErr = recover()
1411 selectWatch.Lock()
1412 selectWatch.info = nil
1413 selectWatch.Unlock()
1416 selectWatch.Lock()
1417 selectWatch.now = time.Now()
1418 selectWatch.info = info
1419 selectWatch.Unlock()
1421 chosen, recv, recvOK = Select(cases)
1422 return
1425 // fmtSelect formats the information about a single select test.
1426 func fmtSelect(info []caseInfo) string {
1427 var buf bytes.Buffer
1428 fmt.Fprintf(&buf, "\nselect {\n")
1429 for i, cas := range info {
1430 fmt.Fprintf(&buf, "%d: %s", i, cas.desc)
1431 if cas.recv.IsValid() {
1432 fmt.Fprintf(&buf, " val=%#v", cas.recv.Interface())
1434 if cas.canSelect {
1435 fmt.Fprintf(&buf, " canselect")
1437 if cas.panic {
1438 fmt.Fprintf(&buf, " panic")
1440 fmt.Fprintf(&buf, "\n")
1442 fmt.Fprintf(&buf, "}")
1443 return buf.String()
1446 type two [2]uintptr
1448 // Difficult test for function call because of
1449 // implicit padding between arguments.
1450 func dummy(b byte, c int, d byte, e two, f byte, g float32, h byte) (i byte, j int, k byte, l two, m byte, n float32, o byte) {
1451 return b, c, d, e, f, g, h
1454 func TestFunc(t *testing.T) {
1455 ret := ValueOf(dummy).Call([]Value{
1456 ValueOf(byte(10)),
1457 ValueOf(20),
1458 ValueOf(byte(30)),
1459 ValueOf(two{40, 50}),
1460 ValueOf(byte(60)),
1461 ValueOf(float32(70)),
1462 ValueOf(byte(80)),
1464 if len(ret) != 7 {
1465 t.Fatalf("Call returned %d values, want 7", len(ret))
1468 i := byte(ret[0].Uint())
1469 j := int(ret[1].Int())
1470 k := byte(ret[2].Uint())
1471 l := ret[3].Interface().(two)
1472 m := byte(ret[4].Uint())
1473 n := float32(ret[5].Float())
1474 o := byte(ret[6].Uint())
1476 if i != 10 || j != 20 || k != 30 || l != (two{40, 50}) || m != 60 || n != 70 || o != 80 {
1477 t.Errorf("Call returned %d, %d, %d, %v, %d, %g, %d; want 10, 20, 30, [40, 50], 60, 70, 80", i, j, k, l, m, n, o)
1480 for i, v := range ret {
1481 if v.CanAddr() {
1482 t.Errorf("result %d is addressable", i)
1487 type emptyStruct struct{}
1489 type nonEmptyStruct struct {
1490 member int
1493 func returnEmpty() emptyStruct {
1494 return emptyStruct{}
1497 func takesEmpty(e emptyStruct) {
1500 func returnNonEmpty(i int) nonEmptyStruct {
1501 return nonEmptyStruct{member: i}
1504 func takesNonEmpty(n nonEmptyStruct) int {
1505 return n.member
1508 func TestCallWithStruct(t *testing.T) {
1509 r := ValueOf(returnEmpty).Call(nil)
1510 if len(r) != 1 || r[0].Type() != TypeOf(emptyStruct{}) {
1511 t.Errorf("returning empty struct returned %#v instead", r)
1513 r = ValueOf(takesEmpty).Call([]Value{ValueOf(emptyStruct{})})
1514 if len(r) != 0 {
1515 t.Errorf("takesEmpty returned values: %#v", r)
1517 r = ValueOf(returnNonEmpty).Call([]Value{ValueOf(42)})
1518 if len(r) != 1 || r[0].Type() != TypeOf(nonEmptyStruct{}) || r[0].Field(0).Int() != 42 {
1519 t.Errorf("returnNonEmpty returned %#v", r)
1521 r = ValueOf(takesNonEmpty).Call([]Value{ValueOf(nonEmptyStruct{member: 42})})
1522 if len(r) != 1 || r[0].Type() != TypeOf(1) || r[0].Int() != 42 {
1523 t.Errorf("takesNonEmpty returned %#v", r)
1527 func BenchmarkCall(b *testing.B) {
1528 fv := ValueOf(func(a, b string) {})
1529 b.ReportAllocs()
1530 b.RunParallel(func(pb *testing.PB) {
1531 args := []Value{ValueOf("a"), ValueOf("b")}
1532 for pb.Next() {
1533 fv.Call(args)
1538 func TestMakeFunc(t *testing.T) {
1539 f := dummy
1540 fv := MakeFunc(TypeOf(f), func(in []Value) []Value { return in })
1541 ValueOf(&f).Elem().Set(fv)
1543 // Call g with small arguments so that there is
1544 // something predictable (and different from the
1545 // correct results) in those positions on the stack.
1546 g := dummy
1547 g(1, 2, 3, two{4, 5}, 6, 7, 8)
1549 // Call constructed function f.
1550 i, j, k, l, m, n, o := f(10, 20, 30, two{40, 50}, 60, 70, 80)
1551 if i != 10 || j != 20 || k != 30 || l != (two{40, 50}) || m != 60 || n != 70 || o != 80 {
1552 t.Errorf("Call returned %d, %d, %d, %v, %d, %g, %d; want 10, 20, 30, [40, 50], 60, 70, 80", i, j, k, l, m, n, o)
1556 func TestMakeFuncInterface(t *testing.T) {
1557 fn := func(i int) int { return i }
1558 incr := func(in []Value) []Value {
1559 return []Value{ValueOf(int(in[0].Int() + 1))}
1561 fv := MakeFunc(TypeOf(fn), incr)
1562 ValueOf(&fn).Elem().Set(fv)
1563 if r := fn(2); r != 3 {
1564 t.Errorf("Call returned %d, want 3", r)
1566 if r := fv.Call([]Value{ValueOf(14)})[0].Int(); r != 15 {
1567 t.Errorf("Call returned %d, want 15", r)
1569 if r := fv.Interface().(func(int) int)(26); r != 27 {
1570 t.Errorf("Call returned %d, want 27", r)
1574 func TestMakeFuncVariadic(t *testing.T) {
1575 // Test that variadic arguments are packed into a slice and passed as last arg
1576 fn := func(_ int, is ...int) []int { return nil }
1577 fv := MakeFunc(TypeOf(fn), func(in []Value) []Value { return in[1:2] })
1578 ValueOf(&fn).Elem().Set(fv)
1580 r := fn(1, 2, 3)
1581 if r[0] != 2 || r[1] != 3 {
1582 t.Errorf("Call returned [%v, %v]; want 2, 3", r[0], r[1])
1585 r = fn(1, []int{2, 3}...)
1586 if r[0] != 2 || r[1] != 3 {
1587 t.Errorf("Call returned [%v, %v]; want 2, 3", r[0], r[1])
1590 r = fv.Call([]Value{ValueOf(1), ValueOf(2), ValueOf(3)})[0].Interface().([]int)
1591 if r[0] != 2 || r[1] != 3 {
1592 t.Errorf("Call returned [%v, %v]; want 2, 3", r[0], r[1])
1595 r = fv.CallSlice([]Value{ValueOf(1), ValueOf([]int{2, 3})})[0].Interface().([]int)
1596 if r[0] != 2 || r[1] != 3 {
1597 t.Errorf("Call returned [%v, %v]; want 2, 3", r[0], r[1])
1600 f := fv.Interface().(func(int, ...int) []int)
1602 r = f(1, 2, 3)
1603 if r[0] != 2 || r[1] != 3 {
1604 t.Errorf("Call returned [%v, %v]; want 2, 3", r[0], r[1])
1606 r = f(1, []int{2, 3}...)
1607 if r[0] != 2 || r[1] != 3 {
1608 t.Errorf("Call returned [%v, %v]; want 2, 3", r[0], r[1])
1612 type Point struct {
1613 x, y int
1616 // This will be index 0.
1617 func (p Point) AnotherMethod(scale int) int {
1618 return -1
1621 // This will be index 1.
1622 func (p Point) Dist(scale int) int {
1623 //println("Point.Dist", p.x, p.y, scale)
1624 return p.x*p.x*scale + p.y*p.y*scale
1627 // This will be index 2.
1628 func (p Point) GCMethod(k int) int {
1629 runtime.GC()
1630 return k + p.x
1633 // This will be index 3.
1634 func (p Point) TotalDist(points ...Point) int {
1635 tot := 0
1636 for _, q := range points {
1637 dx := q.x - p.x
1638 dy := q.y - p.y
1639 tot += dx*dx + dy*dy // Should call Sqrt, but it's just a test.
1642 return tot
1645 func TestMethod(t *testing.T) {
1646 // Non-curried method of type.
1647 p := Point{3, 4}
1648 i := TypeOf(p).Method(1).Func.Call([]Value{ValueOf(p), ValueOf(10)})[0].Int()
1649 if i != 250 {
1650 t.Errorf("Type Method returned %d; want 250", i)
1653 m, ok := TypeOf(p).MethodByName("Dist")
1654 if !ok {
1655 t.Fatalf("method by name failed")
1657 i = m.Func.Call([]Value{ValueOf(p), ValueOf(11)})[0].Int()
1658 if i != 275 {
1659 t.Errorf("Type MethodByName returned %d; want 275", i)
1662 i = TypeOf(&p).Method(1).Func.Call([]Value{ValueOf(&p), ValueOf(12)})[0].Int()
1663 if i != 300 {
1664 t.Errorf("Pointer Type Method returned %d; want 300", i)
1667 m, ok = TypeOf(&p).MethodByName("Dist")
1668 if !ok {
1669 t.Fatalf("ptr method by name failed")
1671 i = m.Func.Call([]Value{ValueOf(&p), ValueOf(13)})[0].Int()
1672 if i != 325 {
1673 t.Errorf("Pointer Type MethodByName returned %d; want 325", i)
1676 // Curried method of value.
1677 tfunc := TypeOf((func(int) int)(nil))
1678 v := ValueOf(p).Method(1)
1679 if tt := v.Type(); tt != tfunc {
1680 t.Errorf("Value Method Type is %s; want %s", tt, tfunc)
1682 i = v.Call([]Value{ValueOf(14)})[0].Int()
1683 if i != 350 {
1684 t.Errorf("Value Method returned %d; want 350", i)
1686 v = ValueOf(p).MethodByName("Dist")
1687 if tt := v.Type(); tt != tfunc {
1688 t.Errorf("Value MethodByName Type is %s; want %s", tt, tfunc)
1690 i = v.Call([]Value{ValueOf(15)})[0].Int()
1691 if i != 375 {
1692 t.Errorf("Value MethodByName returned %d; want 375", i)
1695 // Curried method of pointer.
1696 v = ValueOf(&p).Method(1)
1697 if tt := v.Type(); tt != tfunc {
1698 t.Errorf("Pointer Value Method Type is %s; want %s", tt, tfunc)
1700 i = v.Call([]Value{ValueOf(16)})[0].Int()
1701 if i != 400 {
1702 t.Errorf("Pointer Value Method returned %d; want 400", i)
1704 v = ValueOf(&p).MethodByName("Dist")
1705 if tt := v.Type(); tt != tfunc {
1706 t.Errorf("Pointer Value MethodByName Type is %s; want %s", tt, tfunc)
1708 i = v.Call([]Value{ValueOf(17)})[0].Int()
1709 if i != 425 {
1710 t.Errorf("Pointer Value MethodByName returned %d; want 425", i)
1713 // Curried method of interface value.
1714 // Have to wrap interface value in a struct to get at it.
1715 // Passing it to ValueOf directly would
1716 // access the underlying Point, not the interface.
1717 var x interface {
1718 Dist(int) int
1719 } = p
1720 pv := ValueOf(&x).Elem()
1721 v = pv.Method(0)
1722 if tt := v.Type(); tt != tfunc {
1723 t.Errorf("Interface Method Type is %s; want %s", tt, tfunc)
1725 i = v.Call([]Value{ValueOf(18)})[0].Int()
1726 if i != 450 {
1727 t.Errorf("Interface Method returned %d; want 450", i)
1729 v = pv.MethodByName("Dist")
1730 if tt := v.Type(); tt != tfunc {
1731 t.Errorf("Interface MethodByName Type is %s; want %s", tt, tfunc)
1733 i = v.Call([]Value{ValueOf(19)})[0].Int()
1734 if i != 475 {
1735 t.Errorf("Interface MethodByName returned %d; want 475", i)
1739 func TestMethodValue(t *testing.T) {
1740 p := Point{3, 4}
1741 var i int64
1743 // Curried method of value.
1744 tfunc := TypeOf((func(int) int)(nil))
1745 v := ValueOf(p).Method(1)
1746 if tt := v.Type(); tt != tfunc {
1747 t.Errorf("Value Method Type is %s; want %s", tt, tfunc)
1749 i = ValueOf(v.Interface()).Call([]Value{ValueOf(10)})[0].Int()
1750 if i != 250 {
1751 t.Errorf("Value Method returned %d; want 250", i)
1753 v = ValueOf(p).MethodByName("Dist")
1754 if tt := v.Type(); tt != tfunc {
1755 t.Errorf("Value MethodByName Type is %s; want %s", tt, tfunc)
1757 i = ValueOf(v.Interface()).Call([]Value{ValueOf(11)})[0].Int()
1758 if i != 275 {
1759 t.Errorf("Value MethodByName returned %d; want 275", i)
1762 // Curried method of pointer.
1763 v = ValueOf(&p).Method(1)
1764 if tt := v.Type(); tt != tfunc {
1765 t.Errorf("Pointer Value Method Type is %s; want %s", tt, tfunc)
1767 i = ValueOf(v.Interface()).Call([]Value{ValueOf(12)})[0].Int()
1768 if i != 300 {
1769 t.Errorf("Pointer Value Method returned %d; want 300", i)
1771 v = ValueOf(&p).MethodByName("Dist")
1772 if tt := v.Type(); tt != tfunc {
1773 t.Errorf("Pointer Value MethodByName Type is %s; want %s", tt, tfunc)
1775 i = ValueOf(v.Interface()).Call([]Value{ValueOf(13)})[0].Int()
1776 if i != 325 {
1777 t.Errorf("Pointer Value MethodByName returned %d; want 325", i)
1780 // Curried method of pointer to pointer.
1781 pp := &p
1782 v = ValueOf(&pp).Elem().Method(1)
1783 if tt := v.Type(); tt != tfunc {
1784 t.Errorf("Pointer Pointer Value Method Type is %s; want %s", tt, tfunc)
1786 i = ValueOf(v.Interface()).Call([]Value{ValueOf(14)})[0].Int()
1787 if i != 350 {
1788 t.Errorf("Pointer Pointer Value Method returned %d; want 350", i)
1790 v = ValueOf(&pp).Elem().MethodByName("Dist")
1791 if tt := v.Type(); tt != tfunc {
1792 t.Errorf("Pointer Pointer Value MethodByName Type is %s; want %s", tt, tfunc)
1794 i = ValueOf(v.Interface()).Call([]Value{ValueOf(15)})[0].Int()
1795 if i != 375 {
1796 t.Errorf("Pointer Pointer Value MethodByName returned %d; want 375", i)
1799 // Curried method of interface value.
1800 // Have to wrap interface value in a struct to get at it.
1801 // Passing it to ValueOf directly would
1802 // access the underlying Point, not the interface.
1803 var s = struct {
1804 X interface {
1805 Dist(int) int
1807 }{p}
1808 pv := ValueOf(s).Field(0)
1809 v = pv.Method(0)
1810 if tt := v.Type(); tt != tfunc {
1811 t.Errorf("Interface Method Type is %s; want %s", tt, tfunc)
1813 i = ValueOf(v.Interface()).Call([]Value{ValueOf(16)})[0].Int()
1814 if i != 400 {
1815 t.Errorf("Interface Method returned %d; want 400", i)
1817 v = pv.MethodByName("Dist")
1818 if tt := v.Type(); tt != tfunc {
1819 t.Errorf("Interface MethodByName Type is %s; want %s", tt, tfunc)
1821 i = ValueOf(v.Interface()).Call([]Value{ValueOf(17)})[0].Int()
1822 if i != 425 {
1823 t.Errorf("Interface MethodByName returned %d; want 425", i)
1827 func TestVariadicMethodValue(t *testing.T) {
1828 p := Point{3, 4}
1829 points := []Point{{20, 21}, {22, 23}, {24, 25}}
1830 want := int64(p.TotalDist(points[0], points[1], points[2]))
1832 // Curried method of value.
1833 tfunc := TypeOf((func(...Point) int)(nil))
1834 v := ValueOf(p).Method(3)
1835 if tt := v.Type(); tt != tfunc {
1836 t.Errorf("Variadic Method Type is %s; want %s", tt, tfunc)
1838 i := ValueOf(v.Interface()).Call([]Value{ValueOf(points[0]), ValueOf(points[1]), ValueOf(points[2])})[0].Int()
1839 if i != want {
1840 t.Errorf("Variadic Method returned %d; want %d", i, want)
1842 i = ValueOf(v.Interface()).CallSlice([]Value{ValueOf(points)})[0].Int()
1843 if i != want {
1844 t.Errorf("Variadic Method CallSlice returned %d; want %d", i, want)
1847 f := v.Interface().(func(...Point) int)
1848 i = int64(f(points[0], points[1], points[2]))
1849 if i != want {
1850 t.Errorf("Variadic Method Interface returned %d; want %d", i, want)
1852 i = int64(f(points...))
1853 if i != want {
1854 t.Errorf("Variadic Method Interface Slice returned %d; want %d", i, want)
1858 // Reflect version of $GOROOT/test/method5.go
1860 // Concrete types implementing M method.
1861 // Smaller than a word, word-sized, larger than a word.
1862 // Value and pointer receivers.
1864 type Tinter interface {
1865 M(int, byte) (byte, int)
1868 type Tsmallv byte
1870 func (v Tsmallv) M(x int, b byte) (byte, int) { return b, x + int(v) }
1872 type Tsmallp byte
1874 func (p *Tsmallp) M(x int, b byte) (byte, int) { return b, x + int(*p) }
1876 type Twordv uintptr
1878 func (v Twordv) M(x int, b byte) (byte, int) { return b, x + int(v) }
1880 type Twordp uintptr
1882 func (p *Twordp) M(x int, b byte) (byte, int) { return b, x + int(*p) }
1884 type Tbigv [2]uintptr
1886 func (v Tbigv) M(x int, b byte) (byte, int) { return b, x + int(v[0]) + int(v[1]) }
1888 type Tbigp [2]uintptr
1890 func (p *Tbigp) M(x int, b byte) (byte, int) { return b, x + int(p[0]) + int(p[1]) }
1892 type tinter interface {
1893 m(int, byte) (byte, int)
1896 // Embedding via pointer.
1898 type Tm1 struct {
1902 type Tm2 struct {
1903 *Tm3
1906 type Tm3 struct {
1907 *Tm4
1910 type Tm4 struct {
1913 func (t4 Tm4) M(x int, b byte) (byte, int) { return b, x + 40 }
1915 func TestMethod5(t *testing.T) {
1916 CheckF := func(name string, f func(int, byte) (byte, int), inc int) {
1917 b, x := f(1000, 99)
1918 if b != 99 || x != 1000+inc {
1919 t.Errorf("%s(1000, 99) = %v, %v, want 99, %v", name, b, x, 1000+inc)
1923 CheckV := func(name string, i Value, inc int) {
1924 bx := i.Method(0).Call([]Value{ValueOf(1000), ValueOf(byte(99))})
1925 b := bx[0].Interface()
1926 x := bx[1].Interface()
1927 if b != byte(99) || x != 1000+inc {
1928 t.Errorf("direct %s.M(1000, 99) = %v, %v, want 99, %v", name, b, x, 1000+inc)
1931 CheckF(name+".M", i.Method(0).Interface().(func(int, byte) (byte, int)), inc)
1934 var TinterType = TypeOf(new(Tinter)).Elem()
1936 CheckI := func(name string, i interface{}, inc int) {
1937 v := ValueOf(i)
1938 CheckV(name, v, inc)
1939 CheckV("(i="+name+")", v.Convert(TinterType), inc)
1942 sv := Tsmallv(1)
1943 CheckI("sv", sv, 1)
1944 CheckI("&sv", &sv, 1)
1946 sp := Tsmallp(2)
1947 CheckI("&sp", &sp, 2)
1949 wv := Twordv(3)
1950 CheckI("wv", wv, 3)
1951 CheckI("&wv", &wv, 3)
1953 wp := Twordp(4)
1954 CheckI("&wp", &wp, 4)
1956 bv := Tbigv([2]uintptr{5, 6})
1957 CheckI("bv", bv, 11)
1958 CheckI("&bv", &bv, 11)
1960 bp := Tbigp([2]uintptr{7, 8})
1961 CheckI("&bp", &bp, 15)
1963 t4 := Tm4{}
1964 t3 := Tm3{&t4}
1965 t2 := Tm2{&t3}
1966 t1 := Tm1{t2}
1967 CheckI("t4", t4, 40)
1968 CheckI("&t4", &t4, 40)
1969 CheckI("t3", t3, 40)
1970 CheckI("&t3", &t3, 40)
1971 CheckI("t2", t2, 40)
1972 CheckI("&t2", &t2, 40)
1973 CheckI("t1", t1, 40)
1974 CheckI("&t1", &t1, 40)
1976 var tnil Tinter
1977 vnil := ValueOf(&tnil).Elem()
1978 shouldPanic(func() { vnil.Method(0) })
1981 func TestInterfaceSet(t *testing.T) {
1982 p := &Point{3, 4}
1984 var s struct {
1985 I interface{}
1986 P interface {
1987 Dist(int) int
1990 sv := ValueOf(&s).Elem()
1991 sv.Field(0).Set(ValueOf(p))
1992 if q := s.I.(*Point); q != p {
1993 t.Errorf("i: have %p want %p", q, p)
1996 pv := sv.Field(1)
1997 pv.Set(ValueOf(p))
1998 if q := s.P.(*Point); q != p {
1999 t.Errorf("i: have %p want %p", q, p)
2002 i := pv.Method(0).Call([]Value{ValueOf(10)})[0].Int()
2003 if i != 250 {
2004 t.Errorf("Interface Method returned %d; want 250", i)
2008 type T1 struct {
2009 a string
2013 func TestAnonymousFields(t *testing.T) {
2014 var field StructField
2015 var ok bool
2016 var t1 T1
2017 type1 := TypeOf(t1)
2018 if field, ok = type1.FieldByName("int"); !ok {
2019 t.Fatal("no field 'int'")
2021 if field.Index[0] != 1 {
2022 t.Error("field index should be 1; is", field.Index)
2026 type FTest struct {
2027 s interface{}
2028 name string
2029 index []int
2030 value int
2033 type D1 struct {
2034 d int
2036 type D2 struct {
2037 d int
2040 type S0 struct {
2041 A, B, C int
2046 type S1 struct {
2047 B int
2051 type S2 struct {
2052 A int
2056 type S1x struct {
2060 type S1y struct {
2064 type S3 struct {
2067 D, E int
2068 *S1y
2071 type S4 struct {
2073 A int
2076 // The X in S6 and S7 annihilate, but they also block the X in S8.S9.
2077 type S5 struct {
2083 type S6 struct {
2084 X int
2087 type S7 S6
2089 type S8 struct {
2093 type S9 struct {
2094 X int
2095 Y int
2098 // The X in S11.S6 and S12.S6 annihilate, but they also block the X in S13.S8.S9.
2099 type S10 struct {
2105 type S11 struct {
2109 type S12 struct {
2113 type S13 struct {
2117 // The X in S15.S11.S1 and S16.S11.S1 annihilate.
2118 type S14 struct {
2123 type S15 struct {
2127 type S16 struct {
2131 var fieldTests = []FTest{
2132 {struct{}{}, "", nil, 0},
2133 {struct{}{}, "Foo", nil, 0},
2134 {S0{A: 'a'}, "A", []int{0}, 'a'},
2135 {S0{}, "D", nil, 0},
2136 {S1{S0: S0{A: 'a'}}, "A", []int{1, 0}, 'a'},
2137 {S1{B: 'b'}, "B", []int{0}, 'b'},
2138 {S1{}, "S0", []int{1}, 0},
2139 {S1{S0: S0{C: 'c'}}, "C", []int{1, 2}, 'c'},
2140 {S2{A: 'a'}, "A", []int{0}, 'a'},
2141 {S2{}, "S1", []int{1}, 0},
2142 {S2{S1: &S1{B: 'b'}}, "B", []int{1, 0}, 'b'},
2143 {S2{S1: &S1{S0: S0{C: 'c'}}}, "C", []int{1, 1, 2}, 'c'},
2144 {S2{}, "D", nil, 0},
2145 {S3{}, "S1", nil, 0},
2146 {S3{S2: S2{A: 'a'}}, "A", []int{1, 0}, 'a'},
2147 {S3{}, "B", nil, 0},
2148 {S3{D: 'd'}, "D", []int{2}, 0},
2149 {S3{E: 'e'}, "E", []int{3}, 'e'},
2150 {S4{A: 'a'}, "A", []int{1}, 'a'},
2151 {S4{}, "B", nil, 0},
2152 {S5{}, "X", nil, 0},
2153 {S5{}, "Y", []int{2, 0, 1}, 0},
2154 {S10{}, "X", nil, 0},
2155 {S10{}, "Y", []int{2, 0, 0, 1}, 0},
2156 {S14{}, "X", nil, 0},
2159 func TestFieldByIndex(t *testing.T) {
2160 for _, test := range fieldTests {
2161 s := TypeOf(test.s)
2162 f := s.FieldByIndex(test.index)
2163 if f.Name != "" {
2164 if test.index != nil {
2165 if f.Name != test.name {
2166 t.Errorf("%s.%s found; want %s", s.Name(), f.Name, test.name)
2168 } else {
2169 t.Errorf("%s.%s found", s.Name(), f.Name)
2171 } else if len(test.index) > 0 {
2172 t.Errorf("%s.%s not found", s.Name(), test.name)
2175 if test.value != 0 {
2176 v := ValueOf(test.s).FieldByIndex(test.index)
2177 if v.IsValid() {
2178 if x, ok := v.Interface().(int); ok {
2179 if x != test.value {
2180 t.Errorf("%s%v is %d; want %d", s.Name(), test.index, x, test.value)
2182 } else {
2183 t.Errorf("%s%v value not an int", s.Name(), test.index)
2185 } else {
2186 t.Errorf("%s%v value not found", s.Name(), test.index)
2192 func TestFieldByName(t *testing.T) {
2193 for _, test := range fieldTests {
2194 s := TypeOf(test.s)
2195 f, found := s.FieldByName(test.name)
2196 if found {
2197 if test.index != nil {
2198 // Verify field depth and index.
2199 if len(f.Index) != len(test.index) {
2200 t.Errorf("%s.%s depth %d; want %d: %v vs %v", s.Name(), test.name, len(f.Index), len(test.index), f.Index, test.index)
2201 } else {
2202 for i, x := range f.Index {
2203 if x != test.index[i] {
2204 t.Errorf("%s.%s.Index[%d] is %d; want %d", s.Name(), test.name, i, x, test.index[i])
2208 } else {
2209 t.Errorf("%s.%s found", s.Name(), f.Name)
2211 } else if len(test.index) > 0 {
2212 t.Errorf("%s.%s not found", s.Name(), test.name)
2215 if test.value != 0 {
2216 v := ValueOf(test.s).FieldByName(test.name)
2217 if v.IsValid() {
2218 if x, ok := v.Interface().(int); ok {
2219 if x != test.value {
2220 t.Errorf("%s.%s is %d; want %d", s.Name(), test.name, x, test.value)
2222 } else {
2223 t.Errorf("%s.%s value not an int", s.Name(), test.name)
2225 } else {
2226 t.Errorf("%s.%s value not found", s.Name(), test.name)
2232 func TestImportPath(t *testing.T) {
2233 tests := []struct {
2234 t Type
2235 path string
2237 {TypeOf(&base64.Encoding{}).Elem(), "encoding/base64"},
2238 {TypeOf(int(0)), ""},
2239 {TypeOf(int8(0)), ""},
2240 {TypeOf(int16(0)), ""},
2241 {TypeOf(int32(0)), ""},
2242 {TypeOf(int64(0)), ""},
2243 {TypeOf(uint(0)), ""},
2244 {TypeOf(uint8(0)), ""},
2245 {TypeOf(uint16(0)), ""},
2246 {TypeOf(uint32(0)), ""},
2247 {TypeOf(uint64(0)), ""},
2248 {TypeOf(uintptr(0)), ""},
2249 {TypeOf(float32(0)), ""},
2250 {TypeOf(float64(0)), ""},
2251 {TypeOf(complex64(0)), ""},
2252 {TypeOf(complex128(0)), ""},
2253 {TypeOf(byte(0)), ""},
2254 {TypeOf(rune(0)), ""},
2255 {TypeOf([]byte(nil)), ""},
2256 {TypeOf([]rune(nil)), ""},
2257 {TypeOf(string("")), ""},
2258 {TypeOf((*interface{})(nil)).Elem(), ""},
2259 {TypeOf((*byte)(nil)), ""},
2260 {TypeOf((*rune)(nil)), ""},
2261 {TypeOf((*int64)(nil)), ""},
2262 {TypeOf(map[string]int{}), ""},
2263 {TypeOf((*error)(nil)).Elem(), ""},
2264 {TypeOf((*Point)(nil)), ""},
2265 {TypeOf((*Point)(nil)).Elem(), "reflect_test"},
2267 for _, test := range tests {
2268 if path := test.t.PkgPath(); path != test.path {
2269 t.Errorf("%v.PkgPath() = %q, want %q", test.t, path, test.path)
2274 func TestFieldPkgPath(t *testing.T) {
2275 typ := TypeOf(struct {
2276 Exported string
2277 unexported string
2278 OtherPkgFields
2279 }{})
2280 for _, test := range []struct {
2281 index []int
2282 pkgPath string
2283 anonymous bool
2285 {[]int{0}, "", false}, // Exported
2286 {[]int{1}, "reflect_test", false}, // unexported
2287 {[]int{2}, "", true}, // OtherPkgFields
2288 {[]int{2, 0}, "", false}, // OtherExported
2289 {[]int{2, 1}, "reflect", false}, // otherUnexported
2291 f := typ.FieldByIndex(test.index)
2292 if got, want := f.PkgPath, test.pkgPath; got != want {
2293 t.Errorf("Field(%d).PkgPath = %q, want %q", test.index, got, want)
2295 if got, want := f.Anonymous, test.anonymous; got != want {
2296 t.Errorf("Field(%d).Anonymous = %v, want %v", test.index, got, want)
2301 func TestVariadicType(t *testing.T) {
2302 // Test example from Type documentation.
2303 var f func(x int, y ...float64)
2304 typ := TypeOf(f)
2305 if typ.NumIn() == 2 && typ.In(0) == TypeOf(int(0)) {
2306 sl := typ.In(1)
2307 if sl.Kind() == Slice {
2308 if sl.Elem() == TypeOf(0.0) {
2309 // ok
2310 return
2315 // Failed
2316 t.Errorf("want NumIn() = 2, In(0) = int, In(1) = []float64")
2317 s := fmt.Sprintf("have NumIn() = %d", typ.NumIn())
2318 for i := 0; i < typ.NumIn(); i++ {
2319 s += fmt.Sprintf(", In(%d) = %s", i, typ.In(i))
2321 t.Error(s)
2324 type inner struct {
2325 x int
2328 type outer struct {
2329 y int
2330 inner
2333 func (*inner) M() {}
2334 func (*outer) M() {}
2336 func TestNestedMethods(t *testing.T) {
2337 t.Skip("fails on gccgo due to function wrappers")
2338 typ := TypeOf((*outer)(nil))
2339 if typ.NumMethod() != 1 || typ.Method(0).Func.Pointer() != ValueOf((*outer).M).Pointer() {
2340 t.Errorf("Wrong method table for outer: (M=%p)", (*outer).M)
2341 for i := 0; i < typ.NumMethod(); i++ {
2342 m := typ.Method(i)
2343 t.Errorf("\t%d: %s %#x\n", i, m.Name, m.Func.Pointer())
2348 type unexp struct{}
2350 func (*unexp) f() (int32, int8) { return 7, 7 }
2351 func (*unexp) g() (int64, int8) { return 8, 8 }
2353 type unexpI interface {
2354 f() (int32, int8)
2357 var unexpi unexpI = new(unexp)
2359 func TestUnexportedMethods(t *testing.T) {
2360 typ := TypeOf(unexpi)
2362 if got := typ.NumMethod(); got != 0 {
2363 t.Errorf("NumMethod=%d, want 0 satisfied methods", got)
2367 type InnerInt struct {
2368 X int
2371 type OuterInt struct {
2372 Y int
2373 InnerInt
2376 func (i *InnerInt) M() int {
2377 return i.X
2380 func TestEmbeddedMethods(t *testing.T) {
2381 /* This part of the test fails on gccgo due to function wrappers.
2382 typ := TypeOf((*OuterInt)(nil))
2383 if typ.NumMethod() != 1 || typ.Method(0).Func.Pointer() != ValueOf((*OuterInt).M).Pointer() {
2384 t.Errorf("Wrong method table for OuterInt: (m=%p)", (*OuterInt).M)
2385 for i := 0; i < typ.NumMethod(); i++ {
2386 m := typ.Method(i)
2387 t.Errorf("\t%d: %s %#x\n", i, m.Name, m.Func.Pointer())
2392 i := &InnerInt{3}
2393 if v := ValueOf(i).Method(0).Call(nil)[0].Int(); v != 3 {
2394 t.Errorf("i.M() = %d, want 3", v)
2397 o := &OuterInt{1, InnerInt{2}}
2398 if v := ValueOf(o).Method(0).Call(nil)[0].Int(); v != 2 {
2399 t.Errorf("i.M() = %d, want 2", v)
2402 f := (*OuterInt).M
2403 if v := f(o); v != 2 {
2404 t.Errorf("f(o) = %d, want 2", v)
2408 type FuncDDD func(...interface{}) error
2410 func (f FuncDDD) M() {}
2412 func TestNumMethodOnDDD(t *testing.T) {
2413 rv := ValueOf((FuncDDD)(nil))
2414 if n := rv.NumMethod(); n != 1 {
2415 t.Fatalf("NumMethod()=%d, want 1", n)
2419 func TestPtrTo(t *testing.T) {
2420 var i int
2422 typ := TypeOf(i)
2423 for i = 0; i < 100; i++ {
2424 typ = PtrTo(typ)
2426 for i = 0; i < 100; i++ {
2427 typ = typ.Elem()
2429 if typ != TypeOf(i) {
2430 t.Errorf("after 100 PtrTo and Elem, have %s, want %s", typ, TypeOf(i))
2434 func TestPtrToGC(t *testing.T) {
2435 type T *uintptr
2436 tt := TypeOf(T(nil))
2437 pt := PtrTo(tt)
2438 const n = 100
2439 var x []interface{}
2440 for i := 0; i < n; i++ {
2441 v := New(pt)
2442 p := new(*uintptr)
2443 *p = new(uintptr)
2444 **p = uintptr(i)
2445 v.Elem().Set(ValueOf(p).Convert(pt))
2446 x = append(x, v.Interface())
2448 runtime.GC()
2450 for i, xi := range x {
2451 k := ValueOf(xi).Elem().Elem().Elem().Interface().(uintptr)
2452 if k != uintptr(i) {
2453 t.Errorf("lost x[%d] = %d, want %d", i, k, i)
2458 func TestAddr(t *testing.T) {
2459 var p struct {
2460 X, Y int
2463 v := ValueOf(&p)
2464 v = v.Elem()
2465 v = v.Addr()
2466 v = v.Elem()
2467 v = v.Field(0)
2468 v.SetInt(2)
2469 if p.X != 2 {
2470 t.Errorf("Addr.Elem.Set failed to set value")
2473 // Again but take address of the ValueOf value.
2474 // Exercises generation of PtrTypes not present in the binary.
2475 q := &p
2476 v = ValueOf(&q).Elem()
2477 v = v.Addr()
2478 v = v.Elem()
2479 v = v.Elem()
2480 v = v.Addr()
2481 v = v.Elem()
2482 v = v.Field(0)
2483 v.SetInt(3)
2484 if p.X != 3 {
2485 t.Errorf("Addr.Elem.Set failed to set value")
2488 // Starting without pointer we should get changed value
2489 // in interface.
2490 qq := p
2491 v = ValueOf(&qq).Elem()
2492 v0 := v
2493 v = v.Addr()
2494 v = v.Elem()
2495 v = v.Field(0)
2496 v.SetInt(4)
2497 if p.X != 3 { // should be unchanged from last time
2498 t.Errorf("somehow value Set changed original p")
2500 p = v0.Interface().(struct {
2501 X, Y int
2503 if p.X != 4 {
2504 t.Errorf("Addr.Elem.Set valued to set value in top value")
2507 // Verify that taking the address of a type gives us a pointer
2508 // which we can convert back using the usual interface
2509 // notation.
2510 var s struct {
2511 B *bool
2513 ps := ValueOf(&s).Elem().Field(0).Addr().Interface()
2514 *(ps.(**bool)) = new(bool)
2515 if s.B == nil {
2516 t.Errorf("Addr.Interface direct assignment failed")
2520 /* gccgo does do allocations here.
2522 func noAlloc(t *testing.T, n int, f func(int)) {
2523 if testing.Short() {
2524 t.Skip("skipping malloc count in short mode")
2526 if runtime.GOMAXPROCS(0) > 1 {
2527 t.Skip("skipping; GOMAXPROCS>1")
2529 i := -1
2530 allocs := testing.AllocsPerRun(n, func() {
2531 f(i)
2534 if allocs > 0 {
2535 t.Errorf("%d iterations: got %v mallocs, want 0", n, allocs)
2539 func TestAllocations(t *testing.T) {
2540 noAlloc(t, 100, func(j int) {
2541 var i interface{}
2542 var v Value
2544 // We can uncomment this when compiler escape analysis
2545 // is good enough to see that the integer assigned to i
2546 // does not escape and therefore need not be allocated.
2548 // i = 42 + j
2549 // v = ValueOf(i)
2550 // if int(v.Int()) != 42+j {
2551 // panic("wrong int")
2552 // }
2554 i = func(j int) int { return j }
2555 v = ValueOf(i)
2556 if v.Interface().(func(int) int)(j) != j {
2557 panic("wrong result")
2564 func TestSmallNegativeInt(t *testing.T) {
2565 i := int16(-1)
2566 v := ValueOf(i)
2567 if v.Int() != -1 {
2568 t.Errorf("int16(-1).Int() returned %v", v.Int())
2572 func TestIndex(t *testing.T) {
2573 xs := []byte{1, 2, 3, 4, 5, 6, 7, 8}
2574 v := ValueOf(xs).Index(3).Interface().(byte)
2575 if v != xs[3] {
2576 t.Errorf("xs.Index(3) = %v; expected %v", v, xs[3])
2578 xa := [8]byte{10, 20, 30, 40, 50, 60, 70, 80}
2579 v = ValueOf(xa).Index(2).Interface().(byte)
2580 if v != xa[2] {
2581 t.Errorf("xa.Index(2) = %v; expected %v", v, xa[2])
2583 s := "0123456789"
2584 v = ValueOf(s).Index(3).Interface().(byte)
2585 if v != s[3] {
2586 t.Errorf("s.Index(3) = %v; expected %v", v, s[3])
2590 func TestSlice(t *testing.T) {
2591 xs := []int{1, 2, 3, 4, 5, 6, 7, 8}
2592 v := ValueOf(xs).Slice(3, 5).Interface().([]int)
2593 if len(v) != 2 {
2594 t.Errorf("len(xs.Slice(3, 5)) = %d", len(v))
2596 if cap(v) != 5 {
2597 t.Errorf("cap(xs.Slice(3, 5)) = %d", cap(v))
2599 if !DeepEqual(v[0:5], xs[3:]) {
2600 t.Errorf("xs.Slice(3, 5)[0:5] = %v", v[0:5])
2602 xa := [8]int{10, 20, 30, 40, 50, 60, 70, 80}
2603 v = ValueOf(&xa).Elem().Slice(2, 5).Interface().([]int)
2604 if len(v) != 3 {
2605 t.Errorf("len(xa.Slice(2, 5)) = %d", len(v))
2607 if cap(v) != 6 {
2608 t.Errorf("cap(xa.Slice(2, 5)) = %d", cap(v))
2610 if !DeepEqual(v[0:6], xa[2:]) {
2611 t.Errorf("xs.Slice(2, 5)[0:6] = %v", v[0:6])
2613 s := "0123456789"
2614 vs := ValueOf(s).Slice(3, 5).Interface().(string)
2615 if vs != s[3:5] {
2616 t.Errorf("s.Slice(3, 5) = %q; expected %q", vs, s[3:5])
2619 rv := ValueOf(&xs).Elem()
2620 rv = rv.Slice(3, 4)
2621 ptr2 := rv.Pointer()
2622 rv = rv.Slice(5, 5)
2623 ptr3 := rv.Pointer()
2624 if ptr3 != ptr2 {
2625 t.Errorf("xs.Slice(3,4).Slice3(5,5).Pointer() = %#x, want %#x", ptr3, ptr2)
2629 func TestSlice3(t *testing.T) {
2630 xs := []int{1, 2, 3, 4, 5, 6, 7, 8}
2631 v := ValueOf(xs).Slice3(3, 5, 7).Interface().([]int)
2632 if len(v) != 2 {
2633 t.Errorf("len(xs.Slice3(3, 5, 7)) = %d", len(v))
2635 if cap(v) != 4 {
2636 t.Errorf("cap(xs.Slice3(3, 5, 7)) = %d", cap(v))
2638 if !DeepEqual(v[0:4], xs[3:7:7]) {
2639 t.Errorf("xs.Slice3(3, 5, 7)[0:4] = %v", v[0:4])
2641 rv := ValueOf(&xs).Elem()
2642 shouldPanic(func() { rv.Slice3(1, 2, 1) })
2643 shouldPanic(func() { rv.Slice3(1, 1, 11) })
2644 shouldPanic(func() { rv.Slice3(2, 2, 1) })
2646 xa := [8]int{10, 20, 30, 40, 50, 60, 70, 80}
2647 v = ValueOf(&xa).Elem().Slice3(2, 5, 6).Interface().([]int)
2648 if len(v) != 3 {
2649 t.Errorf("len(xa.Slice(2, 5, 6)) = %d", len(v))
2651 if cap(v) != 4 {
2652 t.Errorf("cap(xa.Slice(2, 5, 6)) = %d", cap(v))
2654 if !DeepEqual(v[0:4], xa[2:6:6]) {
2655 t.Errorf("xs.Slice(2, 5, 6)[0:4] = %v", v[0:4])
2657 rv = ValueOf(&xa).Elem()
2658 shouldPanic(func() { rv.Slice3(1, 2, 1) })
2659 shouldPanic(func() { rv.Slice3(1, 1, 11) })
2660 shouldPanic(func() { rv.Slice3(2, 2, 1) })
2662 s := "hello world"
2663 rv = ValueOf(&s).Elem()
2664 shouldPanic(func() { rv.Slice3(1, 2, 3) })
2666 rv = ValueOf(&xs).Elem()
2667 rv = rv.Slice3(3, 5, 7)
2668 ptr2 := rv.Pointer()
2669 rv = rv.Slice3(4, 4, 4)
2670 ptr3 := rv.Pointer()
2671 if ptr3 != ptr2 {
2672 t.Errorf("xs.Slice3(3,5,7).Slice3(4,4,4).Pointer() = %#x, want %#x", ptr3, ptr2)
2676 func TestSetLenCap(t *testing.T) {
2677 xs := []int{1, 2, 3, 4, 5, 6, 7, 8}
2678 xa := [8]int{10, 20, 30, 40, 50, 60, 70, 80}
2680 vs := ValueOf(&xs).Elem()
2681 shouldPanic(func() { vs.SetLen(10) })
2682 shouldPanic(func() { vs.SetCap(10) })
2683 shouldPanic(func() { vs.SetLen(-1) })
2684 shouldPanic(func() { vs.SetCap(-1) })
2685 shouldPanic(func() { vs.SetCap(6) }) // smaller than len
2686 vs.SetLen(5)
2687 if len(xs) != 5 || cap(xs) != 8 {
2688 t.Errorf("after SetLen(5), len, cap = %d, %d, want 5, 8", len(xs), cap(xs))
2690 vs.SetCap(6)
2691 if len(xs) != 5 || cap(xs) != 6 {
2692 t.Errorf("after SetCap(6), len, cap = %d, %d, want 5, 6", len(xs), cap(xs))
2694 vs.SetCap(5)
2695 if len(xs) != 5 || cap(xs) != 5 {
2696 t.Errorf("after SetCap(5), len, cap = %d, %d, want 5, 5", len(xs), cap(xs))
2698 shouldPanic(func() { vs.SetCap(4) }) // smaller than len
2699 shouldPanic(func() { vs.SetLen(6) }) // bigger than cap
2701 va := ValueOf(&xa).Elem()
2702 shouldPanic(func() { va.SetLen(8) })
2703 shouldPanic(func() { va.SetCap(8) })
2706 func TestVariadic(t *testing.T) {
2707 var b bytes.Buffer
2708 V := ValueOf
2710 b.Reset()
2711 V(fmt.Fprintf).Call([]Value{V(&b), V("%s, %d world"), V("hello"), V(42)})
2712 if b.String() != "hello, 42 world" {
2713 t.Errorf("after Fprintf Call: %q != %q", b.String(), "hello 42 world")
2716 b.Reset()
2717 V(fmt.Fprintf).CallSlice([]Value{V(&b), V("%s, %d world"), V([]interface{}{"hello", 42})})
2718 if b.String() != "hello, 42 world" {
2719 t.Errorf("after Fprintf CallSlice: %q != %q", b.String(), "hello 42 world")
2723 func TestFuncArg(t *testing.T) {
2724 f1 := func(i int, f func(int) int) int { return f(i) }
2725 f2 := func(i int) int { return i + 1 }
2726 r := ValueOf(f1).Call([]Value{ValueOf(100), ValueOf(f2)})
2727 if r[0].Int() != 101 {
2728 t.Errorf("function returned %d, want 101", r[0].Int())
2732 func TestStructArg(t *testing.T) {
2733 type padded struct {
2734 B string
2735 C int32
2737 var (
2738 gotA padded
2739 gotB uint32
2740 wantA = padded{"3", 4}
2741 wantB = uint32(5)
2743 f := func(a padded, b uint32) {
2744 gotA, gotB = a, b
2746 ValueOf(f).Call([]Value{ValueOf(wantA), ValueOf(wantB)})
2747 if gotA != wantA || gotB != wantB {
2748 t.Errorf("function called with (%v, %v), want (%v, %v)", gotA, gotB, wantA, wantB)
2752 var tagGetTests = []struct {
2753 Tag StructTag
2754 Key string
2755 Value string
2757 {`protobuf:"PB(1,2)"`, `protobuf`, `PB(1,2)`},
2758 {`protobuf:"PB(1,2)"`, `foo`, ``},
2759 {`protobuf:"PB(1,2)"`, `rotobuf`, ``},
2760 {`protobuf:"PB(1,2)" json:"name"`, `json`, `name`},
2761 {`protobuf:"PB(1,2)" json:"name"`, `protobuf`, `PB(1,2)`},
2762 {`k0:"values contain spaces" k1:"and\ttabs"`, "k0", "values contain spaces"},
2763 {`k0:"values contain spaces" k1:"and\ttabs"`, "k1", "and\ttabs"},
2766 func TestTagGet(t *testing.T) {
2767 for _, tt := range tagGetTests {
2768 if v := tt.Tag.Get(tt.Key); v != tt.Value {
2769 t.Errorf("StructTag(%#q).Get(%#q) = %#q, want %#q", tt.Tag, tt.Key, v, tt.Value)
2774 func TestBytes(t *testing.T) {
2775 type B []byte
2776 x := B{1, 2, 3, 4}
2777 y := ValueOf(x).Bytes()
2778 if !bytes.Equal(x, y) {
2779 t.Fatalf("ValueOf(%v).Bytes() = %v", x, y)
2781 if &x[0] != &y[0] {
2782 t.Errorf("ValueOf(%p).Bytes() = %p", &x[0], &y[0])
2786 func TestSetBytes(t *testing.T) {
2787 type B []byte
2788 var x B
2789 y := []byte{1, 2, 3, 4}
2790 ValueOf(&x).Elem().SetBytes(y)
2791 if !bytes.Equal(x, y) {
2792 t.Fatalf("ValueOf(%v).Bytes() = %v", x, y)
2794 if &x[0] != &y[0] {
2795 t.Errorf("ValueOf(%p).Bytes() = %p", &x[0], &y[0])
2799 type Private struct {
2800 x int
2801 y **int
2802 Z int
2805 func (p *Private) m() {
2808 type private struct {
2809 Z int
2810 z int
2811 S string
2812 A [1]Private
2813 T []Private
2816 func (p *private) P() {
2819 type Public struct {
2820 X int
2821 Y **int
2822 private
2825 func (p *Public) M() {
2828 func TestUnexported(t *testing.T) {
2829 var pub Public
2830 pub.S = "S"
2831 pub.T = pub.A[:]
2832 v := ValueOf(&pub)
2833 isValid(v.Elem().Field(0))
2834 isValid(v.Elem().Field(1))
2835 isValid(v.Elem().Field(2))
2836 isValid(v.Elem().FieldByName("X"))
2837 isValid(v.Elem().FieldByName("Y"))
2838 isValid(v.Elem().FieldByName("Z"))
2839 isValid(v.Type().Method(0).Func)
2840 m, _ := v.Type().MethodByName("M")
2841 isValid(m.Func)
2842 m, _ = v.Type().MethodByName("P")
2843 isValid(m.Func)
2844 isNonNil(v.Elem().Field(0).Interface())
2845 isNonNil(v.Elem().Field(1).Interface())
2846 isNonNil(v.Elem().Field(2).Field(2).Index(0))
2847 isNonNil(v.Elem().FieldByName("X").Interface())
2848 isNonNil(v.Elem().FieldByName("Y").Interface())
2849 isNonNil(v.Elem().FieldByName("Z").Interface())
2850 isNonNil(v.Elem().FieldByName("S").Index(0).Interface())
2851 isNonNil(v.Type().Method(0).Func.Interface())
2852 m, _ = v.Type().MethodByName("P")
2853 isNonNil(m.Func.Interface())
2855 var priv Private
2856 v = ValueOf(&priv)
2857 isValid(v.Elem().Field(0))
2858 isValid(v.Elem().Field(1))
2859 isValid(v.Elem().FieldByName("x"))
2860 isValid(v.Elem().FieldByName("y"))
2861 shouldPanic(func() { v.Elem().Field(0).Interface() })
2862 shouldPanic(func() { v.Elem().Field(1).Interface() })
2863 shouldPanic(func() { v.Elem().FieldByName("x").Interface() })
2864 shouldPanic(func() { v.Elem().FieldByName("y").Interface() })
2865 shouldPanic(func() { v.Type().Method(0) })
2868 func TestSetPanic(t *testing.T) {
2869 ok := func(f func()) { f() }
2870 bad := shouldPanic
2871 clear := func(v Value) { v.Set(Zero(v.Type())) }
2873 type t0 struct {
2874 W int
2877 type t1 struct {
2878 Y int
2882 type T2 struct {
2883 Z int
2884 namedT0 t0
2887 type T struct {
2888 X int
2891 NamedT1 t1
2892 NamedT2 T2
2893 namedT1 t1
2894 namedT2 T2
2897 // not addressable
2898 v := ValueOf(T{})
2899 bad(func() { clear(v.Field(0)) }) // .X
2900 bad(func() { clear(v.Field(1)) }) // .t1
2901 bad(func() { clear(v.Field(1).Field(0)) }) // .t1.Y
2902 bad(func() { clear(v.Field(1).Field(1)) }) // .t1.t0
2903 bad(func() { clear(v.Field(1).Field(1).Field(0)) }) // .t1.t0.W
2904 bad(func() { clear(v.Field(2)) }) // .T2
2905 bad(func() { clear(v.Field(2).Field(0)) }) // .T2.Z
2906 bad(func() { clear(v.Field(2).Field(1)) }) // .T2.namedT0
2907 bad(func() { clear(v.Field(2).Field(1).Field(0)) }) // .T2.namedT0.W
2908 bad(func() { clear(v.Field(3)) }) // .NamedT1
2909 bad(func() { clear(v.Field(3).Field(0)) }) // .NamedT1.Y
2910 bad(func() { clear(v.Field(3).Field(1)) }) // .NamedT1.t0
2911 bad(func() { clear(v.Field(3).Field(1).Field(0)) }) // .NamedT1.t0.W
2912 bad(func() { clear(v.Field(4)) }) // .NamedT2
2913 bad(func() { clear(v.Field(4).Field(0)) }) // .NamedT2.Z
2914 bad(func() { clear(v.Field(4).Field(1)) }) // .NamedT2.namedT0
2915 bad(func() { clear(v.Field(4).Field(1).Field(0)) }) // .NamedT2.namedT0.W
2916 bad(func() { clear(v.Field(5)) }) // .namedT1
2917 bad(func() { clear(v.Field(5).Field(0)) }) // .namedT1.Y
2918 bad(func() { clear(v.Field(5).Field(1)) }) // .namedT1.t0
2919 bad(func() { clear(v.Field(5).Field(1).Field(0)) }) // .namedT1.t0.W
2920 bad(func() { clear(v.Field(6)) }) // .namedT2
2921 bad(func() { clear(v.Field(6).Field(0)) }) // .namedT2.Z
2922 bad(func() { clear(v.Field(6).Field(1)) }) // .namedT2.namedT0
2923 bad(func() { clear(v.Field(6).Field(1).Field(0)) }) // .namedT2.namedT0.W
2925 // addressable
2926 v = ValueOf(&T{}).Elem()
2927 ok(func() { clear(v.Field(0)) }) // .X
2928 bad(func() { clear(v.Field(1)) }) // .t1
2929 ok(func() { clear(v.Field(1).Field(0)) }) // .t1.Y
2930 bad(func() { clear(v.Field(1).Field(1)) }) // .t1.t0
2931 ok(func() { clear(v.Field(1).Field(1).Field(0)) }) // .t1.t0.W
2932 ok(func() { clear(v.Field(2)) }) // .T2
2933 ok(func() { clear(v.Field(2).Field(0)) }) // .T2.Z
2934 bad(func() { clear(v.Field(2).Field(1)) }) // .T2.namedT0
2935 bad(func() { clear(v.Field(2).Field(1).Field(0)) }) // .T2.namedT0.W
2936 ok(func() { clear(v.Field(3)) }) // .NamedT1
2937 ok(func() { clear(v.Field(3).Field(0)) }) // .NamedT1.Y
2938 bad(func() { clear(v.Field(3).Field(1)) }) // .NamedT1.t0
2939 ok(func() { clear(v.Field(3).Field(1).Field(0)) }) // .NamedT1.t0.W
2940 ok(func() { clear(v.Field(4)) }) // .NamedT2
2941 ok(func() { clear(v.Field(4).Field(0)) }) // .NamedT2.Z
2942 bad(func() { clear(v.Field(4).Field(1)) }) // .NamedT2.namedT0
2943 bad(func() { clear(v.Field(4).Field(1).Field(0)) }) // .NamedT2.namedT0.W
2944 bad(func() { clear(v.Field(5)) }) // .namedT1
2945 bad(func() { clear(v.Field(5).Field(0)) }) // .namedT1.Y
2946 bad(func() { clear(v.Field(5).Field(1)) }) // .namedT1.t0
2947 bad(func() { clear(v.Field(5).Field(1).Field(0)) }) // .namedT1.t0.W
2948 bad(func() { clear(v.Field(6)) }) // .namedT2
2949 bad(func() { clear(v.Field(6).Field(0)) }) // .namedT2.Z
2950 bad(func() { clear(v.Field(6).Field(1)) }) // .namedT2.namedT0
2951 bad(func() { clear(v.Field(6).Field(1).Field(0)) }) // .namedT2.namedT0.W
2954 type timp int
2956 func (t timp) W() {}
2957 func (t timp) Y() {}
2958 func (t timp) w() {}
2959 func (t timp) y() {}
2961 func TestCallPanic(t *testing.T) {
2962 type t0 interface {
2966 type T1 interface {
2970 type T2 struct {
2974 type T struct {
2975 t0 // 0
2976 T1 // 1
2978 NamedT0 t0 // 2
2979 NamedT1 T1 // 3
2980 NamedT2 T2 // 4
2982 namedT0 t0 // 5
2983 namedT1 T1 // 6
2984 namedT2 T2 // 7
2986 ok := func(f func()) { f() }
2987 bad := shouldPanic
2988 call := func(v Value) { v.Call(nil) }
2990 i := timp(0)
2991 v := ValueOf(T{i, i, i, i, T2{i, i}, i, i, T2{i, i}})
2992 ok(func() { call(v.Field(0).Method(0)) }) // .t0.W
2993 ok(func() { call(v.Field(0).Elem().Method(0)) }) // .t0.W
2994 bad(func() { call(v.Field(0).Method(1)) }) // .t0.w
2995 bad(func() { call(v.Field(0).Elem().Method(2)) }) // .t0.w
2996 ok(func() { call(v.Field(1).Method(0)) }) // .T1.Y
2997 ok(func() { call(v.Field(1).Elem().Method(0)) }) // .T1.Y
2998 bad(func() { call(v.Field(1).Method(1)) }) // .T1.y
2999 bad(func() { call(v.Field(1).Elem().Method(2)) }) // .T1.y
3001 ok(func() { call(v.Field(2).Method(0)) }) // .NamedT0.W
3002 ok(func() { call(v.Field(2).Elem().Method(0)) }) // .NamedT0.W
3003 bad(func() { call(v.Field(2).Method(1)) }) // .NamedT0.w
3004 bad(func() { call(v.Field(2).Elem().Method(2)) }) // .NamedT0.w
3006 ok(func() { call(v.Field(3).Method(0)) }) // .NamedT1.Y
3007 ok(func() { call(v.Field(3).Elem().Method(0)) }) // .NamedT1.Y
3008 bad(func() { call(v.Field(3).Method(1)) }) // .NamedT1.y
3009 bad(func() { call(v.Field(3).Elem().Method(3)) }) // .NamedT1.y
3011 ok(func() { call(v.Field(4).Field(0).Method(0)) }) // .NamedT2.T1.Y
3012 ok(func() { call(v.Field(4).Field(0).Elem().Method(0)) }) // .NamedT2.T1.W
3013 ok(func() { call(v.Field(4).Field(1).Method(0)) }) // .NamedT2.t0.W
3014 ok(func() { call(v.Field(4).Field(1).Elem().Method(0)) }) // .NamedT2.t0.W
3016 bad(func() { call(v.Field(5).Method(0)) }) // .namedT0.W
3017 bad(func() { call(v.Field(5).Elem().Method(0)) }) // .namedT0.W
3018 bad(func() { call(v.Field(5).Method(1)) }) // .namedT0.w
3019 bad(func() { call(v.Field(5).Elem().Method(2)) }) // .namedT0.w
3021 bad(func() { call(v.Field(6).Method(0)) }) // .namedT1.Y
3022 bad(func() { call(v.Field(6).Elem().Method(0)) }) // .namedT1.Y
3023 bad(func() { call(v.Field(6).Method(0)) }) // .namedT1.y
3024 bad(func() { call(v.Field(6).Elem().Method(0)) }) // .namedT1.y
3026 bad(func() { call(v.Field(7).Field(0).Method(0)) }) // .namedT2.T1.Y
3027 bad(func() { call(v.Field(7).Field(0).Elem().Method(0)) }) // .namedT2.T1.W
3028 bad(func() { call(v.Field(7).Field(1).Method(0)) }) // .namedT2.t0.W
3029 bad(func() { call(v.Field(7).Field(1).Elem().Method(0)) }) // .namedT2.t0.W
3032 func shouldPanic(f func()) {
3033 defer func() {
3034 if recover() == nil {
3035 panic("did not panic")
3041 func isNonNil(x interface{}) {
3042 if x == nil {
3043 panic("nil interface")
3047 func isValid(v Value) {
3048 if !v.IsValid() {
3049 panic("zero Value")
3053 func TestAlias(t *testing.T) {
3054 x := string("hello")
3055 v := ValueOf(&x).Elem()
3056 oldvalue := v.Interface()
3057 v.SetString("world")
3058 newvalue := v.Interface()
3060 if oldvalue != "hello" || newvalue != "world" {
3061 t.Errorf("aliasing: old=%q new=%q, want hello, world", oldvalue, newvalue)
3065 var V = ValueOf
3067 func EmptyInterfaceV(x interface{}) Value {
3068 return ValueOf(&x).Elem()
3071 func ReaderV(x io.Reader) Value {
3072 return ValueOf(&x).Elem()
3075 func ReadWriterV(x io.ReadWriter) Value {
3076 return ValueOf(&x).Elem()
3079 type Empty struct{}
3080 type MyString string
3081 type MyBytes []byte
3082 type MyRunes []int32
3083 type MyFunc func()
3084 type MyByte byte
3086 var convertTests = []struct {
3087 in Value
3088 out Value
3090 // numbers
3092 Edit .+1,/\*\//-1>cat >/tmp/x.go && go run /tmp/x.go
3094 package main
3096 import "fmt"
3098 var numbers = []string{
3099 "int8", "uint8", "int16", "uint16",
3100 "int32", "uint32", "int64", "uint64",
3101 "int", "uint", "uintptr",
3102 "float32", "float64",
3105 func main() {
3106 // all pairs but in an unusual order,
3107 // to emit all the int8, uint8 cases
3108 // before n grows too big.
3109 n := 1
3110 for i, f := range numbers {
3111 for _, g := range numbers[i:] {
3112 fmt.Printf("\t{V(%s(%d)), V(%s(%d))},\n", f, n, g, n)
3114 if f != g {
3115 fmt.Printf("\t{V(%s(%d)), V(%s(%d))},\n", g, n, f, n)
3122 {V(int8(1)), V(int8(1))},
3123 {V(int8(2)), V(uint8(2))},
3124 {V(uint8(3)), V(int8(3))},
3125 {V(int8(4)), V(int16(4))},
3126 {V(int16(5)), V(int8(5))},
3127 {V(int8(6)), V(uint16(6))},
3128 {V(uint16(7)), V(int8(7))},
3129 {V(int8(8)), V(int32(8))},
3130 {V(int32(9)), V(int8(9))},
3131 {V(int8(10)), V(uint32(10))},
3132 {V(uint32(11)), V(int8(11))},
3133 {V(int8(12)), V(int64(12))},
3134 {V(int64(13)), V(int8(13))},
3135 {V(int8(14)), V(uint64(14))},
3136 {V(uint64(15)), V(int8(15))},
3137 {V(int8(16)), V(int(16))},
3138 {V(int(17)), V(int8(17))},
3139 {V(int8(18)), V(uint(18))},
3140 {V(uint(19)), V(int8(19))},
3141 {V(int8(20)), V(uintptr(20))},
3142 {V(uintptr(21)), V(int8(21))},
3143 {V(int8(22)), V(float32(22))},
3144 {V(float32(23)), V(int8(23))},
3145 {V(int8(24)), V(float64(24))},
3146 {V(float64(25)), V(int8(25))},
3147 {V(uint8(26)), V(uint8(26))},
3148 {V(uint8(27)), V(int16(27))},
3149 {V(int16(28)), V(uint8(28))},
3150 {V(uint8(29)), V(uint16(29))},
3151 {V(uint16(30)), V(uint8(30))},
3152 {V(uint8(31)), V(int32(31))},
3153 {V(int32(32)), V(uint8(32))},
3154 {V(uint8(33)), V(uint32(33))},
3155 {V(uint32(34)), V(uint8(34))},
3156 {V(uint8(35)), V(int64(35))},
3157 {V(int64(36)), V(uint8(36))},
3158 {V(uint8(37)), V(uint64(37))},
3159 {V(uint64(38)), V(uint8(38))},
3160 {V(uint8(39)), V(int(39))},
3161 {V(int(40)), V(uint8(40))},
3162 {V(uint8(41)), V(uint(41))},
3163 {V(uint(42)), V(uint8(42))},
3164 {V(uint8(43)), V(uintptr(43))},
3165 {V(uintptr(44)), V(uint8(44))},
3166 {V(uint8(45)), V(float32(45))},
3167 {V(float32(46)), V(uint8(46))},
3168 {V(uint8(47)), V(float64(47))},
3169 {V(float64(48)), V(uint8(48))},
3170 {V(int16(49)), V(int16(49))},
3171 {V(int16(50)), V(uint16(50))},
3172 {V(uint16(51)), V(int16(51))},
3173 {V(int16(52)), V(int32(52))},
3174 {V(int32(53)), V(int16(53))},
3175 {V(int16(54)), V(uint32(54))},
3176 {V(uint32(55)), V(int16(55))},
3177 {V(int16(56)), V(int64(56))},
3178 {V(int64(57)), V(int16(57))},
3179 {V(int16(58)), V(uint64(58))},
3180 {V(uint64(59)), V(int16(59))},
3181 {V(int16(60)), V(int(60))},
3182 {V(int(61)), V(int16(61))},
3183 {V(int16(62)), V(uint(62))},
3184 {V(uint(63)), V(int16(63))},
3185 {V(int16(64)), V(uintptr(64))},
3186 {V(uintptr(65)), V(int16(65))},
3187 {V(int16(66)), V(float32(66))},
3188 {V(float32(67)), V(int16(67))},
3189 {V(int16(68)), V(float64(68))},
3190 {V(float64(69)), V(int16(69))},
3191 {V(uint16(70)), V(uint16(70))},
3192 {V(uint16(71)), V(int32(71))},
3193 {V(int32(72)), V(uint16(72))},
3194 {V(uint16(73)), V(uint32(73))},
3195 {V(uint32(74)), V(uint16(74))},
3196 {V(uint16(75)), V(int64(75))},
3197 {V(int64(76)), V(uint16(76))},
3198 {V(uint16(77)), V(uint64(77))},
3199 {V(uint64(78)), V(uint16(78))},
3200 {V(uint16(79)), V(int(79))},
3201 {V(int(80)), V(uint16(80))},
3202 {V(uint16(81)), V(uint(81))},
3203 {V(uint(82)), V(uint16(82))},
3204 {V(uint16(83)), V(uintptr(83))},
3205 {V(uintptr(84)), V(uint16(84))},
3206 {V(uint16(85)), V(float32(85))},
3207 {V(float32(86)), V(uint16(86))},
3208 {V(uint16(87)), V(float64(87))},
3209 {V(float64(88)), V(uint16(88))},
3210 {V(int32(89)), V(int32(89))},
3211 {V(int32(90)), V(uint32(90))},
3212 {V(uint32(91)), V(int32(91))},
3213 {V(int32(92)), V(int64(92))},
3214 {V(int64(93)), V(int32(93))},
3215 {V(int32(94)), V(uint64(94))},
3216 {V(uint64(95)), V(int32(95))},
3217 {V(int32(96)), V(int(96))},
3218 {V(int(97)), V(int32(97))},
3219 {V(int32(98)), V(uint(98))},
3220 {V(uint(99)), V(int32(99))},
3221 {V(int32(100)), V(uintptr(100))},
3222 {V(uintptr(101)), V(int32(101))},
3223 {V(int32(102)), V(float32(102))},
3224 {V(float32(103)), V(int32(103))},
3225 {V(int32(104)), V(float64(104))},
3226 {V(float64(105)), V(int32(105))},
3227 {V(uint32(106)), V(uint32(106))},
3228 {V(uint32(107)), V(int64(107))},
3229 {V(int64(108)), V(uint32(108))},
3230 {V(uint32(109)), V(uint64(109))},
3231 {V(uint64(110)), V(uint32(110))},
3232 {V(uint32(111)), V(int(111))},
3233 {V(int(112)), V(uint32(112))},
3234 {V(uint32(113)), V(uint(113))},
3235 {V(uint(114)), V(uint32(114))},
3236 {V(uint32(115)), V(uintptr(115))},
3237 {V(uintptr(116)), V(uint32(116))},
3238 {V(uint32(117)), V(float32(117))},
3239 {V(float32(118)), V(uint32(118))},
3240 {V(uint32(119)), V(float64(119))},
3241 {V(float64(120)), V(uint32(120))},
3242 {V(int64(121)), V(int64(121))},
3243 {V(int64(122)), V(uint64(122))},
3244 {V(uint64(123)), V(int64(123))},
3245 {V(int64(124)), V(int(124))},
3246 {V(int(125)), V(int64(125))},
3247 {V(int64(126)), V(uint(126))},
3248 {V(uint(127)), V(int64(127))},
3249 {V(int64(128)), V(uintptr(128))},
3250 {V(uintptr(129)), V(int64(129))},
3251 {V(int64(130)), V(float32(130))},
3252 {V(float32(131)), V(int64(131))},
3253 {V(int64(132)), V(float64(132))},
3254 {V(float64(133)), V(int64(133))},
3255 {V(uint64(134)), V(uint64(134))},
3256 {V(uint64(135)), V(int(135))},
3257 {V(int(136)), V(uint64(136))},
3258 {V(uint64(137)), V(uint(137))},
3259 {V(uint(138)), V(uint64(138))},
3260 {V(uint64(139)), V(uintptr(139))},
3261 {V(uintptr(140)), V(uint64(140))},
3262 {V(uint64(141)), V(float32(141))},
3263 {V(float32(142)), V(uint64(142))},
3264 {V(uint64(143)), V(float64(143))},
3265 {V(float64(144)), V(uint64(144))},
3266 {V(int(145)), V(int(145))},
3267 {V(int(146)), V(uint(146))},
3268 {V(uint(147)), V(int(147))},
3269 {V(int(148)), V(uintptr(148))},
3270 {V(uintptr(149)), V(int(149))},
3271 {V(int(150)), V(float32(150))},
3272 {V(float32(151)), V(int(151))},
3273 {V(int(152)), V(float64(152))},
3274 {V(float64(153)), V(int(153))},
3275 {V(uint(154)), V(uint(154))},
3276 {V(uint(155)), V(uintptr(155))},
3277 {V(uintptr(156)), V(uint(156))},
3278 {V(uint(157)), V(float32(157))},
3279 {V(float32(158)), V(uint(158))},
3280 {V(uint(159)), V(float64(159))},
3281 {V(float64(160)), V(uint(160))},
3282 {V(uintptr(161)), V(uintptr(161))},
3283 {V(uintptr(162)), V(float32(162))},
3284 {V(float32(163)), V(uintptr(163))},
3285 {V(uintptr(164)), V(float64(164))},
3286 {V(float64(165)), V(uintptr(165))},
3287 {V(float32(166)), V(float32(166))},
3288 {V(float32(167)), V(float64(167))},
3289 {V(float64(168)), V(float32(168))},
3290 {V(float64(169)), V(float64(169))},
3292 // truncation
3293 {V(float64(1.5)), V(int(1))},
3295 // complex
3296 {V(complex64(1i)), V(complex64(1i))},
3297 {V(complex64(2i)), V(complex128(2i))},
3298 {V(complex128(3i)), V(complex64(3i))},
3299 {V(complex128(4i)), V(complex128(4i))},
3301 // string
3302 {V(string("hello")), V(string("hello"))},
3303 {V(string("bytes1")), V([]byte("bytes1"))},
3304 {V([]byte("bytes2")), V(string("bytes2"))},
3305 {V([]byte("bytes3")), V([]byte("bytes3"))},
3306 {V(string("runes♝")), V([]rune("runes♝"))},
3307 {V([]rune("runes♕")), V(string("runes♕"))},
3308 {V([]rune("runes🙈🙉🙊")), V([]rune("runes🙈🙉🙊"))},
3309 {V(int('a')), V(string("a"))},
3310 {V(int8('a')), V(string("a"))},
3311 {V(int16('a')), V(string("a"))},
3312 {V(int32('a')), V(string("a"))},
3313 {V(int64('a')), V(string("a"))},
3314 {V(uint('a')), V(string("a"))},
3315 {V(uint8('a')), V(string("a"))},
3316 {V(uint16('a')), V(string("a"))},
3317 {V(uint32('a')), V(string("a"))},
3318 {V(uint64('a')), V(string("a"))},
3319 {V(uintptr('a')), V(string("a"))},
3320 {V(int(-1)), V(string("\uFFFD"))},
3321 {V(int8(-2)), V(string("\uFFFD"))},
3322 {V(int16(-3)), V(string("\uFFFD"))},
3323 {V(int32(-4)), V(string("\uFFFD"))},
3324 {V(int64(-5)), V(string("\uFFFD"))},
3325 {V(uint(0x110001)), V(string("\uFFFD"))},
3326 {V(uint32(0x110002)), V(string("\uFFFD"))},
3327 {V(uint64(0x110003)), V(string("\uFFFD"))},
3328 {V(uintptr(0x110004)), V(string("\uFFFD"))},
3330 // named string
3331 {V(MyString("hello")), V(string("hello"))},
3332 {V(string("hello")), V(MyString("hello"))},
3333 {V(string("hello")), V(string("hello"))},
3334 {V(MyString("hello")), V(MyString("hello"))},
3335 {V(MyString("bytes1")), V([]byte("bytes1"))},
3336 {V([]byte("bytes2")), V(MyString("bytes2"))},
3337 {V([]byte("bytes3")), V([]byte("bytes3"))},
3338 {V(MyString("runes♝")), V([]rune("runes♝"))},
3339 {V([]rune("runes♕")), V(MyString("runes♕"))},
3340 {V([]rune("runes🙈🙉🙊")), V([]rune("runes🙈🙉🙊"))},
3341 {V([]rune("runes🙈🙉🙊")), V(MyRunes("runes🙈🙉🙊"))},
3342 {V(MyRunes("runes🙈🙉🙊")), V([]rune("runes🙈🙉🙊"))},
3343 {V(int('a')), V(MyString("a"))},
3344 {V(int8('a')), V(MyString("a"))},
3345 {V(int16('a')), V(MyString("a"))},
3346 {V(int32('a')), V(MyString("a"))},
3347 {V(int64('a')), V(MyString("a"))},
3348 {V(uint('a')), V(MyString("a"))},
3349 {V(uint8('a')), V(MyString("a"))},
3350 {V(uint16('a')), V(MyString("a"))},
3351 {V(uint32('a')), V(MyString("a"))},
3352 {V(uint64('a')), V(MyString("a"))},
3353 {V(uintptr('a')), V(MyString("a"))},
3354 {V(int(-1)), V(MyString("\uFFFD"))},
3355 {V(int8(-2)), V(MyString("\uFFFD"))},
3356 {V(int16(-3)), V(MyString("\uFFFD"))},
3357 {V(int32(-4)), V(MyString("\uFFFD"))},
3358 {V(int64(-5)), V(MyString("\uFFFD"))},
3359 {V(uint(0x110001)), V(MyString("\uFFFD"))},
3360 {V(uint32(0x110002)), V(MyString("\uFFFD"))},
3361 {V(uint64(0x110003)), V(MyString("\uFFFD"))},
3362 {V(uintptr(0x110004)), V(MyString("\uFFFD"))},
3364 // named []byte
3365 {V(string("bytes1")), V(MyBytes("bytes1"))},
3366 {V(MyBytes("bytes2")), V(string("bytes2"))},
3367 {V(MyBytes("bytes3")), V(MyBytes("bytes3"))},
3368 {V(MyString("bytes1")), V(MyBytes("bytes1"))},
3369 {V(MyBytes("bytes2")), V(MyString("bytes2"))},
3371 // named []rune
3372 {V(string("runes♝")), V(MyRunes("runes♝"))},
3373 {V(MyRunes("runes♕")), V(string("runes♕"))},
3374 {V(MyRunes("runes🙈🙉🙊")), V(MyRunes("runes🙈🙉🙊"))},
3375 {V(MyString("runes♝")), V(MyRunes("runes♝"))},
3376 {V(MyRunes("runes♕")), V(MyString("runes♕"))},
3378 // named types and equal underlying types
3379 {V(new(int)), V(new(integer))},
3380 {V(new(integer)), V(new(int))},
3381 {V(Empty{}), V(struct{}{})},
3382 {V(new(Empty)), V(new(struct{}))},
3383 {V(struct{}{}), V(Empty{})},
3384 {V(new(struct{})), V(new(Empty))},
3385 {V(Empty{}), V(Empty{})},
3386 {V(MyBytes{}), V([]byte{})},
3387 {V([]byte{}), V(MyBytes{})},
3388 {V((func())(nil)), V(MyFunc(nil))},
3389 {V((MyFunc)(nil)), V((func())(nil))},
3391 // can convert *byte and *MyByte
3392 {V((*byte)(nil)), V((*MyByte)(nil))},
3393 {V((*MyByte)(nil)), V((*byte)(nil))},
3395 // cannot convert mismatched array sizes
3396 {V([2]byte{}), V([2]byte{})},
3397 {V([3]byte{}), V([3]byte{})},
3399 // cannot convert other instances
3400 {V((**byte)(nil)), V((**byte)(nil))},
3401 {V((**MyByte)(nil)), V((**MyByte)(nil))},
3402 {V((chan byte)(nil)), V((chan byte)(nil))},
3403 {V((chan MyByte)(nil)), V((chan MyByte)(nil))},
3404 {V(([]byte)(nil)), V(([]byte)(nil))},
3405 {V(([]MyByte)(nil)), V(([]MyByte)(nil))},
3406 {V((map[int]byte)(nil)), V((map[int]byte)(nil))},
3407 {V((map[int]MyByte)(nil)), V((map[int]MyByte)(nil))},
3408 {V((map[byte]int)(nil)), V((map[byte]int)(nil))},
3409 {V((map[MyByte]int)(nil)), V((map[MyByte]int)(nil))},
3410 {V([2]byte{}), V([2]byte{})},
3411 {V([2]MyByte{}), V([2]MyByte{})},
3413 // other
3414 {V((***int)(nil)), V((***int)(nil))},
3415 {V((***byte)(nil)), V((***byte)(nil))},
3416 {V((***int32)(nil)), V((***int32)(nil))},
3417 {V((***int64)(nil)), V((***int64)(nil))},
3418 {V((chan int)(nil)), V((<-chan int)(nil))},
3419 {V((chan int)(nil)), V((chan<- int)(nil))},
3420 {V((chan string)(nil)), V((<-chan string)(nil))},
3421 {V((chan string)(nil)), V((chan<- string)(nil))},
3422 {V((chan byte)(nil)), V((chan byte)(nil))},
3423 {V((chan MyByte)(nil)), V((chan MyByte)(nil))},
3424 {V((map[int]bool)(nil)), V((map[int]bool)(nil))},
3425 {V((map[int]byte)(nil)), V((map[int]byte)(nil))},
3426 {V((map[uint]bool)(nil)), V((map[uint]bool)(nil))},
3427 {V([]uint(nil)), V([]uint(nil))},
3428 {V([]int(nil)), V([]int(nil))},
3429 {V(new(interface{})), V(new(interface{}))},
3430 {V(new(io.Reader)), V(new(io.Reader))},
3431 {V(new(io.Writer)), V(new(io.Writer))},
3433 // interfaces
3434 {V(int(1)), EmptyInterfaceV(int(1))},
3435 {V(string("hello")), EmptyInterfaceV(string("hello"))},
3436 {V(new(bytes.Buffer)), ReaderV(new(bytes.Buffer))},
3437 {ReadWriterV(new(bytes.Buffer)), ReaderV(new(bytes.Buffer))},
3438 {V(new(bytes.Buffer)), ReadWriterV(new(bytes.Buffer))},
3441 func TestConvert(t *testing.T) {
3442 canConvert := map[[2]Type]bool{}
3443 all := map[Type]bool{}
3445 for _, tt := range convertTests {
3446 t1 := tt.in.Type()
3447 if !t1.ConvertibleTo(t1) {
3448 t.Errorf("(%s).ConvertibleTo(%s) = false, want true", t1, t1)
3449 continue
3452 t2 := tt.out.Type()
3453 if !t1.ConvertibleTo(t2) {
3454 t.Errorf("(%s).ConvertibleTo(%s) = false, want true", t1, t2)
3455 continue
3458 all[t1] = true
3459 all[t2] = true
3460 canConvert[[2]Type{t1, t2}] = true
3462 // vout1 represents the in value converted to the in type.
3463 v1 := tt.in
3464 vout1 := v1.Convert(t1)
3465 out1 := vout1.Interface()
3466 if vout1.Type() != tt.in.Type() || !DeepEqual(out1, tt.in.Interface()) {
3467 t.Errorf("ValueOf(%T(%[1]v)).Convert(%s) = %T(%[3]v), want %T(%[4]v)", tt.in.Interface(), t1, out1, tt.in.Interface())
3470 // vout2 represents the in value converted to the out type.
3471 vout2 := v1.Convert(t2)
3472 out2 := vout2.Interface()
3473 if vout2.Type() != tt.out.Type() || !DeepEqual(out2, tt.out.Interface()) {
3474 t.Errorf("ValueOf(%T(%[1]v)).Convert(%s) = %T(%[3]v), want %T(%[4]v)", tt.in.Interface(), t2, out2, tt.out.Interface())
3477 // vout3 represents a new value of the out type, set to vout2. This makes
3478 // sure the converted value vout2 is really usable as a regular value.
3479 vout3 := New(t2).Elem()
3480 vout3.Set(vout2)
3481 out3 := vout3.Interface()
3482 if vout3.Type() != tt.out.Type() || !DeepEqual(out3, tt.out.Interface()) {
3483 t.Errorf("Set(ValueOf(%T(%[1]v)).Convert(%s)) = %T(%[3]v), want %T(%[4]v)", tt.in.Interface(), t2, out3, tt.out.Interface())
3486 if IsRO(v1) {
3487 t.Errorf("table entry %v is RO, should not be", v1)
3489 if IsRO(vout1) {
3490 t.Errorf("self-conversion output %v is RO, should not be", vout1)
3492 if IsRO(vout2) {
3493 t.Errorf("conversion output %v is RO, should not be", vout2)
3495 if IsRO(vout3) {
3496 t.Errorf("set(conversion output) %v is RO, should not be", vout3)
3498 if !IsRO(MakeRO(v1).Convert(t1)) {
3499 t.Errorf("RO self-conversion output %v is not RO, should be", v1)
3501 if !IsRO(MakeRO(v1).Convert(t2)) {
3502 t.Errorf("RO conversion output %v is not RO, should be", v1)
3506 // Assume that of all the types we saw during the tests,
3507 // if there wasn't an explicit entry for a conversion between
3508 // a pair of types, then it's not to be allowed. This checks for
3509 // things like 'int64' converting to '*int'.
3510 for t1 := range all {
3511 for t2 := range all {
3512 expectOK := t1 == t2 || canConvert[[2]Type{t1, t2}] || t2.Kind() == Interface && t2.NumMethod() == 0
3513 if ok := t1.ConvertibleTo(t2); ok != expectOK {
3514 t.Errorf("(%s).ConvertibleTo(%s) = %v, want %v", t1, t2, ok, expectOK)
3520 type ComparableStruct struct {
3521 X int
3524 type NonComparableStruct struct {
3525 X int
3526 Y map[string]int
3529 var comparableTests = []struct {
3530 typ Type
3531 ok bool
3533 {TypeOf(1), true},
3534 {TypeOf("hello"), true},
3535 {TypeOf(new(byte)), true},
3536 {TypeOf((func())(nil)), false},
3537 {TypeOf([]byte{}), false},
3538 {TypeOf(map[string]int{}), false},
3539 {TypeOf(make(chan int)), true},
3540 {TypeOf(1.5), true},
3541 {TypeOf(false), true},
3542 {TypeOf(1i), true},
3543 {TypeOf(ComparableStruct{}), true},
3544 {TypeOf(NonComparableStruct{}), false},
3545 {TypeOf([10]map[string]int{}), false},
3546 {TypeOf([10]string{}), true},
3547 {TypeOf(new(interface{})).Elem(), true},
3550 func TestComparable(t *testing.T) {
3551 for _, tt := range comparableTests {
3552 if ok := tt.typ.Comparable(); ok != tt.ok {
3553 t.Errorf("TypeOf(%v).Comparable() = %v, want %v", tt.typ, ok, tt.ok)
3558 func TestOverflow(t *testing.T) {
3559 if ovf := V(float64(0)).OverflowFloat(1e300); ovf {
3560 t.Errorf("%v wrongly overflows float64", 1e300)
3563 maxFloat32 := float64((1<<24 - 1) << (127 - 23))
3564 if ovf := V(float32(0)).OverflowFloat(maxFloat32); ovf {
3565 t.Errorf("%v wrongly overflows float32", maxFloat32)
3567 ovfFloat32 := float64((1<<24-1)<<(127-23) + 1<<(127-52))
3568 if ovf := V(float32(0)).OverflowFloat(ovfFloat32); !ovf {
3569 t.Errorf("%v should overflow float32", ovfFloat32)
3571 if ovf := V(float32(0)).OverflowFloat(-ovfFloat32); !ovf {
3572 t.Errorf("%v should overflow float32", -ovfFloat32)
3575 maxInt32 := int64(0x7fffffff)
3576 if ovf := V(int32(0)).OverflowInt(maxInt32); ovf {
3577 t.Errorf("%v wrongly overflows int32", maxInt32)
3579 if ovf := V(int32(0)).OverflowInt(-1 << 31); ovf {
3580 t.Errorf("%v wrongly overflows int32", -int64(1)<<31)
3582 ovfInt32 := int64(1 << 31)
3583 if ovf := V(int32(0)).OverflowInt(ovfInt32); !ovf {
3584 t.Errorf("%v should overflow int32", ovfInt32)
3587 maxUint32 := uint64(0xffffffff)
3588 if ovf := V(uint32(0)).OverflowUint(maxUint32); ovf {
3589 t.Errorf("%v wrongly overflows uint32", maxUint32)
3591 ovfUint32 := uint64(1 << 32)
3592 if ovf := V(uint32(0)).OverflowUint(ovfUint32); !ovf {
3593 t.Errorf("%v should overflow uint32", ovfUint32)
3597 func checkSameType(t *testing.T, x, y interface{}) {
3598 if TypeOf(x) != TypeOf(y) {
3599 t.Errorf("did not find preexisting type for %s (vs %s)", TypeOf(x), TypeOf(y))
3603 func TestArrayOf(t *testing.T) {
3604 // check construction and use of type not in binary
3605 for _, table := range []struct {
3606 n int
3607 value func(i int) interface{}
3608 comparable bool
3609 want string
3612 n: 0,
3613 value: func(i int) interface{} { type Tint int; return Tint(i) },
3614 comparable: true,
3615 want: "[]",
3618 n: 10,
3619 value: func(i int) interface{} { type Tint int; return Tint(i) },
3620 comparable: true,
3621 want: "[0 1 2 3 4 5 6 7 8 9]",
3624 n: 10,
3625 value: func(i int) interface{} { type Tfloat float64; return Tfloat(i) },
3626 comparable: true,
3627 want: "[0 1 2 3 4 5 6 7 8 9]",
3630 n: 10,
3631 value: func(i int) interface{} { type Tstring string; return Tstring(strconv.Itoa(i)) },
3632 comparable: true,
3633 want: "[0 1 2 3 4 5 6 7 8 9]",
3636 n: 10,
3637 value: func(i int) interface{} { type Tstruct struct{ V int }; return Tstruct{i} },
3638 comparable: true,
3639 want: "[{0} {1} {2} {3} {4} {5} {6} {7} {8} {9}]",
3642 n: 10,
3643 value: func(i int) interface{} { type Tint int; return []Tint{Tint(i)} },
3644 comparable: false,
3645 want: "[[0] [1] [2] [3] [4] [5] [6] [7] [8] [9]]",
3648 n: 10,
3649 value: func(i int) interface{} { type Tint int; return [1]Tint{Tint(i)} },
3650 comparable: true,
3651 want: "[[0] [1] [2] [3] [4] [5] [6] [7] [8] [9]]",
3654 n: 10,
3655 value: func(i int) interface{} { type Tstruct struct{ V [1]int }; return Tstruct{[1]int{i}} },
3656 comparable: true,
3657 want: "[{[0]} {[1]} {[2]} {[3]} {[4]} {[5]} {[6]} {[7]} {[8]} {[9]}]",
3660 n: 10,
3661 value: func(i int) interface{} { type Tstruct struct{ V []int }; return Tstruct{[]int{i}} },
3662 comparable: false,
3663 want: "[{[0]} {[1]} {[2]} {[3]} {[4]} {[5]} {[6]} {[7]} {[8]} {[9]}]",
3666 n: 10,
3667 value: func(i int) interface{} { type TstructUV struct{ U, V int }; return TstructUV{i, i} },
3668 comparable: true,
3669 want: "[{0 0} {1 1} {2 2} {3 3} {4 4} {5 5} {6 6} {7 7} {8 8} {9 9}]",
3672 n: 10,
3673 value: func(i int) interface{} {
3674 type TstructUV struct {
3675 U int
3676 V float64
3678 return TstructUV{i, float64(i)}
3680 comparable: true,
3681 want: "[{0 0} {1 1} {2 2} {3 3} {4 4} {5 5} {6 6} {7 7} {8 8} {9 9}]",
3684 at := ArrayOf(table.n, TypeOf(table.value(0)))
3685 v := New(at).Elem()
3686 vok := New(at).Elem()
3687 vnot := New(at).Elem()
3688 for i := 0; i < v.Len(); i++ {
3689 v.Index(i).Set(ValueOf(table.value(i)))
3690 vok.Index(i).Set(ValueOf(table.value(i)))
3691 j := i
3692 if i+1 == v.Len() {
3693 j = i + 1
3695 vnot.Index(i).Set(ValueOf(table.value(j))) // make it differ only by last element
3697 s := fmt.Sprint(v.Interface())
3698 if s != table.want {
3699 t.Errorf("constructed array = %s, want %s", s, table.want)
3702 if table.comparable != at.Comparable() {
3703 t.Errorf("constructed array (%#v) is comparable=%v, want=%v", v.Interface(), at.Comparable(), table.comparable)
3705 if table.comparable {
3706 if table.n > 0 {
3707 if DeepEqual(vnot.Interface(), v.Interface()) {
3708 t.Errorf(
3709 "arrays (%#v) compare ok (but should not)",
3710 v.Interface(),
3714 if !DeepEqual(vok.Interface(), v.Interface()) {
3715 t.Errorf(
3716 "arrays (%#v) compare NOT-ok (but should)",
3717 v.Interface(),
3723 // check that type already in binary is found
3724 type T int
3725 checkSameType(t, Zero(ArrayOf(5, TypeOf(T(1)))).Interface(), [5]T{})
3728 func TestArrayOfGC(t *testing.T) {
3729 type T *uintptr
3730 tt := TypeOf(T(nil))
3731 const n = 100
3732 var x []interface{}
3733 for i := 0; i < n; i++ {
3734 v := New(ArrayOf(n, tt)).Elem()
3735 for j := 0; j < v.Len(); j++ {
3736 p := new(uintptr)
3737 *p = uintptr(i*n + j)
3738 v.Index(j).Set(ValueOf(p).Convert(tt))
3740 x = append(x, v.Interface())
3742 runtime.GC()
3744 for i, xi := range x {
3745 v := ValueOf(xi)
3746 for j := 0; j < v.Len(); j++ {
3747 k := v.Index(j).Elem().Interface()
3748 if k != uintptr(i*n+j) {
3749 t.Errorf("lost x[%d][%d] = %d, want %d", i, j, k, i*n+j)
3755 func TestArrayOfAlg(t *testing.T) {
3756 at := ArrayOf(6, TypeOf(byte(0)))
3757 v1 := New(at).Elem()
3758 v2 := New(at).Elem()
3759 if v1.Interface() != v1.Interface() {
3760 t.Errorf("constructed array %v not equal to itself", v1.Interface())
3762 v1.Index(5).Set(ValueOf(byte(1)))
3763 if i1, i2 := v1.Interface(), v2.Interface(); i1 == i2 {
3764 t.Errorf("constructed arrays %v and %v should not be equal", i1, i2)
3767 at = ArrayOf(6, TypeOf([]int(nil)))
3768 v1 = New(at).Elem()
3769 shouldPanic(func() { _ = v1.Interface() == v1.Interface() })
3772 func TestArrayOfGenericAlg(t *testing.T) {
3773 at1 := ArrayOf(5, TypeOf(string("")))
3774 at := ArrayOf(6, at1)
3775 v1 := New(at).Elem()
3776 v2 := New(at).Elem()
3777 if v1.Interface() != v1.Interface() {
3778 t.Errorf("constructed array %v not equal to itself", v1.Interface())
3781 v1.Index(0).Index(0).Set(ValueOf("abc"))
3782 v2.Index(0).Index(0).Set(ValueOf("efg"))
3783 if i1, i2 := v1.Interface(), v2.Interface(); i1 == i2 {
3784 t.Errorf("constructed arrays %v and %v should not be equal", i1, i2)
3787 v1.Index(0).Index(0).Set(ValueOf("abc"))
3788 v2.Index(0).Index(0).Set(ValueOf((v1.Index(0).Index(0).String() + " ")[:3]))
3789 if i1, i2 := v1.Interface(), v2.Interface(); i1 != i2 {
3790 t.Errorf("constructed arrays %v and %v should be equal", i1, i2)
3793 // Test hash
3794 m := MakeMap(MapOf(at, TypeOf(int(0))))
3795 m.SetMapIndex(v1, ValueOf(1))
3796 if i1, i2 := v1.Interface(), v2.Interface(); !m.MapIndex(v2).IsValid() {
3797 t.Errorf("constructed arrays %v and %v have different hashes", i1, i2)
3801 func TestArrayOfDirectIface(t *testing.T) {
3802 t.Skip("skipping test because gccgo uses a different directiface value")
3804 type T [1]*byte
3805 i1 := Zero(TypeOf(T{})).Interface()
3806 v1 := ValueOf(&i1).Elem()
3807 p1 := v1.InterfaceData()[1]
3809 i2 := Zero(ArrayOf(1, PtrTo(TypeOf(int8(0))))).Interface()
3810 v2 := ValueOf(&i2).Elem()
3811 p2 := v2.InterfaceData()[1]
3813 if p1 != 0 {
3814 t.Errorf("got p1=%v. want=%v", p1, nil)
3817 if p2 != 0 {
3818 t.Errorf("got p2=%v. want=%v", p2, nil)
3822 type T [0]*byte
3823 i1 := Zero(TypeOf(T{})).Interface()
3824 v1 := ValueOf(&i1).Elem()
3825 p1 := v1.InterfaceData()[1]
3827 i2 := Zero(ArrayOf(0, PtrTo(TypeOf(int8(0))))).Interface()
3828 v2 := ValueOf(&i2).Elem()
3829 p2 := v2.InterfaceData()[1]
3831 if p1 == 0 {
3832 t.Errorf("got p1=%v. want=not-%v", p1, nil)
3835 if p2 == 0 {
3836 t.Errorf("got p2=%v. want=not-%v", p2, nil)
3841 func TestSliceOf(t *testing.T) {
3842 // check construction and use of type not in binary
3843 type T int
3844 st := SliceOf(TypeOf(T(1)))
3845 if got, want := st.String(), "[]reflect_test.T"; got != want {
3846 t.Errorf("SliceOf(T(1)).String()=%q, want %q", got, want)
3848 v := MakeSlice(st, 10, 10)
3849 runtime.GC()
3850 for i := 0; i < v.Len(); i++ {
3851 v.Index(i).Set(ValueOf(T(i)))
3852 runtime.GC()
3854 s := fmt.Sprint(v.Interface())
3855 want := "[0 1 2 3 4 5 6 7 8 9]"
3856 if s != want {
3857 t.Errorf("constructed slice = %s, want %s", s, want)
3860 // check that type already in binary is found
3861 type T1 int
3862 checkSameType(t, Zero(SliceOf(TypeOf(T1(1)))).Interface(), []T1{})
3865 func TestSliceOverflow(t *testing.T) {
3866 // check that MakeSlice panics when size of slice overflows uint
3867 const S = 1e6
3868 s := uint(S)
3869 l := (1<<(unsafe.Sizeof((*byte)(nil))*8)-1)/s + 1
3870 if l*s >= s {
3871 t.Fatal("slice size does not overflow")
3873 var x [S]byte
3874 st := SliceOf(TypeOf(x))
3875 defer func() {
3876 err := recover()
3877 if err == nil {
3878 t.Fatal("slice overflow does not panic")
3881 MakeSlice(st, int(l), int(l))
3884 func TestSliceOfGC(t *testing.T) {
3885 type T *uintptr
3886 tt := TypeOf(T(nil))
3887 st := SliceOf(tt)
3888 const n = 100
3889 var x []interface{}
3890 for i := 0; i < n; i++ {
3891 v := MakeSlice(st, n, n)
3892 for j := 0; j < v.Len(); j++ {
3893 p := new(uintptr)
3894 *p = uintptr(i*n + j)
3895 v.Index(j).Set(ValueOf(p).Convert(tt))
3897 x = append(x, v.Interface())
3899 runtime.GC()
3901 for i, xi := range x {
3902 v := ValueOf(xi)
3903 for j := 0; j < v.Len(); j++ {
3904 k := v.Index(j).Elem().Interface()
3905 if k != uintptr(i*n+j) {
3906 t.Errorf("lost x[%d][%d] = %d, want %d", i, j, k, i*n+j)
3912 func TestStructOf(t *testing.T) {
3913 // check construction and use of type not in binary
3914 fields := []StructField{
3915 StructField{
3916 Name: "S",
3917 Tag: "s",
3918 Type: TypeOf(""),
3920 StructField{
3921 Name: "X",
3922 Tag: "x",
3923 Type: TypeOf(byte(0)),
3925 StructField{
3926 Name: "Y",
3927 Type: TypeOf(uint64(0)),
3929 StructField{
3930 Name: "Z",
3931 Type: TypeOf([3]uint16{}),
3935 st := StructOf(fields)
3936 v := New(st).Elem()
3937 runtime.GC()
3938 v.FieldByName("X").Set(ValueOf(byte(2)))
3939 v.FieldByIndex([]int{1}).Set(ValueOf(byte(1)))
3940 runtime.GC()
3942 s := fmt.Sprint(v.Interface())
3943 want := `{ 1 0 [0 0 0]}`
3944 if s != want {
3945 t.Errorf("constructed struct = %s, want %s", s, want)
3947 const stStr = `struct { S string "s"; X uint8 "x"; Y uint64; Z [3]uint16 }`
3948 if got, want := st.String(), stStr; got != want {
3949 t.Errorf("StructOf(fields).String()=%q, want %q", got, want)
3952 // check the size, alignment and field offsets
3953 stt := TypeOf(struct {
3954 String string
3955 X byte
3956 Y uint64
3957 Z [3]uint16
3958 }{})
3959 if st.Size() != stt.Size() {
3960 t.Errorf("constructed struct size = %v, want %v", st.Size(), stt.Size())
3962 if st.Align() != stt.Align() {
3963 t.Errorf("constructed struct align = %v, want %v", st.Align(), stt.Align())
3965 if st.FieldAlign() != stt.FieldAlign() {
3966 t.Errorf("constructed struct field align = %v, want %v", st.FieldAlign(), stt.FieldAlign())
3968 for i := 0; i < st.NumField(); i++ {
3969 o1 := st.Field(i).Offset
3970 o2 := stt.Field(i).Offset
3971 if o1 != o2 {
3972 t.Errorf("constructed struct field %v offset = %v, want %v", i, o1, o2)
3976 // check duplicate names
3977 shouldPanic(func() {
3978 StructOf([]StructField{
3979 StructField{Name: "string", Type: TypeOf("")},
3980 StructField{Name: "string", Type: TypeOf("")},
3983 shouldPanic(func() {
3984 StructOf([]StructField{
3985 StructField{Type: TypeOf("")},
3986 StructField{Name: "string", Type: TypeOf("")},
3989 shouldPanic(func() {
3990 StructOf([]StructField{
3991 StructField{Type: TypeOf("")},
3992 StructField{Type: TypeOf("")},
3995 // check that type already in binary is found
3996 checkSameType(t, Zero(StructOf(fields[2:3])).Interface(), struct{ Y uint64 }{})
3999 func TestStructOfExportRules(t *testing.T) {
4000 type S1 struct{}
4001 type s2 struct{}
4002 type ΦType struct{}
4003 type φType struct{}
4005 testPanic := func(i int, mustPanic bool, f func()) {
4006 defer func() {
4007 err := recover()
4008 if err == nil && mustPanic {
4009 t.Errorf("test-%d did not panic", i)
4011 if err != nil && !mustPanic {
4012 t.Errorf("test-%d panicked: %v\n", i, err)
4018 for i, test := range []struct {
4019 field StructField
4020 mustPanic bool
4021 exported bool
4024 field: StructField{Name: "", Type: TypeOf(S1{})},
4025 mustPanic: false,
4026 exported: true,
4029 field: StructField{Name: "", Type: TypeOf((*S1)(nil))},
4030 mustPanic: false,
4031 exported: true,
4034 field: StructField{Name: "", Type: TypeOf(s2{})},
4035 mustPanic: false,
4036 exported: false,
4039 field: StructField{Name: "", Type: TypeOf((*s2)(nil))},
4040 mustPanic: false,
4041 exported: false,
4044 field: StructField{Name: "", Type: TypeOf(S1{}), PkgPath: "other/pkg"},
4045 mustPanic: true,
4046 exported: true,
4049 field: StructField{Name: "", Type: TypeOf((*S1)(nil)), PkgPath: "other/pkg"},
4050 mustPanic: true,
4051 exported: true,
4054 field: StructField{Name: "", Type: TypeOf(s2{}), PkgPath: "other/pkg"},
4055 mustPanic: true,
4056 exported: false,
4059 field: StructField{Name: "", Type: TypeOf((*s2)(nil)), PkgPath: "other/pkg"},
4060 mustPanic: true,
4061 exported: false,
4064 field: StructField{Name: "S", Type: TypeOf(S1{})},
4065 mustPanic: false,
4066 exported: true,
4069 field: StructField{Name: "S", Type: TypeOf((*S1)(nil))},
4070 mustPanic: false,
4071 exported: true,
4074 field: StructField{Name: "S", Type: TypeOf(s2{})},
4075 mustPanic: false,
4076 exported: true,
4079 field: StructField{Name: "S", Type: TypeOf((*s2)(nil))},
4080 mustPanic: false,
4081 exported: true,
4084 field: StructField{Name: "s", Type: TypeOf(S1{})},
4085 mustPanic: true,
4086 exported: false,
4089 field: StructField{Name: "s", Type: TypeOf((*S1)(nil))},
4090 mustPanic: true,
4091 exported: false,
4094 field: StructField{Name: "s", Type: TypeOf(s2{})},
4095 mustPanic: true,
4096 exported: false,
4099 field: StructField{Name: "s", Type: TypeOf((*s2)(nil))},
4100 mustPanic: true,
4101 exported: false,
4104 field: StructField{Name: "s", Type: TypeOf(S1{}), PkgPath: "other/pkg"},
4105 mustPanic: true, // TODO(sbinet): creating a name with a package path
4106 exported: false,
4109 field: StructField{Name: "s", Type: TypeOf((*S1)(nil)), PkgPath: "other/pkg"},
4110 mustPanic: true, // TODO(sbinet): creating a name with a package path
4111 exported: false,
4114 field: StructField{Name: "s", Type: TypeOf(s2{}), PkgPath: "other/pkg"},
4115 mustPanic: true, // TODO(sbinet): creating a name with a package path
4116 exported: false,
4119 field: StructField{Name: "s", Type: TypeOf((*s2)(nil)), PkgPath: "other/pkg"},
4120 mustPanic: true, // TODO(sbinet): creating a name with a package path
4121 exported: false,
4124 field: StructField{Name: "", Type: TypeOf(ΦType{})},
4125 mustPanic: false,
4126 exported: true,
4129 field: StructField{Name: "", Type: TypeOf(φType{})},
4130 mustPanic: false,
4131 exported: false,
4134 field: StructField{Name: "Φ", Type: TypeOf(0)},
4135 mustPanic: false,
4136 exported: true,
4139 field: StructField{Name: "φ", Type: TypeOf(0)},
4140 mustPanic: false,
4141 exported: false,
4144 testPanic(i, test.mustPanic, func() {
4145 typ := StructOf([]StructField{test.field})
4146 if typ == nil {
4147 t.Errorf("test-%d: error creating struct type", i)
4148 return
4150 field := typ.Field(0)
4151 n := field.Name
4152 if n == "" {
4153 n = field.Type.Name()
4155 exported := isExported(n)
4156 if exported != test.exported {
4157 t.Errorf("test-%d: got exported=%v want exported=%v", i, exported, test.exported)
4163 // isExported reports whether name is an exported Go symbol
4164 // (that is, whether it begins with an upper-case letter).
4166 func isExported(name string) bool {
4167 ch, _ := utf8.DecodeRuneInString(name)
4168 return unicode.IsUpper(ch)
4171 func TestStructOfGC(t *testing.T) {
4172 type T *uintptr
4173 tt := TypeOf(T(nil))
4174 fields := []StructField{
4175 {Name: "X", Type: tt},
4176 {Name: "Y", Type: tt},
4178 st := StructOf(fields)
4180 const n = 10000
4181 var x []interface{}
4182 for i := 0; i < n; i++ {
4183 v := New(st).Elem()
4184 for j := 0; j < v.NumField(); j++ {
4185 p := new(uintptr)
4186 *p = uintptr(i*n + j)
4187 v.Field(j).Set(ValueOf(p).Convert(tt))
4189 x = append(x, v.Interface())
4191 runtime.GC()
4193 for i, xi := range x {
4194 v := ValueOf(xi)
4195 for j := 0; j < v.NumField(); j++ {
4196 k := v.Field(j).Elem().Interface()
4197 if k != uintptr(i*n+j) {
4198 t.Errorf("lost x[%d].%c = %d, want %d", i, "XY"[j], k, i*n+j)
4204 func TestStructOfAlg(t *testing.T) {
4205 st := StructOf([]StructField{{Name: "X", Tag: "x", Type: TypeOf(int(0))}})
4206 v1 := New(st).Elem()
4207 v2 := New(st).Elem()
4208 if !DeepEqual(v1.Interface(), v1.Interface()) {
4209 t.Errorf("constructed struct %v not equal to itself", v1.Interface())
4211 v1.FieldByName("X").Set(ValueOf(int(1)))
4212 if i1, i2 := v1.Interface(), v2.Interface(); DeepEqual(i1, i2) {
4213 t.Errorf("constructed structs %v and %v should not be equal", i1, i2)
4216 st = StructOf([]StructField{{Name: "X", Tag: "x", Type: TypeOf([]int(nil))}})
4217 v1 = New(st).Elem()
4218 shouldPanic(func() { _ = v1.Interface() == v1.Interface() })
4221 func TestStructOfGenericAlg(t *testing.T) {
4222 st1 := StructOf([]StructField{
4223 {Name: "X", Tag: "x", Type: TypeOf(int64(0))},
4224 {Name: "Y", Type: TypeOf(string(""))},
4226 st := StructOf([]StructField{
4227 {Name: "S0", Type: st1},
4228 {Name: "S1", Type: st1},
4231 for _, table := range []struct {
4232 rt Type
4233 idx []int
4236 rt: st,
4237 idx: []int{0, 1},
4240 rt: st1,
4241 idx: []int{1},
4244 rt: StructOf(
4245 []StructField{
4246 {Name: "XX", Type: TypeOf([0]int{})},
4247 {Name: "YY", Type: TypeOf("")},
4250 idx: []int{1},
4253 rt: StructOf(
4254 []StructField{
4255 {Name: "XX", Type: TypeOf([0]int{})},
4256 {Name: "YY", Type: TypeOf("")},
4257 {Name: "ZZ", Type: TypeOf([2]int{})},
4260 idx: []int{1},
4263 rt: StructOf(
4264 []StructField{
4265 {Name: "XX", Type: TypeOf([1]int{})},
4266 {Name: "YY", Type: TypeOf("")},
4269 idx: []int{1},
4272 rt: StructOf(
4273 []StructField{
4274 {Name: "XX", Type: TypeOf([1]int{})},
4275 {Name: "YY", Type: TypeOf("")},
4276 {Name: "ZZ", Type: TypeOf([1]int{})},
4279 idx: []int{1},
4282 rt: StructOf(
4283 []StructField{
4284 {Name: "XX", Type: TypeOf([2]int{})},
4285 {Name: "YY", Type: TypeOf("")},
4286 {Name: "ZZ", Type: TypeOf([2]int{})},
4289 idx: []int{1},
4292 rt: StructOf(
4293 []StructField{
4294 {Name: "XX", Type: TypeOf(int64(0))},
4295 {Name: "YY", Type: TypeOf(byte(0))},
4296 {Name: "ZZ", Type: TypeOf("")},
4299 idx: []int{2},
4302 rt: StructOf(
4303 []StructField{
4304 {Name: "XX", Type: TypeOf(int64(0))},
4305 {Name: "YY", Type: TypeOf(int64(0))},
4306 {Name: "ZZ", Type: TypeOf("")},
4307 {Name: "AA", Type: TypeOf([1]int64{})},
4310 idx: []int{2},
4313 v1 := New(table.rt).Elem()
4314 v2 := New(table.rt).Elem()
4316 if !DeepEqual(v1.Interface(), v1.Interface()) {
4317 t.Errorf("constructed struct %v not equal to itself", v1.Interface())
4320 v1.FieldByIndex(table.idx).Set(ValueOf("abc"))
4321 v2.FieldByIndex(table.idx).Set(ValueOf("def"))
4322 if i1, i2 := v1.Interface(), v2.Interface(); DeepEqual(i1, i2) {
4323 t.Errorf("constructed structs %v and %v should not be equal", i1, i2)
4326 abc := "abc"
4327 v1.FieldByIndex(table.idx).Set(ValueOf(abc))
4328 val := "+" + abc + "-"
4329 v2.FieldByIndex(table.idx).Set(ValueOf(val[1:4]))
4330 if i1, i2 := v1.Interface(), v2.Interface(); !DeepEqual(i1, i2) {
4331 t.Errorf("constructed structs %v and %v should be equal", i1, i2)
4334 // Test hash
4335 m := MakeMap(MapOf(table.rt, TypeOf(int(0))))
4336 m.SetMapIndex(v1, ValueOf(1))
4337 if i1, i2 := v1.Interface(), v2.Interface(); !m.MapIndex(v2).IsValid() {
4338 t.Errorf("constructed structs %#v and %#v have different hashes", i1, i2)
4341 v2.FieldByIndex(table.idx).Set(ValueOf("abc"))
4342 if i1, i2 := v1.Interface(), v2.Interface(); !DeepEqual(i1, i2) {
4343 t.Errorf("constructed structs %v and %v should be equal", i1, i2)
4346 if i1, i2 := v1.Interface(), v2.Interface(); !m.MapIndex(v2).IsValid() {
4347 t.Errorf("constructed structs %v and %v have different hashes", i1, i2)
4353 gccgo does not use the same directiface settings as gc.
4355 func TestStructOfDirectIface(t *testing.T) {
4357 type T struct{ X [1]*byte }
4358 i1 := Zero(TypeOf(T{})).Interface()
4359 v1 := ValueOf(&i1).Elem()
4360 p1 := v1.InterfaceData()[1]
4362 i2 := Zero(StructOf([]StructField{
4364 Name: "X",
4365 Type: ArrayOf(1, TypeOf((*int8)(nil))),
4367 })).Interface()
4368 v2 := ValueOf(&i2).Elem()
4369 p2 := v2.InterfaceData()[1]
4371 if p1 != 0 {
4372 t.Errorf("got p1=%v. want=%v", p1, nil)
4375 if p2 != 0 {
4376 t.Errorf("got p2=%v. want=%v", p2, nil)
4380 type T struct{ X [0]*byte }
4381 i1 := Zero(TypeOf(T{})).Interface()
4382 v1 := ValueOf(&i1).Elem()
4383 p1 := v1.InterfaceData()[1]
4385 i2 := Zero(StructOf([]StructField{
4387 Name: "X",
4388 Type: ArrayOf(0, TypeOf((*int8)(nil))),
4390 })).Interface()
4391 v2 := ValueOf(&i2).Elem()
4392 p2 := v2.InterfaceData()[1]
4394 if p1 == 0 {
4395 t.Errorf("got p1=%v. want=not-%v", p1, nil)
4398 if p2 == 0 {
4399 t.Errorf("got p2=%v. want=not-%v", p2, nil)
4405 type StructI int
4407 func (i StructI) Get() int { return int(i) }
4409 type StructIPtr int
4411 func (i *StructIPtr) Get() int { return int(*i) }
4414 gccgo does not yet support StructOf with methods.
4416 func TestStructOfWithInterface(t *testing.T) {
4417 const want = 42
4418 type Iface interface {
4419 Get() int
4421 for i, table := range []struct {
4422 typ Type
4423 val Value
4424 impl bool
4427 typ: TypeOf(StructI(want)),
4428 val: ValueOf(StructI(want)),
4429 impl: true,
4432 typ: PtrTo(TypeOf(StructI(want))),
4433 val: ValueOf(func() interface{} {
4434 v := StructI(want)
4435 return &v
4436 }()),
4437 impl: true,
4440 typ: PtrTo(TypeOf(StructIPtr(want))),
4441 val: ValueOf(func() interface{} {
4442 v := StructIPtr(want)
4443 return &v
4444 }()),
4445 impl: true,
4448 typ: TypeOf(StructIPtr(want)),
4449 val: ValueOf(StructIPtr(want)),
4450 impl: false,
4452 // {
4453 // typ: TypeOf((*Iface)(nil)).Elem(), // FIXME(sbinet): fix method.ifn/tfn
4454 // val: ValueOf(StructI(want)),
4455 // impl: true,
4456 // },
4458 rt := StructOf(
4459 []StructField{
4461 Name: "",
4462 PkgPath: "",
4463 Type: table.typ,
4467 rv := New(rt).Elem()
4468 rv.Field(0).Set(table.val)
4470 if _, ok := rv.Interface().(Iface); ok != table.impl {
4471 if table.impl {
4472 t.Errorf("test-%d: type=%v fails to implement Iface.\n", i, table.typ)
4473 } else {
4474 t.Errorf("test-%d: type=%v should NOT implement Iface\n", i, table.typ)
4476 continue
4479 if !table.impl {
4480 continue
4483 v := rv.Interface().(Iface).Get()
4484 if v != want {
4485 t.Errorf("test-%d: x.Get()=%v. want=%v\n", i, v, want)
4488 fct := rv.MethodByName("Get")
4489 out := fct.Call(nil)
4490 if !DeepEqual(out[0].Interface(), want) {
4491 t.Errorf("test-%d: x.Get()=%v. want=%v\n", i, out[0].Interface(), want)
4497 func TestChanOf(t *testing.T) {
4498 // check construction and use of type not in binary
4499 type T string
4500 ct := ChanOf(BothDir, TypeOf(T("")))
4501 v := MakeChan(ct, 2)
4502 runtime.GC()
4503 v.Send(ValueOf(T("hello")))
4504 runtime.GC()
4505 v.Send(ValueOf(T("world")))
4506 runtime.GC()
4508 sv1, _ := v.Recv()
4509 sv2, _ := v.Recv()
4510 s1 := sv1.String()
4511 s2 := sv2.String()
4512 if s1 != "hello" || s2 != "world" {
4513 t.Errorf("constructed chan: have %q, %q, want %q, %q", s1, s2, "hello", "world")
4516 // check that type already in binary is found
4517 type T1 int
4518 checkSameType(t, Zero(ChanOf(BothDir, TypeOf(T1(1)))).Interface(), (chan T1)(nil))
4521 func TestChanOfDir(t *testing.T) {
4522 // check construction and use of type not in binary
4523 type T string
4524 crt := ChanOf(RecvDir, TypeOf(T("")))
4525 cst := ChanOf(SendDir, TypeOf(T("")))
4527 // check that type already in binary is found
4528 type T1 int
4529 checkSameType(t, Zero(ChanOf(RecvDir, TypeOf(T1(1)))).Interface(), (<-chan T1)(nil))
4530 checkSameType(t, Zero(ChanOf(SendDir, TypeOf(T1(1)))).Interface(), (chan<- T1)(nil))
4532 // check String form of ChanDir
4533 if crt.ChanDir().String() != "<-chan" {
4534 t.Errorf("chan dir: have %q, want %q", crt.ChanDir().String(), "<-chan")
4536 if cst.ChanDir().String() != "chan<-" {
4537 t.Errorf("chan dir: have %q, want %q", cst.ChanDir().String(), "chan<-")
4541 func TestChanOfGC(t *testing.T) {
4542 done := make(chan bool, 1)
4543 go func() {
4544 select {
4545 case <-done:
4546 case <-time.After(5 * time.Second):
4547 panic("deadlock in TestChanOfGC")
4551 defer func() {
4552 done <- true
4555 type T *uintptr
4556 tt := TypeOf(T(nil))
4557 ct := ChanOf(BothDir, tt)
4559 // NOTE: The garbage collector handles allocated channels specially,
4560 // so we have to save pointers to channels in x; the pointer code will
4561 // use the gc info in the newly constructed chan type.
4562 const n = 100
4563 var x []interface{}
4564 for i := 0; i < n; i++ {
4565 v := MakeChan(ct, n)
4566 for j := 0; j < n; j++ {
4567 p := new(uintptr)
4568 *p = uintptr(i*n + j)
4569 v.Send(ValueOf(p).Convert(tt))
4571 pv := New(ct)
4572 pv.Elem().Set(v)
4573 x = append(x, pv.Interface())
4575 runtime.GC()
4577 for i, xi := range x {
4578 v := ValueOf(xi).Elem()
4579 for j := 0; j < n; j++ {
4580 pv, _ := v.Recv()
4581 k := pv.Elem().Interface()
4582 if k != uintptr(i*n+j) {
4583 t.Errorf("lost x[%d][%d] = %d, want %d", i, j, k, i*n+j)
4589 func TestMapOf(t *testing.T) {
4590 // check construction and use of type not in binary
4591 type K string
4592 type V float64
4594 v := MakeMap(MapOf(TypeOf(K("")), TypeOf(V(0))))
4595 runtime.GC()
4596 v.SetMapIndex(ValueOf(K("a")), ValueOf(V(1)))
4597 runtime.GC()
4599 s := fmt.Sprint(v.Interface())
4600 want := "map[a:1]"
4601 if s != want {
4602 t.Errorf("constructed map = %s, want %s", s, want)
4605 // check that type already in binary is found
4606 checkSameType(t, Zero(MapOf(TypeOf(V(0)), TypeOf(K("")))).Interface(), map[V]K(nil))
4608 // check that invalid key type panics
4609 shouldPanic(func() { MapOf(TypeOf((func())(nil)), TypeOf(false)) })
4612 func TestMapOfGCKeys(t *testing.T) {
4613 type T *uintptr
4614 tt := TypeOf(T(nil))
4615 mt := MapOf(tt, TypeOf(false))
4617 // NOTE: The garbage collector handles allocated maps specially,
4618 // so we have to save pointers to maps in x; the pointer code will
4619 // use the gc info in the newly constructed map type.
4620 const n = 100
4621 var x []interface{}
4622 for i := 0; i < n; i++ {
4623 v := MakeMap(mt)
4624 for j := 0; j < n; j++ {
4625 p := new(uintptr)
4626 *p = uintptr(i*n + j)
4627 v.SetMapIndex(ValueOf(p).Convert(tt), ValueOf(true))
4629 pv := New(mt)
4630 pv.Elem().Set(v)
4631 x = append(x, pv.Interface())
4633 runtime.GC()
4635 for i, xi := range x {
4636 v := ValueOf(xi).Elem()
4637 var out []int
4638 for _, kv := range v.MapKeys() {
4639 out = append(out, int(kv.Elem().Interface().(uintptr)))
4641 sort.Ints(out)
4642 for j, k := range out {
4643 if k != i*n+j {
4644 t.Errorf("lost x[%d][%d] = %d, want %d", i, j, k, i*n+j)
4650 func TestMapOfGCValues(t *testing.T) {
4651 type T *uintptr
4652 tt := TypeOf(T(nil))
4653 mt := MapOf(TypeOf(1), tt)
4655 // NOTE: The garbage collector handles allocated maps specially,
4656 // so we have to save pointers to maps in x; the pointer code will
4657 // use the gc info in the newly constructed map type.
4658 const n = 100
4659 var x []interface{}
4660 for i := 0; i < n; i++ {
4661 v := MakeMap(mt)
4662 for j := 0; j < n; j++ {
4663 p := new(uintptr)
4664 *p = uintptr(i*n + j)
4665 v.SetMapIndex(ValueOf(j), ValueOf(p).Convert(tt))
4667 pv := New(mt)
4668 pv.Elem().Set(v)
4669 x = append(x, pv.Interface())
4671 runtime.GC()
4673 for i, xi := range x {
4674 v := ValueOf(xi).Elem()
4675 for j := 0; j < n; j++ {
4676 k := v.MapIndex(ValueOf(j)).Elem().Interface().(uintptr)
4677 if k != uintptr(i*n+j) {
4678 t.Errorf("lost x[%d][%d] = %d, want %d", i, j, k, i*n+j)
4684 func TestTypelinksSorted(t *testing.T) {
4685 var last string
4686 for i, n := range TypeLinks() {
4687 if n < last {
4688 t.Errorf("typelinks not sorted: %q [%d] > %q [%d]", last, i-1, n, i)
4690 last = n
4694 func TestFuncOf(t *testing.T) {
4695 // check construction and use of type not in binary
4696 type K string
4697 type V float64
4699 fn := func(args []Value) []Value {
4700 if len(args) != 1 {
4701 t.Errorf("args == %v, want exactly one arg", args)
4702 } else if args[0].Type() != TypeOf(K("")) {
4703 t.Errorf("args[0] is type %v, want %v", args[0].Type(), TypeOf(K("")))
4704 } else if args[0].String() != "gopher" {
4705 t.Errorf("args[0] = %q, want %q", args[0].String(), "gopher")
4707 return []Value{ValueOf(V(3.14))}
4709 v := MakeFunc(FuncOf([]Type{TypeOf(K(""))}, []Type{TypeOf(V(0))}, false), fn)
4711 outs := v.Call([]Value{ValueOf(K("gopher"))})
4712 if len(outs) != 1 {
4713 t.Fatalf("v.Call returned %v, want exactly one result", outs)
4714 } else if outs[0].Type() != TypeOf(V(0)) {
4715 t.Fatalf("c.Call[0] is type %v, want %v", outs[0].Type(), TypeOf(V(0)))
4717 f := outs[0].Float()
4718 if f != 3.14 {
4719 t.Errorf("constructed func returned %f, want %f", f, 3.14)
4722 // check that types already in binary are found
4723 type T1 int
4724 testCases := []struct {
4725 in, out []Type
4726 variadic bool
4727 want interface{}
4729 {in: []Type{TypeOf(T1(0))}, want: (func(T1))(nil)},
4730 {in: []Type{TypeOf(int(0))}, want: (func(int))(nil)},
4731 {in: []Type{SliceOf(TypeOf(int(0)))}, variadic: true, want: (func(...int))(nil)},
4732 {in: []Type{TypeOf(int(0))}, out: []Type{TypeOf(false)}, want: (func(int) bool)(nil)},
4733 {in: []Type{TypeOf(int(0))}, out: []Type{TypeOf(false), TypeOf("")}, want: (func(int) (bool, string))(nil)},
4735 for _, tt := range testCases {
4736 checkSameType(t, Zero(FuncOf(tt.in, tt.out, tt.variadic)).Interface(), tt.want)
4739 // check that variadic requires last element be a slice.
4740 FuncOf([]Type{TypeOf(1), TypeOf(""), SliceOf(TypeOf(false))}, nil, true)
4741 shouldPanic(func() { FuncOf([]Type{TypeOf(0), TypeOf(""), TypeOf(false)}, nil, true) })
4742 shouldPanic(func() { FuncOf(nil, nil, true) })
4745 type B1 struct {
4746 X int
4747 Y int
4748 Z int
4751 func BenchmarkFieldByName1(b *testing.B) {
4752 t := TypeOf(B1{})
4753 for i := 0; i < b.N; i++ {
4754 t.FieldByName("Z")
4758 func BenchmarkFieldByName2(b *testing.B) {
4759 t := TypeOf(S3{})
4760 for i := 0; i < b.N; i++ {
4761 t.FieldByName("B")
4765 type R0 struct {
4772 type R1 struct {
4779 type R2 R1
4780 type R3 R1
4781 type R4 R1
4783 type R5 struct {
4785 *R10
4786 *R11
4787 *R12
4790 type R6 R5
4791 type R7 R5
4792 type R8 R5
4794 type R9 struct {
4795 *R13
4796 *R14
4797 *R15
4798 *R16
4801 type R10 R9
4802 type R11 R9
4803 type R12 R9
4805 type R13 struct {
4806 *R17
4807 *R18
4808 *R19
4809 *R20
4812 type R14 R13
4813 type R15 R13
4814 type R16 R13
4816 type R17 struct {
4817 *R21
4818 *R22
4819 *R23
4820 *R24
4823 type R18 R17
4824 type R19 R17
4825 type R20 R17
4827 type R21 struct {
4828 X int
4831 type R22 R21
4832 type R23 R21
4833 type R24 R21
4835 func TestEmbed(t *testing.T) {
4836 typ := TypeOf(R0{})
4837 f, ok := typ.FieldByName("X")
4838 if ok {
4839 t.Fatalf(`FieldByName("X") should fail, returned %v`, f.Index)
4843 func BenchmarkFieldByName3(b *testing.B) {
4844 t := TypeOf(R0{})
4845 for i := 0; i < b.N; i++ {
4846 t.FieldByName("X")
4850 type S struct {
4851 i1 int64
4852 i2 int64
4855 func BenchmarkInterfaceBig(b *testing.B) {
4856 v := ValueOf(S{})
4857 for i := 0; i < b.N; i++ {
4858 v.Interface()
4860 b.StopTimer()
4863 func TestAllocsInterfaceBig(t *testing.T) {
4864 if testing.Short() {
4865 t.Skip("skipping malloc count in short mode")
4867 v := ValueOf(S{})
4868 if allocs := testing.AllocsPerRun(100, func() { v.Interface() }); allocs > 0 {
4869 t.Error("allocs:", allocs)
4873 func BenchmarkInterfaceSmall(b *testing.B) {
4874 v := ValueOf(int64(0))
4875 for i := 0; i < b.N; i++ {
4876 v.Interface()
4880 func TestAllocsInterfaceSmall(t *testing.T) {
4881 if testing.Short() {
4882 t.Skip("skipping malloc count in short mode")
4884 v := ValueOf(int64(0))
4885 if allocs := testing.AllocsPerRun(100, func() { v.Interface() }); allocs > 0 {
4886 t.Error("allocs:", allocs)
4890 // An exhaustive is a mechanism for writing exhaustive or stochastic tests.
4891 // The basic usage is:
4893 // for x.Next() {
4894 // ... code using x.Maybe() or x.Choice(n) to create test cases ...
4895 // }
4897 // Each iteration of the loop returns a different set of results, until all
4898 // possible result sets have been explored. It is okay for different code paths
4899 // to make different method call sequences on x, but there must be no
4900 // other source of non-determinism in the call sequences.
4902 // When faced with a new decision, x chooses randomly. Future explorations
4903 // of that path will choose successive values for the result. Thus, stopping
4904 // the loop after a fixed number of iterations gives somewhat stochastic
4905 // testing.
4907 // Example:
4909 // for x.Next() {
4910 // v := make([]bool, x.Choose(4))
4911 // for i := range v {
4912 // v[i] = x.Maybe()
4913 // }
4914 // fmt.Println(v)
4915 // }
4917 // prints (in some order):
4919 // []
4920 // [false]
4921 // [true]
4922 // [false false]
4923 // [false true]
4924 // ...
4925 // [true true]
4926 // [false false false]
4927 // ...
4928 // [true true true]
4929 // [false false false false]
4930 // ...
4931 // [true true true true]
4933 type exhaustive struct {
4934 r *rand.Rand
4935 pos int
4936 last []choice
4939 type choice struct {
4940 off int
4941 n int
4942 max int
4945 func (x *exhaustive) Next() bool {
4946 if x.r == nil {
4947 x.r = rand.New(rand.NewSource(time.Now().UnixNano()))
4949 x.pos = 0
4950 if x.last == nil {
4951 x.last = []choice{}
4952 return true
4954 for i := len(x.last) - 1; i >= 0; i-- {
4955 c := &x.last[i]
4956 if c.n+1 < c.max {
4957 c.n++
4958 x.last = x.last[:i+1]
4959 return true
4962 return false
4965 func (x *exhaustive) Choose(max int) int {
4966 if x.pos >= len(x.last) {
4967 x.last = append(x.last, choice{x.r.Intn(max), 0, max})
4969 c := &x.last[x.pos]
4970 x.pos++
4971 if c.max != max {
4972 panic("inconsistent use of exhaustive tester")
4974 return (c.n + c.off) % max
4977 func (x *exhaustive) Maybe() bool {
4978 return x.Choose(2) == 1
4981 func GCFunc(args []Value) []Value {
4982 runtime.GC()
4983 return []Value{}
4986 func TestReflectFuncTraceback(t *testing.T) {
4987 f := MakeFunc(TypeOf(func() {}), GCFunc)
4988 f.Call([]Value{})
4991 func TestReflectMethodTraceback(t *testing.T) {
4992 p := Point{3, 4}
4993 m := ValueOf(p).MethodByName("GCMethod")
4994 i := ValueOf(m.Interface()).Call([]Value{ValueOf(5)})[0].Int()
4995 if i != 8 {
4996 t.Errorf("Call returned %d; want 8", i)
5000 func TestBigZero(t *testing.T) {
5001 const size = 1 << 10
5002 var v [size]byte
5003 z := Zero(ValueOf(v).Type()).Interface().([size]byte)
5004 for i := 0; i < size; i++ {
5005 if z[i] != 0 {
5006 t.Fatalf("Zero object not all zero, index %d", i)
5011 func TestFieldByIndexNil(t *testing.T) {
5012 type P struct {
5013 F int
5015 type T struct {
5018 v := ValueOf(T{})
5020 v.FieldByName("P") // should be fine
5022 defer func() {
5023 if err := recover(); err == nil {
5024 t.Fatalf("no error")
5025 } else if !strings.Contains(fmt.Sprint(err), "nil pointer to embedded struct") {
5026 t.Fatalf(`err=%q, wanted error containing "nil pointer to embedded struct"`, err)
5029 v.FieldByName("F") // should panic
5031 t.Fatalf("did not panic")
5034 // Given
5035 // type Outer struct {
5036 // *Inner
5037 // ...
5038 // }
5039 // the compiler generates the implementation of (*Outer).M dispatching to the embedded Inner.
5040 // The implementation is logically:
5041 // func (p *Outer) M() {
5042 // (p.Inner).M()
5043 // }
5044 // but since the only change here is the replacement of one pointer receiver with another,
5045 // the actual generated code overwrites the original receiver with the p.Inner pointer and
5046 // then jumps to the M method expecting the *Inner receiver.
5048 // During reflect.Value.Call, we create an argument frame and the associated data structures
5049 // to describe it to the garbage collector, populate the frame, call reflect.call to
5050 // run a function call using that frame, and then copy the results back out of the frame.
5051 // The reflect.call function does a memmove of the frame structure onto the
5052 // stack (to set up the inputs), runs the call, and the memmoves the stack back to
5053 // the frame structure (to preserve the outputs).
5055 // Originally reflect.call did not distinguish inputs from outputs: both memmoves
5056 // were for the full stack frame. However, in the case where the called function was
5057 // one of these wrappers, the rewritten receiver is almost certainly a different type
5058 // than the original receiver. This is not a problem on the stack, where we use the
5059 // program counter to determine the type information and understand that
5060 // during (*Outer).M the receiver is an *Outer while during (*Inner).M the receiver in the same
5061 // memory word is now an *Inner. But in the statically typed argument frame created
5062 // by reflect, the receiver is always an *Outer. Copying the modified receiver pointer
5063 // off the stack into the frame will store an *Inner there, and then if a garbage collection
5064 // happens to scan that argument frame before it is discarded, it will scan the *Inner
5065 // memory as if it were an *Outer. If the two have different memory layouts, the
5066 // collection will interpret the memory incorrectly.
5068 // One such possible incorrect interpretation is to treat two arbitrary memory words
5069 // (Inner.P1 and Inner.P2 below) as an interface (Outer.R below). Because interpreting
5070 // an interface requires dereferencing the itab word, the misinterpretation will try to
5071 // deference Inner.P1, causing a crash during garbage collection.
5073 // This came up in a real program in issue 7725.
5075 type Outer struct {
5076 *Inner
5077 R io.Reader
5080 type Inner struct {
5081 X *Outer
5082 P1 uintptr
5083 P2 uintptr
5086 func (pi *Inner) M() {
5087 // Clear references to pi so that the only way the
5088 // garbage collection will find the pointer is in the
5089 // argument frame, typed as a *Outer.
5090 pi.X.Inner = nil
5092 // Set up an interface value that will cause a crash.
5093 // P1 = 1 is a non-zero, so the interface looks non-nil.
5094 // P2 = pi ensures that the data word points into the
5095 // allocated heap; if not the collection skips the interface
5096 // value as irrelevant, without dereferencing P1.
5097 pi.P1 = 1
5098 pi.P2 = uintptr(unsafe.Pointer(pi))
5101 func TestCallMethodJump(t *testing.T) {
5102 // In reflect.Value.Call, trigger a garbage collection after reflect.call
5103 // returns but before the args frame has been discarded.
5104 // This is a little clumsy but makes the failure repeatable.
5105 *CallGC = true
5107 p := &Outer{Inner: new(Inner)}
5108 p.Inner.X = p
5109 ValueOf(p).Method(0).Call(nil)
5111 // Stop garbage collecting during reflect.call.
5112 *CallGC = false
5115 func TestMakeFuncStackCopy(t *testing.T) {
5116 target := func(in []Value) []Value {
5117 runtime.GC()
5118 useStack(16)
5119 return []Value{ValueOf(9)}
5122 var concrete func(*int, int) int
5123 fn := MakeFunc(ValueOf(concrete).Type(), target)
5124 ValueOf(&concrete).Elem().Set(fn)
5125 x := concrete(nil, 7)
5126 if x != 9 {
5127 t.Errorf("have %#q want 9", x)
5131 // use about n KB of stack
5132 func useStack(n int) {
5133 if n == 0 {
5134 return
5136 var b [1024]byte // makes frame about 1KB
5137 useStack(n - 1 + int(b[99]))
5140 type Impl struct{}
5142 func (Impl) F() {}
5144 func TestValueString(t *testing.T) {
5145 rv := ValueOf(Impl{})
5146 if rv.String() != "<reflect_test.Impl Value>" {
5147 t.Errorf("ValueOf(Impl{}).String() = %q, want %q", rv.String(), "<reflect_test.Impl Value>")
5150 method := rv.Method(0)
5151 if method.String() != "<func() Value>" {
5152 t.Errorf("ValueOf(Impl{}).Method(0).String() = %q, want %q", method.String(), "<func() Value>")
5156 func TestInvalid(t *testing.T) {
5157 // Used to have inconsistency between IsValid() and Kind() != Invalid.
5158 type T struct{ v interface{} }
5160 v := ValueOf(T{}).Field(0)
5161 if v.IsValid() != true || v.Kind() != Interface {
5162 t.Errorf("field: IsValid=%v, Kind=%v, want true, Interface", v.IsValid(), v.Kind())
5164 v = v.Elem()
5165 if v.IsValid() != false || v.Kind() != Invalid {
5166 t.Errorf("field elem: IsValid=%v, Kind=%v, want false, Invalid", v.IsValid(), v.Kind())
5170 // Issue 8917.
5171 func TestLargeGCProg(t *testing.T) {
5172 fv := ValueOf(func([256]*byte) {})
5173 fv.Call([]Value{ValueOf([256]*byte{})})
5176 func fieldIndexRecover(t Type, i int) (recovered interface{}) {
5177 defer func() {
5178 recovered = recover()
5181 t.Field(i)
5182 return
5185 // Issue 15046.
5186 func TestTypeFieldOutOfRangePanic(t *testing.T) {
5187 typ := TypeOf(struct{ X int }{10})
5188 testIndices := [...]struct {
5189 i int
5190 mustPanic bool
5192 0: {-2, true},
5193 1: {0, false},
5194 2: {1, true},
5195 3: {1 << 10, true},
5197 for i, tt := range testIndices {
5198 recoveredErr := fieldIndexRecover(typ, tt.i)
5199 if tt.mustPanic {
5200 if recoveredErr == nil {
5201 t.Errorf("#%d: fieldIndex %d expected to panic", i, tt.i)
5203 } else {
5204 if recoveredErr != nil {
5205 t.Errorf("#%d: got err=%v, expected no panic", i, recoveredErr)
5211 // Issue 9179.
5212 func TestCallGC(t *testing.T) {
5213 f := func(a, b, c, d, e string) {
5215 g := func(in []Value) []Value {
5216 runtime.GC()
5217 return nil
5219 typ := ValueOf(f).Type()
5220 f2 := MakeFunc(typ, g).Interface().(func(string, string, string, string, string))
5221 f2("four", "five5", "six666", "seven77", "eight888")
5224 type funcLayoutTest struct {
5225 rcvr, t Type
5226 size, argsize, retOffset uintptr
5227 stack []byte // pointer bitmap: 1 is pointer, 0 is scalar (or uninitialized)
5228 gc []byte
5231 var funcLayoutTests []funcLayoutTest
5233 func init() {
5234 var argAlign uintptr = PtrSize
5235 if runtime.GOARCH == "amd64p32" {
5236 argAlign = 2 * PtrSize
5238 roundup := func(x uintptr, a uintptr) uintptr {
5239 return (x + a - 1) / a * a
5242 funcLayoutTests = append(funcLayoutTests,
5243 funcLayoutTest{
5244 nil,
5245 ValueOf(func(a, b string) string { return "" }).Type(),
5246 6 * PtrSize,
5247 4 * PtrSize,
5248 4 * PtrSize,
5249 []byte{1, 0, 1},
5250 []byte{1, 0, 1, 0, 1},
5253 var r []byte
5254 if PtrSize == 4 {
5255 r = []byte{0, 0, 0, 1}
5256 } else {
5257 r = []byte{0, 0, 1}
5259 funcLayoutTests = append(funcLayoutTests,
5260 funcLayoutTest{
5261 nil,
5262 ValueOf(func(a, b, c uint32, p *byte, d uint16) {}).Type(),
5263 roundup(roundup(3*4, PtrSize)+PtrSize+2, argAlign),
5264 roundup(3*4, PtrSize) + PtrSize + 2,
5265 roundup(roundup(3*4, PtrSize)+PtrSize+2, argAlign),
5270 funcLayoutTests = append(funcLayoutTests,
5271 funcLayoutTest{
5272 nil,
5273 ValueOf(func(a map[int]int, b uintptr, c interface{}) {}).Type(),
5274 4 * PtrSize,
5275 4 * PtrSize,
5276 4 * PtrSize,
5277 []byte{1, 0, 1, 1},
5278 []byte{1, 0, 1, 1},
5281 type S struct {
5282 a, b uintptr
5283 c, d *byte
5285 funcLayoutTests = append(funcLayoutTests,
5286 funcLayoutTest{
5287 nil,
5288 ValueOf(func(a S) {}).Type(),
5289 4 * PtrSize,
5290 4 * PtrSize,
5291 4 * PtrSize,
5292 []byte{0, 0, 1, 1},
5293 []byte{0, 0, 1, 1},
5296 funcLayoutTests = append(funcLayoutTests,
5297 funcLayoutTest{
5298 ValueOf((*byte)(nil)).Type(),
5299 ValueOf(func(a uintptr, b *int) {}).Type(),
5300 roundup(3*PtrSize, argAlign),
5301 3 * PtrSize,
5302 roundup(3*PtrSize, argAlign),
5303 []byte{1, 0, 1},
5304 []byte{1, 0, 1},
5307 funcLayoutTests = append(funcLayoutTests,
5308 funcLayoutTest{
5309 nil,
5310 ValueOf(func(a uintptr) {}).Type(),
5311 roundup(PtrSize, argAlign),
5312 PtrSize,
5313 roundup(PtrSize, argAlign),
5314 []byte{},
5315 []byte{},
5318 funcLayoutTests = append(funcLayoutTests,
5319 funcLayoutTest{
5320 nil,
5321 ValueOf(func() uintptr { return 0 }).Type(),
5322 PtrSize,
5325 []byte{},
5326 []byte{},
5329 funcLayoutTests = append(funcLayoutTests,
5330 funcLayoutTest{
5331 ValueOf(uintptr(0)).Type(),
5332 ValueOf(func(a uintptr) {}).Type(),
5333 2 * PtrSize,
5334 2 * PtrSize,
5335 2 * PtrSize,
5336 []byte{1},
5337 []byte{1},
5338 // Note: this one is tricky, as the receiver is not a pointer. But we
5339 // pass the receiver by reference to the autogenerated pointer-receiver
5340 // version of the function.
5344 func TestFuncLayout(t *testing.T) {
5345 t.Skip("gccgo does not use funcLayout")
5346 for _, lt := range funcLayoutTests {
5347 typ, argsize, retOffset, stack, gc, ptrs := FuncLayout(lt.t, lt.rcvr)
5348 if typ.Size() != lt.size {
5349 t.Errorf("funcLayout(%v, %v).size=%d, want %d", lt.t, lt.rcvr, typ.Size(), lt.size)
5351 if argsize != lt.argsize {
5352 t.Errorf("funcLayout(%v, %v).argsize=%d, want %d", lt.t, lt.rcvr, argsize, lt.argsize)
5354 if retOffset != lt.retOffset {
5355 t.Errorf("funcLayout(%v, %v).retOffset=%d, want %d", lt.t, lt.rcvr, retOffset, lt.retOffset)
5357 if !bytes.Equal(stack, lt.stack) {
5358 t.Errorf("funcLayout(%v, %v).stack=%v, want %v", lt.t, lt.rcvr, stack, lt.stack)
5360 if !bytes.Equal(gc, lt.gc) {
5361 t.Errorf("funcLayout(%v, %v).gc=%v, want %v", lt.t, lt.rcvr, gc, lt.gc)
5363 if ptrs && len(stack) == 0 || !ptrs && len(stack) > 0 {
5364 t.Errorf("funcLayout(%v, %v) pointers flag=%v, want %v", lt.t, lt.rcvr, ptrs, !ptrs)
5369 func verifyGCBits(t *testing.T, typ Type, bits []byte) {
5370 heapBits := GCBits(New(typ).Interface())
5371 if !bytes.Equal(heapBits, bits) {
5372 t.Errorf("heapBits incorrect for %v\nhave %v\nwant %v", typ, heapBits, bits)
5376 func verifyGCBitsSlice(t *testing.T, typ Type, cap int, bits []byte) {
5377 // Creating a slice causes the runtime to repeat a bitmap,
5378 // which exercises a different path from making the compiler
5379 // repeat a bitmap for a small array or executing a repeat in
5380 // a GC program.
5381 val := MakeSlice(typ, 0, cap)
5382 data := NewAt(ArrayOf(cap, typ), unsafe.Pointer(val.Pointer()))
5383 heapBits := GCBits(data.Interface())
5384 // Repeat the bitmap for the slice size, trimming scalars in
5385 // the last element.
5386 bits = rep(cap, bits)
5387 for len(bits) > 2 && bits[len(bits)-1] == 0 {
5388 bits = bits[:len(bits)-1]
5390 if len(bits) == 2 && bits[0] == 0 && bits[1] == 0 {
5391 bits = bits[:0]
5393 if !bytes.Equal(heapBits, bits) {
5394 t.Errorf("heapBits incorrect for make(%v, 0, %v)\nhave %v\nwant %v", typ, cap, heapBits, bits)
5398 func TestGCBits(t *testing.T) {
5399 t.Skip("gccgo does not use gcbits yet")
5401 verifyGCBits(t, TypeOf((*byte)(nil)), []byte{1})
5403 // Building blocks for types seen by the compiler (like [2]Xscalar).
5404 // The compiler will create the type structures for the derived types,
5405 // including their GC metadata.
5406 type Xscalar struct{ x uintptr }
5407 type Xptr struct{ x *byte }
5408 type Xptrscalar struct {
5409 *byte
5410 uintptr
5412 type Xscalarptr struct {
5413 uintptr
5414 *byte
5416 type Xbigptrscalar struct {
5417 _ [100]*byte
5418 _ [100]uintptr
5421 var Tscalar, Tint64, Tptr, Tscalarptr, Tptrscalar, Tbigptrscalar Type
5423 // Building blocks for types constructed by reflect.
5424 // This code is in a separate block so that code below
5425 // cannot accidentally refer to these.
5426 // The compiler must NOT see types derived from these
5427 // (for example, [2]Scalar must NOT appear in the program),
5428 // or else reflect will use it instead of having to construct one.
5429 // The goal is to test the construction.
5430 type Scalar struct{ x uintptr }
5431 type Ptr struct{ x *byte }
5432 type Ptrscalar struct {
5433 *byte
5434 uintptr
5436 type Scalarptr struct {
5437 uintptr
5438 *byte
5440 type Bigptrscalar struct {
5441 _ [100]*byte
5442 _ [100]uintptr
5444 type Int64 int64
5445 Tscalar = TypeOf(Scalar{})
5446 Tint64 = TypeOf(Int64(0))
5447 Tptr = TypeOf(Ptr{})
5448 Tscalarptr = TypeOf(Scalarptr{})
5449 Tptrscalar = TypeOf(Ptrscalar{})
5450 Tbigptrscalar = TypeOf(Bigptrscalar{})
5453 empty := []byte{}
5455 verifyGCBits(t, TypeOf(Xscalar{}), empty)
5456 verifyGCBits(t, Tscalar, empty)
5457 verifyGCBits(t, TypeOf(Xptr{}), lit(1))
5458 verifyGCBits(t, Tptr, lit(1))
5459 verifyGCBits(t, TypeOf(Xscalarptr{}), lit(0, 1))
5460 verifyGCBits(t, Tscalarptr, lit(0, 1))
5461 verifyGCBits(t, TypeOf(Xptrscalar{}), lit(1))
5462 verifyGCBits(t, Tptrscalar, lit(1))
5464 verifyGCBits(t, TypeOf([0]Xptr{}), empty)
5465 verifyGCBits(t, ArrayOf(0, Tptr), empty)
5466 verifyGCBits(t, TypeOf([1]Xptrscalar{}), lit(1))
5467 verifyGCBits(t, ArrayOf(1, Tptrscalar), lit(1))
5468 verifyGCBits(t, TypeOf([2]Xscalar{}), empty)
5469 verifyGCBits(t, ArrayOf(2, Tscalar), empty)
5470 verifyGCBits(t, TypeOf([10000]Xscalar{}), empty)
5471 verifyGCBits(t, ArrayOf(10000, Tscalar), empty)
5472 verifyGCBits(t, TypeOf([2]Xptr{}), lit(1, 1))
5473 verifyGCBits(t, ArrayOf(2, Tptr), lit(1, 1))
5474 verifyGCBits(t, TypeOf([10000]Xptr{}), rep(10000, lit(1)))
5475 verifyGCBits(t, ArrayOf(10000, Tptr), rep(10000, lit(1)))
5476 verifyGCBits(t, TypeOf([2]Xscalarptr{}), lit(0, 1, 0, 1))
5477 verifyGCBits(t, ArrayOf(2, Tscalarptr), lit(0, 1, 0, 1))
5478 verifyGCBits(t, TypeOf([10000]Xscalarptr{}), rep(10000, lit(0, 1)))
5479 verifyGCBits(t, ArrayOf(10000, Tscalarptr), rep(10000, lit(0, 1)))
5480 verifyGCBits(t, TypeOf([2]Xptrscalar{}), lit(1, 0, 1))
5481 verifyGCBits(t, ArrayOf(2, Tptrscalar), lit(1, 0, 1))
5482 verifyGCBits(t, TypeOf([10000]Xptrscalar{}), rep(10000, lit(1, 0)))
5483 verifyGCBits(t, ArrayOf(10000, Tptrscalar), rep(10000, lit(1, 0)))
5484 verifyGCBits(t, TypeOf([1][10000]Xptrscalar{}), rep(10000, lit(1, 0)))
5485 verifyGCBits(t, ArrayOf(1, ArrayOf(10000, Tptrscalar)), rep(10000, lit(1, 0)))
5486 verifyGCBits(t, TypeOf([2][10000]Xptrscalar{}), rep(2*10000, lit(1, 0)))
5487 verifyGCBits(t, ArrayOf(2, ArrayOf(10000, Tptrscalar)), rep(2*10000, lit(1, 0)))
5488 verifyGCBits(t, TypeOf([4]Xbigptrscalar{}), join(rep(3, join(rep(100, lit(1)), rep(100, lit(0)))), rep(100, lit(1))))
5489 verifyGCBits(t, ArrayOf(4, Tbigptrscalar), join(rep(3, join(rep(100, lit(1)), rep(100, lit(0)))), rep(100, lit(1))))
5491 verifyGCBitsSlice(t, TypeOf([]Xptr{}), 0, empty)
5492 verifyGCBitsSlice(t, SliceOf(Tptr), 0, empty)
5493 verifyGCBitsSlice(t, TypeOf([]Xptrscalar{}), 1, lit(1))
5494 verifyGCBitsSlice(t, SliceOf(Tptrscalar), 1, lit(1))
5495 verifyGCBitsSlice(t, TypeOf([]Xscalar{}), 2, lit(0))
5496 verifyGCBitsSlice(t, SliceOf(Tscalar), 2, lit(0))
5497 verifyGCBitsSlice(t, TypeOf([]Xscalar{}), 10000, lit(0))
5498 verifyGCBitsSlice(t, SliceOf(Tscalar), 10000, lit(0))
5499 verifyGCBitsSlice(t, TypeOf([]Xptr{}), 2, lit(1))
5500 verifyGCBitsSlice(t, SliceOf(Tptr), 2, lit(1))
5501 verifyGCBitsSlice(t, TypeOf([]Xptr{}), 10000, lit(1))
5502 verifyGCBitsSlice(t, SliceOf(Tptr), 10000, lit(1))
5503 verifyGCBitsSlice(t, TypeOf([]Xscalarptr{}), 2, lit(0, 1))
5504 verifyGCBitsSlice(t, SliceOf(Tscalarptr), 2, lit(0, 1))
5505 verifyGCBitsSlice(t, TypeOf([]Xscalarptr{}), 10000, lit(0, 1))
5506 verifyGCBitsSlice(t, SliceOf(Tscalarptr), 10000, lit(0, 1))
5507 verifyGCBitsSlice(t, TypeOf([]Xptrscalar{}), 2, lit(1, 0))
5508 verifyGCBitsSlice(t, SliceOf(Tptrscalar), 2, lit(1, 0))
5509 verifyGCBitsSlice(t, TypeOf([]Xptrscalar{}), 10000, lit(1, 0))
5510 verifyGCBitsSlice(t, SliceOf(Tptrscalar), 10000, lit(1, 0))
5511 verifyGCBitsSlice(t, TypeOf([][10000]Xptrscalar{}), 1, rep(10000, lit(1, 0)))
5512 verifyGCBitsSlice(t, SliceOf(ArrayOf(10000, Tptrscalar)), 1, rep(10000, lit(1, 0)))
5513 verifyGCBitsSlice(t, TypeOf([][10000]Xptrscalar{}), 2, rep(10000, lit(1, 0)))
5514 verifyGCBitsSlice(t, SliceOf(ArrayOf(10000, Tptrscalar)), 2, rep(10000, lit(1, 0)))
5515 verifyGCBitsSlice(t, TypeOf([]Xbigptrscalar{}), 4, join(rep(100, lit(1)), rep(100, lit(0))))
5516 verifyGCBitsSlice(t, SliceOf(Tbigptrscalar), 4, join(rep(100, lit(1)), rep(100, lit(0))))
5518 verifyGCBits(t, TypeOf((chan [100]Xscalar)(nil)), lit(1))
5519 verifyGCBits(t, ChanOf(BothDir, ArrayOf(100, Tscalar)), lit(1))
5521 verifyGCBits(t, TypeOf((func([10000]Xscalarptr))(nil)), lit(1))
5522 verifyGCBits(t, FuncOf([]Type{ArrayOf(10000, Tscalarptr)}, nil, false), lit(1))
5524 verifyGCBits(t, TypeOf((map[[10000]Xscalarptr]Xscalar)(nil)), lit(1))
5525 verifyGCBits(t, MapOf(ArrayOf(10000, Tscalarptr), Tscalar), lit(1))
5527 verifyGCBits(t, TypeOf((*[10000]Xscalar)(nil)), lit(1))
5528 verifyGCBits(t, PtrTo(ArrayOf(10000, Tscalar)), lit(1))
5530 verifyGCBits(t, TypeOf(([][10000]Xscalar)(nil)), lit(1))
5531 verifyGCBits(t, SliceOf(ArrayOf(10000, Tscalar)), lit(1))
5533 hdr := make([]byte, 8/PtrSize)
5535 verifyMapBucket := func(t *testing.T, k, e Type, m interface{}, want []byte) {
5536 verifyGCBits(t, MapBucketOf(k, e), want)
5537 verifyGCBits(t, CachedBucketOf(TypeOf(m)), want)
5539 verifyMapBucket(t,
5540 Tscalar, Tptr,
5541 map[Xscalar]Xptr(nil),
5542 join(hdr, rep(8, lit(0)), rep(8, lit(1)), lit(1)))
5543 verifyMapBucket(t,
5544 Tscalarptr, Tptr,
5545 map[Xscalarptr]Xptr(nil),
5546 join(hdr, rep(8, lit(0, 1)), rep(8, lit(1)), lit(1)))
5547 verifyMapBucket(t, Tint64, Tptr,
5548 map[int64]Xptr(nil),
5549 join(hdr, rep(8, rep(8/PtrSize, lit(0))), rep(8, lit(1)), naclpad(), lit(1)))
5550 verifyMapBucket(t,
5551 Tscalar, Tscalar,
5552 map[Xscalar]Xscalar(nil),
5553 empty)
5554 verifyMapBucket(t,
5555 ArrayOf(2, Tscalarptr), ArrayOf(3, Tptrscalar),
5556 map[[2]Xscalarptr][3]Xptrscalar(nil),
5557 join(hdr, rep(8*2, lit(0, 1)), rep(8*3, lit(1, 0)), lit(1)))
5558 verifyMapBucket(t,
5559 ArrayOf(64/PtrSize, Tscalarptr), ArrayOf(64/PtrSize, Tptrscalar),
5560 map[[64 / PtrSize]Xscalarptr][64 / PtrSize]Xptrscalar(nil),
5561 join(hdr, rep(8*64/PtrSize, lit(0, 1)), rep(8*64/PtrSize, lit(1, 0)), lit(1)))
5562 verifyMapBucket(t,
5563 ArrayOf(64/PtrSize+1, Tscalarptr), ArrayOf(64/PtrSize, Tptrscalar),
5564 map[[64/PtrSize + 1]Xscalarptr][64 / PtrSize]Xptrscalar(nil),
5565 join(hdr, rep(8, lit(1)), rep(8*64/PtrSize, lit(1, 0)), lit(1)))
5566 verifyMapBucket(t,
5567 ArrayOf(64/PtrSize, Tscalarptr), ArrayOf(64/PtrSize+1, Tptrscalar),
5568 map[[64 / PtrSize]Xscalarptr][64/PtrSize + 1]Xptrscalar(nil),
5569 join(hdr, rep(8*64/PtrSize, lit(0, 1)), rep(8, lit(1)), lit(1)))
5570 verifyMapBucket(t,
5571 ArrayOf(64/PtrSize+1, Tscalarptr), ArrayOf(64/PtrSize+1, Tptrscalar),
5572 map[[64/PtrSize + 1]Xscalarptr][64/PtrSize + 1]Xptrscalar(nil),
5573 join(hdr, rep(8, lit(1)), rep(8, lit(1)), lit(1)))
5576 func naclpad() []byte {
5577 if runtime.GOARCH == "amd64p32" {
5578 return lit(0)
5580 return nil
5583 func rep(n int, b []byte) []byte { return bytes.Repeat(b, n) }
5584 func join(b ...[]byte) []byte { return bytes.Join(b, nil) }
5585 func lit(x ...byte) []byte { return x }
5587 func TestTypeOfTypeOf(t *testing.T) {
5588 // Check that all the type constructors return concrete *rtype implementations.
5589 // It's difficult to test directly because the reflect package is only at arm's length.
5590 // The easiest thing to do is just call a function that crashes if it doesn't get an *rtype.
5591 check := func(name string, typ Type) {
5592 if underlying := TypeOf(typ).String(); underlying != "*reflect.rtype" {
5593 t.Errorf("%v returned %v, not *reflect.rtype", name, underlying)
5597 type T struct{ int }
5598 check("TypeOf", TypeOf(T{}))
5600 check("ArrayOf", ArrayOf(10, TypeOf(T{})))
5601 check("ChanOf", ChanOf(BothDir, TypeOf(T{})))
5602 check("FuncOf", FuncOf([]Type{TypeOf(T{})}, nil, false))
5603 check("MapOf", MapOf(TypeOf(T{}), TypeOf(T{})))
5604 check("PtrTo", PtrTo(TypeOf(T{})))
5605 check("SliceOf", SliceOf(TypeOf(T{})))
5608 type XM struct{}
5610 func (*XM) String() string { return "" }
5612 func TestPtrToMethods(t *testing.T) {
5613 var y struct{ XM }
5614 yp := New(TypeOf(y)).Interface()
5615 _, ok := yp.(fmt.Stringer)
5616 if !ok {
5617 t.Fatal("does not implement Stringer, but should")
5621 func TestMapAlloc(t *testing.T) {
5622 if runtime.Compiler == "gccgo" {
5623 t.Skip("skipping on gccgo until we have escape analysis")
5625 m := ValueOf(make(map[int]int, 10))
5626 k := ValueOf(5)
5627 v := ValueOf(7)
5628 allocs := testing.AllocsPerRun(100, func() {
5629 m.SetMapIndex(k, v)
5631 if allocs > 0.5 {
5632 t.Errorf("allocs per map assignment: want 0 got %f", allocs)
5636 func TestChanAlloc(t *testing.T) {
5637 if runtime.Compiler == "gccgo" {
5638 t.Skip("skipping on gccgo until we have escape analysis")
5640 // Note: for a chan int, the return Value must be allocated, so we
5641 // use a chan *int instead.
5642 c := ValueOf(make(chan *int, 1))
5643 v := ValueOf(new(int))
5644 allocs := testing.AllocsPerRun(100, func() {
5645 c.Send(v)
5646 _, _ = c.Recv()
5648 if allocs < 0.5 || allocs > 1.5 {
5649 t.Errorf("allocs per chan send/recv: want 1 got %f", allocs)
5651 // Note: there is one allocation in reflect.recv which seems to be
5652 // a limitation of escape analysis. If that is ever fixed the
5653 // allocs < 0.5 condition will trigger and this test should be fixed.
5656 type TheNameOfThisTypeIsExactly255BytesLongSoWhenTheCompilerPrependsTheReflectTestPackageNameAndExtraStarTheLinkerRuntimeAndReflectPackagesWillHaveToCorrectlyDecodeTheSecondLengthByte0123456789_0123456789_0123456789_0123456789_0123456789_012345678 int
5658 type nameTest struct {
5659 v interface{}
5660 want string
5663 var nameTests = []nameTest{
5664 {(*int32)(nil), "int32"},
5665 {(*D1)(nil), "D1"},
5666 {(*[]D1)(nil), ""},
5667 {(*chan D1)(nil), ""},
5668 {(*func() D1)(nil), ""},
5669 {(*<-chan D1)(nil), ""},
5670 {(*chan<- D1)(nil), ""},
5671 {(*interface{})(nil), ""},
5672 {(*interface {
5674 })(nil), ""},
5675 {(*TheNameOfThisTypeIsExactly255BytesLongSoWhenTheCompilerPrependsTheReflectTestPackageNameAndExtraStarTheLinkerRuntimeAndReflectPackagesWillHaveToCorrectlyDecodeTheSecondLengthByte0123456789_0123456789_0123456789_0123456789_0123456789_012345678)(nil), "TheNameOfThisTypeIsExactly255BytesLongSoWhenTheCompilerPrependsTheReflectTestPackageNameAndExtraStarTheLinkerRuntimeAndReflectPackagesWillHaveToCorrectlyDecodeTheSecondLengthByte0123456789_0123456789_0123456789_0123456789_0123456789_012345678"},
5678 func TestNames(t *testing.T) {
5679 for _, test := range nameTests {
5680 typ := TypeOf(test.v).Elem()
5681 if got := typ.Name(); got != test.want {
5682 t.Errorf("%v Name()=%q, want %q", typ, got, test.want)
5688 gccgo doesn't really record whether a type is exported.
5689 It's not in the reflect API anyhow.
5691 func TestExported(t *testing.T) {
5692 type ΦExported struct{}
5693 type φUnexported struct{}
5694 type BigP *big
5695 type P int
5696 type p *P
5697 type P2 p
5698 type p3 p
5700 type exportTest struct {
5701 v interface{}
5702 want bool
5704 exportTests := []exportTest{
5705 {D1{}, true},
5706 {(*D1)(nil), true},
5707 {big{}, false},
5708 {(*big)(nil), false},
5709 {(BigP)(nil), true},
5710 {(*BigP)(nil), true},
5711 {ΦExported{}, true},
5712 {φUnexported{}, false},
5713 {P(0), true},
5714 {(p)(nil), false},
5715 {(P2)(nil), true},
5716 {(p3)(nil), false},
5719 for i, test := range exportTests {
5720 typ := TypeOf(test.v)
5721 if got := IsExported(typ); got != test.want {
5722 t.Errorf("%d: %s exported=%v, want %v", i, typ.Name(), got, test.want)
5728 type embed struct {
5729 EmbedWithUnexpMeth
5733 func TestNameBytesAreAligned(t *testing.T) {
5734 typ := TypeOf(embed{})
5735 b := FirstMethodNameBytes(typ)
5736 v := uintptr(unsafe.Pointer(b))
5737 if v%unsafe.Alignof((*byte)(nil)) != 0 {
5738 t.Errorf("reflect.name.bytes pointer is not aligned: %x", v)
5743 func TestTypeStrings(t *testing.T) {
5744 type stringTest struct {
5745 typ Type
5746 want string
5748 stringTests := []stringTest{
5749 {TypeOf(func(int) {}), "func(int)"},
5750 {FuncOf([]Type{TypeOf(int(0))}, nil, false), "func(int)"},
5751 {TypeOf(XM{}), "reflect_test.XM"},
5752 {TypeOf(new(XM)), "*reflect_test.XM"},
5753 {TypeOf(new(XM).String), "func() string"},
5754 {TypeOf(new(XM)).Method(0).Type, "func(*reflect_test.XM) string"},
5757 for i, test := range stringTests {
5758 if got, want := test.typ.String(), test.want; got != want {
5759 t.Errorf("type %d String()=%q, want %q", i, got, want)
5765 gccgo does not have resolveReflectName.
5767 func TestOffsetLock(t *testing.T) {
5768 var wg sync.WaitGroup
5769 for i := 0; i < 4; i++ {
5770 i := i
5771 wg.Add(1)
5772 go func() {
5773 for j := 0; j < 50; j++ {
5774 ResolveReflectName(fmt.Sprintf("OffsetLockName:%d:%d", i, j))
5776 wg.Done()
5779 wg.Wait()
5783 func BenchmarkNew(b *testing.B) {
5784 v := TypeOf(XM{})
5785 for i := 0; i < b.N; i++ {
5786 New(v)